opensourceui
GitHubTwitter/X
  1. Home
  2. Components
  3. Calender
  4. Ios Calender
Back to Calender

Components / Calender

Ios Calender

Free Calender React component — IosCalenderWidget. MIT licensed, copy-paste ready for Next.js and Tailwind CSS.

Today's date in the classic iOS calendar tile — red weekday, big day number, month underneath. Updates live, no refresh needed.

Preview

Setup

How to use

Free for personal and commercial use. No UI attribution required. Include the MIT copyright notice when copying component source into your project. Read the MIT license.

  1. 1

    Run in your terminal:

    $npm install clsx tailwind-merge lucide-react
  2. 2

    Copy lib/cn.ts below. Skip if you already have cn().

  3. 3

    Copy the code below and create components/calender/ios-calender-widget.tsx in your project.

  4. 4

    Import and render:

    Example

    import { IosCalenderWidget } from "@/components/calender/ios-calender-widget";

    <IosCalenderWidget />

lib/cn.ts

1
2
3
4
5
6
import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
 
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}

components/calender/ios-calender-widget.tsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
"use client";
 
import {
forwardRef,
useEffect,
useState,
type ComponentPropsWithoutRef,
} from "react";
 
import { cn } from "@/lib/cn";
 
const IOS_RED = "#FF3B30";
const IOS_LABEL = "#8E8E93";
 
export type IosCalenderWidgetProps = Readonly<ComponentPropsWithoutRef<"div">>;
 
// iOS-style calendar tile: weekday on top, day + month at the bottom.
export const IosCalenderWidget = forwardRef<
HTMLDivElement,
IosCalenderWidgetProps
>(({ className, ...props }, ref) => {
// Start as null so the first paint matches SSR; date only changes once per minute.
const [now, setNow] = useState<Date | null>(null);
 
useEffect(() => {
const update = () => setNow(new Date());
update();
const timer = globalThis.setInterval(update, 60_000);
return () => globalThis.clearInterval(timer);
}, []);
 
const weekday = now
? now.toLocaleDateString("en-US", { weekday: "short" }).toUpperCase()
: "";
const day = now ? now.getDate() : 0;
const month = now ? now.toLocaleDateString("en-US", { month: "long" }) : "";
 
return (
<div
ref={ref}
data-slot="ios-calender-widget"
className={cn(
"flex h-44 w-44 flex-col overflow-hidden rounded-[22px] border border-neutral-100 bg-white px-4 pt-4 pb-3.5 font-sans shadow-lg shadow-black/5 select-none",
className,
)}
{...props}
>
{now ? (
<div className="flex h-full flex-col opacity-100 starting:opacity-0 transition-opacity duration-500 ease-out">
<p
className="text-[13px] leading-none font-semibold tracking-[-0.02em] transition-colors duration-300"
style={{ color: IOS_RED }}
>
{weekday}
</p>
 
<div className="mt-auto flex items-baseline gap-1.5">
<p
key={day}
className="text-7xl leading-none font-medium tracking-tighter text-black tabular-nums opacity-100 starting:opacity-0 starting:translate-y-1 transition-all duration-500 ease-[cubic-bezier(0.25,0.46,0.45,0.94)]"
>
{day}
</p>
<p
className="pb-1 text-[17px] leading-none font-normal tracking-[-0.01em]"
style={{ color: IOS_LABEL }}
>
{month}
</p>
</div>
</div>
) : (
<div className="flex h-full flex-col pt-0.5">
<div className="h-3 w-9 rounded bg-neutral-100" aria-hidden />
<div className="mt-auto flex items-baseline gap-1.5">
<div className="h-12 w-10 rounded bg-neutral-100" aria-hidden />
<div className="h-4 w-14 rounded bg-neutral-100" aria-hidden />
</div>
</div>
)}
</div>
);
});
 
IosCalenderWidget.displayName = "IosCalenderWidget";
PreviousNext

On this

page

Jump to a section on this page.

  • lib/cn.ts
  • components/calender/ios-calender-widget.tsx

Sponsor spot · demo preview

Logo

Your brand name

Your tagline or category

A short pitch about your product or service goes here. This is a preview of how sponsor cards will look in this sidebar.

Your call to action

This slot is available. Sponsor Opensource UI and reach developers browsing components every day.