@gridui/calendar 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/calendar/style.ts", "../src/calendar/calendar.tsx", "../src/calendar-event/style.ts", "../src/calendar-event/calendar-event.tsx", "../src/shared/date.ts", "../src/shared/events.ts", "../src/calendar-agenda-view/calendar-agenda-view.tsx", "../src/shared/time-grid.tsx", "../src/calendar-day-view/calendar-day-view.tsx", "../src/calendar-month-view/calendar-month-view.tsx", "../src/calendar-toolbar/calendar-toolbar.tsx", "../src/calendar-week-view/calendar-week-view.tsx", "../src/use-calendar/use-calendar.ts"],
4
+ "sourcesContent": ["/**\n * @author WMXPY\n * @package Calendar\n * @namespace Calendar\n * @description Style\n */\n\nimport { cva } from \"class-variance-authority\";\n\nexport const calendarStyles = cva(\"gridui-calendar min-w-0 bg-background text-foreground\", {\n variants: {\n frame: {\n none: \"\",\n outline: \"border border-solid border-border\",\n },\n },\n defaultVariants: { frame: \"none\" },\n});\n", "/**\n * @author WMXPY\n * @package Calendar\n * @namespace Calendar\n * @description Calendar\n */\n\nimport { calendarStyles } from \"./style\";\nimport { cn } from \"@gridui/style-utils\";\nimport type { ComponentPropsWithRef, FC } from \"react\";\n\nexport type CalendarProps = ComponentPropsWithRef<\"div\"> & {\n readonly frame?: \"none\" | \"outline\";\n};\n\n/** Optional surface. Views and toolbar have no dependency on this wrapper. */\nexport const Calendar: FC<CalendarProps> = (props: CalendarProps) => {\n const { frame, className, ...restProps } = props;\n return (<div\n {...restProps}\n className={cn(calendarStyles({ frame }), className)}\n />);\n};\n", "/**\n * @author WMXPY\n * @package Calendar\n * @namespace CalendarEvent\n * @description Style\n */\n\nimport { cva } from \"class-variance-authority\";\n\nexport const eventStyles = cva(\"gridui-calendar-event gridui-hover-surface gridui-focus-contained box-border min-w-0 w-full cursor-pointer text-left type-supporting disabled:cursor-not-allowed disabled:opacity-50\", {\n variants: {\n appearance: {\n block: \"gridui-calendar-event-block\",\n compact: \"gridui-calendar-event-compact\",\n },\n },\n defaultVariants: {\n appearance: \"block\",\n },\n});\n", "/**\n * @author WMXPY\n * @package Calendar\n * @namespace CalendarEvent\n * @description Calendar Event\n */\n\nimport type { CalendarEventColors } from \"../shared/types\";\nimport { eventStyles } from \"./style\";\nimport { cn } from \"@gridui/style-utils\";\nimport type { ComponentPropsWithRef, CSSProperties, FC } from \"react\";\n\nexport type CalendarEventProps = ComponentPropsWithRef<\"button\"> & {\n readonly colors?: CalendarEventColors | undefined;\n readonly appearance?: \"block\" | \"compact\";\n readonly selected?: boolean;\n};\n\nexport const CalendarEvent: FC<CalendarEventProps> = (props: CalendarEventProps) => {\n const { colors, appearance, selected, type = \"button\", className, style, ...restProps } = props;\n return (<button\n {...restProps}\n type={type}\n aria-pressed={selected}\n data-selected={selected || undefined}\n className={cn(eventStyles({\n appearance,\n }), className)}\n style={{\n \"--gridui-calendar-event-accent\": colors?.accent,\n \"--gridui-calendar-event-background\": colors?.background,\n \"--gridui-calendar-event-foreground\": colors?.foreground,\n ...style,\n } as CSSProperties}\n />);\n};\n", "/**\n * @author WMXPY\n * @package Calendar\n * @namespace Shared\n * @description Date\n */\n\nimport type { CalendarDate } from \"./types\";\n\nexport const parseDate = (value: CalendarDate): Date => {\n const date = new Date(`${value}T00:00:00Z`);\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(value) || !Number.isFinite(date.getTime()) || date.toISOString().slice(0, 10) !== value) {\n throw new RangeError(`Invalid calendar date: ${value}`);\n }\n return date;\n};\n\nexport const addDays = (value: CalendarDate, amount: number): CalendarDate => {\n const date = parseDate(value);\n date.setUTCDate(date.getUTCDate() + amount);\n return date.toISOString().slice(0, 10);\n};\n\nexport const addMonths = (value: CalendarDate, amount: number): CalendarDate => {\n const date = parseDate(value);\n const day = date.getUTCDate();\n date.setUTCDate(1);\n date.setUTCMonth(date.getUTCMonth() + amount);\n const last = new Date(date);\n last.setUTCMonth(last.getUTCMonth() + 1, 0);\n date.setUTCDate(Math.min(day, last.getUTCDate()));\n return date.toISOString().slice(0, 10);\n};\n\nexport const startOfWeek = (value: CalendarDate, weekStartsOn: number): CalendarDate => {\n if (!Number.isInteger(weekStartsOn) || weekStartsOn < 0 || weekStartsOn > 6) {\n throw new RangeError(\"weekStartsOn must be an integer from 0 to 6.\");\n }\n return addDays(value, -((parseDate(value).getUTCDay() - weekStartsOn + 7) % 7));\n};\n\nexport const formatDate = (value: CalendarDate, locale: string, options: Intl.DateTimeFormatOptions): string => {\n return new Intl.DateTimeFormat(locale, {\n ...options,\n timeZone: \"UTC\",\n }).format(parseDate(value));\n};\n\nexport const formatMinute = (minute: number): string => {\n return `${String(Math.floor(minute / 60)).padStart(2, \"0\")}:${String(minute % 60).padStart(2, \"0\")}`;\n};\n", "/**\n * @author WMXPY\n * @package Calendar\n * @namespace Shared\n * @description Events\n */\n\nimport { addDays, parseDate } from \"./date\";\nimport type { CalendarDate, CalendarEventData } from \"./types\";\n\nexport type EventSegment = {\n readonly event: CalendarEventData;\n readonly date: CalendarDate;\n readonly start: number;\n readonly end: number;\n readonly continuesBefore: boolean;\n readonly continuesAfter: boolean;\n};\n\nexport type PositionedEvent = EventSegment & {\n readonly column: number;\n readonly columns: number;\n};\n\nconst parseTime = (value: string, allDay: boolean): number => {\n if (allDay) {\n return parseDate(value).getTime() / 60000;\n }\n if (!/^\\d{4}-\\d{2}-\\d{2}T(?:[01]\\d|2[0-3]):[0-5]\\d$/.test(value)) {\n throw new RangeError(`Invalid calendar time: ${value}`);\n }\n return parseDate(value.slice(0, 10)).getTime() / 60000 + Number(value.slice(11, 13)) * 60 + Number(value.slice(14, 16));\n};\n\nexport const validateEvents = (events: readonly CalendarEventData[]): void => {\n const ids = new Set<string>();\n for (const event of events) {\n if (!event.id || ids.has(event.id)) {\n throw new RangeError(\"Calendar event IDs must be nonempty and unique.\");\n }\n ids.add(event.id);\n if (parseTime(event.end, event.allDay === true) <= parseTime(event.start, event.allDay === true)) {\n throw new RangeError(`Calendar event ${event.id} must end after it starts.`);\n }\n }\n};\n\nexport const segmentsForDate = (events: readonly CalendarEventData[], date: CalendarDate): EventSegment[] => {\n const start = parseDate(date).getTime() / 60000;\n const end = parseDate(addDays(date, 1)).getTime() / 60000;\n return events.flatMap((event) => {\n const from = parseTime(event.start, event.allDay === true);\n const to = parseTime(event.end, event.allDay === true);\n if (from >= end || to <= start) {\n return [];\n }\n return [\n {\n event,\n date,\n start: Math.max(from - start, 0),\n end: Math.min(to - start, 1440),\n continuesBefore: from < start,\n continuesAfter: to > end,\n },\n ];\n }).sort((a, b) => {\n return Number(b.event.allDay ?? false) - Number(a.event.allDay ?? false) || a.start - b.start || b.end - a.end || a.event.id.localeCompare(b.event.id);\n });\n};\n\n/** Partition connected overlaps, then reuse the first free column inside each group. */\nexport const positionEvents = (segments: readonly EventSegment[], start: number, end: number): PositionedEvent[] => {\n const visible = segments.filter((segment) => {\n return !segment.event.allDay && segment.start < end && segment.end > start;\n }).map((segment) => {\n return {\n ...segment,\n start: Math.max(segment.start, start),\n end: Math.min(segment.end, end),\n };\n })\n .sort((a, b) => {\n return a.start - b.start || b.end - a.end || a.event.id.localeCompare(b.event.id);\n });\n const groups: {\n end: number;\n segments: EventSegment[];\n }[] = [];\n for (const segment of visible) {\n let group = groups.at(-1);\n if (!group || segment.start >= group.end) {\n group = {\n end: segment.end,\n segments: [],\n };\n groups.push(group);\n }\n group.end = Math.max(group.end, segment.end);\n group.segments.push(segment);\n }\n return groups.flatMap((group) => {\n const ends: number[] = [];\n const positioned = group.segments.map((segment) => {\n let column = ends.findIndex((columnEnd) => {\n return columnEnd <= segment.start;\n });\n if (column < 0) {\n column = ends.length;\n }\n ends[column] = segment.end;\n return {\n ...segment,\n column,\n };\n });\n return positioned.map((segment) => {\n return {\n ...segment,\n columns: ends.length,\n };\n });\n });\n};\n", "/**\n * @author WMXPY\n * @package Calendar\n * @namespace CalendarAgendaView\n * @description Calendar Agenda View\n */\n\nimport { CalendarEvent } from \"../calendar-event/calendar-event\";\nimport { addDays, formatDate, formatMinute } from \"../shared/date\";\nimport { segmentsForDate, validateEvents } from \"../shared/events\";\nimport type { CalendarEventContext, CalendarViewOptions } from \"../shared/types\";\nimport { cn } from \"@gridui/style-utils\";\nimport type { ComponentPropsWithRef, FC, ReactNode } from \"react\";\n\nexport type CalendarAgendaViewProps = Omit<ComponentPropsWithRef<\"div\">, \"children\"> & CalendarViewOptions & {\n readonly days?: number;\n readonly empty?: ReactNode;\n readonly allDayLabel?: string;\n readonly formatTime?: (minute: number) => string;\n};\n\nexport const CalendarAgendaView: FC<CalendarAgendaViewProps> = (props: CalendarAgendaViewProps) => {\n const { date, events, locale = \"en-US\", today, days = 7, empty = \"No events\", allDayLabel = \"All day\", formatTime = formatMinute,\n selectedEventId, onEventSelect, renderEvent, getEventLabel, className, ...restProps } = props;\n validateEvents(events);\n if (!Number.isInteger(days) || days < 1 || days > 366) {\n throw new RangeError(\"CalendarAgendaView days must be an integer from 1 to 366.\");\n }\n const groups = Array.from({ length: days }, (_, index) => {\n const day = addDays(date, index);\n return {\n day,\n segments: segmentsForDate(events, day),\n };\n }).filter((group) => {\n return group.segments.length > 0;\n });\n return (<div\n {...restProps}\n className={cn(\"gridui-calendar-agenda\", className)}\n role={restProps.role ?? \"region\"}\n aria-label={restProps[\"aria-label\"] ?? formatDate(date, locale, { dateStyle: \"full\" })}\n >\n {groups.length === 0 ? empty : groups.map(({ day, segments }) => {\n return (<section\n key={day}\n className=\"gridui-calendar-agenda-day\"\n aria-label={formatDate(day, locale, { dateStyle: \"full\" })}\n >\n <h3\n className=\"m-0 type-ui\"\n aria-current={day === today ? \"date\" : undefined}\n >\n {formatDate(day, locale, {\n month: \"short\",\n day: \"numeric\",\n weekday: \"short\",\n })}\n </h3>\n <ol\n className=\"gridui-calendar-agenda-events\"\n >\n {segments.map((segment) => {\n const context: CalendarEventContext = {\n date: day,\n view: \"agenda\",\n continuesBefore: segment.continuesBefore,\n continuesAfter: segment.continuesAfter,\n };\n return (<li\n key={segment.event.id}\n >\n <CalendarEvent\n colors={segment.event.colors}\n selected={selectedEventId === segment.event.id}\n disabled={segment.event.disabled}\n className=\"gridui-calendar-agenda-event\"\n aria-label={getEventLabel?.(segment.event, context) ?? `${segment.event.title}, ${segment.event.start} \u2013 ${segment.event.end}`}\n onClick={() => {\n onEventSelect?.(segment.event, context);\n }}\n >\n {renderEvent?.(segment.event, context) ?? (<>\n <span\n className=\"type-caption tabular-nums\"\n >\n {segment.event.allDay ? allDayLabel : `${formatTime(segment.start)}\u2013${formatTime(segment.end)}`}\n </span>\n <span\n className=\"wrap-anywhere\"\n >\n {segment.event.title}\n </span>\n </>)}\n </CalendarEvent>\n </li>);\n })}\n </ol>\n </section>);\n })}\n </div>);\n};\n", "/**\n * @author WMXPY\n * @package Calendar\n * @namespace Shared\n * @description Time Grid\n */\n\nimport { CalendarEvent } from \"../calendar-event/calendar-event\";\nimport { formatDate, formatMinute } from \"./date\";\nimport { positionEvents, segmentsForDate, validateEvents } from \"./events\";\nimport type { CalendarDate, CalendarEventContext, CalendarTimeOptions } from \"./types\";\nimport { cn } from \"@gridui/style-utils\";\nimport type { ComponentPropsWithRef, CSSProperties, FC, ReactNode } from \"react\";\n\nexport type TimeColumn = {\n readonly id: string;\n readonly date: CalendarDate;\n readonly resourceId?: string;\n readonly label: ReactNode;\n readonly description?: ReactNode;\n};\n\nexport type TimeSelection = {\n readonly date: CalendarDate;\n readonly minute: number;\n readonly resourceId?: string;\n};\n\nexport type TimeGridProps = Omit<ComponentPropsWithRef<\"div\">, \"children\"> & CalendarTimeOptions & {\n readonly columns: readonly TimeColumn[];\n readonly view: \"day\" | \"week\";\n readonly onTimeSelect?: (selection: TimeSelection) => void;\n readonly getTimeLabel?: (selection: TimeSelection) => string;\n};\n\nexport const TimeGrid: FC<TimeGridProps> = (props: TimeGridProps) => {\n const { columns, view, date, events, locale = \"en-US\", today, selectedEventId, onEventSelect, renderEvent, getEventLabel,\n startHour = 8, endHour = 18, hourHeight = 56, allDayLabel = \"All day\", formatTime = formatMinute,\n onTimeSelect, getTimeLabel, className, style, ...restProps } = props;\n validateEvents(events);\n if (!columns.length || new Set(columns.map((column) => {\n return column.id;\n })).size !== columns.length) {\n throw new RangeError(\"Calendar columns must have unique IDs and cannot be empty.\");\n }\n if (!Number.isInteger(startHour) || !Number.isInteger(endHour) || startHour < 0 || endHour > 24\n || startHour >= endHour || !Number.isFinite(hourHeight) || hourHeight <= 0) {\n throw new RangeError(\"Calendar hours must form an ordered range within 0\u201324; hourHeight must be positive.\");\n }\n const hours = Array.from({ length: endHour - startHour }, (_, index) => {\n return startHour + index;\n });\n const lanes = columns.map((column) => {\n const segments = segmentsForDate(events, column.date).filter((segment) => {\n return column.resourceId === undefined || segment.event.resourceId === column.resourceId;\n });\n return {\n column,\n segments,\n };\n });\n const context = (segment: ReturnType<typeof segmentsForDate>[number]): CalendarEventContext => {\n return {\n date: segment.date,\n view,\n continuesBefore: segment.continuesBefore,\n continuesAfter: segment.continuesAfter,\n };\n };\n const label = (segment: ReturnType<typeof segmentsForDate>[number]): string => {\n return getEventLabel?.(segment.event, context(segment)) ?? `${segment.event.title}, ${segment.event.start} \u2013 ${segment.event.end}`;\n };\n return (<div\n {...restProps}\n role={restProps.role ?? \"region\"}\n aria-label={restProps[\"aria-label\"] ?? formatDate(date, locale, { dateStyle: \"full\" })}\n className={cn(\"gridui-calendar-time-grid\", className)}\n style={{\n \"--gridui-calendar-columns\": columns.length,\n \"--gridui-calendar-hour-height\": `${hourHeight}px`,\n \"--gridui-calendar-hours\": hours.length,\n ...style,\n } as CSSProperties}\n >\n <div\n className=\"gridui-calendar-time-corner\"\n />\n {columns.map((column) => {\n return (<div\n key={column.id}\n className=\"gridui-calendar-time-heading\"\n data-today={column.date === today || undefined}\n >\n <div\n className=\"type-ui\"\n >\n {column.label}\n </div>\n {column.description !== undefined && (<div\n className=\"type-caption text-muted\"\n >\n {column.description}\n </div>)}\n </div>);\n })}\n {lanes.some((lane) => {\n return lane.segments.some((segment) => {\n return segment.event.allDay;\n });\n }) && (<>\n <div\n className=\"gridui-calendar-all-day-label type-caption text-muted\"\n >\n {allDayLabel}\n </div>\n {lanes.map(({ column, segments }) => {\n return (<div\n key={column.id}\n className=\"gridui-calendar-all-day\"\n >\n {segments.filter((segment) => {\n return segment.event.allDay;\n }).map((segment) => {\n return (<CalendarEvent\n key={segment.event.id}\n colors={segment.event.colors}\n appearance=\"compact\"\n selected={selectedEventId === segment.event.id}\n disabled={segment.event.disabled}\n aria-label={label(segment)}\n onClick={() => {\n onEventSelect?.(segment.event, context(segment));\n }}\n >\n {renderEvent?.(segment.event, context(segment)) ?? segment.event.title}\n </CalendarEvent>);\n })}\n </div>);\n })}\n </>)}\n <div\n className=\"gridui-calendar-time-axis\"\n aria-hidden=\"true\"\n >\n {hours.map((hour) => {\n return (<span\n key={hour}\n className=\"type-caption text-muted tabular-nums\"\n >\n {formatTime(hour * 60)}\n </span>);\n })}\n </div>\n {lanes.map(({ column, segments }) => {\n return (<div\n key={column.id}\n className=\"gridui-calendar-time-lane\"\n >\n {onTimeSelect && hours.map((hour) => {\n const selection: TimeSelection = {\n date: column.date,\n minute: hour * 60,\n ...(column.resourceId === undefined ? {} : { resourceId: column.resourceId }),\n };\n return (<button\n key={hour}\n type=\"button\"\n className=\"gridui-calendar-time-slot gridui-focus-contained gridui-hover-surface\"\n aria-label={getTimeLabel?.(selection) ?? `${column.date} ${formatTime(hour * 60)}${column.resourceId ? `, ${column.resourceId}` : \"\"}`}\n onClick={() => {\n onTimeSelect(selection);\n }}\n />);\n })}\n {positionEvents(segments, startHour * 60, endHour * 60).map((segment) => {\n const range = (endHour - startHour) * 60;\n return (<CalendarEvent\n key={segment.event.id}\n colors={segment.event.colors}\n selected={selectedEventId === segment.event.id}\n disabled={segment.event.disabled}\n aria-label={label(segment)}\n data-event-id={segment.event.id}\n data-continues-before={segment.continuesBefore || undefined}\n data-continues-after={segment.continuesAfter || undefined}\n className=\"gridui-calendar-positioned-event\"\n style={{\n top: `${(segment.start - startHour * 60) / range * 100}%`,\n height: `calc(${(segment.end - segment.start) / range * 100}% - 2px)`,\n insetInlineStart: `calc(${segment.column / segment.columns * 100}% + 2px)`,\n width: `calc(${100 / segment.columns}% - 4px)`,\n }}\n onClick={() => {\n onEventSelect?.(segment.event, context(segment));\n }}\n >\n {renderEvent?.(segment.event, context(segment)) ?? (<>\n <span\n className=\"gridui-calendar-event-title\"\n >\n {segment.event.title}\n </span>\n <span\n className=\"gridui-calendar-event-time type-caption tabular-nums\"\n >\n {formatTime(segment.start)}\n \u2013\n {formatTime(segment.end)}\n </span>\n </>)}\n </CalendarEvent>);\n })}\n </div>);\n })}\n </div>);\n};\n", "/**\n * @author WMXPY\n * @package Calendar\n * @namespace CalendarDayView\n * @description Calendar Day View\n */\n\nimport { formatDate } from \"../shared/date\";\nimport { TimeGrid, type TimeGridProps } from \"../shared/time-grid\";\nimport type { CalendarResource } from \"../shared/types\";\nimport type { FC } from \"react\";\n\nexport type CalendarDayViewProps = Omit<TimeGridProps, \"columns\" | \"view\"> & {\n readonly resources?: readonly CalendarResource[];\n};\n\nexport const CalendarDayView: FC<CalendarDayViewProps> = (props: CalendarDayViewProps) => {\n const { resources, ...restProps } = props;\n const columns = resources?.map((resource) => {\n return {\n id: resource.id,\n resourceId: resource.id,\n date: props.date,\n label: resource.label,\n description: resource.description,\n };\n }) ?? [\n {\n id: props.date,\n date: props.date,\n label: formatDate(props.date, props.locale ?? \"en-US\", {\n weekday: \"long\",\n month: \"short\",\n day: \"numeric\",\n }),\n },\n ];\n return (<TimeGrid\n {...restProps}\n columns={columns}\n view=\"day\"\n />);\n};\n", "/**\n * @author WMXPY\n * @package Calendar\n * @namespace CalendarMonthView\n * @description Calendar Month View\n */\n\nimport { CalendarEvent } from \"../calendar-event/calendar-event\";\nimport { addDays, formatDate, parseDate, startOfWeek } from \"../shared/date\";\nimport { segmentsForDate, validateEvents } from \"../shared/events\";\nimport type { CalendarDate, CalendarEventContext, CalendarViewOptions } from \"../shared/types\";\nimport { cn } from \"@gridui/style-utils\";\nimport type { ComponentPropsWithRef, FC } from \"react\";\n\nexport type CalendarMonthViewProps = Omit<ComponentPropsWithRef<\"div\">, \"children\"> & CalendarViewOptions & {\n readonly weekStartsOn?: number;\n readonly maxEvents?: number;\n readonly onDateSelect?: (date: CalendarDate) => void;\n readonly getMoreLabel?: (count: number, date: CalendarDate) => string;\n};\n\nexport const CalendarMonthView: FC<CalendarMonthViewProps> = (props: CalendarMonthViewProps) => {\n const { date, events, locale = \"en-US\", today, weekStartsOn = 1, maxEvents = 3, selectedEventId, onDateSelect, onEventSelect, renderEvent, getEventLabel, getMoreLabel, className, ...restProps } = props;\n validateEvents(events);\n if (!Number.isInteger(maxEvents) || maxEvents < 1) {\n throw new RangeError(\"CalendarMonthView maxEvents must be a positive integer.\");\n }\n const month = date.slice(0, 7);\n parseDate(date);\n const start = startOfWeek(`${month}-01`, weekStartsOn);\n return (<div\n {...restProps}\n className={cn(\"gridui-calendar-month\", className)}\n role={restProps.role ?? \"region\"}\n aria-label={restProps[\"aria-label\"] ?? formatDate(date, locale, {\n month: \"long\",\n year: \"numeric\",\n })}\n >\n <table\n className=\"gridui-calendar-month-table\"\n >\n <thead>\n <tr>\n {Array.from({ length: 7 }, (_, index) => {\n const day = addDays(start, index);\n return (<th\n key={day}\n scope=\"col\"\n className=\"type-caption text-muted\"\n >\n {formatDate(day, locale, { weekday: \"short\" })}\n </th>);\n })}\n </tr>\n </thead>\n <tbody>\n {Array.from({ length: 6 }, (_, row) => {\n return (<tr\n key={row}\n >\n {Array.from({ length: 7 }, (_column, col) => {\n const day = addDays(start, row * 7 + col);\n const segments = segmentsForDate(events, day);\n const shown = onDateSelect ? segments.slice(0, maxEvents) : segments;\n return (<td\n key={day}\n data-outside={!day.startsWith(month) || undefined}\n >\n <button\n type=\"button\"\n className=\"gridui-calendar-day-number gridui-hover-surface gridui-focus-contained\"\n aria-label={formatDate(day, locale, { dateStyle: \"full\" })}\n aria-current={day === today ? \"date\" : undefined}\n aria-pressed={day === date}\n onClick={() => {\n onDateSelect?.(day);\n }}\n >\n {parseDate(day).getUTCDate()}\n </button>\n <div\n className=\"gridui-calendar-month-events\"\n >\n {shown.map((segment) => {\n const context: CalendarEventContext = {\n date: day,\n view: \"month\",\n continuesBefore: segment.continuesBefore,\n continuesAfter: segment.continuesAfter,\n };\n return (<CalendarEvent\n key={segment.event.id}\n appearance=\"compact\"\n colors={segment.event.colors}\n selected={selectedEventId === segment.event.id}\n disabled={segment.event.disabled}\n aria-label={getEventLabel?.(segment.event, context) ?? `${segment.event.title}, ${segment.event.start} \u2013 ${segment.event.end}`}\n onClick={() => {\n onEventSelect?.(segment.event, context);\n }}\n >\n {renderEvent?.(segment.event, context) ?? segment.event.title}\n </CalendarEvent>);\n })}\n {segments.length > shown.length && (<button\n type=\"button\"\n className=\"gridui-calendar-more gridui-hover-surface gridui-focus-contained type-caption\"\n onClick={() => {\n onDateSelect?.(day);\n }}\n >\n {getMoreLabel?.(segments.length - shown.length, day) ?? `+${segments.length - shown.length} more`}\n </button>)}\n </div>\n </td>);\n })}\n </tr>);\n })}\n </tbody>\n </table>\n </div>);\n};\n", "/**\n * @author WMXPY\n * @package Calendar\n * @namespace CalendarToolbar\n * @description Calendar Toolbar\n */\n\nimport { addDays, formatDate, startOfWeek } from \"../shared/date\";\nimport type { CalendarDate, CalendarView } from \"../shared/types\";\nimport { Button } from \"@gridui/button\";\nimport { cn } from \"@gridui/style-utils\";\nimport { ChevronLeft, ChevronRight } from \"lucide-react\";\nimport type { ComponentPropsWithRef, FC, ReactNode } from \"react\";\n\nexport type CalendarToolbarLabels = {\n readonly previous: string;\n readonly next: string;\n readonly today: string;\n readonly views: string;\n readonly day: string;\n readonly week: string;\n readonly month: string;\n readonly agenda: string;\n};\n\nexport type CalendarToolbarProps = Omit<ComponentPropsWithRef<\"div\">, \"title\"> & {\n readonly date: CalendarDate;\n readonly view: CalendarView;\n readonly onNavigate: (direction: -1 | 1) => void;\n readonly onViewChange: (view: CalendarView) => void;\n readonly onToday?: () => void;\n readonly locale?: string;\n readonly weekStartsOn?: number;\n readonly views?: readonly CalendarView[];\n readonly labels?: Partial<CalendarToolbarLabels>;\n readonly title?: ReactNode;\n};\n\nconst defaults: CalendarToolbarLabels = {\n previous: \"Previous period\",\n next: \"Next period\",\n today: \"Today\",\n views: \"Calendar views\",\n day: \"Day\",\n week: \"Week\",\n month: \"Month\",\n agenda: \"Agenda\",\n};\n\nexport const CalendarToolbar: FC<CalendarToolbarProps> = (props: CalendarToolbarProps) => {\n const { date, view, onNavigate, onViewChange, onToday, locale = \"en-US\", weekStartsOn = 1, views = [\n \"day\",\n \"week\",\n \"month\",\n \"agenda\",\n ], labels, title, children, className, ...restProps } = props;\n const text = {\n ...defaults,\n ...labels,\n };\n const start = view === \"week\" ? startOfWeek(date, weekStartsOn) : date;\n let caption = formatDate(date, locale, {\n month: \"long\",\n day: \"numeric\",\n year: \"numeric\",\n });\n if (view === \"month\") {\n caption = formatDate(date, locale, {\n month: \"long\",\n year: \"numeric\",\n });\n } else if (view === \"week\") {\n const first = formatDate(start, locale, {\n month: \"short\",\n day: \"numeric\",\n });\n const last = formatDate(addDays(start, 6), locale, {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\n caption = `${first} \u2013 ${last}`;\n }\n return (<div\n {...restProps}\n className={cn(\"gridui-calendar-toolbar flex min-w-0 flex-wrap items-center gap-gridui-8\", className)}\n >\n <div\n className=\"flex min-w-0 flex-wrap items-center gap-gridui-4\"\n >\n <Button\n variant=\"quiet\"\n layout=\"icon\"\n size=\"small\"\n aria-label={text.previous}\n onClick={() => {\n onNavigate(-1);\n }}\n >\n <ChevronLeft\n aria-hidden=\"true\"\n />\n </Button>\n <Button\n variant=\"quiet\"\n layout=\"icon\"\n size=\"small\"\n aria-label={text.next}\n onClick={() => {\n onNavigate(1);\n }}\n >\n <ChevronRight\n aria-hidden=\"true\"\n />\n </Button>\n {onToday && (<Button\n variant=\"secondary\"\n size=\"small\"\n onClick={onToday}\n >\n {text.today}\n </Button>)}\n </div>\n <div\n className=\"min-w-0 flex-1 type-ui wrap-anywhere\"\n aria-live=\"polite\"\n >\n {title ?? caption}\n </div>\n <div\n className=\"flex flex-wrap gap-gridui-4\"\n role=\"group\"\n aria-label={text.views}\n >\n {views.map((item) => {\n return (<Button\n key={item}\n size=\"small\"\n variant={item === view ? \"primary\" : \"quiet\"}\n aria-pressed={item === view}\n onClick={() => {\n onViewChange(item);\n }}\n >\n {text[item]}\n </Button>);\n })}\n </div>\n {children}\n </div>);\n};\n", "/**\n * @author WMXPY\n * @package Calendar\n * @namespace CalendarWeekView\n * @description Calendar Week View\n */\n\nimport { addDays, formatDate, startOfWeek } from \"../shared/date\";\nimport { TimeGrid, type TimeGridProps } from \"../shared/time-grid\";\nimport type { FC } from \"react\";\n\nexport type CalendarWeekViewProps = Omit<TimeGridProps, \"columns\" | \"view\"> & {\n readonly weekStartsOn?: number;\n readonly days?: number;\n};\n\nexport const CalendarWeekView: FC<CalendarWeekViewProps> = (props: CalendarWeekViewProps) => {\n const { weekStartsOn = 1, days = 7, ...restProps } = props;\n if (!Number.isInteger(days) || days < 1 || days > 7) {\n throw new RangeError(\"CalendarWeekView days must be an integer from 1 to 7.\");\n }\n const start = startOfWeek(props.date, weekStartsOn);\n const columns = Array.from({ length: days }, (_, index) => {\n const date = addDays(start, index);\n return {\n id: date,\n date,\n label: formatDate(date, props.locale ?? \"en-US\", { weekday: \"short\" }),\n description: formatDate(date, props.locale ?? \"en-US\", { day: \"numeric\" }),\n };\n });\n return (<TimeGrid\n {...restProps}\n columns={columns}\n view=\"week\"\n />);\n};\n", "/**\n * @author WMXPY\n * @package Calendar\n * @namespace UseCalendar\n * @description Use Calendar\n */\n\nimport { addDays, addMonths, parseDate } from \"../shared/date\";\nimport type { CalendarDate, CalendarView } from \"../shared/types\";\nimport { useState } from \"react\";\n\nexport type UseCalendarOptions = {\n readonly defaultDate: CalendarDate;\n readonly date?: CalendarDate;\n readonly defaultView?: CalendarView;\n readonly view?: CalendarView;\n readonly onDateChange?: (date: CalendarDate) => void;\n readonly onViewChange?: (view: CalendarView) => void;\n};\n\nexport const useCalendar = (options: UseCalendarOptions) => {\n const { defaultDate, date: controlledDate, defaultView = \"day\", view: controlledView, onDateChange, onViewChange } = options;\n parseDate(controlledDate ?? defaultDate);\n const [\n localDate,\n setLocalDate,\n ] = useState(defaultDate);\n const [\n localView,\n setLocalView,\n ] = useState(defaultView);\n const date = controlledDate ?? localDate;\n const view = controlledView ?? localView;\n const setDate = (next: CalendarDate) => {\n parseDate(next);\n if (next === date) {\n return;\n }\n if (controlledDate === undefined) {\n setLocalDate(next);\n }\n onDateChange?.(next);\n };\n const setView = (next: CalendarView) => {\n if (next === view) {\n return;\n }\n if (controlledView === undefined) {\n setLocalView(next);\n }\n onViewChange?.(next);\n };\n const navigate = (direction: -1 | 1) => {\n setDate(view === \"month\" ? addMonths(date, direction) : addDays(date, direction * (view === \"day\" ? 1 : 7)));\n };\n return {\n date,\n view,\n setDate,\n setView,\n navigate,\n };\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["cva", "cn", "jsx", "cn", "jsx", "cn", "Fragment", "jsx", "jsxs", "jsx", "cn", "jsx", "jsxs", "cn", "jsx", "jsxs", "jsx"]
7
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @author WMXPY
3
+ * @package Calendar
4
+ * @namespace Shared
5
+ * @description Date
6
+ */
7
+ import type { CalendarDate } from "./types";
8
+ export declare const parseDate: (value: CalendarDate) => Date;
9
+ export declare const addDays: (value: CalendarDate, amount: number) => CalendarDate;
10
+ export declare const addMonths: (value: CalendarDate, amount: number) => CalendarDate;
11
+ export declare const startOfWeek: (value: CalendarDate, weekStartsOn: number) => CalendarDate;
12
+ export declare const formatDate: (value: CalendarDate, locale: string, options: Intl.DateTimeFormatOptions) => string;
13
+ export declare const formatMinute: (minute: number) => string;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @author WMXPY
3
+ * @package Calendar
4
+ * @namespace Shared
5
+ * @description Events
6
+ */
7
+ import type { CalendarDate, CalendarEventData } from "./types";
8
+ export type EventSegment = {
9
+ readonly event: CalendarEventData;
10
+ readonly date: CalendarDate;
11
+ readonly start: number;
12
+ readonly end: number;
13
+ readonly continuesBefore: boolean;
14
+ readonly continuesAfter: boolean;
15
+ };
16
+ export type PositionedEvent = EventSegment & {
17
+ readonly column: number;
18
+ readonly columns: number;
19
+ };
20
+ export declare const validateEvents: (events: readonly CalendarEventData[]) => void;
21
+ export declare const segmentsForDate: (events: readonly CalendarEventData[], date: CalendarDate) => EventSegment[];
22
+ /** Partition connected overlaps, then reuse the first free column inside each group. */
23
+ export declare const positionEvents: (segments: readonly EventSegment[], start: number, end: number) => PositionedEvent[];
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @author WMXPY
3
+ * @package Calendar
4
+ * @namespace Shared
5
+ * @description Time Grid
6
+ */
7
+ import type { CalendarDate, CalendarTimeOptions } from "./types";
8
+ import type { ComponentPropsWithRef, FC, ReactNode } from "react";
9
+ export type TimeColumn = {
10
+ readonly id: string;
11
+ readonly date: CalendarDate;
12
+ readonly resourceId?: string;
13
+ readonly label: ReactNode;
14
+ readonly description?: ReactNode;
15
+ };
16
+ export type TimeSelection = {
17
+ readonly date: CalendarDate;
18
+ readonly minute: number;
19
+ readonly resourceId?: string;
20
+ };
21
+ export type TimeGridProps = Omit<ComponentPropsWithRef<"div">, "children"> & CalendarTimeOptions & {
22
+ readonly columns: readonly TimeColumn[];
23
+ readonly view: "day" | "week";
24
+ readonly onTimeSelect?: (selection: TimeSelection) => void;
25
+ readonly getTimeLabel?: (selection: TimeSelection) => string;
26
+ };
27
+ export declare const TimeGrid: FC<TimeGridProps>;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * @author WMXPY
3
+ * @package Calendar
4
+ * @namespace Shared
5
+ * @description Types
6
+ */
7
+ import type { CSSProperties, ReactNode } from "react";
8
+ /** A Gregorian civil date (YYYY-MM-DD), with no implicit timezone. */
9
+ export type CalendarDate = string;
10
+ export type CalendarView = "day" | "week" | "month" | "agenda";
11
+ export type CalendarEventColors = {
12
+ readonly accent?: CSSProperties["color"];
13
+ readonly background?: CSSProperties["backgroundColor"];
14
+ readonly foreground?: CSSProperties["color"];
15
+ };
16
+ /** End is exclusive. Timed events use YYYY-MM-DDTHH:mm; all-day events use YYYY-MM-DD. */
17
+ export type CalendarEventData = {
18
+ readonly id: string;
19
+ readonly title: string;
20
+ readonly start: string;
21
+ readonly end: string;
22
+ readonly allDay?: boolean;
23
+ readonly resourceId?: string;
24
+ readonly colors?: CalendarEventColors;
25
+ readonly disabled?: boolean;
26
+ };
27
+ export type CalendarResource = {
28
+ readonly id: string;
29
+ readonly label: ReactNode;
30
+ readonly description?: ReactNode;
31
+ };
32
+ export type CalendarEventContext = {
33
+ readonly date: CalendarDate;
34
+ readonly view: CalendarView;
35
+ readonly continuesBefore: boolean;
36
+ readonly continuesAfter: boolean;
37
+ };
38
+ export type CalendarViewOptions = {
39
+ readonly date: CalendarDate;
40
+ readonly events: readonly CalendarEventData[];
41
+ readonly locale?: string;
42
+ readonly today?: CalendarDate;
43
+ readonly selectedEventId?: string;
44
+ readonly onEventSelect?: (event: CalendarEventData, context: CalendarEventContext) => void;
45
+ readonly renderEvent?: (event: CalendarEventData, context: CalendarEventContext) => ReactNode;
46
+ readonly getEventLabel?: (event: CalendarEventData, context: CalendarEventContext) => string;
47
+ };
48
+ export type CalendarTimeOptions = CalendarViewOptions & {
49
+ readonly startHour?: number;
50
+ readonly endHour?: number;
51
+ readonly hourHeight?: number;
52
+ readonly allDayLabel?: string;
53
+ readonly formatTime?: (minute: number) => string;
54
+ };
@@ -0,0 +1,357 @@
1
+ /*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
2
+ @layer properties;
3
+ @layer theme, base, components, utilities;
4
+ @layer utilities {
5
+ .visible {
6
+ visibility: visible;
7
+ }
8
+ .m-0 {
9
+ margin: 0px;
10
+ }
11
+ .box-border {
12
+ box-sizing: border-box;
13
+ }
14
+ .block {
15
+ display: block;
16
+ }
17
+ .flex {
18
+ display: flex;
19
+ }
20
+ .w-full {
21
+ width: 100%;
22
+ }
23
+ .min-w-0 {
24
+ min-width: 0px;
25
+ }
26
+ .flex-1 {
27
+ flex: 1;
28
+ }
29
+ .cursor-pointer {
30
+ cursor: pointer;
31
+ }
32
+ .flex-wrap {
33
+ flex-wrap: wrap;
34
+ }
35
+ .items-center {
36
+ align-items: center;
37
+ }
38
+ .gap-gridui-4 {
39
+ gap: var(--gridui-space-4);
40
+ }
41
+ .gap-gridui-8 {
42
+ gap: var(--gridui-space-8);
43
+ }
44
+ .border {
45
+ border-style: var(--tw-border-style);
46
+ border-width: 1px;
47
+ }
48
+ .border-solid {
49
+ --tw-border-style: solid;
50
+ border-style: solid;
51
+ }
52
+ .border-border {
53
+ border-color: var(--gridui-border);
54
+ }
55
+ .bg-background {
56
+ background-color: var(--gridui-background);
57
+ }
58
+ .text-left {
59
+ text-align: left;
60
+ }
61
+ .type-caption {
62
+ font: var(--gridui-type-caption);
63
+ letter-spacing: normal;
64
+ }
65
+ .type-supporting {
66
+ font: var(--gridui-type-supporting);
67
+ letter-spacing: normal;
68
+ }
69
+ .type-ui {
70
+ font: var(--gridui-type-ui);
71
+ letter-spacing: normal;
72
+ }
73
+ .wrap-anywhere {
74
+ overflow-wrap: anywhere;
75
+ }
76
+ .text-foreground {
77
+ color: var(--gridui-foreground);
78
+ }
79
+ .text-muted {
80
+ color: var(--gridui-muted);
81
+ }
82
+ .tabular-nums {
83
+ --tw-numeric-spacing: tabular-nums;
84
+ font-variant-numeric: var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);
85
+ }
86
+ .outline {
87
+ outline-style: var(--tw-outline-style);
88
+ outline-width: 1px;
89
+ }
90
+ .disabled\:cursor-not-allowed:disabled {
91
+ cursor: not-allowed;
92
+ }
93
+ .disabled\:opacity-50:disabled {
94
+ opacity: 50%;
95
+ }
96
+ }
97
+ @layer components {
98
+ .gridui-calendar-event {
99
+ --gridui-calendar-event-accent: var(--gridui-accent-background);
100
+ --gridui-calendar-event-background: var(--gridui-calendar-event-accent);
101
+ @supports (color: color-mix(in lab, red, red)) {
102
+ --gridui-calendar-event-background: color-mix(in srgb, var(--gridui-calendar-event-accent) 12%, var(--gridui-background));
103
+ }
104
+ --gridui-calendar-event-foreground: var(--gridui-foreground);
105
+ border: 0;
106
+ border-inline-start: 3px solid var(--gridui-calendar-event-accent);
107
+ border-radius: var(--gridui-control-radius);
108
+ background: var(--gridui-calendar-event-background);
109
+ color: var(--gridui-calendar-event-foreground);
110
+ }
111
+ .gridui-calendar-event[data-selected] {
112
+ box-shadow: inset 0 0 0 2px var(--gridui-calendar-event-accent);
113
+ }
114
+ .gridui-calendar-event:hover:not(:disabled) {
115
+ filter: brightness(0.97);
116
+ }
117
+ .gridui-calendar-event-block {
118
+ display: flex;
119
+ flex-direction: column;
120
+ gap: var(--gridui-space-4);
121
+ padding: var(--gridui-space-8);
122
+ }
123
+ .gridui-calendar-event-compact {
124
+ padding: var(--gridui-space-4);
125
+ overflow: hidden;
126
+ text-overflow: ellipsis;
127
+ white-space: nowrap;
128
+ }
129
+ .gridui-calendar-time-grid {
130
+ display: grid;
131
+ grid-template-columns: 3.5rem repeat(var(--gridui-calendar-columns), minmax(0, 1fr));
132
+ min-width: 0;
133
+ background: var(--gridui-background);
134
+ color: var(--gridui-foreground);
135
+ }
136
+ .gridui-calendar-time-corner, .gridui-calendar-time-heading {
137
+ min-width: 0;
138
+ padding: var(--gridui-space-8) var(--gridui-space-4);
139
+ border-block-end: 1px solid var(--gridui-border);
140
+ background: var(--gridui-surface);
141
+ text-align: center;
142
+ overflow-wrap: anywhere;
143
+ }
144
+ .gridui-calendar-time-heading, .gridui-calendar-time-lane, .gridui-calendar-all-day {
145
+ border-inline-start: 1px solid var(--gridui-border);
146
+ }
147
+ .gridui-calendar-time-heading[data-today] {
148
+ box-shadow: inset 0 -2px var(--gridui-accent-background);
149
+ }
150
+ .gridui-calendar-all-day, .gridui-calendar-all-day-label {
151
+ min-width: 0;
152
+ padding: var(--gridui-space-4);
153
+ border-block-end: 1px solid var(--gridui-border);
154
+ }
155
+ .gridui-calendar-all-day {
156
+ display: flex;
157
+ flex-direction: column;
158
+ gap: var(--gridui-space-4);
159
+ }
160
+ .gridui-calendar-time-axis, .gridui-calendar-time-lane {
161
+ height: calc(var(--gridui-calendar-hours) * var(--gridui-calendar-hour-height));
162
+ }
163
+ .gridui-calendar-time-axis {
164
+ display: grid;
165
+ grid-template-rows: repeat(var(--gridui-calendar-hours), var(--gridui-calendar-hour-height));
166
+ text-align: end;
167
+ }
168
+ .gridui-calendar-time-axis > span {
169
+ padding-inline-end: var(--gridui-space-4);
170
+ }
171
+ .gridui-calendar-time-lane {
172
+ position: relative;
173
+ min-width: 0;
174
+ background-repeat: no-repeat;
175
+ background-size: 100% calc(100% - var(--gridui-calendar-hour-height));
176
+ background-image: repeating-linear-gradient(to bottom, transparent 0, transparent calc(var(--gridui-calendar-hour-height) - 1px), var(--gridui-border) calc(var(--gridui-calendar-hour-height) - 1px), var(--gridui-border) var(--gridui-calendar-hour-height));
177
+ }
178
+ .gridui-calendar-time-slot {
179
+ display: block;
180
+ width: 100%;
181
+ height: var(--gridui-calendar-hour-height);
182
+ border: 0;
183
+ background: transparent;
184
+ cursor: pointer;
185
+ }
186
+ .gridui-calendar-time-slot:hover {
187
+ background: var(--gridui-accent-background);
188
+ @supports (color: color-mix(in lab, red, red)) {
189
+ background: color-mix(in srgb, var(--gridui-accent-background) 6%, transparent);
190
+ }
191
+ }
192
+ .gridui-calendar-positioned-event {
193
+ position: absolute;
194
+ z-index: var(--gridui-z-content);
195
+ gap: 0;
196
+ padding: var(--gridui-space-4);
197
+ overflow: hidden;
198
+ }
199
+ .gridui-calendar-event-title, .gridui-calendar-event-time {
200
+ display: block;
201
+ max-width: 100%;
202
+ overflow: hidden;
203
+ text-overflow: ellipsis;
204
+ white-space: nowrap;
205
+ }
206
+ .gridui-calendar-month {
207
+ min-width: 0;
208
+ background: var(--gridui-background);
209
+ color: var(--gridui-foreground);
210
+ container-type: inline-size;
211
+ }
212
+ .gridui-calendar-month-table {
213
+ width: 100%;
214
+ border-collapse: separate;
215
+ border-spacing: 0;
216
+ table-layout: fixed;
217
+ }
218
+ .gridui-calendar-month-table th {
219
+ padding: var(--gridui-space-8) var(--gridui-space-4);
220
+ font-weight: 400;
221
+ text-align: center;
222
+ }
223
+ .gridui-calendar-month-table td {
224
+ height: 7rem;
225
+ padding: var(--gridui-space-4);
226
+ border-block-start: 1px solid var(--gridui-border);
227
+ vertical-align: top;
228
+ }
229
+ .gridui-calendar-month-table td + td {
230
+ border-inline-start: 1px solid var(--gridui-border);
231
+ }
232
+ .gridui-calendar-month-table td[data-outside] {
233
+ background: var(--gridui-surface);
234
+ color: var(--gridui-muted);
235
+ }
236
+ .gridui-calendar-day-number {
237
+ display: grid;
238
+ place-items: center;
239
+ min-width: 2rem;
240
+ min-height: 2rem;
241
+ padding: var(--gridui-space-4);
242
+ border: 0;
243
+ border-radius: var(--gridui-control-radius);
244
+ background: transparent;
245
+ color: inherit;
246
+ font: inherit;
247
+ cursor: pointer;
248
+ }
249
+ .gridui-calendar-day-number[aria-current="date"] {
250
+ box-shadow: inset 0 0 0 1px var(--gridui-accent-background);
251
+ }
252
+ .gridui-calendar-day-number[aria-pressed="true"] {
253
+ background: var(--gridui-accent-background);
254
+ color: var(--gridui-accent-foreground);
255
+ }
256
+ .gridui-calendar-month-events {
257
+ display: grid;
258
+ gap: var(--gridui-space-4);
259
+ margin-block-start: var(--gridui-space-4);
260
+ }
261
+ .gridui-calendar-more {
262
+ width: 100%;
263
+ border: 0;
264
+ padding: var(--gridui-space-4);
265
+ background: transparent;
266
+ color: var(--gridui-muted);
267
+ text-align: start;
268
+ cursor: pointer;
269
+ overflow-wrap: anywhere;
270
+ }
271
+ @container (max-width: 32rem) {
272
+ .gridui-calendar-month-table td {
273
+ padding: 2px;
274
+ }
275
+ .gridui-calendar-month-events .gridui-calendar-event {
276
+ padding-inline: 2px;
277
+ writing-mode: vertical-rl;
278
+ max-height: 4.5rem;
279
+ }
280
+ }
281
+ .gridui-calendar-agenda {
282
+ min-width: 0;
283
+ background: var(--gridui-background);
284
+ color: var(--gridui-foreground);
285
+ }
286
+ .gridui-calendar-agenda-day {
287
+ display: grid;
288
+ grid-template-columns: minmax(0, 7rem) minmax(0, 1fr);
289
+ gap: var(--gridui-space-16);
290
+ padding: var(--gridui-space-16);
291
+ }
292
+ .gridui-calendar-agenda-day + .gridui-calendar-agenda-day {
293
+ border-block-start: 1px solid var(--gridui-border);
294
+ }
295
+ .gridui-calendar-agenda-events {
296
+ display: grid;
297
+ gap: var(--gridui-space-8);
298
+ margin: 0;
299
+ padding: 0;
300
+ list-style: none;
301
+ }
302
+ .gridui-calendar-agenda-event {
303
+ display: flex;
304
+ flex-wrap: wrap;
305
+ flex-direction: row;
306
+ align-items: center;
307
+ gap: var(--gridui-space-8) var(--gridui-space-16);
308
+ }
309
+ @media (max-width: 40rem) {
310
+ .gridui-calendar-agenda-day {
311
+ grid-template-columns: minmax(0, 1fr);
312
+ }
313
+ }
314
+ }
315
+ @property --tw-border-style {
316
+ syntax: "*";
317
+ inherits: false;
318
+ initial-value: solid;
319
+ }
320
+ @property --tw-ordinal {
321
+ syntax: "*";
322
+ inherits: false;
323
+ }
324
+ @property --tw-slashed-zero {
325
+ syntax: "*";
326
+ inherits: false;
327
+ }
328
+ @property --tw-numeric-figure {
329
+ syntax: "*";
330
+ inherits: false;
331
+ }
332
+ @property --tw-numeric-spacing {
333
+ syntax: "*";
334
+ inherits: false;
335
+ }
336
+ @property --tw-numeric-fraction {
337
+ syntax: "*";
338
+ inherits: false;
339
+ }
340
+ @property --tw-outline-style {
341
+ syntax: "*";
342
+ inherits: false;
343
+ initial-value: solid;
344
+ }
345
+ @layer properties {
346
+ @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {
347
+ *, ::before, ::after, ::backdrop {
348
+ --tw-border-style: solid;
349
+ --tw-ordinal: initial;
350
+ --tw-slashed-zero: initial;
351
+ --tw-numeric-figure: initial;
352
+ --tw-numeric-spacing: initial;
353
+ --tw-numeric-fraction: initial;
354
+ --tw-outline-style: solid;
355
+ }
356
+ }
357
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @author WMXPY
3
+ * @package Calendar
4
+ * @namespace UseCalendar
5
+ * @description Use Calendar
6
+ */
7
+ import type { CalendarDate, CalendarView } from "../shared/types";
8
+ export type UseCalendarOptions = {
9
+ readonly defaultDate: CalendarDate;
10
+ readonly date?: CalendarDate;
11
+ readonly defaultView?: CalendarView;
12
+ readonly view?: CalendarView;
13
+ readonly onDateChange?: (date: CalendarDate) => void;
14
+ readonly onViewChange?: (view: CalendarView) => void;
15
+ };
16
+ export declare const useCalendar: (options: UseCalendarOptions) => {
17
+ date: string;
18
+ view: CalendarView;
19
+ setDate: (next: CalendarDate) => void;
20
+ setView: (next: CalendarView) => void;
21
+ navigate: (direction: -1 | 1) => void;
22
+ };