@refraktor/dates 0.0.1 → 0.0.3

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 (40) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/build/components/date-input/date-input.d.ts.map +1 -1
  3. package/build/components/date-input/date-input.js +5 -3
  4. package/build/components/index.d.ts +2 -0
  5. package/build/components/index.d.ts.map +1 -1
  6. package/build/components/index.js +2 -0
  7. package/build/components/month-input/month-input.d.ts.map +1 -1
  8. package/build/components/month-input/month-input.js +5 -3
  9. package/build/components/time-input/index.d.ts +3 -0
  10. package/build/components/time-input/index.d.ts.map +1 -0
  11. package/build/components/time-input/index.js +1 -0
  12. package/build/components/time-input/time-input.d.ts +4 -0
  13. package/build/components/time-input/time-input.d.ts.map +1 -0
  14. package/build/components/time-input/time-input.js +207 -0
  15. package/build/components/time-input/time-input.types.d.ts +99 -0
  16. package/build/components/time-input/time-input.types.d.ts.map +1 -0
  17. package/build/components/time-input/time-input.types.js +1 -0
  18. package/build/components/time-picker/index.d.ts +3 -0
  19. package/build/components/time-picker/index.d.ts.map +1 -0
  20. package/build/components/time-picker/index.js +1 -0
  21. package/build/components/time-picker/time-picker.d.ts +4 -0
  22. package/build/components/time-picker/time-picker.d.ts.map +1 -0
  23. package/build/components/time-picker/time-picker.js +405 -0
  24. package/build/components/time-picker/time-picker.types.d.ts +79 -0
  25. package/build/components/time-picker/time-picker.types.d.ts.map +1 -0
  26. package/build/components/time-picker/time-picker.types.js +1 -0
  27. package/build/components/year-input/year-input.d.ts.map +1 -1
  28. package/build/components/year-input/year-input.js +5 -3
  29. package/build/style.css +1 -1
  30. package/package.json +3 -3
  31. package/src/components/date-input/date-input.tsx +5 -2
  32. package/src/components/index.ts +2 -0
  33. package/src/components/month-input/month-input.tsx +5 -2
  34. package/src/components/time-input/index.ts +23 -0
  35. package/src/components/time-input/time-input.tsx +453 -0
  36. package/src/components/time-input/time-input.types.ts +163 -0
  37. package/src/components/time-picker/index.ts +19 -0
  38. package/src/components/time-picker/time-picker.tsx +737 -0
  39. package/src/components/time-picker/time-picker.types.ts +135 -0
  40. package/src/components/year-input/year-input.tsx +5 -2
@@ -0,0 +1,405 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useId, useUncontrolled } from "@refraktor/utils";
3
+ import { useMemo } from "react";
4
+ import { createClassNamesConfig, createComponentConfig, factory, useClassNames, useProps, useTheme } from "@refraktor/core";
5
+ import { getGridColumns, getPickerSizeStyles } from "../picker-shared";
6
+ const HOURS_IN_DAY = 24;
7
+ const MINUTES_IN_HOUR = 60;
8
+ const SECONDS_IN_MINUTE = 60;
9
+ const SECONDS_IN_DAY = HOURS_IN_DAY * MINUTES_IN_HOUR * SECONDS_IN_MINUTE;
10
+ const DEFAULT_MODE = "24h";
11
+ const TIME_SEGMENT_PATTERN = /^\d{1,2}$/;
12
+ const defaultProps = {
13
+ mode: DEFAULT_MODE,
14
+ disabled: false,
15
+ size: "md",
16
+ radius: "default"
17
+ };
18
+ const pad = (value) => String(value).padStart(2, "0");
19
+ const to12Hour = (hours24) => {
20
+ const normalized = hours24 % 12;
21
+ return normalized === 0 ? 12 : normalized;
22
+ };
23
+ const to24Hour = (hour12, period) => {
24
+ const normalizedHour = hour12 % 12;
25
+ return period === "pm" ? normalizedHour + 12 : normalizedHour;
26
+ };
27
+ const toSecondsOfDay = (hours24, minutes, seconds) => hours24 * MINUTES_IN_HOUR * SECONDS_IN_MINUTE + minutes * SECONDS_IN_MINUTE + seconds;
28
+ const createTimeParts = (hours24, minutes, seconds) => {
29
+ const normalizedHours24 = hours24 % HOURS_IN_DAY;
30
+ return {
31
+ hours24: normalizedHours24,
32
+ hour12: to12Hour(normalizedHours24),
33
+ minutes,
34
+ seconds,
35
+ period: normalizedHours24 >= 12 ? "pm" : "am"
36
+ };
37
+ };
38
+ const parseTimeValue = (value) => {
39
+ if (typeof value !== "string") {
40
+ return undefined;
41
+ }
42
+ const segments = value.trim().split(":");
43
+ if (segments.length !== 3 ||
44
+ !segments.every((segment) => TIME_SEGMENT_PATTERN.test(segment))) {
45
+ return undefined;
46
+ }
47
+ const [hoursText, minutesText, secondsText] = segments;
48
+ const hours24 = Number.parseInt(hoursText, 10);
49
+ const minutes = Number.parseInt(minutesText, 10);
50
+ const seconds = Number.parseInt(secondsText, 10);
51
+ if (hours24 < 0 ||
52
+ hours24 >= HOURS_IN_DAY ||
53
+ minutes < 0 ||
54
+ minutes >= MINUTES_IN_HOUR ||
55
+ seconds < 0 ||
56
+ seconds >= SECONDS_IN_MINUTE) {
57
+ return undefined;
58
+ }
59
+ return createTimeParts(hours24, minutes, seconds);
60
+ };
61
+ const formatTimeValue = (hours24, minutes, seconds) => `${pad(hours24)}:${pad(minutes)}:${pad(seconds)}`;
62
+ const toTimePartsFromSeconds = (seconds) => {
63
+ const normalizedSeconds = ((seconds % SECONDS_IN_DAY) + SECONDS_IN_DAY) % SECONDS_IN_DAY;
64
+ const hours24 = Math.floor(normalizedSeconds / (MINUTES_IN_HOUR * SECONDS_IN_MINUTE));
65
+ const minutes = Math.floor((normalizedSeconds % (MINUTES_IN_HOUR * SECONDS_IN_MINUTE)) /
66
+ SECONDS_IN_MINUTE);
67
+ const remainingSeconds = normalizedSeconds % SECONDS_IN_MINUTE;
68
+ return createTimeParts(hours24, minutes, remainingSeconds);
69
+ };
70
+ const clampTimeParts = (parts, bounds) => {
71
+ const seconds = toSecondsOfDay(parts.hours24, parts.minutes, parts.seconds);
72
+ if (bounds.hasMin && seconds < bounds.minSeconds) {
73
+ return toTimePartsFromSeconds(bounds.minSeconds);
74
+ }
75
+ if (bounds.hasMax && seconds > bounds.maxSeconds) {
76
+ return toTimePartsFromSeconds(bounds.maxSeconds);
77
+ }
78
+ return parts;
79
+ };
80
+ const getCurrentTimeParts = () => {
81
+ const current = new Date();
82
+ return createTimeParts(current.getHours(), current.getMinutes(), current.getSeconds());
83
+ };
84
+ const getTimeBounds = (minTime, maxTime) => {
85
+ const minParts = parseTimeValue(minTime);
86
+ const maxParts = parseTimeValue(maxTime);
87
+ const hasMin = minParts !== undefined;
88
+ const hasMax = maxParts !== undefined;
89
+ const minSeconds = hasMin
90
+ ? toSecondsOfDay(minParts.hours24, minParts.minutes, minParts.seconds)
91
+ : Number.NEGATIVE_INFINITY;
92
+ const maxSeconds = hasMax
93
+ ? toSecondsOfDay(maxParts.hours24, maxParts.minutes, maxParts.seconds)
94
+ : Number.POSITIVE_INFINITY;
95
+ if (hasMin && hasMax && minSeconds > maxSeconds) {
96
+ return {
97
+ minSeconds: maxSeconds,
98
+ maxSeconds: minSeconds,
99
+ hasMin: true,
100
+ hasMax: true
101
+ };
102
+ }
103
+ return {
104
+ minSeconds,
105
+ maxSeconds,
106
+ hasMin,
107
+ hasMax
108
+ };
109
+ };
110
+ const isTimeDisabled = (seconds, disabled, bounds) => disabled ||
111
+ (bounds.hasMin && seconds < bounds.minSeconds) ||
112
+ (bounds.hasMax && seconds > bounds.maxSeconds);
113
+ const getSelectablePeriodRange = (period, bounds) => {
114
+ const periodStart = period === "am" ? 0 : SECONDS_IN_DAY / 2;
115
+ const periodEnd = period === "am" ? SECONDS_IN_DAY / 2 - 1 : SECONDS_IN_DAY - 1;
116
+ const start = Math.max(periodStart, bounds.minSeconds);
117
+ const end = Math.min(periodEnd, bounds.maxSeconds);
118
+ if (start > end) {
119
+ return undefined;
120
+ }
121
+ return { start, end };
122
+ };
123
+ const getFirstEnabledIndex = (options) => options.findIndex((option) => !option.disabled);
124
+ const getLastEnabledIndex = (options) => {
125
+ for (let index = options.length - 1; index >= 0; index -= 1) {
126
+ if (!options[index].disabled) {
127
+ return index;
128
+ }
129
+ }
130
+ return -1;
131
+ };
132
+ const findNextEnabledIndex = (options, startIndex, direction) => {
133
+ let index = startIndex + direction;
134
+ while (index >= 0 && index < options.length) {
135
+ if (!options[index].disabled) {
136
+ return index;
137
+ }
138
+ index += direction;
139
+ }
140
+ return startIndex;
141
+ };
142
+ const handleListKeyDown = (event, options, onSelect) => {
143
+ const firstEnabledIndex = getFirstEnabledIndex(options);
144
+ const lastEnabledIndex = getLastEnabledIndex(options);
145
+ if (firstEnabledIndex === -1 || lastEnabledIndex === -1) {
146
+ return;
147
+ }
148
+ const selectedIndex = options.findIndex((option) => option.selected);
149
+ if (event.key === "Home") {
150
+ event.preventDefault();
151
+ onSelect(options[firstEnabledIndex].value);
152
+ return;
153
+ }
154
+ if (event.key === "End") {
155
+ event.preventDefault();
156
+ onSelect(options[lastEnabledIndex].value);
157
+ return;
158
+ }
159
+ const applyStep = (direction, repeat = 1) => {
160
+ event.preventDefault();
161
+ let index = selectedIndex === -1
162
+ ? direction === 1
163
+ ? firstEnabledIndex
164
+ : lastEnabledIndex
165
+ : selectedIndex;
166
+ for (let step = 0; step < repeat; step += 1) {
167
+ const nextIndex = findNextEnabledIndex(options, index, direction);
168
+ if (nextIndex === index) {
169
+ break;
170
+ }
171
+ index = nextIndex;
172
+ }
173
+ onSelect(options[index].value);
174
+ };
175
+ if (event.key === "ArrowDown") {
176
+ applyStep(1);
177
+ return;
178
+ }
179
+ if (event.key === "ArrowUp") {
180
+ applyStep(-1);
181
+ return;
182
+ }
183
+ if (event.key === "PageDown") {
184
+ applyStep(1, 5);
185
+ return;
186
+ }
187
+ if (event.key === "PageUp") {
188
+ applyStep(-1, 5);
189
+ }
190
+ };
191
+ const TimePicker = factory((_props, ref) => {
192
+ const { cx, getRadius } = useTheme();
193
+ const { id, value, defaultValue, onChange, minTime, maxTime, mode, disabled, size, radius, getHourLabel, getMinuteLabel, getSecondLabel, getPeriodLabel, getHourAriaLabel, getMinuteAriaLabel, getSecondAriaLabel, getPeriodAriaLabel, className, classNames, ...props } = useProps("TimePicker", defaultProps, _props);
194
+ const classes = useClassNames("TimePicker", classNames);
195
+ const _id = useId(id);
196
+ const sizeStyles = getPickerSizeStyles(size);
197
+ const bounds = useMemo(() => getTimeBounds(minTime, maxTime), [minTime, maxTime]);
198
+ const [selectedTimeState, setSelectedTime] = useUncontrolled({
199
+ value,
200
+ defaultValue,
201
+ finalValue: undefined,
202
+ onChange: (nextTime) => {
203
+ if (nextTime !== undefined) {
204
+ onChange?.(nextTime);
205
+ }
206
+ }
207
+ });
208
+ const selectedParts = useMemo(() => {
209
+ const parsed = parseTimeValue(selectedTimeState);
210
+ if (!parsed) {
211
+ return undefined;
212
+ }
213
+ return clampTimeParts(parsed, bounds);
214
+ }, [bounds, selectedTimeState]);
215
+ const selectedTime = useMemo(() => selectedParts
216
+ ? formatTimeValue(selectedParts.hours24, selectedParts.minutes, selectedParts.seconds)
217
+ : undefined, [selectedParts]);
218
+ const fallbackParts = useMemo(() => clampTimeParts(getCurrentTimeParts(), bounds), [bounds]);
219
+ const activeParts = selectedParts ?? fallbackParts;
220
+ const applyTime = (hours24, minutes, seconds) => {
221
+ if (disabled) {
222
+ return;
223
+ }
224
+ const nextSeconds = toSecondsOfDay(hours24, minutes, seconds);
225
+ if (isTimeDisabled(nextSeconds, false, bounds)) {
226
+ return;
227
+ }
228
+ const nextTime = formatTimeValue(hours24, minutes, seconds);
229
+ if (selectedTime === nextTime) {
230
+ return;
231
+ }
232
+ setSelectedTime(nextTime);
233
+ };
234
+ const setHour = (hour) => {
235
+ const nextHour = mode === "12h" ? to24Hour(hour, activeParts.period) : hour;
236
+ applyTime(nextHour, activeParts.minutes, activeParts.seconds);
237
+ };
238
+ const setMinute = (minute) => {
239
+ applyTime(activeParts.hours24, minute, activeParts.seconds);
240
+ };
241
+ const setSecond = (second) => {
242
+ applyTime(activeParts.hours24, activeParts.minutes, second);
243
+ };
244
+ const setPeriod = (period) => {
245
+ const selectableRange = getSelectablePeriodRange(period, bounds);
246
+ if (!selectableRange) {
247
+ return;
248
+ }
249
+ const nextHour24 = to24Hour(activeParts.hour12, period);
250
+ const candidateSeconds = toSecondsOfDay(nextHour24, activeParts.minutes, activeParts.seconds);
251
+ const nextSeconds = Math.min(selectableRange.end, Math.max(selectableRange.start, candidateSeconds));
252
+ const nextParts = toTimePartsFromSeconds(nextSeconds);
253
+ applyTime(nextParts.hours24, nextParts.minutes, nextParts.seconds);
254
+ };
255
+ const hourOptions = useMemo(() => {
256
+ const totalHours = mode === "12h" ? 12 : HOURS_IN_DAY;
257
+ return Array.from({ length: totalHours }, (_, index) => {
258
+ const hour = mode === "12h" ? index + 1 : index;
259
+ const hours24 = mode === "12h" ? to24Hour(hour, activeParts.period) : hour;
260
+ const nextSeconds = toSecondsOfDay(hours24, activeParts.minutes, activeParts.seconds);
261
+ const selected = selectedParts !== undefined &&
262
+ (mode === "12h"
263
+ ? selectedParts.hour12 === hour
264
+ : selectedParts.hours24 === hour);
265
+ return {
266
+ value: hour,
267
+ label: getHourLabel ? getHourLabel(hour, mode) : pad(hour),
268
+ ariaLabel: getHourAriaLabel
269
+ ? getHourAriaLabel(hour, mode, selected)
270
+ : selected
271
+ ? `Hour ${pad(hour)}, selected`
272
+ : `Choose hour ${pad(hour)}`,
273
+ selected,
274
+ disabled: isTimeDisabled(nextSeconds, disabled ?? false, bounds)
275
+ };
276
+ });
277
+ }, [
278
+ activeParts.minutes,
279
+ activeParts.period,
280
+ activeParts.seconds,
281
+ bounds,
282
+ disabled,
283
+ getHourAriaLabel,
284
+ getHourLabel,
285
+ mode,
286
+ selectedParts
287
+ ]);
288
+ const minuteOptions = useMemo(() => Array.from({ length: MINUTES_IN_HOUR }, (_, minute) => {
289
+ const nextSeconds = toSecondsOfDay(activeParts.hours24, minute, activeParts.seconds);
290
+ const selected = selectedParts?.minutes === minute;
291
+ return {
292
+ value: minute,
293
+ label: getMinuteLabel ? getMinuteLabel(minute) : pad(minute),
294
+ ariaLabel: getMinuteAriaLabel
295
+ ? getMinuteAriaLabel(minute, selected)
296
+ : selected
297
+ ? `Minute ${pad(minute)}, selected`
298
+ : `Choose minute ${pad(minute)}`,
299
+ selected,
300
+ disabled: isTimeDisabled(nextSeconds, disabled ?? false, bounds)
301
+ };
302
+ }), [
303
+ activeParts.hours24,
304
+ activeParts.seconds,
305
+ bounds,
306
+ disabled,
307
+ getMinuteAriaLabel,
308
+ getMinuteLabel,
309
+ selectedParts
310
+ ]);
311
+ const secondOptions = useMemo(() => Array.from({ length: SECONDS_IN_MINUTE }, (_, second) => {
312
+ const nextSeconds = toSecondsOfDay(activeParts.hours24, activeParts.minutes, second);
313
+ const selected = selectedParts?.seconds === second;
314
+ return {
315
+ value: second,
316
+ label: getSecondLabel ? getSecondLabel(second) : pad(second),
317
+ ariaLabel: getSecondAriaLabel
318
+ ? getSecondAriaLabel(second, selected)
319
+ : selected
320
+ ? `Second ${pad(second)}, selected`
321
+ : `Choose second ${pad(second)}`,
322
+ selected,
323
+ disabled: isTimeDisabled(nextSeconds, disabled ?? false, bounds)
324
+ };
325
+ }), [
326
+ activeParts.hours24,
327
+ activeParts.minutes,
328
+ bounds,
329
+ disabled,
330
+ getSecondAriaLabel,
331
+ getSecondLabel,
332
+ selectedParts
333
+ ]);
334
+ const periodOptions = useMemo(() => ["am", "pm"].map((period) => {
335
+ const selected = selectedParts?.period === period;
336
+ return {
337
+ value: period,
338
+ label: getPeriodLabel
339
+ ? getPeriodLabel(period)
340
+ : period.toUpperCase(),
341
+ ariaLabel: getPeriodAriaLabel
342
+ ? getPeriodAriaLabel(period, selected)
343
+ : selected
344
+ ? `${period.toUpperCase()}, selected`
345
+ : `Choose ${period.toUpperCase()}`,
346
+ selected,
347
+ disabled: (disabled ?? false) ||
348
+ !getSelectablePeriodRange(period, bounds)
349
+ };
350
+ }), [
351
+ bounds,
352
+ disabled,
353
+ getPeriodAriaLabel,
354
+ getPeriodLabel,
355
+ selectedParts
356
+ ]);
357
+ const renderSection = ({ label, labelId, listLabel, options, onSelect, className }) => {
358
+ const hasVisibleSelection = options.some((option) => option.selected);
359
+ const firstEnabledIndex = getFirstEnabledIndex(options);
360
+ return (_jsxs("div", { role: "group", "aria-labelledby": labelId, className: cx("flex flex-col min-w-0", classes.section, className), children: [_jsx("div", { id: labelId, className: cx("py-2 text-center font-medium text-[var(--refraktor-text-secondary)] border-b border-[var(--refraktor-border)] bg-[var(--refraktor-bg-subtle)]", sizeStyles.label, classes.sectionLabel), children: label }), _jsx("div", { role: "listbox", "aria-label": listLabel, className: cx("refraktor-scrollbar flex max-h-64 flex-col p-1 overflow-y-auto", sizeStyles.gridGap, classes.list), onKeyDown: (event) => handleListKeyDown(event, options, onSelect), children: options.map((option, index) => {
361
+ const tabIndex = option.selected ||
362
+ (!hasVisibleSelection && index === firstEnabledIndex)
363
+ ? 0
364
+ : -1;
365
+ return (_jsx("button", { type: "button", role: "option", "aria-selected": option.selected, "aria-label": option.ariaLabel, "data-active": option.selected, "data-disabled": option.disabled, disabled: option.disabled, tabIndex: tabIndex, className: cx("inline-flex w-full items-center justify-center font-medium text-[var(--refraktor-text)] transition-colors", option.selected
366
+ ? "bg-[var(--refraktor-primary)] text-[var(--refraktor-primary-text)]"
367
+ : "hover:bg-[var(--refraktor-bg-hover)]", option.disabled &&
368
+ "pointer-events-none cursor-not-allowed opacity-50", sizeStyles.cell, getRadius(radius), classes.option, option.selected && classes.optionActive, option.disabled && classes.optionDisabled), onClick: () => onSelect(option.value), children: option.label }, `${labelId}-${String(option.value)}`));
369
+ }) })] }));
370
+ };
371
+ return (_jsx("div", { ref: ref, id: _id, className: cx("inline-flex w-full flex-col bg-[var(--refraktor-bg)] overflow-hidden border border-[var(--refraktor-border)]", getRadius(radius), classes.root, className), ...props, children: _jsxs("div", { className: cx("grid divide-x divide-[var(--refraktor-border)]", getGridColumns(mode === "12h" ? 4 : 3), classes.grid), children: [renderSection({
372
+ label: "Hour",
373
+ labelId: `${_id}-hour-label`,
374
+ listLabel: "Hour options",
375
+ options: hourOptions,
376
+ onSelect: setHour,
377
+ className: classes.hourSection
378
+ }), renderSection({
379
+ label: "Minute",
380
+ labelId: `${_id}-minute-label`,
381
+ listLabel: "Minute options",
382
+ options: minuteOptions,
383
+ onSelect: setMinute,
384
+ className: classes.minuteSection
385
+ }), renderSection({
386
+ label: "Second",
387
+ labelId: `${_id}-second-label`,
388
+ listLabel: "Second options",
389
+ options: secondOptions,
390
+ onSelect: setSecond,
391
+ className: classes.secondSection
392
+ }), mode === "12h" &&
393
+ renderSection({
394
+ label: "Period",
395
+ labelId: `${_id}-period-label`,
396
+ listLabel: "AM or PM options",
397
+ options: periodOptions,
398
+ onSelect: setPeriod,
399
+ className: classes.periodSection
400
+ })] }) }));
401
+ });
402
+ TimePicker.displayName = "@refraktor/dates/TimePicker";
403
+ TimePicker.configure = createComponentConfig();
404
+ TimePicker.classNames = createClassNamesConfig();
405
+ export default TimePicker;
@@ -0,0 +1,79 @@
1
+ import { ComponentPropsWithoutRef, ReactNode } from "react";
2
+ import { RefraktorRadius, RefraktorSize, createClassNamesConfig, createComponentConfig, FactoryPayload } from "@refraktor/core";
3
+ export type TimePickerValue = string;
4
+ export type TimePickerMode = "12h" | "24h";
5
+ export type TimePickerPeriod = "am" | "pm";
6
+ export type TimePickerSize = RefraktorSize;
7
+ export type TimePickerRadius = RefraktorRadius;
8
+ export type TimePickerOnChange = (value: TimePickerValue) => void;
9
+ export type TimePickerGetHourLabel = (hour: number, mode: TimePickerMode) => ReactNode;
10
+ export type TimePickerGetMinuteLabel = (minute: number) => ReactNode;
11
+ export type TimePickerGetSecondLabel = (second: number) => ReactNode;
12
+ export type TimePickerGetPeriodLabel = (period: TimePickerPeriod) => ReactNode;
13
+ export type TimePickerGetHourAriaLabel = (hour: number, mode: TimePickerMode, selected: boolean) => string;
14
+ export type TimePickerGetMinuteAriaLabel = (minute: number, selected: boolean) => string;
15
+ export type TimePickerGetSecondAriaLabel = (second: number, selected: boolean) => string;
16
+ export type TimePickerGetPeriodAriaLabel = (period: TimePickerPeriod, selected: boolean) => string;
17
+ export type TimePickerClassNames = {
18
+ root?: string;
19
+ grid?: string;
20
+ section?: string;
21
+ sectionLabel?: string;
22
+ list?: string;
23
+ option?: string;
24
+ optionActive?: string;
25
+ optionDisabled?: string;
26
+ hourSection?: string;
27
+ minuteSection?: string;
28
+ secondSection?: string;
29
+ periodSection?: string;
30
+ };
31
+ export interface TimePickerProps extends Omit<ComponentPropsWithoutRef<"div">, "onChange" | "value" | "defaultValue"> {
32
+ /** Active time (controlled), accepts `H:mm:ss` or `HH:mm:ss` (24h). */
33
+ value?: TimePickerValue;
34
+ /** Initial active time (uncontrolled), accepts `H:mm:ss` or `HH:mm:ss` (24h). */
35
+ defaultValue?: TimePickerValue;
36
+ /** Callback called when active time changes in normalized `HH:mm:ss` format (24h). */
37
+ onChange?: TimePickerOnChange;
38
+ /** Lower selectable bound for time-of-day, accepts `H:mm:ss` or `HH:mm:ss` (24h). */
39
+ minTime?: TimePickerValue;
40
+ /** Upper selectable bound for time-of-day, accepts `H:mm:ss` or `HH:mm:ss` (24h). */
41
+ maxTime?: TimePickerValue;
42
+ /** Time display mode @default `24h` */
43
+ mode?: TimePickerMode;
44
+ /** Whether all controls are disabled @default `false` */
45
+ disabled?: boolean;
46
+ /** Component size @default `md` */
47
+ size?: TimePickerSize;
48
+ /** Border radius @default `default` */
49
+ radius?: TimePickerRadius;
50
+ /** Custom hour label renderer. */
51
+ getHourLabel?: TimePickerGetHourLabel;
52
+ /** Custom minute label renderer. */
53
+ getMinuteLabel?: TimePickerGetMinuteLabel;
54
+ /** Custom second label renderer. */
55
+ getSecondLabel?: TimePickerGetSecondLabel;
56
+ /** Custom AM/PM label renderer in 12h mode. */
57
+ getPeriodLabel?: TimePickerGetPeriodLabel;
58
+ /** Custom aria-label generator for hour options. */
59
+ getHourAriaLabel?: TimePickerGetHourAriaLabel;
60
+ /** Custom aria-label generator for minute options. */
61
+ getMinuteAriaLabel?: TimePickerGetMinuteAriaLabel;
62
+ /** Custom aria-label generator for second options. */
63
+ getSecondAriaLabel?: TimePickerGetSecondAriaLabel;
64
+ /** Custom aria-label generator for period options. */
65
+ getPeriodAriaLabel?: TimePickerGetPeriodAriaLabel;
66
+ /** Used for editing root class name. */
67
+ className?: string;
68
+ /** Used for styling different parts of the component. */
69
+ classNames?: TimePickerClassNames;
70
+ }
71
+ export interface TimePickerFactoryPayload extends FactoryPayload {
72
+ props: TimePickerProps;
73
+ ref: HTMLDivElement;
74
+ compound: {
75
+ configure: ReturnType<typeof createComponentConfig<TimePickerProps>>;
76
+ classNames: ReturnType<typeof createClassNamesConfig<TimePickerClassNames>>;
77
+ };
78
+ }
79
+ //# sourceMappingURL=time-picker.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time-picker.types.d.ts","sourceRoot":"","sources":["../../../src/components/time-picker/time-picker.types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -1 +1 @@
1
- {"version":3,"file":"year-input.d.ts","sourceRoot":"","sources":["../../../src/components/year-input/year-input.tsx"],"names":[],"mappings":"AA6BA,OAAO,EAEH,uBAAuB,EAE1B,MAAM,oBAAoB,CAAC;AAkC5B,QAAA,MAAM,SAAS,uEAiRb,CAAC;AAMH,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"year-input.d.ts","sourceRoot":"","sources":["../../../src/components/year-input/year-input.tsx"],"names":[],"mappings":"AA6BA,OAAO,EAEH,uBAAuB,EAE1B,MAAM,oBAAoB,CAAC;AAkC5B,QAAA,MAAM,SAAS,uEAoRb,CAAC;AAMH,eAAe,SAAS,CAAC"}
@@ -88,7 +88,8 @@ const YearInput = factory((_props, ref) => {
88
88
  open: isOpen,
89
89
  onOpenChange: handleOpenChange,
90
90
  middleware,
91
- whileElementsMounted: autoUpdate
91
+ whileElementsMounted: autoUpdate,
92
+ strategy: "fixed"
92
93
  });
93
94
  const focus = useFocus(floating.context, {
94
95
  enabled: !disabled
@@ -145,8 +146,9 @@ const YearInput = factory((_props, ref) => {
145
146
  onClick,
146
147
  onKeyDown: handleInputKeyDown
147
148
  });
148
- const dropdownContent = (_jsx(Transition, { transition: "fade", duration: 150, mounted: isOpen, ...transitionProps, children: _jsx("div", { ref: floating.refs.setFloating, id: dropdownId, style: {
149
- ...floating.floatingStyles
149
+ const dropdownContent = (_jsx(Transition, { transition: "fade", duration: 150, mounted: isOpen, style: { position: "relative", zIndex: 1000 }, ...transitionProps, children: _jsx("div", { ref: floating.refs.setFloating, id: dropdownId, style: {
150
+ ...floating.floatingStyles,
151
+ zIndex: 1000
150
152
  }, className: cx("w-60 z-50 border border-[var(--refraktor-border)] bg-[var(--refraktor-bg)] p-2 text-[var(--refraktor-text)] shadow-md", getRadius(radius), classes.dropdown), ...getFloatingProps(), children: _jsx(YearPicker, { value: selectedYear, onChange: handleYearChange, minYear: minYear, maxYear: maxYear, yearsPerPage: yearsPerPage, columns: columns, disabled: disabled, size: size, radius: radius, className: cx("bg-transparent p-0", classes.yearPicker) }) }) }));
151
153
  const wrappedContent = isOpen ? (_jsx(FloatingFocusManager, { context: floating.context, modal: false, initialFocus: -1, returnFocus: false, children: dropdownContent })) : (dropdownContent);
152
154
  return (_jsxs(_Fragment, { children: [_jsx(Input, { ref: setInputRef, id: _id, readOnly: true, value: inputValue, disabled: disabled, size: size, radius: radius, role: "combobox", "aria-haspopup": "dialog", "aria-expanded": isOpen, "aria-controls": isOpen ? dropdownId : undefined, className: cx(classes.input, className), classNames: inputClassNames, ...inputProps, ...mergedReferenceProps }), withinPortal ? (_jsx(FloatingPortal, { children: wrappedContent })) : (wrappedContent)] }));
package/build/style.css CHANGED
@@ -1,2 +1,2 @@
1
1
  /*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */
2
- @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height:calc(1.5/1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--font-weight-medium:500;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.visible{visibility:visible}.relative{position:relative}.z-50{z-index:50}.flex{display:flex}.grid{display:grid}.inline{display:inline}.inline-flex{display:inline-flex}.size-6{width:calc(var(--spacing)*6);height:calc(var(--spacing)*6)}.size-7{width:calc(var(--spacing)*7);height:calc(var(--spacing)*7)}.size-8{width:calc(var(--spacing)*8);height:calc(var(--spacing)*8)}.size-9{width:calc(var(--spacing)*9);height:calc(var(--spacing)*9)}.size-10{width:calc(var(--spacing)*10);height:calc(var(--spacing)*10)}.h-7{height:calc(var(--spacing)*7)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-11{height:calc(var(--spacing)*11)}.w-60{width:calc(var(--spacing)*60)}.w-72{width:calc(var(--spacing)*72)}.w-80{width:calc(var(--spacing)*80)}.w-full{width:100%}.min-w-0{min-width:calc(var(--spacing)*0)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.rotate-180{rotate:180deg}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.border{border-style:var(--tw-border-style);border-width:1px}.border-\[var\(--refraktor-border\)\]{border-color:var(--refraktor-border)}.bg-\[var\(--refraktor-bg\)\]{background-color:var(--refraktor-bg)}.bg-\[var\(--refraktor-primary\)\]{background-color:var(--refraktor-primary)}.bg-transparent{background-color:#0000}.p-0{padding:calc(var(--spacing)*0)}.p-2{padding:calc(var(--spacing)*2)}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.text-center{text-align:center}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.text-\[var\(--refraktor-primary-text\)\]{color:var(--refraktor-primary-text)}.text-\[var\(--refraktor-text\)\]{color:var(--refraktor-text)}.text-\[var\(--refraktor-text-secondary\)\]{color:var(--refraktor-text-secondary)}.opacity-50{opacity:.5}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-\[var\(--refraktor-primary\)\]{--tw-ring-color:var(--refraktor-primary)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media (hover:hover){.hover\:bg-\[var\(--refraktor-bg-hover\)\]:hover{background-color:var(--refraktor-bg-hover)}.hover\:bg-\[var\(--refraktor-primary\)\]:hover{background-color:var(--refraktor-primary)}}.focus-visible\:outline:focus-visible{outline-style:var(--tw-outline-style);outline-width:1px}.focus-visible\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\:outline-offset-2:focus-visible{outline-offset:2px}.focus-visible\:outline-\[var\(--refraktor-primary\)\]:focus-visible{outline-color:var(--refraktor-primary)}.data-\[disabled\=true\]\:pointer-events-none[data-disabled=true]{pointer-events:none}.data-\[disabled\=true\]\:cursor-not-allowed[data-disabled=true]{cursor:not-allowed}.data-\[disabled\=true\]\:opacity-50[data-disabled=true]{opacity:.5}}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-divide-x-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height:calc(1.5/1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--font-weight-medium:500;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.visible{visibility:visible}.fixed{position:fixed}.relative{position:relative}.z-50{z-index:50}.flex{display:flex}.grid{display:grid}.inline{display:inline}.inline-flex{display:inline-flex}.size-6{width:calc(var(--spacing)*6);height:calc(var(--spacing)*6)}.size-7{width:calc(var(--spacing)*7);height:calc(var(--spacing)*7)}.size-8{width:calc(var(--spacing)*8);height:calc(var(--spacing)*8)}.size-9{width:calc(var(--spacing)*9);height:calc(var(--spacing)*9)}.size-10{width:calc(var(--spacing)*10);height:calc(var(--spacing)*10)}.h-7{height:calc(var(--spacing)*7)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-11{height:calc(var(--spacing)*11)}.max-h-64{max-height:calc(var(--spacing)*64)}.w-60{width:calc(var(--spacing)*60)}.w-72{width:calc(var(--spacing)*72)}.w-80{width:calc(var(--spacing)*80)}.w-\[calc\(100vw-1rem\)\]{width:calc(100vw - 1rem)}.w-full{width:100%}.max-w-\[22rem\]{max-width:22rem}.max-w-\[28rem\]{max-width:28rem}.min-w-0{min-width:calc(var(--spacing)*0)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.rotate-180{rotate:180deg}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}:where(.divide-x>:not(:last-child)){--tw-divide-x-reverse:0;border-inline-style:var(--tw-border-style);border-inline-start-width:calc(1px*var(--tw-divide-x-reverse));border-inline-end-width:calc(1px*calc(1 - var(--tw-divide-x-reverse)))}:where(.divide-\[var\(--refraktor-border\)\]>:not(:last-child)){border-color:var(--refraktor-border)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.border{border-style:var(--tw-border-style);border-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-\[var\(--refraktor-border\)\]{border-color:var(--refraktor-border)}.bg-\[var\(--refraktor-bg\)\]{background-color:var(--refraktor-bg)}.bg-\[var\(--refraktor-bg-subtle\)\]{background-color:var(--refraktor-bg-subtle)}.bg-\[var\(--refraktor-primary\)\]{background-color:var(--refraktor-primary)}.bg-transparent{background-color:#0000}.p-0{padding:calc(var(--spacing)*0)}.p-1{padding:calc(var(--spacing)*1)}.p-2{padding:calc(var(--spacing)*2)}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.text-center{text-align:center}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.text-\[var\(--refraktor-primary-text\)\]{color:var(--refraktor-primary-text)}.text-\[var\(--refraktor-text\)\]{color:var(--refraktor-text)}.text-\[var\(--refraktor-text-secondary\)\]{color:var(--refraktor-text-secondary)}.opacity-50{opacity:.5}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-\[var\(--refraktor-primary\)\]{--tw-ring-color:var(--refraktor-primary)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media (hover:hover){.hover\:bg-\[var\(--refraktor-bg-hover\)\]:hover{background-color:var(--refraktor-bg-hover)}.hover\:bg-\[var\(--refraktor-primary\)\]:hover{background-color:var(--refraktor-primary)}}.focus-visible\:outline:focus-visible{outline-style:var(--tw-outline-style);outline-width:1px}.focus-visible\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\:outline-offset-2:focus-visible{outline-offset:2px}.focus-visible\:outline-\[var\(--refraktor-primary\)\]:focus-visible{outline-color:var(--refraktor-primary)}.data-\[disabled\=true\]\:pointer-events-none[data-disabled=true]{pointer-events:none}.data-\[disabled\=true\]\:cursor-not-allowed[data-disabled=true]{cursor:not-allowed}.data-\[disabled\=true\]\:opacity-50[data-disabled=true]{opacity:.5}}@property --tw-divide-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@refraktor/dates",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -24,8 +24,8 @@
24
24
  "react": ">=18.0.0",
25
25
  "react-dom": ">=18.0.0",
26
26
  "dayjs": "^1.11.19",
27
- "@refraktor/core": "0.0.1",
28
- "@refraktor/utils": "0.0.1"
27
+ "@refraktor/core": "0.0.3",
28
+ "@refraktor/utils": "0.0.3"
29
29
  },
30
30
  "devDependencies": {
31
31
  "typescript": "^5.9.3"
@@ -195,7 +195,8 @@ const DateInput = factory<DateInputFactoryPayload>((_props, ref) => {
195
195
  open: isOpen,
196
196
  onOpenChange: handleOpenChange,
197
197
  middleware,
198
- whileElementsMounted: autoUpdate
198
+ whileElementsMounted: autoUpdate,
199
+ strategy: "fixed"
199
200
  });
200
201
 
201
202
  const focus = useFocus(floating.context, {
@@ -286,13 +287,15 @@ const DateInput = factory<DateInputFactoryPayload>((_props, ref) => {
286
287
  transition="fade"
287
288
  duration={150}
288
289
  mounted={isOpen}
290
+ style={{ position: "relative", zIndex: 1000 }}
289
291
  {...transitionProps}
290
292
  >
291
293
  <div
292
294
  ref={floating.refs.setFloating}
293
295
  id={dropdownId}
294
296
  style={{
295
- ...floating.floatingStyles
297
+ ...floating.floatingStyles,
298
+ zIndex: 1000
296
299
  }}
297
300
  className={cx(
298
301
  "w-80 z-50 border border-[var(--refraktor-border)] bg-[var(--refraktor-bg)] p-2 text-[var(--refraktor-text)] shadow-md",
@@ -5,3 +5,5 @@ export * from "./month-picker";
5
5
  export * from "./month-input";
6
6
  export * from "./year-picker";
7
7
  export * from "./year-input";
8
+ export * from "./time-picker";
9
+ export * from "./time-input";