@ttt-productions/ui-core 0.11.18 → 0.11.20

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 (60) hide show
  1. package/dist/react/components/date-time-picker.d.ts +43 -0
  2. package/dist/react/components/date-time-picker.d.ts.map +1 -0
  3. package/dist/react/components/date-time-picker.js +188 -0
  4. package/dist/react/components/date-time-picker.js.map +1 -0
  5. package/dist/react/index.d.ts +2 -0
  6. package/dist/react/index.d.ts.map +1 -1
  7. package/dist/react/index.js +1 -0
  8. package/dist/react/index.js.map +1 -1
  9. package/package.json +4 -6
  10. package/src/index.ts +0 -3
  11. package/src/lib/format-numbers.ts +0 -17
  12. package/src/lib/utils.ts +0 -9
  13. package/src/react/components/accordion.tsx +0 -53
  14. package/src/react/components/alert-dialog.tsx +0 -131
  15. package/src/react/components/alert.tsx +0 -59
  16. package/src/react/components/avatar.tsx +0 -51
  17. package/src/react/components/badge.tsx +0 -31
  18. package/src/react/components/button.tsx +0 -102
  19. package/src/react/components/card.tsx +0 -54
  20. package/src/react/components/checkbox.tsx +0 -28
  21. package/src/react/components/chunk-error-recovery.tsx +0 -57
  22. package/src/react/components/collapsible.tsx +0 -11
  23. package/src/react/components/consequence-dialog.tsx +0 -282
  24. package/src/react/components/date-picker.tsx +0 -567
  25. package/src/react/components/dialog.tsx +0 -114
  26. package/src/react/components/dropdown-menu.tsx +0 -200
  27. package/src/react/components/end-of-list-indicator.tsx +0 -27
  28. package/src/react/components/form.tsx +0 -174
  29. package/src/react/components/input.tsx +0 -23
  30. package/src/react/components/label.tsx +0 -21
  31. package/src/react/components/layout/screen-adaptive-view.tsx +0 -106
  32. package/src/react/components/list-pagination.tsx +0 -101
  33. package/src/react/components/menubar.tsx +0 -220
  34. package/src/react/components/popover.tsx +0 -31
  35. package/src/react/components/progress.tsx +0 -27
  36. package/src/react/components/radio-group.tsx +0 -36
  37. package/src/react/components/relative-time.tsx +0 -56
  38. package/src/react/components/scroll-area.tsx +0 -56
  39. package/src/react/components/scroll-to-top-button.tsx +0 -85
  40. package/src/react/components/search-dropdown.tsx +0 -233
  41. package/src/react/components/select.tsx +0 -165
  42. package/src/react/components/separator.tsx +0 -26
  43. package/src/react/components/sheet.tsx +0 -140
  44. package/src/react/components/skeleton.tsx +0 -16
  45. package/src/react/components/slider.tsx +0 -25
  46. package/src/react/components/spinner.tsx +0 -49
  47. package/src/react/components/switch.tsx +0 -41
  48. package/src/react/components/table.tsx +0 -121
  49. package/src/react/components/tabs.tsx +0 -59
  50. package/src/react/components/textarea.tsx +0 -22
  51. package/src/react/components/toast.tsx +0 -193
  52. package/src/react/components/toaster.tsx +0 -43
  53. package/src/react/components/tooltip.tsx +0 -28
  54. package/src/react/hooks/use-async-action.ts +0 -63
  55. package/src/react/hooks/use-cursor-page.ts +0 -139
  56. package/src/react/hooks/use-media-query.tsx +0 -26
  57. package/src/react/hooks/use-paged-list.ts +0 -106
  58. package/src/react/hooks/use-return-scroll.ts +0 -149
  59. package/src/react/hooks/use-toast.tsx +0 -176
  60. package/src/react/index.ts +0 -85
@@ -0,0 +1,43 @@
1
+ import * as React from "react";
2
+ export interface DateTimePickerTime {
3
+ /** 0–23 */
4
+ hours: number;
5
+ /** 0–59 */
6
+ minutes: number;
7
+ }
8
+ export interface DateTimePickerProps {
9
+ /** The chosen instant (local time). */
10
+ value?: Date;
11
+ /** Called with the new instant — always inside `min`/`max`, seconds and milliseconds zero. */
12
+ onChange?: (value: Date) => void;
13
+ /** The earliest selectable instant. Earlier days and times are unavailable. */
14
+ min?: Date;
15
+ /** The latest selectable instant. Later days and times are unavailable. */
16
+ max?: Date;
17
+ /** Minutes offered are multiples of this (default 1). */
18
+ minuteStep?: number;
19
+ /** Time of day a picked day takes when there is no `value` yet (default 23:59 — end of day). */
20
+ defaultTime?: DateTimePickerTime;
21
+ className?: string;
22
+ }
23
+ /**
24
+ * Generic date-and-time picker: `DatePicker` for the day, then hour / minute / AM-PM
25
+ * columns of buttons for the time of day — never a native time input, so it looks and
26
+ * behaves the same everywhere and honours `min` / `max` to the minute.
27
+ *
28
+ * Every offered day, hour, minute, and period is one the value may take: a day with
29
+ * no allowed instant is disabled in the calendar, and an hour, minute, or period
30
+ * that would land outside `min` / `max` on the chosen day is disabled. Picking a day
31
+ * keeps the chosen time of day (or `defaultTime` when there is no value) and moves it
32
+ * to the nearest allowed time on that day; picking an hour or period whose current
33
+ * minute is unavailable takes the nearest allowed minute.
34
+ *
35
+ * Keyboard: each time column is one tab stop with roving focus (ArrowUp / ArrowDown,
36
+ * Home / End); Enter or Space picks.
37
+ */
38
+ declare function DateTimePicker({ value, onChange, min, max, minuteStep, defaultTime, className, }: DateTimePickerProps): React.JSX.Element;
39
+ declare namespace DateTimePicker {
40
+ var displayName: string;
41
+ }
42
+ export { DateTimePicker };
43
+ //# sourceMappingURL=date-time-picker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-time-picker.d.ts","sourceRoot":"","sources":["../../../src/react/components/date-time-picker.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,MAAM,WAAW,kBAAkB;IACjC,WAAW;IACX,KAAK,EAAE,MAAM,CAAA;IACb,WAAW;IACX,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,uCAAuC;IACvC,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,8FAA8F;IAC9F,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK,IAAI,CAAA;IAChC,+EAA+E;IAC/E,GAAG,CAAC,EAAE,IAAI,CAAA;IACV,2EAA2E;IAC3E,GAAG,CAAC,EAAE,IAAI,CAAA;IACV,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gGAAgG;IAChG,WAAW,CAAC,EAAE,kBAAkB,CAAA;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAeD;;;;;;;;;;;;;;GAcG;AACH,iBAAS,cAAc,CAAC,EACtB,KAAK,EACL,QAAQ,EACR,GAAG,EACH,GAAG,EACH,UAAc,EACd,WAAwC,EACxC,SAAS,GACV,EAAE,mBAAmB,qBAmJrB;kBA3JQ,cAAc;;;AAuPvB,OAAO,EAAE,cAAc,EAAE,CAAA"}
@@ -0,0 +1,188 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { DatePicker } from "./date-picker.js";
5
+ import { cn } from "../../lib/utils.js";
6
+ const MINUTES_PER_DAY = 24 * 60;
7
+ const HOURS_12 = [12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
8
+ const PERIODS = ["AM", "PM"];
9
+ const pad2 = (n) => String(n).padStart(2, "0");
10
+ const at = (day, minuteOfDay) => new Date(day.getFullYear(), day.getMonth(), day.getDate(), Math.floor(minuteOfDay / 60), minuteOfDay % 60, 0, 0);
11
+ const minuteOfDayOf = (date) => date.getHours() * 60 + date.getMinutes();
12
+ const to24 = (hour12, period) => (hour12 % 12) + (period === "PM" ? 12 : 0);
13
+ const periodOf = (hours) => (hours >= 12 ? "PM" : "AM");
14
+ const hour12Of = (hours) => (hours % 12 === 0 ? 12 : hours % 12);
15
+ /**
16
+ * Generic date-and-time picker: `DatePicker` for the day, then hour / minute / AM-PM
17
+ * columns of buttons for the time of day — never a native time input, so it looks and
18
+ * behaves the same everywhere and honours `min` / `max` to the minute.
19
+ *
20
+ * Every offered day, hour, minute, and period is one the value may take: a day with
21
+ * no allowed instant is disabled in the calendar, and an hour, minute, or period
22
+ * that would land outside `min` / `max` on the chosen day is disabled. Picking a day
23
+ * keeps the chosen time of day (or `defaultTime` when there is no value) and moves it
24
+ * to the nearest allowed time on that day; picking an hour or period whose current
25
+ * minute is unavailable takes the nearest allowed minute.
26
+ *
27
+ * Keyboard: each time column is one tab stop with roving focus (ArrowUp / ArrowDown,
28
+ * Home / End); Enter or Space picks.
29
+ */
30
+ function DateTimePicker({ value, onChange, min, max, minuteStep = 1, defaultTime = { hours: 23, minutes: 59 }, className, }) {
31
+ const step = Math.max(1, Math.min(60, Math.floor(minuteStep)));
32
+ const minuteOptions = React.useMemo(() => Array.from({ length: Math.ceil(60 / step) }, (_, i) => i * step).filter((m) => m < 60), [step]);
33
+ const isAllowed = React.useCallback((instant) => (!min || instant >= min) && (!max || instant <= max), [min, max]);
34
+ const offeredMinutes = React.useMemo(() => new Set(minuteOptions), [minuteOptions]);
35
+ const isOffered = React.useCallback((minuteOfDay) => offeredMinutes.has(minuteOfDay % 60), [offeredMinutes]);
36
+ /** Allowed minutes-of-day on `day`, ascending. */
37
+ const allowedMinutesOn = React.useCallback((day) => {
38
+ const out = [];
39
+ for (let m = 0; m < MINUTES_PER_DAY; m++) {
40
+ if (isOffered(m) && isAllowed(at(day, m)))
41
+ out.push(m);
42
+ }
43
+ return out;
44
+ }, [isAllowed, isOffered]);
45
+ const nearestAllowed = (day, wanted) => {
46
+ const allowed = allowedMinutesOn(day);
47
+ if (allowed.length === 0)
48
+ return null;
49
+ let best = allowed[0];
50
+ for (const m of allowed)
51
+ if (Math.abs(m - wanted) < Math.abs(best - wanted))
52
+ best = m;
53
+ return best;
54
+ };
55
+ const commit = (day, wanted) => {
56
+ const m = nearestAllowed(day, wanted);
57
+ if (m === null)
58
+ return;
59
+ onChange?.(at(day, m));
60
+ };
61
+ // A day strictly between the bounds' own days is decided by its first and last offered
62
+ // minute; only the bounds' days need the minute-by-minute check.
63
+ const firstOfferedMinute = minuteOptions[0];
64
+ const lastOfferedMinute = 23 * 60 + minuteOptions[minuteOptions.length - 1];
65
+ const isSameDay = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
66
+ const isDayDisabled = (day) => {
67
+ if ((min && isSameDay(day, min)) || (max && isSameDay(day, max))) {
68
+ return allowedMinutesOn(day).length === 0;
69
+ }
70
+ if (min && at(day, lastOfferedMinute) < min)
71
+ return true;
72
+ if (max && at(day, firstOfferedMinute) > max)
73
+ return true;
74
+ return false;
75
+ };
76
+ const handleDayPick = (day) => {
77
+ if (!day)
78
+ return;
79
+ const wanted = value ? minuteOfDayOf(value) : defaultTime.hours * 60 + defaultTime.minutes;
80
+ commit(day, wanted);
81
+ };
82
+ const current = value ? minuteOfDayOf(value) : null;
83
+ const currentHours = current === null ? null : Math.floor(current / 60);
84
+ const currentMinutes = current === null ? null : current % 60;
85
+ const currentPeriod = currentHours === null ? null : periodOf(currentHours);
86
+ const allowedSet = React.useMemo(() => new Set(value ? allowedMinutesOn(value) : []), [value, allowedMinutesOn]);
87
+ const hourEnabled = (hours) => minuteOptions.some((m) => allowedSet.has(hours * 60 + m));
88
+ const minuteEnabled = (minutes) => currentHours !== null && allowedSet.has(currentHours * 60 + minutes);
89
+ const periodEnabled = (period) => {
90
+ const base = period === "PM" ? 12 : 0;
91
+ for (let h = base; h < base + 12; h++)
92
+ if (hourEnabled(h))
93
+ return true;
94
+ return false;
95
+ };
96
+ const pickHour = (hour12) => {
97
+ if (!value || currentPeriod === null || currentMinutes === null)
98
+ return;
99
+ const hours = to24(hour12, currentPeriod);
100
+ const firstInHour = minuteOptions.find((m) => allowedSet.has(hours * 60 + m));
101
+ if (firstInHour === undefined)
102
+ return;
103
+ const minutes = allowedSet.has(hours * 60 + currentMinutes) ? currentMinutes : firstInHour;
104
+ commit(value, hours * 60 + minutes);
105
+ };
106
+ const pickMinute = (minutes) => {
107
+ if (!value || currentHours === null)
108
+ return;
109
+ commit(value, currentHours * 60 + minutes);
110
+ };
111
+ const pickPeriod = (period) => {
112
+ if (!value || currentHours === null || currentMinutes === null)
113
+ return;
114
+ const hours = to24(hour12Of(currentHours), period);
115
+ commit(value, hours * 60 + currentMinutes);
116
+ };
117
+ const timeDisabled = !value;
118
+ return (_jsxs("div", { className: cn("flex flex-col gap-3 sm:flex-row sm:items-start", className), children: [_jsx(DatePicker, { selected: value, onSelect: handleDayPick, disabled: isDayDisabled }), _jsxs("div", { className: "flex gap-2 p-4 bg-card rounded-lg", role: "group", "aria-label": "Time", "aria-disabled": timeDisabled || undefined, children: [_jsx(TimeColumn, { label: "Hour", options: HOURS_12.map((h) => ({
119
+ key: h,
120
+ text: String(h),
121
+ ariaLabel: `${h} o'clock`,
122
+ selected: currentHours !== null && hour12Of(currentHours) === h,
123
+ disabled: timeDisabled || currentPeriod === null || !hourEnabled(to24(h, currentPeriod)),
124
+ onPick: () => pickHour(h),
125
+ })) }), _jsx(TimeColumn, { label: "Minute", options: minuteOptions.map((m) => ({
126
+ key: m,
127
+ text: pad2(m),
128
+ ariaLabel: `${pad2(m)} minutes`,
129
+ selected: currentMinutes === m,
130
+ disabled: timeDisabled || !minuteEnabled(m),
131
+ onPick: () => pickMinute(m),
132
+ })) }), _jsx(TimeColumn, { label: "AM or PM", options: PERIODS.map((p) => ({
133
+ key: p,
134
+ text: p,
135
+ ariaLabel: p,
136
+ selected: currentPeriod === p,
137
+ disabled: timeDisabled || !periodEnabled(p),
138
+ onPick: () => pickPeriod(p),
139
+ })) })] })] }));
140
+ }
141
+ DateTimePicker.displayName = "DateTimePicker";
142
+ function TimeColumn({ label, options }) {
143
+ const listRef = React.useRef(null);
144
+ const selectedIndex = options.findIndex((o) => o.selected && !o.disabled);
145
+ const firstEnabled = options.findIndex((o) => !o.disabled);
146
+ const [focusIndex, setFocusIndex] = React.useState(null);
147
+ const rovingIndex = focusIndex !== null && options[focusIndex] && !options[focusIndex].disabled
148
+ ? focusIndex
149
+ : selectedIndex >= 0
150
+ ? selectedIndex
151
+ : firstEnabled;
152
+ // Keep the chosen option in view inside the fixed-height column.
153
+ React.useLayoutEffect(() => {
154
+ if (selectedIndex < 0)
155
+ return;
156
+ const el = listRef.current?.querySelector(`[data-index="${selectedIndex}"]`);
157
+ el?.scrollIntoView?.({ block: "nearest" });
158
+ }, [selectedIndex]);
159
+ const focusAt = (index) => {
160
+ setFocusIndex(index);
161
+ listRef.current?.querySelector(`[data-index="${index}"]`)?.focus();
162
+ };
163
+ const handleKeyDown = (e) => {
164
+ const enabled = options.map((o, i) => (o.disabled ? -1 : i)).filter((i) => i >= 0);
165
+ if (enabled.length === 0 || rovingIndex < 0)
166
+ return;
167
+ const pos = enabled.indexOf(rovingIndex);
168
+ let next;
169
+ if (e.key === "ArrowDown")
170
+ next = enabled[Math.min(enabled.length - 1, pos + 1)];
171
+ else if (e.key === "ArrowUp")
172
+ next = enabled[Math.max(0, pos - 1)];
173
+ else if (e.key === "Home")
174
+ next = enabled[0];
175
+ else if (e.key === "End")
176
+ next = enabled[enabled.length - 1];
177
+ if (next === undefined)
178
+ return;
179
+ e.preventDefault();
180
+ focusAt(next);
181
+ };
182
+ return (_jsxs("div", { className: "flex flex-col items-center gap-1", children: [_jsx("div", { className: "text-xs font-semibold text-muted-foreground", "aria-hidden": "true", children: label }), _jsx("div", { ref: listRef, role: "group", "aria-label": label, onKeyDown: handleKeyDown, className: "flex h-64 w-14 flex-col gap-1 overflow-y-auto", children: options.map((o, i) => (_jsx("button", { type: "button", "data-index": i, tabIndex: i === rovingIndex ? 0 : -1, disabled: o.disabled, "aria-pressed": o.selected, "aria-label": o.ariaLabel, onClick: () => {
183
+ setFocusIndex(i);
184
+ o.onPick();
185
+ }, className: cn("h-9 shrink-0 rounded-lg text-sm font-semibold flex items-center justify-center", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background", !o.disabled && !o.selected && "text-foreground hover:bg-primary/10", o.selected && "bg-primary text-primary-foreground font-bold", o.disabled && "opacity-30 cursor-not-allowed"), children: o.text }, o.key))) })] }));
186
+ }
187
+ export { DateTimePicker };
188
+ //# sourceMappingURL=date-time-picker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-time-picker.js","sourceRoot":"","sources":["../../../src/react/components/date-time-picker.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { DatePicker } from \"./date-picker.js\"\nimport { cn } from \"../../lib/utils.js\"\n\nexport interface DateTimePickerTime {\n /** 0–23 */\n hours: number\n /** 0–59 */\n minutes: number\n}\n\nexport interface DateTimePickerProps {\n /** The chosen instant (local time). */\n value?: Date\n /** Called with the new instant — always inside `min`/`max`, seconds and milliseconds zero. */\n onChange?: (value: Date) => void\n /** The earliest selectable instant. Earlier days and times are unavailable. */\n min?: Date\n /** The latest selectable instant. Later days and times are unavailable. */\n max?: Date\n /** Minutes offered are multiples of this (default 1). */\n minuteStep?: number\n /** Time of day a picked day takes when there is no `value` yet (default 23:59 — end of day). */\n defaultTime?: DateTimePickerTime\n className?: string\n}\n\nconst MINUTES_PER_DAY = 24 * 60\nconst HOURS_12 = [12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]\nconst PERIODS = [\"AM\", \"PM\"] as const\ntype Period = (typeof PERIODS)[number]\n\nconst pad2 = (n: number) => String(n).padStart(2, \"0\")\nconst at = (day: Date, minuteOfDay: number) =>\n new Date(day.getFullYear(), day.getMonth(), day.getDate(), Math.floor(minuteOfDay / 60), minuteOfDay % 60, 0, 0)\nconst minuteOfDayOf = (date: Date) => date.getHours() * 60 + date.getMinutes()\nconst to24 = (hour12: number, period: Period) => (hour12 % 12) + (period === \"PM\" ? 12 : 0)\nconst periodOf = (hours: number): Period => (hours >= 12 ? \"PM\" : \"AM\")\nconst hour12Of = (hours: number) => (hours % 12 === 0 ? 12 : hours % 12)\n\n/**\n * Generic date-and-time picker: `DatePicker` for the day, then hour / minute / AM-PM\n * columns of buttons for the time of day — never a native time input, so it looks and\n * behaves the same everywhere and honours `min` / `max` to the minute.\n *\n * Every offered day, hour, minute, and period is one the value may take: a day with\n * no allowed instant is disabled in the calendar, and an hour, minute, or period\n * that would land outside `min` / `max` on the chosen day is disabled. Picking a day\n * keeps the chosen time of day (or `defaultTime` when there is no value) and moves it\n * to the nearest allowed time on that day; picking an hour or period whose current\n * minute is unavailable takes the nearest allowed minute.\n *\n * Keyboard: each time column is one tab stop with roving focus (ArrowUp / ArrowDown,\n * Home / End); Enter or Space picks.\n */\nfunction DateTimePicker({\n value,\n onChange,\n min,\n max,\n minuteStep = 1,\n defaultTime = { hours: 23, minutes: 59 },\n className,\n}: DateTimePickerProps) {\n const step = Math.max(1, Math.min(60, Math.floor(minuteStep)))\n const minuteOptions = React.useMemo(\n () => Array.from({ length: Math.ceil(60 / step) }, (_, i) => i * step).filter((m) => m < 60),\n [step],\n )\n\n const isAllowed = React.useCallback(\n (instant: Date) => (!min || instant >= min) && (!max || instant <= max),\n [min, max],\n )\n const offeredMinutes = React.useMemo(() => new Set(minuteOptions), [minuteOptions])\n const isOffered = React.useCallback(\n (minuteOfDay: number) => offeredMinutes.has(minuteOfDay % 60),\n [offeredMinutes],\n )\n\n /** Allowed minutes-of-day on `day`, ascending. */\n const allowedMinutesOn = React.useCallback(\n (day: Date) => {\n const out: number[] = []\n for (let m = 0; m < MINUTES_PER_DAY; m++) {\n if (isOffered(m) && isAllowed(at(day, m))) out.push(m)\n }\n return out\n },\n [isAllowed, isOffered],\n )\n\n const nearestAllowed = (day: Date, wanted: number): number | null => {\n const allowed = allowedMinutesOn(day)\n if (allowed.length === 0) return null\n let best = allowed[0]\n for (const m of allowed) if (Math.abs(m - wanted) < Math.abs(best - wanted)) best = m\n return best\n }\n\n const commit = (day: Date, wanted: number) => {\n const m = nearestAllowed(day, wanted)\n if (m === null) return\n onChange?.(at(day, m))\n }\n\n // A day strictly between the bounds' own days is decided by its first and last offered\n // minute; only the bounds' days need the minute-by-minute check.\n const firstOfferedMinute = minuteOptions[0]\n const lastOfferedMinute = 23 * 60 + minuteOptions[minuteOptions.length - 1]\n const isSameDay = (a: Date, b: Date) =>\n a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate()\n const isDayDisabled = (day: Date) => {\n if ((min && isSameDay(day, min)) || (max && isSameDay(day, max))) {\n return allowedMinutesOn(day).length === 0\n }\n if (min && at(day, lastOfferedMinute) < min) return true\n if (max && at(day, firstOfferedMinute) > max) return true\n return false\n }\n\n const handleDayPick = (day: Date | undefined) => {\n if (!day) return\n const wanted = value ? minuteOfDayOf(value) : defaultTime.hours * 60 + defaultTime.minutes\n commit(day, wanted)\n }\n\n const current = value ? minuteOfDayOf(value) : null\n const currentHours = current === null ? null : Math.floor(current / 60)\n const currentMinutes = current === null ? null : current % 60\n const currentPeriod = currentHours === null ? null : periodOf(currentHours)\n\n const allowedSet = React.useMemo(\n () => new Set(value ? allowedMinutesOn(value) : []),\n [value, allowedMinutesOn],\n )\n const hourEnabled = (hours: number) => minuteOptions.some((m) => allowedSet.has(hours * 60 + m))\n const minuteEnabled = (minutes: number) =>\n currentHours !== null && allowedSet.has(currentHours * 60 + minutes)\n const periodEnabled = (period: Period) => {\n const base = period === \"PM\" ? 12 : 0\n for (let h = base; h < base + 12; h++) if (hourEnabled(h)) return true\n return false\n }\n\n const pickHour = (hour12: number) => {\n if (!value || currentPeriod === null || currentMinutes === null) return\n const hours = to24(hour12, currentPeriod)\n const firstInHour = minuteOptions.find((m) => allowedSet.has(hours * 60 + m))\n if (firstInHour === undefined) return\n const minutes = allowedSet.has(hours * 60 + currentMinutes) ? currentMinutes : firstInHour\n commit(value, hours * 60 + minutes)\n }\n const pickMinute = (minutes: number) => {\n if (!value || currentHours === null) return\n commit(value, currentHours * 60 + minutes)\n }\n const pickPeriod = (period: Period) => {\n if (!value || currentHours === null || currentMinutes === null) return\n const hours = to24(hour12Of(currentHours), period)\n commit(value, hours * 60 + currentMinutes)\n }\n\n const timeDisabled = !value\n\n return (\n <div className={cn(\"flex flex-col gap-3 sm:flex-row sm:items-start\", className)}>\n <DatePicker selected={value} onSelect={handleDayPick} disabled={isDayDisabled} />\n <div\n className=\"flex gap-2 p-4 bg-card rounded-lg\"\n role=\"group\"\n aria-label=\"Time\"\n aria-disabled={timeDisabled || undefined}\n >\n <TimeColumn\n label=\"Hour\"\n options={HOURS_12.map((h) => ({\n key: h,\n text: String(h),\n ariaLabel: `${h} o'clock`,\n selected: currentHours !== null && hour12Of(currentHours) === h,\n disabled: timeDisabled || currentPeriod === null || !hourEnabled(to24(h, currentPeriod)),\n onPick: () => pickHour(h),\n }))}\n />\n <TimeColumn\n label=\"Minute\"\n options={minuteOptions.map((m) => ({\n key: m,\n text: pad2(m),\n ariaLabel: `${pad2(m)} minutes`,\n selected: currentMinutes === m,\n disabled: timeDisabled || !minuteEnabled(m),\n onPick: () => pickMinute(m),\n }))}\n />\n <TimeColumn\n label=\"AM or PM\"\n options={PERIODS.map((p) => ({\n key: p,\n text: p,\n ariaLabel: p,\n selected: currentPeriod === p,\n disabled: timeDisabled || !periodEnabled(p),\n onPick: () => pickPeriod(p),\n }))}\n />\n </div>\n </div>\n )\n}\n\nDateTimePicker.displayName = \"DateTimePicker\"\n\ninterface TimeOption {\n key: string | number\n text: string\n ariaLabel: string\n selected: boolean\n disabled: boolean\n onPick: () => void\n}\n\nfunction TimeColumn({ label, options }: { label: string; options: TimeOption[] }) {\n const listRef = React.useRef<HTMLDivElement | null>(null)\n const selectedIndex = options.findIndex((o) => o.selected && !o.disabled)\n const firstEnabled = options.findIndex((o) => !o.disabled)\n const [focusIndex, setFocusIndex] = React.useState<number | null>(null)\n const rovingIndex =\n focusIndex !== null && options[focusIndex] && !options[focusIndex].disabled\n ? focusIndex\n : selectedIndex >= 0\n ? selectedIndex\n : firstEnabled\n\n // Keep the chosen option in view inside the fixed-height column.\n React.useLayoutEffect(() => {\n if (selectedIndex < 0) return\n const el = listRef.current?.querySelector<HTMLButtonElement>(`[data-index=\"${selectedIndex}\"]`)\n el?.scrollIntoView?.({ block: \"nearest\" })\n }, [selectedIndex])\n\n const focusAt = (index: number) => {\n setFocusIndex(index)\n listRef.current?.querySelector<HTMLButtonElement>(`[data-index=\"${index}\"]`)?.focus()\n }\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n const enabled = options.map((o, i) => (o.disabled ? -1 : i)).filter((i) => i >= 0)\n if (enabled.length === 0 || rovingIndex < 0) return\n const pos = enabled.indexOf(rovingIndex)\n let next: number | undefined\n if (e.key === \"ArrowDown\") next = enabled[Math.min(enabled.length - 1, pos + 1)]\n else if (e.key === \"ArrowUp\") next = enabled[Math.max(0, pos - 1)]\n else if (e.key === \"Home\") next = enabled[0]\n else if (e.key === \"End\") next = enabled[enabled.length - 1]\n if (next === undefined) return\n e.preventDefault()\n focusAt(next)\n }\n\n return (\n <div className=\"flex flex-col items-center gap-1\">\n <div className=\"text-xs font-semibold text-muted-foreground\" aria-hidden=\"true\">\n {label}\n </div>\n <div\n ref={listRef}\n role=\"group\"\n aria-label={label}\n onKeyDown={handleKeyDown}\n className=\"flex h-64 w-14 flex-col gap-1 overflow-y-auto\"\n >\n {options.map((o, i) => (\n <button\n key={o.key}\n type=\"button\"\n data-index={i}\n tabIndex={i === rovingIndex ? 0 : -1}\n disabled={o.disabled}\n aria-pressed={o.selected}\n aria-label={o.ariaLabel}\n onClick={() => {\n setFocusIndex(i)\n o.onPick()\n }}\n className={cn(\n \"h-9 shrink-0 rounded-lg text-sm font-semibold flex items-center justify-center\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\",\n !o.disabled && !o.selected && \"text-foreground hover:bg-primary/10\",\n o.selected && \"bg-primary text-primary-foreground font-bold\",\n o.disabled && \"opacity-30 cursor-not-allowed\",\n )}\n >\n {o.text}\n </button>\n ))}\n </div>\n </div>\n )\n}\n\nexport { DateTimePicker }\n"]}
@@ -34,6 +34,8 @@ export { Progress } from "./components/progress.js";
34
34
  export { Slider } from "./components/slider.js";
35
35
  export type { DatePickerProps } from "./components/date-picker.js";
36
36
  export { DatePicker } from "./components/date-picker.js";
37
+ export type { DateTimePickerProps, DateTimePickerTime } from "./components/date-time-picker.js";
38
+ export { DateTimePicker } from "./components/date-time-picker.js";
37
39
  export { ScrollArea, ScrollBar } from "./components/scroll-area.js";
38
40
  export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption } from "./components/table.js";
39
41
  export { Sheet, SheetPortal, SheetOverlay, SheetTrigger, SheetClose, SheetContent, SheetHeader, SheetFooter, SheetTitle, SheetDescription } from "./components/sheet.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}
@@ -29,6 +29,7 @@ export { RadioGroup, RadioGroupItem } from "./components/radio-group.js";
29
29
  export { Progress } from "./components/progress.js";
30
30
  export { Slider } from "./components/slider.js";
31
31
  export { DatePicker } from "./components/date-picker.js";
32
+ export { DateTimePicker } from "./components/date-time-picker.js";
32
33
  export { ScrollArea, ScrollBar } from "./components/scroll-area.js";
33
34
  export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption } from "./components/table.js";
34
35
  export { Sheet, SheetPortal, SheetOverlay, SheetTrigger, SheetClose, SheetContent, SheetHeader, SheetFooter, SheetTitle, SheetDescription } from "./components/sheet.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\nexport type { ButtonProps } from \"./components/button.js\";\nexport { Button, buttonVariants } from \"./components/button.js\";\nexport type { SpinnerProps, SpinnerSize } from \"./components/spinner.js\";\nexport { Spinner } from \"./components/spinner.js\";\nexport { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } from \"./components/card.js\";\nexport { Label } from \"./components/label.js\";\nexport { Textarea } from \"./components/textarea.js\";\nexport { Skeleton } from \"./components/skeleton.js\";\nexport { Dialog, DialogPortal, DialogOverlay, DialogClose, DialogTrigger, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription } from \"./components/dialog.js\";\nexport { Popover, PopoverTrigger, PopoverContent, PopoverAnchor } from \"./components/popover.js\";\nexport { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuGroup, DropdownMenuPortal, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuRadioGroup } from \"./components/dropdown-menu.js\";\nexport { Menubar, MenubarMenu, MenubarTrigger, MenubarContent, MenubarItem, MenubarSeparator, MenubarLabel, MenubarCheckboxItem, MenubarRadioGroup, MenubarRadioItem, MenubarPortal, MenubarSubContent, MenubarSubTrigger, MenubarGroup, MenubarSub, MenubarShortcut } from \"./components/menubar.js\";\nexport { AlertDialog, AlertDialogPortal, AlertDialogOverlay, AlertDialogTrigger, AlertDialogContent, AlertDialogHeader, AlertDialogFooter, AlertDialogTitle, AlertDialogDescription, AlertDialogAction, AlertDialogCancel } from \"./components/alert-dialog.js\";\nexport { Alert, AlertTitle, AlertDescription } from \"./components/alert.js\";\nexport type { ToastProps, ToastActionElement } from \"./components/toast.js\";\nexport { ToastProvider, ToastViewport, Toast, ToastTitle, ToastDescription, ToastClose, ToastAction } from \"./components/toast.js\";\nexport { Toaster } from \"./components/toaster.js\";\nexport type { ToastVariant, ToasterToast } from \"./hooks/use-toast.js\";\nexport { toast, useToast } from \"./hooks/use-toast.js\";\nexport { Input } from \"./components/input.js\";\nexport { Select, SelectGroup, SelectValue, SelectTrigger, SelectContent, SelectLabel, SelectItem, SelectSeparator, SelectScrollUpButton, SelectScrollDownButton } from \"./components/select.js\";\nexport { Tabs, TabsList, TabsTrigger, TabsContent } from \"./components/tabs.js\";\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from \"./components/tooltip.js\";\nexport { useFormField, Form, FormItem, FormLabel, FormControl, FormDescription, FormMessage, FormField } from \"./components/form.js\";\nexport { Checkbox } from \"./components/checkbox.js\";\nexport { Switch } from \"./components/switch.js\";\nexport type { BadgeProps } from \"./components/badge.js\";\nexport { Badge, badgeVariants } from \"./components/badge.js\";\nexport { Avatar, AvatarImage, AvatarFallback } from \"./components/avatar.js\";\nexport { Separator } from \"./components/separator.js\";\nexport { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from \"./components/accordion.js\";\nexport { RadioGroup, RadioGroupItem } from \"./components/radio-group.js\";\nexport { Progress } from \"./components/progress.js\";\nexport { Slider } from \"./components/slider.js\";\nexport type { DatePickerProps } from \"./components/date-picker.js\";\nexport { DatePicker } from \"./components/date-picker.js\";\nexport { ScrollArea, ScrollBar } from \"./components/scroll-area.js\";\nexport { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption } from \"./components/table.js\";\nexport { Sheet, SheetPortal, SheetOverlay, SheetTrigger, SheetClose, SheetContent, SheetHeader, SheetFooter, SheetTitle, SheetDescription } from \"./components/sheet.js\";\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent } from \"./components/collapsible.js\";\nexport type { SearchDropdownProps } from \"./components/search-dropdown.js\";\nexport { SearchDropdown } from \"./components/search-dropdown.js\";\n\nexport type { ConsequenceDialogProps, ConsequenceDialogReason, ConsequenceDialogTypedConfirmation } from \"./components/consequence-dialog.js\";\nexport { ConsequenceDialog } from \"./components/consequence-dialog.js\";\n\nexport type { MaxWidthOption, ScreenAdaptiveViewProps } from \"./components/layout/screen-adaptive-view.js\";\nexport { ScreenAdaptiveView } from \"./components/layout/screen-adaptive-view.js\";\n\nexport { useMediaQuery } from \"./hooks/use-media-query.js\";\n\nexport { useAsyncAction } from \"./hooks/use-async-action.js\";\nexport type { AsyncAction, UseAsyncActionOptions } from \"./hooks/use-async-action.js\";\n\n// Shared building blocks\nexport { RelativeTime } from \"./components/relative-time.js\";\nexport type { RelativeTimeProps } from \"./components/relative-time.js\";\n\nexport { EndOfListIndicator } from \"./components/end-of-list-indicator.js\";\nexport type { EndOfListIndicatorProps } from \"./components/end-of-list-indicator.js\";\n\nexport { ScrollToTopButton } from \"./components/scroll-to-top-button.js\";\nexport type { ScrollToTopButtonProps } from \"./components/scroll-to-top-button.js\";\n\nexport { ChunkErrorRecovery } from \"./components/chunk-error-recovery.js\";\nexport type { ChunkErrorRecoveryProps } from \"./components/chunk-error-recovery.js\";\n\n// List pagination — the one Previous / counter / Next control plus the page-state\n// hooks for its two flavors (known total, and cursor/`hasMore`).\nexport { ListPagination } from \"./components/list-pagination.js\";\nexport type { ListPaginationProps } from \"./components/list-pagination.js\";\n\nexport { usePagedList } from \"./hooks/use-paged-list.js\";\nexport type { ListPaginationState, PagedList, UsePagedListOptions } from \"./hooks/use-paged-list.js\";\n\nexport { useCursorPage } from \"./hooks/use-cursor-page.js\";\nexport type { CursorPage, CursorPager, UseCursorPageOptions } from \"./hooks/use-cursor-page.js\";\n\n// Return-scroll: restore a list's window offset when the user comes back to it after a\n// route change (save on leave, restore once on an eligible + ready return, keyed by the\n// caller's canonical list URL).\nexport { useReturnScroll, saveReturnScroll, clearReturnScroll, readReturnScroll } from \"./hooks/use-return-scroll.js\";\nexport type { ReturnScrollEntry, UseReturnScrollOptions, UseReturnScrollResult } from \"./hooks/use-return-scroll.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\nexport type { ButtonProps } from \"./components/button.js\";\nexport { Button, buttonVariants } from \"./components/button.js\";\nexport type { SpinnerProps, SpinnerSize } from \"./components/spinner.js\";\nexport { Spinner } from \"./components/spinner.js\";\nexport { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } from \"./components/card.js\";\nexport { Label } from \"./components/label.js\";\nexport { Textarea } from \"./components/textarea.js\";\nexport { Skeleton } from \"./components/skeleton.js\";\nexport { Dialog, DialogPortal, DialogOverlay, DialogClose, DialogTrigger, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription } from \"./components/dialog.js\";\nexport { Popover, PopoverTrigger, PopoverContent, PopoverAnchor } from \"./components/popover.js\";\nexport { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuGroup, DropdownMenuPortal, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuRadioGroup } from \"./components/dropdown-menu.js\";\nexport { Menubar, MenubarMenu, MenubarTrigger, MenubarContent, MenubarItem, MenubarSeparator, MenubarLabel, MenubarCheckboxItem, MenubarRadioGroup, MenubarRadioItem, MenubarPortal, MenubarSubContent, MenubarSubTrigger, MenubarGroup, MenubarSub, MenubarShortcut } from \"./components/menubar.js\";\nexport { AlertDialog, AlertDialogPortal, AlertDialogOverlay, AlertDialogTrigger, AlertDialogContent, AlertDialogHeader, AlertDialogFooter, AlertDialogTitle, AlertDialogDescription, AlertDialogAction, AlertDialogCancel } from \"./components/alert-dialog.js\";\nexport { Alert, AlertTitle, AlertDescription } from \"./components/alert.js\";\nexport type { ToastProps, ToastActionElement } from \"./components/toast.js\";\nexport { ToastProvider, ToastViewport, Toast, ToastTitle, ToastDescription, ToastClose, ToastAction } from \"./components/toast.js\";\nexport { Toaster } from \"./components/toaster.js\";\nexport type { ToastVariant, ToasterToast } from \"./hooks/use-toast.js\";\nexport { toast, useToast } from \"./hooks/use-toast.js\";\nexport { Input } from \"./components/input.js\";\nexport { Select, SelectGroup, SelectValue, SelectTrigger, SelectContent, SelectLabel, SelectItem, SelectSeparator, SelectScrollUpButton, SelectScrollDownButton } from \"./components/select.js\";\nexport { Tabs, TabsList, TabsTrigger, TabsContent } from \"./components/tabs.js\";\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from \"./components/tooltip.js\";\nexport { useFormField, Form, FormItem, FormLabel, FormControl, FormDescription, FormMessage, FormField } from \"./components/form.js\";\nexport { Checkbox } from \"./components/checkbox.js\";\nexport { Switch } from \"./components/switch.js\";\nexport type { BadgeProps } from \"./components/badge.js\";\nexport { Badge, badgeVariants } from \"./components/badge.js\";\nexport { Avatar, AvatarImage, AvatarFallback } from \"./components/avatar.js\";\nexport { Separator } from \"./components/separator.js\";\nexport { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from \"./components/accordion.js\";\nexport { RadioGroup, RadioGroupItem } from \"./components/radio-group.js\";\nexport { Progress } from \"./components/progress.js\";\nexport { Slider } from \"./components/slider.js\";\nexport type { DatePickerProps } from \"./components/date-picker.js\";\nexport { DatePicker } from \"./components/date-picker.js\";\nexport type { DateTimePickerProps, DateTimePickerTime } from \"./components/date-time-picker.js\";\nexport { DateTimePicker } from \"./components/date-time-picker.js\";\nexport { ScrollArea, ScrollBar } from \"./components/scroll-area.js\";\nexport { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption } from \"./components/table.js\";\nexport { Sheet, SheetPortal, SheetOverlay, SheetTrigger, SheetClose, SheetContent, SheetHeader, SheetFooter, SheetTitle, SheetDescription } from \"./components/sheet.js\";\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent } from \"./components/collapsible.js\";\nexport type { SearchDropdownProps } from \"./components/search-dropdown.js\";\nexport { SearchDropdown } from \"./components/search-dropdown.js\";\n\nexport type { ConsequenceDialogProps, ConsequenceDialogReason, ConsequenceDialogTypedConfirmation } from \"./components/consequence-dialog.js\";\nexport { ConsequenceDialog } from \"./components/consequence-dialog.js\";\n\nexport type { MaxWidthOption, ScreenAdaptiveViewProps } from \"./components/layout/screen-adaptive-view.js\";\nexport { ScreenAdaptiveView } from \"./components/layout/screen-adaptive-view.js\";\n\nexport { useMediaQuery } from \"./hooks/use-media-query.js\";\n\nexport { useAsyncAction } from \"./hooks/use-async-action.js\";\nexport type { AsyncAction, UseAsyncActionOptions } from \"./hooks/use-async-action.js\";\n\n// Shared building blocks\nexport { RelativeTime } from \"./components/relative-time.js\";\nexport type { RelativeTimeProps } from \"./components/relative-time.js\";\n\nexport { EndOfListIndicator } from \"./components/end-of-list-indicator.js\";\nexport type { EndOfListIndicatorProps } from \"./components/end-of-list-indicator.js\";\n\nexport { ScrollToTopButton } from \"./components/scroll-to-top-button.js\";\nexport type { ScrollToTopButtonProps } from \"./components/scroll-to-top-button.js\";\n\nexport { ChunkErrorRecovery } from \"./components/chunk-error-recovery.js\";\nexport type { ChunkErrorRecoveryProps } from \"./components/chunk-error-recovery.js\";\n\n// List pagination — the one Previous / counter / Next control plus the page-state\n// hooks for its two flavors (known total, and cursor/`hasMore`).\nexport { ListPagination } from \"./components/list-pagination.js\";\nexport type { ListPaginationProps } from \"./components/list-pagination.js\";\n\nexport { usePagedList } from \"./hooks/use-paged-list.js\";\nexport type { ListPaginationState, PagedList, UsePagedListOptions } from \"./hooks/use-paged-list.js\";\n\nexport { useCursorPage } from \"./hooks/use-cursor-page.js\";\nexport type { CursorPage, CursorPager, UseCursorPageOptions } from \"./hooks/use-cursor-page.js\";\n\n// Return-scroll: restore a list's window offset when the user comes back to it after a\n// route change (save on leave, restore once on an eligible + ready return, keyed by the\n// caller's canonical list URL).\nexport { useReturnScroll, saveReturnScroll, clearReturnScroll, readReturnScroll } from \"./hooks/use-return-scroll.js\";\nexport type { ReturnScrollEntry, UseReturnScrollOptions, UseReturnScrollResult } from \"./hooks/use-return-scroll.js\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttt-productions/ui-core",
3
- "version": "0.11.18",
3
+ "version": "0.11.20",
4
4
  "description": "Shared UI components for TTT Productions projects",
5
5
  "repository": {
6
6
  "type": "git",
@@ -16,8 +16,7 @@
16
16
  "**/*.css"
17
17
  ],
18
18
  "files": [
19
- "dist",
20
- "src"
19
+ "dist"
21
20
  ],
22
21
  "exports": {
23
22
  ".": {
@@ -49,7 +48,7 @@
49
48
  "react-dom": ">=19.0.0",
50
49
  "react-hook-form": ">=7.0.0",
51
50
  "@hookform/resolvers": ">=3.0.0",
52
- "@ttt-productions/firebase-helpers": "^0.12.9",
51
+ "@ttt-productions/firebase-helpers": "^0.12.10",
53
52
  "lucide-react": "^1.30.0"
54
53
  },
55
54
  "peerDependenciesMeta": {
@@ -99,10 +98,9 @@
99
98
  "@types/react-dom": "^19.0.0",
100
99
  "react": "^19.2.0",
101
100
  "react-dom": "^19.2.0",
102
- "typescript": "^5.8.3",
103
101
  "react-hook-form": "^7.69.0",
104
102
  "@hookform/resolvers": "^5.2.2",
105
- "@ttt-productions/firebase-helpers": "^0.12.9",
103
+ "@ttt-productions/firebase-helpers": "^0.12.10",
106
104
  "lucide-react": "^1.30.0"
107
105
  },
108
106
  "author": "DJ (TTT Productions)",
package/src/index.ts DELETED
@@ -1,3 +0,0 @@
1
- // Server-safe utilities only. React components and hooks live behind ./react.
2
- export * from "./lib/utils.js";
3
- export * from "./lib/format-numbers.js";
@@ -1,17 +0,0 @@
1
- /**
2
- * Compact number formatter:
3
- * < 10,000 → "1234"
4
- * 10,000 ≤ n < 1,000,000 → "12.3k" (trailing ".0" stripped)
5
- * ≥ 1,000,000 → "1.2M" (trailing ".0" stripped)
6
- */
7
- export function formatLargeNumber(num: number): string {
8
- if (num >= 1_000_000) {
9
- const formatted = (num / 1_000_000).toFixed(1);
10
- return (formatted.endsWith(".0") ? formatted.slice(0, -2) : formatted) + "M";
11
- }
12
- if (num >= 10_000) {
13
- const formatted = (num / 1000).toFixed(1);
14
- return (formatted.endsWith(".0") ? formatted.slice(0, -2) : formatted) + "k";
15
- }
16
- return num.toString();
17
- }
package/src/lib/utils.ts DELETED
@@ -1,9 +0,0 @@
1
- import { type ClassValue, clsx } from 'clsx';
2
- import { twMerge } from 'tailwind-merge';
3
-
4
- /**
5
- * Merge Tailwind CSS classes with proper precedence
6
- */
7
- export function cn(...inputs: ClassValue[]) {
8
- return twMerge(clsx(inputs));
9
- }
@@ -1,53 +0,0 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import * as AccordionPrimitive from "@radix-ui/react-accordion"
5
- import { ChevronDown } from "lucide-react"
6
-
7
- import { cn } from "../../lib/utils.js"
8
-
9
- const Accordion = AccordionPrimitive.Root
10
-
11
- const AccordionItem = React.forwardRef<
12
- React.ElementRef<typeof AccordionPrimitive.Item>,
13
- React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
14
- >(({ className, ...props }, ref) => (
15
- <AccordionPrimitive.Item ref={ref} className={cn(className)} {...props} />
16
- ))
17
- AccordionItem.displayName = "AccordionItem"
18
-
19
- const AccordionTrigger = React.forwardRef<
20
- React.ElementRef<typeof AccordionPrimitive.Trigger>,
21
- React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
22
- >(({ className, children, ...props }, ref) => (
23
- <AccordionPrimitive.Header className="flex">
24
- <AccordionPrimitive.Trigger
25
- ref={ref}
26
- className={cn(
27
- "flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
28
- className
29
- )}
30
- {...props}
31
- >
32
- {children}
33
- <ChevronDown className="h-4 w-4 shrink-0 transition-transform duration-200" />
34
- </AccordionPrimitive.Trigger>
35
- </AccordionPrimitive.Header>
36
- ))
37
- AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName
38
-
39
- const AccordionContent = React.forwardRef<
40
- React.ElementRef<typeof AccordionPrimitive.Content>,
41
- React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
42
- >(({ className, children, ...props }, ref) => (
43
- <AccordionPrimitive.Content
44
- ref={ref}
45
- className="overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
46
- {...props}
47
- >
48
- <div className={cn("pb-4 pt-0", className)}>{children}</div>
49
- </AccordionPrimitive.Content>
50
- ))
51
- AccordionContent.displayName = AccordionPrimitive.Content.displayName
52
-
53
- export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }