@particle-academy/react-fancy 5.54.1 → 5.55.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.
Files changed (50) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/dist/button.cjs +3 -3
  3. package/dist/button.js +1 -1
  4. package/dist/{chunk-ZFU4FY3Q.js → chunk-4FZOH7BJ.js} +3 -3
  5. package/dist/{chunk-ZFU4FY3Q.js.map → chunk-4FZOH7BJ.js.map} +1 -1
  6. package/dist/{chunk-TCW72JBU.cjs → chunk-6XX6OHAP.cjs} +15 -15
  7. package/dist/{chunk-TCW72JBU.cjs.map → chunk-6XX6OHAP.cjs.map} +1 -1
  8. package/dist/{chunk-I2TBENUQ.cjs → chunk-7R7HENZG.cjs} +6 -6
  9. package/dist/{chunk-I2TBENUQ.cjs.map → chunk-7R7HENZG.cjs.map} +1 -1
  10. package/dist/{chunk-XOXA3QZR.cjs → chunk-C5YX5XVL.cjs} +3 -3
  11. package/dist/chunk-C5YX5XVL.cjs.map +1 -0
  12. package/dist/{chunk-EULOJOTU.js → chunk-DAJPPKPO.js} +3 -3
  13. package/dist/{chunk-EULOJOTU.js.map → chunk-DAJPPKPO.js.map} +1 -1
  14. package/dist/{chunk-REKY2CM6.js → chunk-KQYOIPHQ.js} +3 -3
  15. package/dist/{chunk-REKY2CM6.js.map → chunk-KQYOIPHQ.js.map} +1 -1
  16. package/dist/{chunk-4I4Y5MZO.cjs → chunk-LVE6ERRS.cjs} +4 -4
  17. package/dist/{chunk-4I4Y5MZO.cjs.map → chunk-LVE6ERRS.cjs.map} +1 -1
  18. package/dist/chunk-SFJ5WOX5.js +703 -0
  19. package/dist/chunk-SFJ5WOX5.js.map +1 -0
  20. package/dist/{chunk-6GKR5OAW.cjs → chunk-SIEPD6NR.cjs} +4 -4
  21. package/dist/{chunk-6GKR5OAW.cjs.map → chunk-SIEPD6NR.cjs.map} +1 -1
  22. package/dist/{chunk-45JO5BEZ.js → chunk-TLRRMYNV.js} +3 -3
  23. package/dist/chunk-TLRRMYNV.js.map +1 -0
  24. package/dist/chunk-XO4UWQCU.cjs +705 -0
  25. package/dist/chunk-XO4UWQCU.cjs.map +1 -0
  26. package/dist/{chunk-TBXZ3NGR.js → chunk-YBRQTZKV.js} +3 -3
  27. package/dist/{chunk-TBXZ3NGR.js.map → chunk-YBRQTZKV.js.map} +1 -1
  28. package/dist/index.cjs +27 -27
  29. package/dist/index.d.cts +1 -1
  30. package/dist/index.d.ts +1 -1
  31. package/dist/index.js +6 -6
  32. package/dist/json-editor.cjs +13 -13
  33. package/dist/json-editor.js +2 -2
  34. package/dist/magic-wand.cjs +3 -3
  35. package/dist/magic-wand.js +2 -2
  36. package/dist/prompt-input.cjs +3 -3
  37. package/dist/prompt-input.js +2 -2
  38. package/dist/reason-tag.cjs +3 -3
  39. package/dist/reason-tag.js +2 -2
  40. package/dist/time-grid.cjs +3 -2
  41. package/dist/time-grid.d.cts +120 -17
  42. package/dist/time-grid.d.ts +120 -17
  43. package/dist/time-grid.js +2 -1
  44. package/package.json +1 -1
  45. package/dist/chunk-45JO5BEZ.js.map +0 -1
  46. package/dist/chunk-GF23UBOT.js +0 -129
  47. package/dist/chunk-GF23UBOT.js.map +0 -1
  48. package/dist/chunk-WFHK2DKG.cjs +0 -131
  49. package/dist/chunk-WFHK2DKG.cjs.map +0 -1
  50. package/dist/chunk-XOXA3QZR.cjs.map +0 -1
@@ -1,4 +1,5 @@
1
1
  import * as react from 'react';
2
+ import { ReactNode } from 'react';
2
3
 
3
4
  /**
4
5
  * Subset of palette colors the TimeGrid offers for the "cell-on" tone —
@@ -6,20 +7,88 @@ import * as react from 'react';
6
7
  * use cases.
7
8
  */
8
9
  type TimeGridTone = "violet" | "emerald" | "sky" | "rose" | "amber" | "indigo" | "blue" | "zinc";
10
+ /**
11
+ * One typed cell. The kit declares the SHAPE; the host declares the
12
+ * vocabulary through `states` and `marks`.
13
+ */
14
+ type TimeGridCell = {
15
+ /** A key of `states`. The exclusive dimension (open / closed / booked …). */
16
+ state: string;
17
+ /** Blocks selection. Distinct from a state that merely looks unavailable. */
18
+ disabled?: boolean;
19
+ /** Why — surfaced in the title, the cell's aria-description and `onBlockedSelect`. */
20
+ reasons?: string[];
21
+ /** Keys of `marks`. Overlays drawn on top of the state tone. Non-exclusive. */
22
+ marks?: string[];
23
+ /** Passed back verbatim in every callback. The kit never reads it. */
24
+ meta?: unknown;
25
+ };
26
+ /** A state in the host's vocabulary. */
27
+ type TimeGridStateDef = {
28
+ /** Fill tone. Omit for the neutral surface (`--fancy-surface-muted`). */
29
+ tone?: TimeGridTone;
30
+ /** What a screen reader hears for this state. Default: the state id. */
31
+ label?: string;
32
+ /** Extra classes on every cell in this state — the host's own styling. */
33
+ className?: string;
34
+ };
35
+ /** An overlay mark: a tone dot or an icon, plus the label a screen reader gets. */
36
+ type TimeGridMarkDef = {
37
+ tone?: TimeGridTone;
38
+ /**
39
+ * Drawn instead of the tone dot, in a 10px box — e.g. `<Icon name="lock" />`.
40
+ * A node rather than an icon name on purpose: resolving names would make
41
+ * TimeGrid import the whole Lucide set into every bundle that uses it.
42
+ */
43
+ icon?: ReactNode;
44
+ label?: string;
45
+ };
46
+ /** A cell coordinate: row index, column index. */
47
+ type TimeGridCoord = {
48
+ r: number;
49
+ c: number;
50
+ };
51
+ /**
52
+ * Both shapes are real and they are NOT the same value:
53
+ *
54
+ * - `rectangle`: the same window across several rows — 09:00-17:00 Mon-Fri.
55
+ * Normalised so r1 <= r2 and c1 <= c2.
56
+ * - `linear`: ONE continuous run in reading order (row-major), which may cross
57
+ * a row end and keep going — 23:54 Monday through 00:06 Tuesday. Normalised
58
+ * so `from` precedes `to`.
59
+ */
60
+ type TimeGridSelection = {
61
+ shape: "rectangle";
62
+ r1: number;
63
+ c1: number;
64
+ r2: number;
65
+ c2: number;
66
+ } | {
67
+ shape: "linear";
68
+ from: TimeGridCoord;
69
+ to: TimeGridCoord;
70
+ };
71
+ type TimeGridSelectionShape = TimeGridSelection["shape"];
72
+ /** What a range that crosses a disabled cell does. */
73
+ type TimeGridDisabledRange = "clamp" | "refuse" | "span";
74
+ type TimeGridBlockedCell = {
75
+ r: number;
76
+ c: number;
77
+ reasons?: string[];
78
+ };
9
79
  interface TimeGridProps {
10
- /** Row labels, one per row in `value` (e.g. ["Sun","Mon",…]). */
80
+ /** Row labels, one per row (e.g. ["Sun","Mon",…]). */
11
81
  rows: string[];
12
- /** Column labels, one per column in `value` (e.g. ["0","1",…,"23"]). */
82
+ /** Column labels, one per column (e.g. ["0","1",…,"23"]). */
13
83
  cols: string[];
14
84
  /**
15
- * Controlled cell state. Must be a rectangular `rows.length × cols.length`
16
- * matrix of booleans. The component never mutates it — every change
17
- * produces a new array passed to `onChange`.
85
+ * Boolean grid: controlled cell state, a rectangular
86
+ * `rows.length × cols.length` matrix. Ignored when `cells` is given.
18
87
  */
19
- value: boolean[][];
20
- /** Called with the next matrix whenever a cell, row, or column toggles. */
21
- onChange: (next: boolean[][]) => void;
22
- /** Cell-on tone. Default `"violet"`. */
88
+ value?: boolean[][];
89
+ /** Boolean grid: called with the next matrix whenever a cell, row, or column toggles. */
90
+ onChange?: (next: boolean[][]) => void;
91
+ /** Boolean grid: cell-on tone. Default `"violet"`. */
23
92
  toneOn?: TimeGridTone;
24
93
  /** Cell width in px. Default `20`. */
25
94
  cellWidth?: number;
@@ -30,24 +99,58 @@ interface TimeGridProps {
30
99
  * top axis legible at small `cellWidth`. Set false to show all labels.
31
100
  */
32
101
  sparseColLabels?: boolean;
33
- /** If true (default), clicking a row/column header toggles that strip. */
102
+ /**
103
+ * If true (default), clicking a row/column header toggles that strip
104
+ * (boolean grid) or selects it (typed grid).
105
+ */
34
106
  toggleStripsOnHeaderClick?: boolean;
35
107
  /**
36
- * Optional accessible label per cell. Default produces
37
- * `${rows[r]} ${cols[c]} on|off`. Override for richer context
38
- * (e.g. include unit: `${rows[r]} ${cols[c]}:00 ${on ? "on" : "off"}`).
108
+ * Optional accessible label per cell. Boolean grid default:
109
+ * `${rows[r]} ${cols[c]} on|off`; `on` is the cell value. Typed grid default:
110
+ * `${rows[r]} ${cols[c]} ${state label}[, mark labels]`; `on` is whether the
111
+ * cell is selected.
39
112
  */
40
113
  ariaCell?: (rowIdx: number, colIdx: number, on: boolean) => string;
41
114
  /**
42
- * Stable per-cell identifier. Emitted as `data-react-fancy-timegrid-cell`
43
- * on the button so MCP bridges can address a specific cell from a tool
44
- * call without DOM walking. Default `${row}:${col}`.
115
+ * Stable per-cell identifier, emitted as `data-react-fancy-timegrid-cell` so
116
+ * MCP bridges can address a specific cell without DOM walking. Default
117
+ * `${row}:${col}`.
45
118
  */
46
119
  cellId?: (rowIdx: number, colIdx: number) => string;
47
120
  /** Additional CSS classes on the outer scroll container. */
48
121
  className?: string;
122
+ /** Host's state vocabulary: id -> tone + label. Required with `cells`. */
123
+ states?: Record<string, TimeGridStateDef>;
124
+ /** Host's overlay vocabulary: id -> tone/icon + label. */
125
+ marks?: Record<string, TimeGridMarkDef>;
126
+ /**
127
+ * Typed cells, `rows.length × cols.length`. When present the grid renders
128
+ * these (with `states`) and `value`/`onChange` are ignored.
129
+ */
130
+ cells?: TimeGridCell[][];
131
+ /** Which shape a drag / Shift+arrow produces. Default `"rectangle"`. */
132
+ selectionShape?: TimeGridSelectionShape;
133
+ /** Controlled selection. `null` = nothing selected. Omit for uncontrolled. */
134
+ selection?: TimeGridSelection | null;
135
+ /** `cells` arrive in SELECTION ORDER — row-major, so time order for a linear run. */
136
+ onSelectionChange?: (next: TimeGridSelection | null, cells: TimeGridCell[]) => void;
137
+ /** A drag ended, or Enter was pressed. Same arguments as `onSelectionChange`. */
138
+ onSelectionCommit?: (selection: TimeGridSelection, cells: TimeGridCell[]) => void;
139
+ /** What a range that crosses a disabled cell does. Default `"clamp"`. */
140
+ disabledRange?: TimeGridDisabledRange;
141
+ /** Fires when a selection was refused or clipped by disabled cells. */
142
+ onBlockedSelect?: (blocked: TimeGridBlockedCell[]) => void;
143
+ /** Hover, for a host-owned detail panel. `null, null` when the pointer leaves. */
144
+ onCellHover?: (cell: TimeGridCell | null, at: TimeGridCoord | null) => void;
145
+ /** Accessible name of the grid (typed grid). */
146
+ "aria-label"?: string;
49
147
  }
50
148
 
149
+ /**
150
+ * Two grids behind one name. `cells` (5.55.0) selects the typed grid: the
151
+ * host's state vocabulary, range selection, keyboard. Without it this is the
152
+ * boolean grid, unchanged since before 5.55.0.
153
+ */
51
154
  declare const TimeGrid: react.ForwardRefExoticComponent<TimeGridProps & react.RefAttributes<HTMLDivElement>>;
52
155
 
53
- export { TimeGrid, type TimeGridProps, type TimeGridTone };
156
+ export { TimeGrid, type TimeGridBlockedCell, type TimeGridCell, type TimeGridCoord, type TimeGridDisabledRange, type TimeGridMarkDef, type TimeGridProps, type TimeGridSelection, type TimeGridSelectionShape, type TimeGridStateDef, type TimeGridTone };
package/dist/time-grid.js CHANGED
@@ -1,4 +1,5 @@
1
- export { TimeGrid } from './chunk-GF23UBOT.js';
1
+ export { TimeGrid } from './chunk-SFJ5WOX5.js';
2
+ import './chunk-SV5BW3IA.js';
2
3
  import './chunk-MMW2JGKZ.js';
3
4
  //# sourceMappingURL=time-grid.js.map
4
5
  //# sourceMappingURL=time-grid.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@particle-academy/react-fancy",
3
- "version": "5.54.1",
3
+ "version": "5.55.0",
4
4
  "description": "React UI component library for Human+ UX — controlled, agent-bridgeable primitives",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/Button/Button.colors.ts","../src/components/Button/Button.tsx"],"names":[],"mappings":"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","file":"chunk-45JO5BEZ.js","sourcesContent":["// AUTO-GENERATED by scripts/gen-button-colors — do not edit by hand.\n// Literal Tailwind class strings for every color in the v4 palette so the\n// scanner can detect them in the published dist (template-built names are\n// invisible to Tailwind's JIT). Regenerate after changing the palette.\nimport type { Color } from \"../../utils/types\";\n\nexport const buttonColorClasses: Record<Color, string> = {\n // The host's colour, from CSS variables -- no dark: variant, because a\n // host that themes per mode scopes the variables themselves.\n brand: \"bg-brand text-brand-contrast border border-brand hover:bg-brand-hover\",\n slate: \"bg-slate-500 text-white border border-slate-600 hover:bg-slate-600 dark:bg-slate-600 dark:border-slate-500 dark:hover:bg-slate-500\",\n gray: \"bg-gray-500 text-white border border-gray-600 hover:bg-gray-600 dark:bg-gray-600 dark:border-gray-500 dark:hover:bg-gray-500\",\n zinc: \"bg-zinc-500 text-white border border-zinc-600 hover:bg-zinc-600 dark:bg-zinc-600 dark:border-zinc-500 dark:hover:bg-zinc-500\",\n neutral: \"bg-neutral-500 text-white border border-neutral-600 hover:bg-neutral-600 dark:bg-neutral-600 dark:border-neutral-500 dark:hover:bg-neutral-500\",\n stone: \"bg-stone-500 text-white border border-stone-600 hover:bg-stone-600 dark:bg-stone-600 dark:border-stone-500 dark:hover:bg-stone-500\",\n red: \"bg-red-500 text-white border border-red-600 hover:bg-red-600 dark:bg-red-600 dark:border-red-500 dark:hover:bg-red-500\",\n orange: \"bg-orange-500 text-white border border-orange-600 hover:bg-orange-600 dark:bg-orange-600 dark:border-orange-500 dark:hover:bg-orange-500\",\n amber: \"bg-amber-400 text-amber-950 border border-amber-500 hover:bg-amber-500 dark:bg-amber-300 dark:text-amber-950 dark:border-amber-400 dark:hover:bg-amber-400\",\n yellow: \"bg-yellow-400 text-yellow-950 border border-yellow-500 hover:bg-yellow-500 dark:bg-yellow-300 dark:text-yellow-950 dark:border-yellow-400 dark:hover:bg-yellow-400\",\n lime: \"bg-lime-400 text-lime-950 border border-lime-500 hover:bg-lime-500 dark:bg-lime-300 dark:text-lime-950 dark:border-lime-400 dark:hover:bg-lime-400\",\n green: \"bg-green-500 text-white border border-green-600 hover:bg-green-600 dark:bg-green-600 dark:border-green-500 dark:hover:bg-green-500\",\n emerald: \"bg-emerald-500 text-white border border-emerald-600 hover:bg-emerald-600 dark:bg-emerald-600 dark:border-emerald-500 dark:hover:bg-emerald-500\",\n teal: \"bg-teal-500 text-white border border-teal-600 hover:bg-teal-600 dark:bg-teal-600 dark:border-teal-500 dark:hover:bg-teal-500\",\n cyan: \"bg-cyan-500 text-white border border-cyan-600 hover:bg-cyan-600 dark:bg-cyan-600 dark:border-cyan-500 dark:hover:bg-cyan-500\",\n sky: \"bg-sky-500 text-white border border-sky-600 hover:bg-sky-600 dark:bg-sky-600 dark:border-sky-500 dark:hover:bg-sky-500\",\n blue: \"bg-blue-500 text-white border border-blue-600 hover:bg-blue-600 dark:bg-blue-600 dark:border-blue-500 dark:hover:bg-blue-500\",\n indigo: \"bg-indigo-500 text-white border border-indigo-600 hover:bg-indigo-600 dark:bg-indigo-600 dark:border-indigo-500 dark:hover:bg-indigo-500\",\n violet: \"bg-violet-500 text-white border border-violet-600 hover:bg-violet-600 dark:bg-violet-600 dark:border-violet-500 dark:hover:bg-violet-500\",\n purple: \"bg-purple-500 text-white border border-purple-600 hover:bg-purple-600 dark:bg-purple-600 dark:border-purple-500 dark:hover:bg-purple-500\",\n fuchsia: \"bg-fuchsia-500 text-white border border-fuchsia-600 hover:bg-fuchsia-600 dark:bg-fuchsia-600 dark:border-fuchsia-500 dark:hover:bg-fuchsia-500\",\n pink: \"bg-pink-500 text-white border border-pink-600 hover:bg-pink-600 dark:bg-pink-600 dark:border-pink-500 dark:hover:bg-pink-500\",\n rose: \"bg-rose-500 text-white border border-rose-600 hover:bg-rose-600 dark:bg-rose-600 dark:border-rose-500 dark:hover:bg-rose-500\",\n};\n\nexport const buttonGhostClasses: Record<Color, string> = {\n // The host's colour, from CSS variables -- no dark: variant, because a\n // host that themes per mode scopes the variables themselves.\n brand: \"bg-transparent text-brand hover:bg-brand/10\",\n slate: \"bg-transparent text-slate-600 hover:bg-slate-50 dark:text-slate-400 dark:hover:bg-slate-950/50\",\n gray: \"bg-transparent text-gray-600 hover:bg-gray-50 dark:text-gray-400 dark:hover:bg-gray-950/50\",\n zinc: \"bg-transparent text-zinc-600 hover:bg-zinc-50 dark:text-zinc-400 dark:hover:bg-zinc-950/50\",\n neutral: \"bg-transparent text-neutral-600 hover:bg-neutral-50 dark:text-neutral-400 dark:hover:bg-neutral-950/50\",\n stone: \"bg-transparent text-stone-600 hover:bg-stone-50 dark:text-stone-400 dark:hover:bg-stone-950/50\",\n red: \"bg-transparent text-red-600 hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-950/50\",\n orange: \"bg-transparent text-orange-600 hover:bg-orange-50 dark:text-orange-400 dark:hover:bg-orange-950/50\",\n amber: \"bg-transparent text-amber-600 hover:bg-amber-50 dark:text-amber-400 dark:hover:bg-amber-950/50\",\n yellow: \"bg-transparent text-yellow-600 hover:bg-yellow-50 dark:text-yellow-400 dark:hover:bg-yellow-950/50\",\n lime: \"bg-transparent text-lime-600 hover:bg-lime-50 dark:text-lime-400 dark:hover:bg-lime-950/50\",\n green: \"bg-transparent text-green-600 hover:bg-green-50 dark:text-green-400 dark:hover:bg-green-950/50\",\n emerald: \"bg-transparent text-emerald-600 hover:bg-emerald-50 dark:text-emerald-400 dark:hover:bg-emerald-950/50\",\n teal: \"bg-transparent text-teal-600 hover:bg-teal-50 dark:text-teal-400 dark:hover:bg-teal-950/50\",\n cyan: \"bg-transparent text-cyan-600 hover:bg-cyan-50 dark:text-cyan-400 dark:hover:bg-cyan-950/50\",\n sky: \"bg-transparent text-sky-600 hover:bg-sky-50 dark:text-sky-400 dark:hover:bg-sky-950/50\",\n blue: \"bg-transparent text-blue-600 hover:bg-blue-50 dark:text-blue-400 dark:hover:bg-blue-950/50\",\n indigo: \"bg-transparent text-indigo-600 hover:bg-indigo-50 dark:text-indigo-400 dark:hover:bg-indigo-950/50\",\n violet: \"bg-transparent text-violet-600 hover:bg-violet-50 dark:text-violet-400 dark:hover:bg-violet-950/50\",\n purple: \"bg-transparent text-purple-600 hover:bg-purple-50 dark:text-purple-400 dark:hover:bg-purple-950/50\",\n fuchsia: \"bg-transparent text-fuchsia-600 hover:bg-fuchsia-50 dark:text-fuchsia-400 dark:hover:bg-fuchsia-950/50\",\n pink: \"bg-transparent text-pink-600 hover:bg-pink-50 dark:text-pink-400 dark:hover:bg-pink-950/50\",\n rose: \"bg-transparent text-rose-600 hover:bg-rose-50 dark:text-rose-400 dark:hover:bg-rose-950/50\",\n};\n","import { forwardRef, type AnchorHTMLAttributes, type ElementType, type ForwardedRef, type ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { sanitizeHref } from \"../../utils/sanitize\";\nimport { resolve } from \"../../data/emoji-utils\";\nimport { Icon } from \"../Icon/Icon\";\nimport type { ButtonProps } from \"./Button.types\";\nimport type { ButtonColor, Size } from \"../../utils/types\";\nimport {\n buttonColorClasses as colorClasses,\n buttonGhostClasses as ghostColorClasses,\n} from \"./Button.colors\";\n\nconst iconSizeMap: Record<Size, \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\"> = {\n xs: \"xs\",\n sm: \"xs\",\n md: \"sm\",\n lg: \"md\",\n xl: \"lg\",\n};\n\nconst alertIconSizeMap: Record<Size, \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\"> = {\n xs: \"xs\",\n sm: \"xs\",\n md: \"xs\",\n lg: \"sm\",\n xl: \"sm\",\n};\n\n// ---------------------------------------------------------------------------\n// Color classes\n//\n// Solid + ghost color maps live in ./Button.colors (AUTO-GENERATED, all 22\n// Tailwind v4 hues as literal strings). The state-color classes below\n// (default/active/checked/warn) branch on flags, not specific colors.\n// ---------------------------------------------------------------------------\n\nconst defaultClasses =\n \"bg-white text-[color:var(--fancy-text-soft,var(--color-zinc-700))] border border-[color:var(--fancy-border,var(--color-zinc-200))] hover:bg-zinc-50 hover:border-zinc-300 dark:bg-zinc-800 dark:text-[color:var(--fancy-text-soft-dark,var(--color-zinc-300))] dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:hover:bg-zinc-700\";\n\nconst activeClasses =\n \"bg-blue-500 text-white border border-blue-600 hover:bg-blue-600 dark:bg-blue-600 dark:border-blue-500 dark:hover:bg-blue-500\";\n\nconst checkedClasses =\n \"bg-emerald-500 text-white border border-emerald-600 hover:bg-emerald-600 dark:bg-emerald-600 dark:border-emerald-500 dark:hover:bg-emerald-500\";\n\nconst warnClasses =\n \"bg-amber-50 text-amber-700 border border-amber-200 hover:bg-amber-100 dark:bg-amber-900/30 dark:text-amber-300 dark:border-amber-700 dark:hover:bg-amber-900/50\";\n\nconst ghostDefaultClasses =\n \"bg-transparent 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\nconst ghostActiveClasses =\n \"bg-blue-50 text-blue-700 hover:bg-blue-100 dark:bg-blue-950/50 dark:text-blue-300 dark:hover:bg-blue-950\";\n\nconst ghostCheckedClasses =\n \"bg-emerald-50 text-emerald-700 hover:bg-emerald-100 dark:bg-emerald-950/50 dark:text-emerald-300 dark:hover:bg-emerald-950\";\n\nconst ghostWarnClasses =\n \"bg-transparent text-amber-700 hover:bg-amber-50 dark:text-amber-300 dark:hover:bg-amber-950/50\";\n\n// ---------------------------------------------------------------------------\n// Size helpers\n// ---------------------------------------------------------------------------\n\nconst horizontalSize: Record<Size, string> = {\n xs: \"px-2 py-1 text-xs\",\n sm: \"px-2 py-1 text-xs\",\n md: \"px-3 py-1.5 text-sm\",\n lg: \"px-4 py-2.5 text-base\",\n xl: \"px-5 py-3 text-lg\",\n};\n\nconst circleSize: Record<Size, string> = {\n xs: \"w-7 h-7 text-xs\",\n sm: \"w-8 h-8 text-xs\",\n md: \"w-10 h-10 text-sm\",\n lg: \"w-12 h-12 text-base\",\n xl: \"w-14 h-14 text-lg\",\n};\n\nconst iconSize: Record<Size, string> = {\n xs: \"w-3 h-3\",\n sm: \"w-3 h-3\",\n md: \"w-4 h-4\",\n lg: \"w-5 h-5\",\n xl: \"w-6 h-6\",\n};\n\nconst avatarSize: Record<Size, string> = {\n xs: \"w-4 h-4\",\n sm: \"w-4 h-4\",\n md: \"w-5 h-5\",\n lg: \"w-6 h-6\",\n xl: \"w-7 h-7\",\n};\n\nconst alertIconSize: Record<Size, string> = {\n xs: \"w-2 h-2\",\n sm: \"w-2.5 h-2.5\",\n md: \"w-3 h-3\",\n lg: \"w-4 h-4\",\n xl: \"w-4 h-4\",\n};\n\nconst badgeSize: Record<Size, string> = {\n xs: \"text-[10px] px-1 min-w-[14px] h-3.5\",\n sm: \"text-[10px] px-1.5 min-w-[16px] h-4\",\n md: \"text-[11px] px-1.5 min-w-[18px] h-[18px]\",\n lg: \"text-xs px-2 min-w-[22px] h-5\",\n xl: \"text-xs px-2 min-w-[24px] h-5\",\n};\n\nconst externalIconOffset: Record<Size, string> = {\n xs: \"0.75rem\",\n sm: \"0.75rem\",\n md: \"1rem\",\n lg: \"1.25rem\",\n xl: \"1.5rem\",\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction isColored(color?: ButtonColor, active?: boolean, checked?: boolean): boolean {\n return !!(color || active || checked);\n}\n\nfunction getColorClasses(\n color?: ButtonColor,\n active?: boolean,\n checked?: boolean,\n warn?: boolean,\n ghost?: boolean,\n): string {\n if (ghost) {\n if (color) return ghostColorClasses[color];\n if (checked) return ghostCheckedClasses;\n if (active) return ghostActiveClasses;\n if (warn) return ghostWarnClasses;\n return ghostDefaultClasses;\n }\n if (color) return colorClasses[color];\n if (checked) return checkedClasses;\n if (active) return activeClasses;\n if (warn) return warnClasses;\n return defaultClasses;\n}\n\nfunction getIconColorClasses(\n color?: ButtonColor,\n active?: boolean,\n checked?: boolean,\n warn?: boolean,\n ghost?: boolean,\n): string {\n if (ghost) {\n // Ghost variant: icon inherits currentColor from the button text\n return \"text-current\";\n }\n // A filled button's icon takes the label's colour — whatever that colour class\n // says, including a host's per-mode `text-brand-contrast` and the dark labels on\n // amber / yellow / lime. Hard-coded white was invisible on any light fill.\n if (color || active || checked) return \"text-current\";\n if (warn) return \"text-amber-600 dark:text-amber-400\";\n return \"text-[color:var(--fancy-text-muted,var(--color-zinc-500))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))]\";\n}\n\nfunction getBadgeClasses(\n color?: ButtonColor,\n active?: boolean,\n checked?: boolean,\n warn?: boolean,\n ghost?: boolean,\n): string {\n if (ghost) {\n return \"bg-current/10 text-current\";\n }\n // Tinted with the label's own colour, for the same reason as the icon.\n if (isColored(color, active, checked)) return \"bg-current/20 text-current\";\n if (warn) return \"bg-amber-200 text-amber-800 dark:bg-amber-800 dark:text-amber-200\";\n return \"bg-zinc-200 text-zinc-700 dark:bg-zinc-600 dark:text-zinc-200\";\n}\n\n// ---------------------------------------------------------------------------\n// Placement parsing\n// ---------------------------------------------------------------------------\n\ntype PlacementAxis = \"left\" | \"right\" | \"top\" | \"bottom\";\n\nfunction parsePlacement(iconPlace: string): { primary: PlacementAxis; secondary?: PlacementAxis } {\n const parts = iconPlace.split(\" \") as PlacementAxis[];\n return { primary: parts[0], secondary: parts[1] };\n}\n\nfunction isVerticalPrimary(primary: PlacementAxis): boolean {\n return primary === \"top\" || primary === \"bottom\";\n}\n\n// ---------------------------------------------------------------------------\n// Sort parsing\n// ---------------------------------------------------------------------------\n\ntype ElementKey = \"e\" | \"i\" | \"a\" | \"b\";\nconst DEFAULT_SORT = \"eiab\";\n\nfunction parseSortOrder(sort?: string): ElementKey[] {\n const chars = (sort ?? DEFAULT_SORT).split(\"\") as ElementKey[];\n const valid: ElementKey[] = [];\n const seen = new Set<string>();\n for (const c of chars) {\n if (\"eiab\".includes(c) && !seen.has(c)) {\n valid.push(c);\n seen.add(c);\n }\n }\n // Add missing keys in default order\n for (const c of DEFAULT_SORT.split(\"\") as ElementKey[]) {\n if (!seen.has(c)) valid.push(c);\n }\n return valid;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n children,\n className,\n variant = \"default\",\n color,\n size = \"md\",\n active,\n checked,\n warn,\n alert: alertProp,\n icon,\n iconTrailing,\n iconPlace = \"left\",\n alertIcon,\n alertIconTrailing,\n emoji,\n emojiTrailing,\n avatar,\n avatarTrailing,\n badge,\n badgeTrailing,\n sort,\n loading = false,\n disabled,\n href,\n as: As,\n responsive,\n labelClassName,\n ...props\n },\n ref,\n ) => {\n const isCircle = variant === \"circle\";\n const isGhost = variant === \"ghost\";\n const { primary, secondary } = parsePlacement(iconPlace);\n const isVertical = isVerticalPrimary(primary);\n const isCompound = !!secondary;\n const needsWrapper = isVertical || isCompound;\n const isReversed = iconPlace === \"right\";\n\n // -----------------------------------------------------------------------\n // Sizing — always use horizontalSize for the button itself\n // -----------------------------------------------------------------------\n const sizeClass = isCircle ? circleSize[size] : horizontalSize[size];\n\n // -----------------------------------------------------------------------\n // Build decorative elements\n // -----------------------------------------------------------------------\n const iconColorCls = getIconColorClasses(color, active, checked, warn, isGhost);\n\n const buildElement = (key: ElementKey, trailing: boolean): ReactNode => {\n switch (key) {\n case \"e\": {\n const slug = trailing ? emojiTrailing : emoji;\n if (!slug) return null;\n const char = resolve(slug);\n if (!char) return null;\n return (\n <span key={`emoji-${trailing ? \"t\" : \"l\"}`} data-action-emoji>\n {char}\n </span>\n );\n }\n case \"i\": {\n if (loading && !trailing) {\n return (\n <span\n key=\"spinner\"\n className={cn(\"animate-spin border-2 border-current border-t-transparent rounded-full\", iconSize[size])}\n />\n );\n }\n const iconSlug = trailing ? iconTrailing : icon;\n if (!iconSlug) return null;\n // For vertical/compound placements, icons render outside the button — not inside\n if (needsWrapper) return null;\n return (\n <span\n key={`icon-${trailing ? \"t\" : \"l\"}`}\n data-action-icon={trailing ? \"trailing\" : \"leading\"}\n className={cn(\"inline-flex items-center flex-shrink-0\", iconColorCls)}\n >\n <Icon name={iconSlug} size={iconSizeMap[size]} />\n </span>\n );\n }\n case \"a\": {\n if (!avatar) return null;\n const isTrailing = avatarTrailing ?? false;\n if (isTrailing !== trailing) return null;\n return (\n <img\n key=\"avatar\"\n src={avatar}\n alt=\"\"\n className={cn(avatarSize[size], \"rounded-full object-cover flex-shrink-0\")}\n data-action-avatar\n />\n );\n }\n case \"b\": {\n if (!badge) return null;\n const isTrailing = badgeTrailing ?? false;\n if (isTrailing !== trailing) return null;\n return (\n <span\n key=\"badge\"\n className={cn(\n \"inline-flex items-center justify-center font-medium rounded-full\",\n badgeSize[size],\n getBadgeClasses(color, active, checked, warn, isGhost),\n )}\n data-action-badge\n >\n {badge}\n </span>\n );\n }\n default:\n return null;\n }\n };\n\n // Alert icon element\n const renderAlertIcon = (trailing: boolean): ReactNode => {\n if (!alertIcon) return null;\n const isTrailing = alertIconTrailing ?? false;\n if (isTrailing !== trailing) return null;\n const alertIconEl = <Icon name={alertIcon} size={alertIconSizeMap[size]} />;\n return (\n <span\n key=\"alert-icon\"\n className=\"relative inline-flex flex-shrink-0\"\n data-action-alert\n >\n <span className=\"text-red-500 dark:text-red-400 animate-pulse\">\n {alertIconEl}\n </span>\n <span className=\"absolute inset-0 flex items-center justify-center text-red-400 dark:text-red-300 animate-ping opacity-75\">\n {alertIconEl}\n </span>\n </span>\n );\n };\n\n const sortOrder = parseSortOrder(sort);\n\n const leadingElements: ReactNode[] = [];\n const trailingElements: ReactNode[] = [];\n\n for (const key of sortOrder) {\n const leading = buildElement(key, false);\n if (leading) leadingElements.push(leading);\n const trailing = buildElement(key, true);\n if (trailing) trailingElements.push(trailing);\n }\n\n // Insert alert icon\n const leadingAlert = renderAlertIcon(false);\n if (leadingAlert) leadingElements.push(leadingAlert);\n const trailingAlert = renderAlertIcon(true);\n if (trailingAlert) trailingElements.push(trailingAlert);\n\n // -----------------------------------------------------------------------\n // Classes\n // -----------------------------------------------------------------------\n const classes = cn(\n // `text-left` overrides the UA <button> center default so a wrapped,\n // width-constrained multi-word label stacks left-aligned. Overridable —\n // twMerge lets a `text-center` / `text-right` in `className` win.\n \"inline-flex items-center justify-center text-left font-medium transition-all duration-200\",\n \"focus:outline-none focus:ring-2 focus:ring-offset-1\",\n \"disabled:opacity-50 disabled:cursor-not-allowed\",\n isCircle ? \"rounded-full\" : \"rounded-lg\",\n sizeClass,\n getColorClasses(color, active, checked, warn, isGhost),\n !isCircle && !needsWrapper && \"gap-2\",\n !isCircle && needsWrapper && \"gap-2\",\n isReversed && !needsWrapper && \"flex-row-reverse\",\n alertProp && \"animate-pulse\",\n className,\n );\n\n // -----------------------------------------------------------------------\n // Content\n // -----------------------------------------------------------------------\n const content = isCircle ? (\n <>\n {loading ? (\n <span\n className={cn(\n \"animate-spin border-2 border-current border-t-transparent rounded-full\",\n iconSize[size],\n )}\n />\n ) : (\n icon ? <Icon name={icon} size={iconSizeMap[size]} /> : children\n )}\n </>\n ) : (\n <>\n {leadingElements}\n {children != null && (\n <span\n data-react-fancy-button-label=\"\"\n className={cn(\n // A button narrower than its label WRAPS the label inside itself\n // (left-aligned, via the button's `text-left`); the icon is its own\n // shrink-0 flex item, so it stays put beside the text. `min-w-0`\n // lets the span shrink below its text. Words are never split\n // (measured: in the showcase's 104px column `break-words` turned\n // \"customer\" into \"custome/r\"). Unconstrained, nothing wraps and\n // the button looks as it always did.\n //\n // No white-space class here, on purpose: `labelClassName=\"truncate\"`\n // must win uncontested to give one line with an ellipsis, and a\n // `whitespace-normal` would fight its nowrap in the cascade.\n // (5.54.0 and earlier forced `whitespace-nowrap`, so a constrained\n // label spilled out of the button and over its neighbours.)\n \"min-w-0\",\n // `responsive` collapses to icon-only when squeezed, while keeping\n // the label readable to screen readers.\n responsive && \"sr-only sm:not-sr-only\",\n labelClassName,\n )}\n >\n {children}\n </span>\n )}\n {trailingElements}\n </>\n );\n\n // -----------------------------------------------------------------------\n // Build the button element\n // -----------------------------------------------------------------------\n const safeHref = sanitizeHref(href);\n // Anchor mode renders `as` when provided (e.g. a router's <Link> for\n // client-side navigation — Inertia, React Router, Next). Previously `as`\n // fell through ...props onto the <a> where React silently DROPS a\n // function-valued unknown attribute — so `<Button as={Link}>` looked fine\n // but did a full page load. `as` only applies in anchor mode; without an\n // href (or when disabled) the plain <button> renders as always.\n const Anchor = (As ?? \"a\") as ElementType;\n const buttonEl = safeHref && !disabled ? (\n // Anchor mode forwards the same rest props as the <button> branch so\n // onClick / target / rel / ref / ARIA / data-* reach the <a> (issue #7).\n <Anchor\n ref={ref as ForwardedRef<HTMLAnchorElement>}\n href={safeHref}\n className={classes}\n data-react-fancy-button=\"\"\n data-react-fancy-action=\"\"\n {...(props as AnchorHTMLAttributes<HTMLAnchorElement>)}\n >\n {content}\n </Anchor>\n ) : (\n <button\n ref={ref}\n className={classes}\n disabled={disabled || loading}\n data-react-fancy-button=\"\"\n data-react-fancy-action=\"\"\n {...props}\n >\n {content}\n </button>\n );\n\n // -----------------------------------------------------------------------\n // Wrap for vertical/compound icon placement\n // The icon is absolutely positioned so it never shifts the button.\n // -----------------------------------------------------------------------\n if (needsWrapper && (icon || iconTrailing)) {\n const iconSlug = icon ?? iconTrailing;\n const offset = externalIconOffset[size];\n\n // Determine position styles for the icon\n const posStyle: React.CSSProperties = { position: \"absolute\" };\n\n // Primary axis: which side of the button\n if (primary === \"top\") {\n posStyle.bottom = \"100%\";\n posStyle.marginBottom = \"0.125rem\";\n } else if (primary === \"bottom\") {\n posStyle.top = \"100%\";\n posStyle.marginTop = \"0.125rem\";\n } else if (primary === \"left\") {\n posStyle.right = \"100%\";\n posStyle.marginRight = \"0.125rem\";\n } else if (primary === \"right\") {\n posStyle.left = \"100%\";\n posStyle.marginLeft = \"0.125rem\";\n }\n\n // Secondary axis: cross-axis alignment\n if (isVerticalPrimary(primary)) {\n // Vertical primary → secondary controls horizontal position\n if (secondary === \"left\") {\n posStyle.left = \"0\";\n } else if (secondary === \"right\") {\n posStyle.right = \"0\";\n } else {\n // center (default)\n posStyle.left = \"50%\";\n posStyle.transform = \"translateX(-50%)\";\n }\n } else {\n // Horizontal primary → secondary controls vertical position\n if (secondary === \"top\") {\n posStyle.top = \"0\";\n } else if (secondary === \"bottom\") {\n posStyle.bottom = \"0\";\n } else {\n // center (default)\n posStyle.top = \"50%\";\n posStyle.transform = \"translateY(-50%)\";\n }\n }\n\n const externalIcon = (\n <span\n className={cn(\"absolute flex-shrink-0\", iconColorCls)}\n style={posStyle}\n >\n <Icon name={iconSlug!} size={iconSizeMap[size]} />\n </span>\n );\n\n return (\n <span\n data-react-fancy-action-group=\"\"\n className=\"relative inline-flex\"\n >\n {buttonEl}\n {externalIcon}\n </span>\n );\n }\n\n return buttonEl;\n },\n);\n\nButton.displayName = \"Button\";\n\n/**\n * @deprecated Renamed to {@link Button}. `Action` remains as an alias for\n * backward compatibility and will be removed in a future major version.\n * Prefer importing `Button` from \"@particle-academy/react-fancy\".\n */\nexport const Action = Button;\n"]}
@@ -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,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"]}