@particle-academy/react-fancy 5.54.2 → 5.56.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.
package/docs/Calendar.md CHANGED
@@ -25,6 +25,29 @@ import { Calendar } from "@particle-academy/react-fancy";
25
25
  | `maxDate` | `Date` | - | Latest selectable date |
26
26
  | `disabledDates` | `Date[]` | `[]` | Specific dates to disable |
27
27
  | `className` | `string` | - | Additional CSS classes |
28
+ | `dateId` | `(date: Date) => string` | `YYYY-MM-DD` (local) | Stable id per day, emitted as `data-react-fancy-calendar-day` (5.56.0) |
29
+ | `renderDay` | `(ctx: CalendarDayContext) => ReactNode` | day number | The day cell's content; the cell itself stays the Calendar's (5.56.0) |
30
+ | `dayClassName` | `(ctx: CalendarDayContext) => string \| undefined` | - | Extra classes for one day, merged after the built-in ones (5.56.0) |
31
+ | `dayAriaLabel` | `(ctx: CalendarDayContext) => string \| undefined` | - | The day's accessible name. Required in practice whenever `dayClassName` shades a day: colour alone is not a signal. Replaces the name, so include the date (5.56.0) |
32
+ | `visibleMonth` | `Date` | - | Controlled visible month (any day in it). Uncontrolled when omitted (5.56.0) |
33
+ | `onVisibleMonthChange` | `(month: Date) => void` | - | Called with the 1st of the month navigated to (5.56.0) |
34
+
35
+ ### CalendarDayContext
36
+
37
+ ```ts
38
+ interface CalendarDayContext {
39
+ date: Date;
40
+ id: string; // dateId(date)
41
+ selected: boolean;
42
+ disabled: boolean;
43
+ inRange: boolean; // strictly between a range's ends
44
+ outsideMonth: boolean;
45
+ today: boolean;
46
+ }
47
+ ```
48
+
49
+ Out-of-month day cells also carry `data-outside-month`, and the month heading
50
+ carries `data-react-fancy-calendar-month`.
28
51
 
29
52
  ### DateRange type
30
53
 
@@ -56,6 +79,20 @@ const [range, setRange] = useState<DateRange>({ start: null, end: null });
56
79
  />
57
80
  ```
58
81
 
82
+ ### Coverage shading, a controlled month, open a day on click
83
+
84
+ ```tsx
85
+ const [month, setMonth] = useState(new Date(2026, 9, 1));
86
+
87
+ <Calendar
88
+ visibleMonth={month}
89
+ onVisibleMonthChange={setMonth}
90
+ onChange={(d) => openDay(d as Date)}
91
+ dayClassName={(ctx) => (coverage[ctx.id] === "full" ? "bg-emerald-100 dark:bg-emerald-900/50" : undefined)}
92
+ dayAriaLabel={(ctx) => (coverage[ctx.id] ? `${ctx.date.toDateString()}, ${coverage[ctx.id]} coverage` : undefined)}
93
+ />
94
+ ```
95
+
59
96
  ### Multiple dates with constraints
60
97
 
61
98
  ```tsx
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@particle-academy/react-fancy",
3
- "version": "5.54.2",
3
+ "version": "5.56.0",
4
4
  "description": "React UI component library for Human+ UX — controlled, agent-bridgeable primitives",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,129 +0,0 @@
1
- import { cn } from './chunk-MMW2JGKZ.js';
2
- import { forwardRef, useState } from 'react';
3
- import { jsx, jsxs } from 'react/jsx-runtime';
4
-
5
- var TONE_CLASSES = {
6
- violet: "bg-violet-500 hover:bg-violet-600",
7
- emerald: "bg-emerald-500 hover:bg-emerald-600",
8
- sky: "bg-sky-500 hover:bg-sky-600",
9
- rose: "bg-rose-500 hover:bg-rose-600",
10
- amber: "bg-amber-500 hover:bg-amber-600",
11
- indigo: "bg-indigo-500 hover:bg-indigo-600",
12
- blue: "bg-blue-500 hover:bg-blue-600",
13
- zinc: "bg-zinc-500 hover:bg-zinc-600"
14
- };
15
- var OFF_CLASSES = "bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] hover:bg-zinc-200 dark:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))] dark:hover:bg-zinc-700";
16
- var TimeGrid = forwardRef(
17
- ({
18
- rows,
19
- cols,
20
- value,
21
- onChange,
22
- toneOn = "violet",
23
- cellWidth = 20,
24
- cellHeight = 16,
25
- sparseColLabels = true,
26
- toggleStripsOnHeaderClick = true,
27
- ariaCell,
28
- cellId,
29
- className
30
- }, ref) => {
31
- const [drag, setDrag] = useState(null);
32
- const setCell = (r, c, v) => {
33
- if (value[r]?.[c] === v) return;
34
- const next = value.map((row) => row.slice());
35
- next[r][c] = v;
36
- onChange(next);
37
- };
38
- const toggleRow = (r) => {
39
- if (!toggleStripsOnHeaderClick) return;
40
- const all = value[r].every(Boolean);
41
- const next = value.map((row) => row.slice());
42
- for (let c = 0; c < cols.length; c++) next[r][c] = !all;
43
- onChange(next);
44
- };
45
- const toggleCol = (c) => {
46
- if (!toggleStripsOnHeaderClick) return;
47
- const all = value.every((row) => row[c]);
48
- const next = value.map((row) => row.slice());
49
- for (let r = 0; r < rows.length; r++) next[r][c] = !all;
50
- onChange(next);
51
- };
52
- const colStep = Math.max(1, Math.floor(cols.length / 6));
53
- const onTone = TONE_CLASSES[toneOn];
54
- return /* @__PURE__ */ jsx(
55
- "div",
56
- {
57
- ref,
58
- "data-react-fancy-timegrid": "",
59
- className: cn(
60
- "select-none overflow-x-auto",
61
- className
62
- ),
63
- onMouseLeave: () => setDrag(null),
64
- onMouseUp: () => setDrag(null),
65
- children: /* @__PURE__ */ jsxs("table", { className: "text-[10px]", children: [
66
- /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
67
- /* @__PURE__ */ jsx("th", {}),
68
- cols.map((label, c) => /* @__PURE__ */ jsx(
69
- "th",
70
- {
71
- onClick: () => toggleCol(c),
72
- style: { width: cellWidth },
73
- "data-react-fancy-timegrid-col": c,
74
- className: cn(
75
- "text-zinc-400",
76
- toggleStripsOnHeaderClick && "cursor-pointer hover:text-zinc-700 dark:hover:text-zinc-200"
77
- ),
78
- children: sparseColLabels ? c % colStep === 0 ? label : "" : label
79
- },
80
- c
81
- ))
82
- ] }) }),
83
- /* @__PURE__ */ jsx("tbody", { children: rows.map((label, r) => /* @__PURE__ */ jsxs("tr", { children: [
84
- /* @__PURE__ */ jsx(
85
- "th",
86
- {
87
- onClick: () => toggleRow(r),
88
- "data-react-fancy-timegrid-row": r,
89
- className: cn(
90
- "pr-1 text-right font-medium text-zinc-500",
91
- toggleStripsOnHeaderClick && "cursor-pointer hover:text-zinc-800 dark:hover:text-zinc-200"
92
- ),
93
- children: label
94
- }
95
- ),
96
- cols.map((_, c) => {
97
- const on = value[r]?.[c] ?? false;
98
- return /* @__PURE__ */ jsx("td", { className: "p-px", children: /* @__PURE__ */ jsx(
99
- "button",
100
- {
101
- type: "button",
102
- onMouseDown: () => {
103
- const v = !on;
104
- setDrag(v);
105
- setCell(r, c, v);
106
- },
107
- onMouseEnter: () => drag !== null && setCell(r, c, drag),
108
- style: { width: cellWidth, height: cellHeight },
109
- "data-react-fancy-timegrid-cell": cellId ? cellId(r, c) : `${r}:${c}`,
110
- "aria-pressed": on,
111
- "aria-label": ariaCell ? ariaCell(r, c, on) : `${rows[r]} ${cols[c]} ${on ? "on" : "off"}`,
112
- className: cn(
113
- "block rounded-sm transition",
114
- on ? onTone : OFF_CLASSES
115
- )
116
- }
117
- ) }, c);
118
- })
119
- ] }, r)) })
120
- ] })
121
- }
122
- );
123
- }
124
- );
125
- TimeGrid.displayName = "TimeGrid";
126
-
127
- export { TimeGrid };
128
- //# sourceMappingURL=chunk-GF23UBOT.js.map
129
- //# sourceMappingURL=chunk-GF23UBOT.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/TimeGrid/TimeGrid.tsx"],"names":[],"mappings":"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","file":"chunk-GF23UBOT.js","sourcesContent":["import { forwardRef, useState } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport type { TimeGridProps, TimeGridTone } from \"./TimeGrid.types\";\n\nconst TONE_CLASSES: Record<TimeGridTone, string> = {\n violet: \"bg-violet-500 hover:bg-violet-600\",\n emerald: \"bg-emerald-500 hover:bg-emerald-600\",\n sky: \"bg-sky-500 hover:bg-sky-600\",\n rose: \"bg-rose-500 hover:bg-rose-600\",\n amber: \"bg-amber-500 hover:bg-amber-600\",\n indigo: \"bg-indigo-500 hover:bg-indigo-600\",\n blue: \"bg-blue-500 hover:bg-blue-600\",\n zinc: \"bg-zinc-500 hover:bg-zinc-600\",\n};\n\nconst OFF_CLASSES =\n \"bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] hover:bg-zinc-200 dark:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))] dark:hover:bg-zinc-700\";\n\nexport const TimeGrid = forwardRef<HTMLDivElement, TimeGridProps>(\n (\n {\n rows,\n cols,\n value,\n onChange,\n toneOn = \"violet\",\n cellWidth = 20,\n cellHeight = 16,\n sparseColLabels = true,\n toggleStripsOnHeaderClick = true,\n ariaCell,\n cellId,\n className,\n },\n ref,\n ) => {\n const [drag, setDrag] = useState<boolean | null>(null);\n\n const setCell = (r: number, c: number, v: boolean) => {\n if (value[r]?.[c] === v) return;\n const next = value.map((row) => row.slice());\n next[r][c] = v;\n onChange(next);\n };\n\n const toggleRow = (r: number) => {\n if (!toggleStripsOnHeaderClick) return;\n const all = value[r].every(Boolean);\n const next = value.map((row) => row.slice());\n for (let c = 0; c < cols.length; c++) next[r][c] = !all;\n onChange(next);\n };\n\n const toggleCol = (c: number) => {\n if (!toggleStripsOnHeaderClick) return;\n const all = value.every((row) => row[c]);\n const next = value.map((row) => row.slice());\n for (let r = 0; r < rows.length; r++) next[r][c] = !all;\n onChange(next);\n };\n\n const colStep = Math.max(1, Math.floor(cols.length / 6));\n const onTone = TONE_CLASSES[toneOn];\n\n return (\n <div\n ref={ref}\n data-react-fancy-timegrid=\"\"\n className={cn(\n \"select-none overflow-x-auto\",\n className,\n )}\n onMouseLeave={() => setDrag(null)}\n onMouseUp={() => setDrag(null)}\n >\n <table className=\"text-[10px]\">\n <thead>\n <tr>\n <th />\n {cols.map((label, c) => (\n <th\n key={c}\n onClick={() => toggleCol(c)}\n style={{ width: cellWidth }}\n data-react-fancy-timegrid-col={c}\n className={cn(\n \"text-zinc-400\",\n toggleStripsOnHeaderClick &&\n \"cursor-pointer hover:text-zinc-700 dark:hover:text-zinc-200\",\n )}\n >\n {sparseColLabels ? (c % colStep === 0 ? label : \"\") : label}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {rows.map((label, r) => (\n <tr key={r}>\n <th\n onClick={() => toggleRow(r)}\n data-react-fancy-timegrid-row={r}\n className={cn(\n \"pr-1 text-right font-medium text-zinc-500\",\n toggleStripsOnHeaderClick &&\n \"cursor-pointer hover:text-zinc-800 dark:hover:text-zinc-200\",\n )}\n >\n {label}\n </th>\n {cols.map((_, c) => {\n const on = value[r]?.[c] ?? false;\n return (\n <td key={c} className=\"p-px\">\n <button\n type=\"button\"\n onMouseDown={() => {\n const v = !on;\n setDrag(v);\n setCell(r, c, v);\n }}\n onMouseEnter={() => drag !== null && setCell(r, c, drag)}\n style={{ width: cellWidth, height: cellHeight }}\n data-react-fancy-timegrid-cell={\n cellId ? cellId(r, c) : `${r}:${c}`\n }\n aria-pressed={on}\n aria-label={\n ariaCell\n ? ariaCell(r, c, on)\n : `${rows[r]} ${cols[c]} ${on ? \"on\" : \"off\"}`\n }\n className={cn(\n \"block rounded-sm transition\",\n on ? onTone : OFF_CLASSES,\n )}\n />\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n },\n);\n\nTimeGrid.displayName = \"TimeGrid\";\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/Calendar/Calendar.tsx"],"names":["Calendar"],"mappings":"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","file":"chunk-HVND2IIB.js","sourcesContent":["import { forwardRef, useCallback, useMemo, useState } from \"react\";\nimport { ChevronLeft, ChevronRight } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport type { CalendarProps, DateRange } from \"./Calendar.types\";\n\nconst DAYS = [\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\"];\nconst MONTHS = [\n \"January\", \"February\", \"March\", \"April\", \"May\", \"June\",\n \"July\", \"August\", \"September\", \"October\", \"November\", \"December\",\n];\n\nfunction isSameDay(a: Date, b: Date): boolean {\n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n );\n}\n\nfunction getDaysInMonth(year: number, month: number): Date[] {\n const days: Date[] = [];\n const firstDay = new Date(year, month, 1);\n const startDayOfWeek = firstDay.getDay();\n\n // Fill leading days from previous month\n for (let i = startDayOfWeek - 1; i >= 0; i--) {\n days.push(new Date(year, month, -i));\n }\n\n // Fill current month\n const lastDate = new Date(year, month + 1, 0).getDate();\n for (let d = 1; d <= lastDate; d++) {\n days.push(new Date(year, month, d));\n }\n\n // Fill trailing days to complete 6 rows\n while (days.length < 42) {\n days.push(new Date(year, month + 1, days.length - startDayOfWeek - lastDate + 1));\n }\n\n return days;\n}\n\nexport const Calendar = forwardRef<HTMLDivElement, CalendarProps>(\n function Calendar(\n {\n mode = \"single\",\n value,\n onChange,\n minDate,\n maxDate,\n disabledDates = [],\n className,\n },\n ref,\n ) {\n const today = useMemo(() => new Date(), []);\n const [viewMonth, setViewMonth] = useState(today.getMonth());\n const [viewYear, setViewYear] = useState(today.getFullYear());\n const [rangeHover, setRangeHover] = useState<Date | null>(null);\n\n const days = useMemo(\n () => getDaysInMonth(viewYear, viewMonth),\n [viewYear, viewMonth],\n );\n\n const prevMonth = useCallback(() => {\n setViewMonth((m) => {\n if (m === 0) {\n setViewYear((y) => y - 1);\n return 11;\n }\n return m - 1;\n });\n }, []);\n\n const nextMonth = useCallback(() => {\n setViewMonth((m) => {\n if (m === 11) {\n setViewYear((y) => y + 1);\n return 0;\n }\n return m + 1;\n });\n }, []);\n\n const isDisabled = useCallback(\n (date: Date): boolean => {\n if (minDate && date < minDate) return true;\n if (maxDate && date > maxDate) return true;\n return disabledDates.some((d) => isSameDay(d, date));\n },\n [minDate, maxDate, disabledDates],\n );\n\n const isSelected = useCallback(\n (date: Date): boolean => {\n if (!value) return false;\n if (mode === \"single\" && value instanceof Date) {\n return isSameDay(date, value);\n }\n if (mode === \"multiple\" && Array.isArray(value)) {\n return value.some((v) => isSameDay(date, v));\n }\n if (mode === \"range\" && value && typeof value === \"object\" && \"start\" in value) {\n const range = value as DateRange;\n if (range.start && isSameDay(date, range.start)) return true;\n if (range.end && isSameDay(date, range.end)) return true;\n }\n return false;\n },\n [value, mode],\n );\n\n const isInRange = useCallback(\n (date: Date): boolean => {\n if (mode !== \"range\" || !value || typeof value !== \"object\" || !(\"start\" in value))\n return false;\n const range = value as DateRange;\n if (!range.start) return false;\n const end = range.end ?? rangeHover;\n if (!end) return false;\n const [s, e] = range.start <= end ? [range.start, end] : [end, range.start];\n return date > s && date < e;\n },\n [value, mode, rangeHover],\n );\n\n const handleSelect = useCallback(\n (date: Date) => {\n if (isDisabled(date)) return;\n\n if (mode === \"single\") {\n onChange?.(date);\n } else if (mode === \"multiple\") {\n const arr = (Array.isArray(value) ? value : []) as Date[];\n const exists = arr.findIndex((d) => isSameDay(d, date));\n if (exists >= 0) {\n onChange?.(arr.filter((_, i) => i !== exists));\n } else {\n onChange?.([...arr, date]);\n }\n } else if (mode === \"range\") {\n const range = (value && typeof value === \"object\" && \"start\" in value\n ? value\n : { start: null, end: null }) as DateRange;\n\n if (!range.start || range.end) {\n onChange?.({ start: date, end: null });\n } else {\n const [s, e] =\n date >= range.start ? [range.start, date] : [date, range.start];\n onChange?.({ start: s, end: e });\n }\n }\n },\n [mode, value, onChange, isDisabled],\n );\n\n const btnBase =\n \"flex h-8 w-8 items-center justify-center rounded-lg text-sm transition-colors\";\n\n return (\n <div\n data-react-fancy-calendar=\"\"\n ref={ref}\n className={cn(\n \"inline-block w-72 rounded-xl border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-[color:var(--fancy-surface,var(--color-white))] p-4 dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))]\",\n className,\n )}\n >\n {/* Header */}\n <div className=\"mb-3 flex items-center justify-between\">\n <button\n type=\"button\"\n onClick={prevMonth}\n className=\"rounded-lg p-1 text-zinc-400 hover:bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] dark:hover:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\"\n aria-label=\"Previous month\"\n >\n <ChevronLeft size={16} />\n </button>\n <span className=\"text-sm font-semibold\">\n {MONTHS[viewMonth]} {viewYear}\n </span>\n <button\n type=\"button\"\n onClick={nextMonth}\n className=\"rounded-lg p-1 text-zinc-400 hover:bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] dark:hover:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\"\n aria-label=\"Next month\"\n >\n <ChevronRight size={16} />\n </button>\n </div>\n\n {/* Day headers */}\n <div className=\"mb-1 grid grid-cols-7 gap-1\">\n {DAYS.map((d) => (\n <div\n key={d}\n className=\"flex h-8 items-center justify-center text-xs font-medium text-zinc-400\"\n >\n {d}\n </div>\n ))}\n </div>\n\n {/* Day grid */}\n <div className=\"grid grid-cols-7 gap-1\">\n {days.map((date, i) => {\n const isCurrentMonth = date.getMonth() === viewMonth;\n const selected = isSelected(date);\n const inRange = isInRange(date);\n const disabled = isDisabled(date);\n const isToday = isSameDay(date, today);\n\n return (\n <button\n key={i}\n type=\"button\"\n disabled={disabled}\n onClick={() => handleSelect(date)}\n onMouseEnter={() =>\n mode === \"range\" && setRangeHover(date)\n }\n className={cn(\n btnBase,\n !isCurrentMonth && \"text-zinc-300 dark:text-zinc-600\",\n isCurrentMonth &&\n !selected &&\n !inRange &&\n \"text-[color:var(--fancy-text-soft,var(--color-zinc-700))] hover:bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] dark:text-[color:var(--fancy-text-soft-dark,var(--color-zinc-300))] dark:hover:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\",\n inRange &&\n \"bg-blue-50 text-blue-700 dark:bg-blue-950 dark:text-blue-300\",\n selected &&\n \"bg-zinc-900 text-white dark:bg-white dark:text-zinc-900\",\n isToday && !selected && \"font-bold\",\n disabled && \"cursor-not-allowed opacity-30\",\n )}\n >\n {date.getDate()}\n </button>\n );\n })}\n </div>\n </div>\n );\n },\n);\n\nCalendar.displayName = \"Calendar\";\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/Calendar/Calendar.tsx"],"names":["forwardRef","Calendar","useMemo","useState","useCallback","jsxs","cn","jsx","ChevronLeft","ChevronRight"],"mappings":"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","file":"chunk-UET6D7B3.cjs","sourcesContent":["import { forwardRef, useCallback, useMemo, useState } from \"react\";\nimport { ChevronLeft, ChevronRight } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport type { CalendarProps, DateRange } from \"./Calendar.types\";\n\nconst DAYS = [\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\"];\nconst MONTHS = [\n \"January\", \"February\", \"March\", \"April\", \"May\", \"June\",\n \"July\", \"August\", \"September\", \"October\", \"November\", \"December\",\n];\n\nfunction isSameDay(a: Date, b: Date): boolean {\n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n );\n}\n\nfunction getDaysInMonth(year: number, month: number): Date[] {\n const days: Date[] = [];\n const firstDay = new Date(year, month, 1);\n const startDayOfWeek = firstDay.getDay();\n\n // Fill leading days from previous month\n for (let i = startDayOfWeek - 1; i >= 0; i--) {\n days.push(new Date(year, month, -i));\n }\n\n // Fill current month\n const lastDate = new Date(year, month + 1, 0).getDate();\n for (let d = 1; d <= lastDate; d++) {\n days.push(new Date(year, month, d));\n }\n\n // Fill trailing days to complete 6 rows\n while (days.length < 42) {\n days.push(new Date(year, month + 1, days.length - startDayOfWeek - lastDate + 1));\n }\n\n return days;\n}\n\nexport const Calendar = forwardRef<HTMLDivElement, CalendarProps>(\n function Calendar(\n {\n mode = \"single\",\n value,\n onChange,\n minDate,\n maxDate,\n disabledDates = [],\n className,\n },\n ref,\n ) {\n const today = useMemo(() => new Date(), []);\n const [viewMonth, setViewMonth] = useState(today.getMonth());\n const [viewYear, setViewYear] = useState(today.getFullYear());\n const [rangeHover, setRangeHover] = useState<Date | null>(null);\n\n const days = useMemo(\n () => getDaysInMonth(viewYear, viewMonth),\n [viewYear, viewMonth],\n );\n\n const prevMonth = useCallback(() => {\n setViewMonth((m) => {\n if (m === 0) {\n setViewYear((y) => y - 1);\n return 11;\n }\n return m - 1;\n });\n }, []);\n\n const nextMonth = useCallback(() => {\n setViewMonth((m) => {\n if (m === 11) {\n setViewYear((y) => y + 1);\n return 0;\n }\n return m + 1;\n });\n }, []);\n\n const isDisabled = useCallback(\n (date: Date): boolean => {\n if (minDate && date < minDate) return true;\n if (maxDate && date > maxDate) return true;\n return disabledDates.some((d) => isSameDay(d, date));\n },\n [minDate, maxDate, disabledDates],\n );\n\n const isSelected = useCallback(\n (date: Date): boolean => {\n if (!value) return false;\n if (mode === \"single\" && value instanceof Date) {\n return isSameDay(date, value);\n }\n if (mode === \"multiple\" && Array.isArray(value)) {\n return value.some((v) => isSameDay(date, v));\n }\n if (mode === \"range\" && value && typeof value === \"object\" && \"start\" in value) {\n const range = value as DateRange;\n if (range.start && isSameDay(date, range.start)) return true;\n if (range.end && isSameDay(date, range.end)) return true;\n }\n return false;\n },\n [value, mode],\n );\n\n const isInRange = useCallback(\n (date: Date): boolean => {\n if (mode !== \"range\" || !value || typeof value !== \"object\" || !(\"start\" in value))\n return false;\n const range = value as DateRange;\n if (!range.start) return false;\n const end = range.end ?? rangeHover;\n if (!end) return false;\n const [s, e] = range.start <= end ? [range.start, end] : [end, range.start];\n return date > s && date < e;\n },\n [value, mode, rangeHover],\n );\n\n const handleSelect = useCallback(\n (date: Date) => {\n if (isDisabled(date)) return;\n\n if (mode === \"single\") {\n onChange?.(date);\n } else if (mode === \"multiple\") {\n const arr = (Array.isArray(value) ? value : []) as Date[];\n const exists = arr.findIndex((d) => isSameDay(d, date));\n if (exists >= 0) {\n onChange?.(arr.filter((_, i) => i !== exists));\n } else {\n onChange?.([...arr, date]);\n }\n } else if (mode === \"range\") {\n const range = (value && typeof value === \"object\" && \"start\" in value\n ? value\n : { start: null, end: null }) as DateRange;\n\n if (!range.start || range.end) {\n onChange?.({ start: date, end: null });\n } else {\n const [s, e] =\n date >= range.start ? [range.start, date] : [date, range.start];\n onChange?.({ start: s, end: e });\n }\n }\n },\n [mode, value, onChange, isDisabled],\n );\n\n const btnBase =\n \"flex h-8 w-8 items-center justify-center rounded-lg text-sm transition-colors\";\n\n return (\n <div\n data-react-fancy-calendar=\"\"\n ref={ref}\n className={cn(\n \"inline-block w-72 rounded-xl border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-[color:var(--fancy-surface,var(--color-white))] p-4 dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))]\",\n className,\n )}\n >\n {/* Header */}\n <div className=\"mb-3 flex items-center justify-between\">\n <button\n type=\"button\"\n onClick={prevMonth}\n className=\"rounded-lg p-1 text-zinc-400 hover:bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] dark:hover:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\"\n aria-label=\"Previous month\"\n >\n <ChevronLeft size={16} />\n </button>\n <span className=\"text-sm font-semibold\">\n {MONTHS[viewMonth]} {viewYear}\n </span>\n <button\n type=\"button\"\n onClick={nextMonth}\n className=\"rounded-lg p-1 text-zinc-400 hover:bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] dark:hover:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\"\n aria-label=\"Next month\"\n >\n <ChevronRight size={16} />\n </button>\n </div>\n\n {/* Day headers */}\n <div className=\"mb-1 grid grid-cols-7 gap-1\">\n {DAYS.map((d) => (\n <div\n key={d}\n className=\"flex h-8 items-center justify-center text-xs font-medium text-zinc-400\"\n >\n {d}\n </div>\n ))}\n </div>\n\n {/* Day grid */}\n <div className=\"grid grid-cols-7 gap-1\">\n {days.map((date, i) => {\n const isCurrentMonth = date.getMonth() === viewMonth;\n const selected = isSelected(date);\n const inRange = isInRange(date);\n const disabled = isDisabled(date);\n const isToday = isSameDay(date, today);\n\n return (\n <button\n key={i}\n type=\"button\"\n disabled={disabled}\n onClick={() => handleSelect(date)}\n onMouseEnter={() =>\n mode === \"range\" && setRangeHover(date)\n }\n className={cn(\n btnBase,\n !isCurrentMonth && \"text-zinc-300 dark:text-zinc-600\",\n isCurrentMonth &&\n !selected &&\n !inRange &&\n \"text-[color:var(--fancy-text-soft,var(--color-zinc-700))] hover:bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] dark:text-[color:var(--fancy-text-soft-dark,var(--color-zinc-300))] dark:hover:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\",\n inRange &&\n \"bg-blue-50 text-blue-700 dark:bg-blue-950 dark:text-blue-300\",\n selected &&\n \"bg-zinc-900 text-white dark:bg-white dark:text-zinc-900\",\n isToday && !selected && \"font-bold\",\n disabled && \"cursor-not-allowed opacity-30\",\n )}\n >\n {date.getDate()}\n </button>\n );\n })}\n </div>\n </div>\n );\n },\n);\n\nCalendar.displayName = \"Calendar\";\n"]}
@@ -1,131 +0,0 @@
1
- 'use strict';
2
-
3
- var chunkZU5Q77OT_cjs = require('./chunk-ZU5Q77OT.cjs');
4
- var react = require('react');
5
- var jsxRuntime = require('react/jsx-runtime');
6
-
7
- var TONE_CLASSES = {
8
- violet: "bg-violet-500 hover:bg-violet-600",
9
- emerald: "bg-emerald-500 hover:bg-emerald-600",
10
- sky: "bg-sky-500 hover:bg-sky-600",
11
- rose: "bg-rose-500 hover:bg-rose-600",
12
- amber: "bg-amber-500 hover:bg-amber-600",
13
- indigo: "bg-indigo-500 hover:bg-indigo-600",
14
- blue: "bg-blue-500 hover:bg-blue-600",
15
- zinc: "bg-zinc-500 hover:bg-zinc-600"
16
- };
17
- var OFF_CLASSES = "bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] hover:bg-zinc-200 dark:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))] dark:hover:bg-zinc-700";
18
- var TimeGrid = react.forwardRef(
19
- ({
20
- rows,
21
- cols,
22
- value,
23
- onChange,
24
- toneOn = "violet",
25
- cellWidth = 20,
26
- cellHeight = 16,
27
- sparseColLabels = true,
28
- toggleStripsOnHeaderClick = true,
29
- ariaCell,
30
- cellId,
31
- className
32
- }, ref) => {
33
- const [drag, setDrag] = react.useState(null);
34
- const setCell = (r, c, v) => {
35
- if (value[r]?.[c] === v) return;
36
- const next = value.map((row) => row.slice());
37
- next[r][c] = v;
38
- onChange(next);
39
- };
40
- const toggleRow = (r) => {
41
- if (!toggleStripsOnHeaderClick) return;
42
- const all = value[r].every(Boolean);
43
- const next = value.map((row) => row.slice());
44
- for (let c = 0; c < cols.length; c++) next[r][c] = !all;
45
- onChange(next);
46
- };
47
- const toggleCol = (c) => {
48
- if (!toggleStripsOnHeaderClick) return;
49
- const all = value.every((row) => row[c]);
50
- const next = value.map((row) => row.slice());
51
- for (let r = 0; r < rows.length; r++) next[r][c] = !all;
52
- onChange(next);
53
- };
54
- const colStep = Math.max(1, Math.floor(cols.length / 6));
55
- const onTone = TONE_CLASSES[toneOn];
56
- return /* @__PURE__ */ jsxRuntime.jsx(
57
- "div",
58
- {
59
- ref,
60
- "data-react-fancy-timegrid": "",
61
- className: chunkZU5Q77OT_cjs.cn(
62
- "select-none overflow-x-auto",
63
- className
64
- ),
65
- onMouseLeave: () => setDrag(null),
66
- onMouseUp: () => setDrag(null),
67
- children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "text-[10px]", children: [
68
- /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
69
- /* @__PURE__ */ jsxRuntime.jsx("th", {}),
70
- cols.map((label, c) => /* @__PURE__ */ jsxRuntime.jsx(
71
- "th",
72
- {
73
- onClick: () => toggleCol(c),
74
- style: { width: cellWidth },
75
- "data-react-fancy-timegrid-col": c,
76
- className: chunkZU5Q77OT_cjs.cn(
77
- "text-zinc-400",
78
- toggleStripsOnHeaderClick && "cursor-pointer hover:text-zinc-700 dark:hover:text-zinc-200"
79
- ),
80
- children: sparseColLabels ? c % colStep === 0 ? label : "" : label
81
- },
82
- c
83
- ))
84
- ] }) }),
85
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: rows.map((label, r) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
86
- /* @__PURE__ */ jsxRuntime.jsx(
87
- "th",
88
- {
89
- onClick: () => toggleRow(r),
90
- "data-react-fancy-timegrid-row": r,
91
- className: chunkZU5Q77OT_cjs.cn(
92
- "pr-1 text-right font-medium text-zinc-500",
93
- toggleStripsOnHeaderClick && "cursor-pointer hover:text-zinc-800 dark:hover:text-zinc-200"
94
- ),
95
- children: label
96
- }
97
- ),
98
- cols.map((_, c) => {
99
- const on = value[r]?.[c] ?? false;
100
- return /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-px", children: /* @__PURE__ */ jsxRuntime.jsx(
101
- "button",
102
- {
103
- type: "button",
104
- onMouseDown: () => {
105
- const v = !on;
106
- setDrag(v);
107
- setCell(r, c, v);
108
- },
109
- onMouseEnter: () => drag !== null && setCell(r, c, drag),
110
- style: { width: cellWidth, height: cellHeight },
111
- "data-react-fancy-timegrid-cell": cellId ? cellId(r, c) : `${r}:${c}`,
112
- "aria-pressed": on,
113
- "aria-label": ariaCell ? ariaCell(r, c, on) : `${rows[r]} ${cols[c]} ${on ? "on" : "off"}`,
114
- className: chunkZU5Q77OT_cjs.cn(
115
- "block rounded-sm transition",
116
- on ? onTone : OFF_CLASSES
117
- )
118
- }
119
- ) }, c);
120
- })
121
- ] }, r)) })
122
- ] })
123
- }
124
- );
125
- }
126
- );
127
- TimeGrid.displayName = "TimeGrid";
128
-
129
- exports.TimeGrid = TimeGrid;
130
- //# sourceMappingURL=chunk-WFHK2DKG.cjs.map
131
- //# sourceMappingURL=chunk-WFHK2DKG.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/TimeGrid/TimeGrid.tsx"],"names":["forwardRef","useState","jsx","cn","jsxs"],"mappings":"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","file":"chunk-WFHK2DKG.cjs","sourcesContent":["import { forwardRef, useState } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport type { TimeGridProps, TimeGridTone } from \"./TimeGrid.types\";\n\nconst TONE_CLASSES: Record<TimeGridTone, string> = {\n violet: \"bg-violet-500 hover:bg-violet-600\",\n emerald: \"bg-emerald-500 hover:bg-emerald-600\",\n sky: \"bg-sky-500 hover:bg-sky-600\",\n rose: \"bg-rose-500 hover:bg-rose-600\",\n amber: \"bg-amber-500 hover:bg-amber-600\",\n indigo: \"bg-indigo-500 hover:bg-indigo-600\",\n blue: \"bg-blue-500 hover:bg-blue-600\",\n zinc: \"bg-zinc-500 hover:bg-zinc-600\",\n};\n\nconst OFF_CLASSES =\n \"bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] hover:bg-zinc-200 dark:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))] dark:hover:bg-zinc-700\";\n\nexport const TimeGrid = forwardRef<HTMLDivElement, TimeGridProps>(\n (\n {\n rows,\n cols,\n value,\n onChange,\n toneOn = \"violet\",\n cellWidth = 20,\n cellHeight = 16,\n sparseColLabels = true,\n toggleStripsOnHeaderClick = true,\n ariaCell,\n cellId,\n className,\n },\n ref,\n ) => {\n const [drag, setDrag] = useState<boolean | null>(null);\n\n const setCell = (r: number, c: number, v: boolean) => {\n if (value[r]?.[c] === v) return;\n const next = value.map((row) => row.slice());\n next[r][c] = v;\n onChange(next);\n };\n\n const toggleRow = (r: number) => {\n if (!toggleStripsOnHeaderClick) return;\n const all = value[r].every(Boolean);\n const next = value.map((row) => row.slice());\n for (let c = 0; c < cols.length; c++) next[r][c] = !all;\n onChange(next);\n };\n\n const toggleCol = (c: number) => {\n if (!toggleStripsOnHeaderClick) return;\n const all = value.every((row) => row[c]);\n const next = value.map((row) => row.slice());\n for (let r = 0; r < rows.length; r++) next[r][c] = !all;\n onChange(next);\n };\n\n const colStep = Math.max(1, Math.floor(cols.length / 6));\n const onTone = TONE_CLASSES[toneOn];\n\n return (\n <div\n ref={ref}\n data-react-fancy-timegrid=\"\"\n className={cn(\n \"select-none overflow-x-auto\",\n className,\n )}\n onMouseLeave={() => setDrag(null)}\n onMouseUp={() => setDrag(null)}\n >\n <table className=\"text-[10px]\">\n <thead>\n <tr>\n <th />\n {cols.map((label, c) => (\n <th\n key={c}\n onClick={() => toggleCol(c)}\n style={{ width: cellWidth }}\n data-react-fancy-timegrid-col={c}\n className={cn(\n \"text-zinc-400\",\n toggleStripsOnHeaderClick &&\n \"cursor-pointer hover:text-zinc-700 dark:hover:text-zinc-200\",\n )}\n >\n {sparseColLabels ? (c % colStep === 0 ? label : \"\") : label}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {rows.map((label, r) => (\n <tr key={r}>\n <th\n onClick={() => toggleRow(r)}\n data-react-fancy-timegrid-row={r}\n className={cn(\n \"pr-1 text-right font-medium text-zinc-500\",\n toggleStripsOnHeaderClick &&\n \"cursor-pointer hover:text-zinc-800 dark:hover:text-zinc-200\",\n )}\n >\n {label}\n </th>\n {cols.map((_, c) => {\n const on = value[r]?.[c] ?? false;\n return (\n <td key={c} className=\"p-px\">\n <button\n type=\"button\"\n onMouseDown={() => {\n const v = !on;\n setDrag(v);\n setCell(r, c, v);\n }}\n onMouseEnter={() => drag !== null && setCell(r, c, drag)}\n style={{ width: cellWidth, height: cellHeight }}\n data-react-fancy-timegrid-cell={\n cellId ? cellId(r, c) : `${r}:${c}`\n }\n aria-pressed={on}\n aria-label={\n ariaCell\n ? ariaCell(r, c, on)\n : `${rows[r]} ${cols[c]} ${on ? \"on\" : \"off\"}`\n }\n className={cn(\n \"block rounded-sm transition\",\n on ? onTone : OFF_CLASSES,\n )}\n />\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n },\n);\n\nTimeGrid.displayName = \"TimeGrid\";\n"]}