jaci-ui 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/README.md +168 -0
- package/dist/components/color-picker/color-picker.cjs +77 -22
- package/dist/components/color-picker/color-picker.cjs.map +1 -1
- package/dist/components/color-picker/color-picker.d.cts +3 -3
- package/dist/components/color-picker/color-picker.d.ts +3 -3
- package/dist/components/color-picker/color-picker.js +77 -22
- package/dist/components/color-picker/color-picker.js.map +1 -1
- package/dist/components/date-picker/date-picker.cjs +227 -30
- package/dist/components/date-picker/date-picker.cjs.map +1 -1
- package/dist/components/date-picker/date-picker.d.cts +23 -5
- package/dist/components/date-picker/date-picker.d.ts +23 -5
- package/dist/components/date-picker/date-picker.js +226 -32
- package/dist/components/date-picker/date-picker.js.map +1 -1
- package/dist/components/date-picker/date-utils.cjs +32 -2
- package/dist/components/date-picker/date-utils.cjs.map +1 -1
- package/dist/components/date-picker/date-utils.d.cts +5 -0
- package/dist/components/date-picker/date-utils.d.ts +5 -0
- package/dist/components/date-picker/date-utils.js +29 -3
- package/dist/components/date-picker/date-utils.js.map +1 -1
- package/dist/components/date-picker/index.d.cts +3 -2
- package/dist/components/date-picker/index.d.ts +3 -2
- package/dist/components/menu/menu.cjs +1 -2
- package/dist/components/menu/menu.cjs.map +1 -1
- package/dist/components/menu/menu.d.cts +1 -2
- package/dist/components/menu/menu.d.ts +1 -2
- package/dist/components/menu/menu.js +1 -2
- package/dist/components/menu/menu.js.map +1 -1
- package/dist/components/option-selector/option-selector.cjs.map +1 -1
- package/dist/components/option-selector/option-selector.d.cts +2 -2
- package/dist/components/option-selector/option-selector.d.ts +2 -2
- package/dist/components/option-selector/option-selector.js.map +1 -1
- package/dist/components/toast/toast.cjs +1 -1
- package/dist/components/toast/toast.cjs.map +1 -1
- package/dist/components/toast/toast.d.cts +1 -1
- package/dist/components/toast/toast.d.ts +1 -1
- package/dist/components/toast/toast.js +1 -1
- package/dist/components/toast/toast.js.map +1 -1
- package/dist/index.cjs +3 -0
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -2
- package/dist/styled-system/recipes/color-picker.cjs +1 -0
- package/dist/styled-system/recipes/color-picker.cjs.map +1 -1
- package/dist/styled-system/recipes/color-picker.js +1 -0
- package/dist/styled-system/recipes/color-picker.js.map +1 -1
- package/dist/styled-system/recipes/date-picker.cjs +6 -0
- package/dist/styled-system/recipes/date-picker.cjs.map +1 -1
- package/dist/styled-system/recipes/date-picker.js +6 -0
- package/dist/styled-system/recipes/date-picker.js.map +1 -1
- package/dist/styles.css +190 -4
- package/package.json +5 -2
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { cx } from "../../styled-system/css/cx.js";
|
|
3
3
|
import { withRecipeClassName } from "../base-ui.js";
|
|
4
4
|
import { datePicker } from "../../styled-system/recipes/date-picker.js";
|
|
5
|
-
import { addDays, addMonths, createCalendarDate, dateKey, formatDateLabel, formatMonthLabel, getCalendarDays, getDateRangeLabel, getWeekdayLabels, isAfterDay, isBeforeDay, isSameDay, startOfMonth, toInputDate } from "./date-utils.js";
|
|
5
|
+
import { addDays, addMonths, createCalendarDate, dateKey, formatDateLabel, formatMonthLabel, getCalendarDays, getDateRangeLabel, getMonthLabels, getWeekdayLabels, isAfterDay, isBeforeDay, isSameDay, startOfMonth, toInputDate, toInputDateTime, toInputMonth, toTimeInput } from "./date-utils.js";
|
|
6
6
|
import { createContext, forwardRef, useCallback, useContext, useEffect, useId, useMemo, useRef, useState } from "react";
|
|
7
7
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import { Popover } from "@base-ui/react/popover";
|
|
@@ -23,7 +23,7 @@ function composeRefs(first, second) {
|
|
|
23
23
|
else if (first) first.current = value;
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
|
-
function DatePickerRoot({ children, closeOnSelect
|
|
26
|
+
function DatePickerRoot({ children, closeOnSelect: closeOnSelectProp, defaultValue = null, disabled = false, granularity = "day", isDateDisabled, locale = "pt-BR", maxDate, minDate, name, onValueChange, onMonthChange, placeholder = "Select a date", size = "md", value: controlledValue, weekStartsOn = 0, yearRange: configuredYearRange, actionsRef: externalActionsRef, ...popoverProps }) {
|
|
27
27
|
const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);
|
|
28
28
|
const selected = controlledValue === void 0 ? uncontrolledValue : controlledValue;
|
|
29
29
|
const [month, setMonthState] = useState(() => startOfMonth(selected ?? /* @__PURE__ */ new Date()));
|
|
@@ -37,6 +37,29 @@ function DatePickerRoot({ children, closeOnSelect = true, defaultValue = null, d
|
|
|
37
37
|
const styles = datePicker({ size });
|
|
38
38
|
const minMonth = minDate ? startOfMonth(minDate) : void 0;
|
|
39
39
|
const maxMonth = maxDate ? startOfMonth(maxDate) : void 0;
|
|
40
|
+
const closeOnSelect = closeOnSelectProp ?? granularity !== "date-time";
|
|
41
|
+
const yearRange = useMemo(() => {
|
|
42
|
+
const defaultStart = today.getFullYear() - 100;
|
|
43
|
+
const defaultEnd = today.getFullYear() + 20;
|
|
44
|
+
const start = configuredYearRange?.start ?? defaultStart;
|
|
45
|
+
const end = configuredYearRange?.end ?? defaultEnd;
|
|
46
|
+
const years = [
|
|
47
|
+
selected?.getFullYear(),
|
|
48
|
+
minDate?.getFullYear(),
|
|
49
|
+
maxDate?.getFullYear()
|
|
50
|
+
].filter((year) => year !== void 0);
|
|
51
|
+
return {
|
|
52
|
+
end: Math.max(start, end, ...years),
|
|
53
|
+
start: Math.min(start, end, ...years)
|
|
54
|
+
};
|
|
55
|
+
}, [
|
|
56
|
+
configuredYearRange?.end,
|
|
57
|
+
configuredYearRange?.start,
|
|
58
|
+
maxDate,
|
|
59
|
+
minDate,
|
|
60
|
+
selected,
|
|
61
|
+
today
|
|
62
|
+
]);
|
|
40
63
|
const clampMonth = useCallback((nextMonth) => {
|
|
41
64
|
const normalized = startOfMonth(nextMonth);
|
|
42
65
|
if (minMonth && isBeforeDay(normalized, minMonth)) return minMonth;
|
|
@@ -68,26 +91,102 @@ function DatePickerRoot({ children, closeOnSelect = true, defaultValue = null, d
|
|
|
68
91
|
const close = useCallback(() => {
|
|
69
92
|
(externalActionsRef ?? internalActionsRef).current?.close();
|
|
70
93
|
}, [externalActionsRef]);
|
|
71
|
-
const
|
|
72
|
-
if (disabled || dateDisabled(date)) return;
|
|
73
|
-
const nextValue = createCalendarDate(date.getFullYear(), date.getMonth(), date.getDate());
|
|
94
|
+
const setValue = useCallback((nextValue) => {
|
|
74
95
|
setUncontrolledValue(nextValue);
|
|
96
|
+
onValueChange?.(nextValue);
|
|
97
|
+
}, [onValueChange]);
|
|
98
|
+
const monthDisabled = useCallback((candidate) => {
|
|
99
|
+
const firstDay = startOfMonth(candidate);
|
|
100
|
+
const lastDay = createCalendarDate(candidate.getFullYear(), candidate.getMonth() + 1, 0);
|
|
101
|
+
return Boolean(minDate && isBeforeDay(lastDay, minDate) || maxDate && isAfterDay(firstDay, maxDate));
|
|
102
|
+
}, [maxDate, minDate]);
|
|
103
|
+
const onSelect = useCallback((date) => {
|
|
104
|
+
if (disabled || (granularity === "month" ? monthDisabled(date) : dateDisabled(date))) return;
|
|
105
|
+
const nextValue = createCalendarDate(date.getFullYear(), date.getMonth(), granularity === "month" ? 1 : date.getDate());
|
|
106
|
+
if (granularity === "date-time") {
|
|
107
|
+
nextValue.setHours(selected?.getHours() ?? 12, selected?.getMinutes() ?? 0, 0, 0);
|
|
108
|
+
if (minDate && isSameDay(nextValue, minDate) && nextValue < minDate) nextValue.setHours(minDate.getHours(), minDate.getMinutes(), 0, 0);
|
|
109
|
+
if (maxDate && isSameDay(nextValue, maxDate) && nextValue > maxDate) nextValue.setHours(maxDate.getHours(), maxDate.getMinutes(), 0, 0);
|
|
110
|
+
}
|
|
111
|
+
setValue(nextValue);
|
|
75
112
|
setFocusedDate(nextValue);
|
|
76
113
|
setMonth(startOfMonth(nextValue));
|
|
77
|
-
onValueChange?.(nextValue);
|
|
78
114
|
if (closeOnSelect) close();
|
|
79
115
|
}, [
|
|
80
116
|
close,
|
|
81
117
|
closeOnSelect,
|
|
82
118
|
dateDisabled,
|
|
83
119
|
disabled,
|
|
84
|
-
|
|
85
|
-
|
|
120
|
+
granularity,
|
|
121
|
+
maxDate,
|
|
122
|
+
monthDisabled,
|
|
123
|
+
minDate,
|
|
124
|
+
selected,
|
|
125
|
+
setMonth,
|
|
126
|
+
setValue
|
|
86
127
|
]);
|
|
87
128
|
const onClear = useCallback(() => {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
129
|
+
setValue(null);
|
|
130
|
+
}, [setValue]);
|
|
131
|
+
const selectMonth = useCallback((monthIndex) => {
|
|
132
|
+
const nextMonth = clampMonth(createCalendarDate(month.getFullYear(), monthIndex, 1));
|
|
133
|
+
if (monthDisabled(nextMonth)) return;
|
|
134
|
+
setMonth(nextMonth);
|
|
135
|
+
if (granularity === "month") {
|
|
136
|
+
const nextValue = createCalendarDate(nextMonth.getFullYear(), nextMonth.getMonth(), 1);
|
|
137
|
+
setFocusedDate(nextValue);
|
|
138
|
+
setValue(nextValue);
|
|
139
|
+
if (closeOnSelect) close();
|
|
140
|
+
}
|
|
141
|
+
}, [
|
|
142
|
+
clampMonth,
|
|
143
|
+
close,
|
|
144
|
+
closeOnSelect,
|
|
145
|
+
granularity,
|
|
146
|
+
month,
|
|
147
|
+
monthDisabled,
|
|
148
|
+
setMonth,
|
|
149
|
+
setValue
|
|
150
|
+
]);
|
|
151
|
+
const selectYear = useCallback((year) => {
|
|
152
|
+
const nextMonth = clampMonth(createCalendarDate(year, month.getMonth(), 1));
|
|
153
|
+
if (monthDisabled(nextMonth)) return;
|
|
154
|
+
setMonth(nextMonth);
|
|
155
|
+
if (granularity === "month") {
|
|
156
|
+
const nextValue = createCalendarDate(nextMonth.getFullYear(), nextMonth.getMonth(), 1);
|
|
157
|
+
setFocusedDate(nextValue);
|
|
158
|
+
setValue(nextValue);
|
|
159
|
+
if (closeOnSelect) close();
|
|
160
|
+
}
|
|
161
|
+
}, [
|
|
162
|
+
clampMonth,
|
|
163
|
+
close,
|
|
164
|
+
closeOnSelect,
|
|
165
|
+
granularity,
|
|
166
|
+
month,
|
|
167
|
+
monthDisabled,
|
|
168
|
+
setMonth,
|
|
169
|
+
setValue
|
|
170
|
+
]);
|
|
171
|
+
const onTimeChange = useCallback((value) => {
|
|
172
|
+
const match = value.match(/^(\d{2}):(\d{2})$/);
|
|
173
|
+
if (!match) return;
|
|
174
|
+
const hours = Number(match[1]);
|
|
175
|
+
const minutes = Number(match[2]);
|
|
176
|
+
if (hours > 23 || minutes > 59) return;
|
|
177
|
+
const baseDate = selected ?? focusedDate;
|
|
178
|
+
const nextValue = createCalendarDate(baseDate.getFullYear(), baseDate.getMonth(), baseDate.getDate());
|
|
179
|
+
nextValue.setHours(hours, minutes, 0, 0);
|
|
180
|
+
if (minDate && isSameDay(nextValue, minDate) && nextValue < minDate) return;
|
|
181
|
+
if (maxDate && isSameDay(nextValue, maxDate) && nextValue > maxDate) return;
|
|
182
|
+
setValue(nextValue);
|
|
183
|
+
}, [
|
|
184
|
+
focusedDate,
|
|
185
|
+
maxDate,
|
|
186
|
+
minDate,
|
|
187
|
+
selected,
|
|
188
|
+
setValue
|
|
189
|
+
]);
|
|
91
190
|
const focusDate = useCallback((date, direction = 1) => {
|
|
92
191
|
let nextDate = createCalendarDate(date.getFullYear(), date.getMonth(), date.getDate());
|
|
93
192
|
const step = direction < 0 ? -1 : 1;
|
|
@@ -102,39 +201,51 @@ function DatePickerRoot({ children, closeOnSelect = true, defaultValue = null, d
|
|
|
102
201
|
focusTarget();
|
|
103
202
|
queueMicrotask(focusTarget);
|
|
104
203
|
}, [dateDisabled, setMonth]);
|
|
204
|
+
const canNavigate = useCallback((amount) => {
|
|
205
|
+
const nextMonth = addMonths(month, amount);
|
|
206
|
+
return !(minMonth && isBeforeDay(nextMonth, minMonth) || maxMonth && isAfterDay(nextMonth, maxMonth));
|
|
207
|
+
}, [
|
|
208
|
+
maxMonth,
|
|
209
|
+
minMonth,
|
|
210
|
+
month
|
|
211
|
+
]);
|
|
212
|
+
const registerDay = useCallback((key, node) => {
|
|
213
|
+
if (node) dayRefs.current.set(key, node);
|
|
214
|
+
else dayRefs.current.delete(key);
|
|
215
|
+
}, []);
|
|
216
|
+
const timeMin = selected && minDate && isSameDay(selected, minDate) ? toTimeInput(minDate) : void 0;
|
|
217
|
+
const timeMax = selected && maxDate && isSameDay(selected, maxDate) ? toTimeInput(maxDate) : void 0;
|
|
105
218
|
const context = {
|
|
106
|
-
canNavigate
|
|
107
|
-
const nextMonth = addMonths(month, amount);
|
|
108
|
-
return !(minMonth && isBeforeDay(nextMonth, minMonth) || maxMonth && isAfterDay(nextMonth, maxMonth));
|
|
109
|
-
}, [
|
|
110
|
-
maxMonth,
|
|
111
|
-
minMonth,
|
|
112
|
-
month
|
|
113
|
-
]),
|
|
219
|
+
canNavigate,
|
|
114
220
|
close,
|
|
115
221
|
dateDisabled,
|
|
222
|
+
granularity,
|
|
116
223
|
disabled,
|
|
117
224
|
focusDate,
|
|
118
225
|
focusedDate,
|
|
119
|
-
formatDate: (date) => formatDateLabel(date, locale, String(placeholder)),
|
|
226
|
+
formatDate: (date) => formatDateLabel(date, locale, String(placeholder), granularity),
|
|
120
227
|
labelId,
|
|
121
228
|
locale,
|
|
122
229
|
month,
|
|
230
|
+
monthDisabled,
|
|
123
231
|
onClear,
|
|
232
|
+
onTimeChange,
|
|
124
233
|
onSelect,
|
|
234
|
+
selectMonth,
|
|
235
|
+
selectYear,
|
|
125
236
|
placeholder,
|
|
126
|
-
registerDay
|
|
127
|
-
if (node) dayRefs.current.set(key, node);
|
|
128
|
-
else dayRefs.current.delete(key);
|
|
129
|
-
}, []),
|
|
237
|
+
registerDay,
|
|
130
238
|
selected,
|
|
131
239
|
setFocusedDate,
|
|
132
240
|
setMonth,
|
|
133
241
|
size,
|
|
134
242
|
styles,
|
|
135
243
|
today: createCalendarDate(today.getFullYear(), today.getMonth(), today.getDate()),
|
|
244
|
+
timeMax,
|
|
245
|
+
timeMin,
|
|
136
246
|
triggerId,
|
|
137
|
-
weekStartsOn
|
|
247
|
+
weekStartsOn,
|
|
248
|
+
yearRange
|
|
138
249
|
};
|
|
139
250
|
return /* @__PURE__ */ jsxs(DatePickerContext.Provider, {
|
|
140
251
|
value: context,
|
|
@@ -146,7 +257,7 @@ function DatePickerRoot({ children, closeOnSelect = true, defaultValue = null, d
|
|
|
146
257
|
disabled,
|
|
147
258
|
name,
|
|
148
259
|
type: "hidden",
|
|
149
|
-
value: toInputDate(selected)
|
|
260
|
+
value: granularity === "month" ? toInputMonth(selected) : granularity === "date-time" ? toInputDateTime(selected) : toInputDate(selected)
|
|
150
261
|
}) : null]
|
|
151
262
|
});
|
|
152
263
|
}
|
|
@@ -245,7 +356,7 @@ const DatePickerClose = forwardRef(function DatePickerClose({ className, ...prop
|
|
|
245
356
|
return /* @__PURE__ */ jsx(Popover.Close, {
|
|
246
357
|
...props,
|
|
247
358
|
ref,
|
|
248
|
-
className: withRecipeClassName(styles.
|
|
359
|
+
className: withRecipeClassName(styles.close, className),
|
|
249
360
|
"data-slot": "date-picker-close"
|
|
250
361
|
});
|
|
251
362
|
});
|
|
@@ -268,6 +379,59 @@ const DatePickerCaption = forwardRef(function DatePickerCaption({ children, clas
|
|
|
268
379
|
children: children ?? formatMonthLabel(month, locale)
|
|
269
380
|
});
|
|
270
381
|
});
|
|
382
|
+
const DatePickerMonthSelect = forwardRef(function DatePickerMonthSelect({ className, ...props }, ref) {
|
|
383
|
+
const { locale, month, monthDisabled, selectMonth, styles } = useDatePickerContext();
|
|
384
|
+
const labels = getMonthLabels(locale);
|
|
385
|
+
return /* @__PURE__ */ jsx("select", {
|
|
386
|
+
...props,
|
|
387
|
+
"aria-label": props["aria-label"] ?? "Select month",
|
|
388
|
+
className: cx(styles.monthSelect, className),
|
|
389
|
+
"data-slot": "date-picker-month-select",
|
|
390
|
+
onChange: (event) => selectMonth(Number(event.currentTarget.value)),
|
|
391
|
+
ref,
|
|
392
|
+
value: month.getMonth(),
|
|
393
|
+
children: labels.map((label, monthIndex) => /* @__PURE__ */ jsx("option", {
|
|
394
|
+
disabled: monthDisabled(createCalendarDate(month.getFullYear(), monthIndex, 1)),
|
|
395
|
+
value: monthIndex,
|
|
396
|
+
children: label
|
|
397
|
+
}, label))
|
|
398
|
+
});
|
|
399
|
+
});
|
|
400
|
+
const DatePickerYearSelect = forwardRef(function DatePickerYearSelect({ className, ...props }, ref) {
|
|
401
|
+
const { month, monthDisabled, selectYear, styles, yearRange } = useDatePickerContext();
|
|
402
|
+
const years = Array.from({ length: yearRange.end - yearRange.start + 1 }, (_, index) => yearRange.start + index);
|
|
403
|
+
return /* @__PURE__ */ jsx("select", {
|
|
404
|
+
...props,
|
|
405
|
+
"aria-label": props["aria-label"] ?? "Select year",
|
|
406
|
+
className: cx(styles.yearSelect, className),
|
|
407
|
+
"data-slot": "date-picker-year-select",
|
|
408
|
+
onChange: (event) => selectYear(Number(event.currentTarget.value)),
|
|
409
|
+
ref,
|
|
410
|
+
value: month.getFullYear(),
|
|
411
|
+
children: years.map((year) => /* @__PURE__ */ jsx("option", {
|
|
412
|
+
disabled: monthDisabled(createCalendarDate(year, month.getMonth(), 1)),
|
|
413
|
+
value: year,
|
|
414
|
+
children: year
|
|
415
|
+
}, year))
|
|
416
|
+
});
|
|
417
|
+
});
|
|
418
|
+
const DatePickerTimeField = forwardRef(function DatePickerTimeField({ className, ...props }, ref) {
|
|
419
|
+
const { disabled, granularity, onTimeChange, selected, styles, timeMax, timeMin } = useDatePickerContext();
|
|
420
|
+
if (granularity !== "date-time") return null;
|
|
421
|
+
return /* @__PURE__ */ jsx("input", {
|
|
422
|
+
...props,
|
|
423
|
+
"aria-label": props["aria-label"] ?? "Select time",
|
|
424
|
+
className: cx(styles.timeField, className),
|
|
425
|
+
"data-slot": "date-picker-time-field",
|
|
426
|
+
disabled: disabled || !selected,
|
|
427
|
+
max: timeMax,
|
|
428
|
+
min: timeMin,
|
|
429
|
+
onChange: (event) => onTimeChange(event.currentTarget.value),
|
|
430
|
+
ref,
|
|
431
|
+
type: "time",
|
|
432
|
+
value: toTimeInput(selected)
|
|
433
|
+
});
|
|
434
|
+
});
|
|
271
435
|
const DatePickerNavigationButton = forwardRef(function DatePickerNavigationButton({ amount, children, className, onClick, ...props }, ref) {
|
|
272
436
|
const { canNavigate, month, setMonth, styles } = useDatePickerContext();
|
|
273
437
|
const direction = amount ?? 1;
|
|
@@ -380,17 +544,44 @@ const DatePickerDay = forwardRef(function DatePickerDay({ children, className, d
|
|
|
380
544
|
children: children ?? date.getDate()
|
|
381
545
|
});
|
|
382
546
|
});
|
|
547
|
+
const DatePickerMonthButton = forwardRef(function DatePickerMonthButton({ date }, ref) {
|
|
548
|
+
const { disabled, granularity, locale, monthDisabled, onSelect, selected, styles } = useDatePickerContext();
|
|
549
|
+
const isDisabled = disabled || monthDisabled(date);
|
|
550
|
+
const isSelected = granularity === "month" && Boolean(selected && isSameMonth(selected, date));
|
|
551
|
+
return /* @__PURE__ */ jsx("button", {
|
|
552
|
+
"aria-label": new Intl.DateTimeFormat(locale, { month: "long" }).format(date),
|
|
553
|
+
"aria-selected": isSelected,
|
|
554
|
+
className: styles.month,
|
|
555
|
+
"data-disabled": isDisabled || void 0,
|
|
556
|
+
"data-selected": isSelected || void 0,
|
|
557
|
+
"data-slot": "date-picker-month",
|
|
558
|
+
disabled: isDisabled,
|
|
559
|
+
onClick: () => onSelect(date),
|
|
560
|
+
ref,
|
|
561
|
+
role: "gridcell",
|
|
562
|
+
type: "button",
|
|
563
|
+
children: new Intl.DateTimeFormat(locale, { month: "short" }).format(date)
|
|
564
|
+
});
|
|
565
|
+
});
|
|
383
566
|
const DatePickerCalendar = forwardRef(function DatePickerCalendar({ "aria-label": ariaLabel, className, ...props }, ref) {
|
|
384
|
-
const { locale, month, styles, weekStartsOn } = useDatePickerContext();
|
|
567
|
+
const { granularity, locale, month, styles, weekStartsOn } = useDatePickerContext();
|
|
385
568
|
const days = useMemo(() => getCalendarDays(month, weekStartsOn), [month, weekStartsOn]);
|
|
386
569
|
const weekdays = useMemo(() => getWeekdayLabels(locale, weekStartsOn), [locale, weekStartsOn]);
|
|
387
|
-
|
|
570
|
+
const monthDates = useMemo(() => Array.from({ length: 12 }, (_, index) => createCalendarDate(month.getFullYear(), index, 1)), [month]);
|
|
571
|
+
return /* @__PURE__ */ jsx("section", {
|
|
388
572
|
...props,
|
|
389
573
|
ref,
|
|
390
574
|
"aria-label": ariaLabel ?? formatMonthLabel(month, locale),
|
|
391
575
|
className: cx(styles.calendar, className),
|
|
576
|
+
"data-granularity": granularity,
|
|
392
577
|
"data-slot": "date-picker-calendar",
|
|
393
|
-
children:
|
|
578
|
+
children: granularity === "month" ? /* @__PURE__ */ jsx("div", {
|
|
579
|
+
"aria-label": String(month.getFullYear()),
|
|
580
|
+
className: styles.monthGrid,
|
|
581
|
+
"data-slot": "date-picker-month-grid",
|
|
582
|
+
role: "grid",
|
|
583
|
+
children: monthDates.map((date) => /* @__PURE__ */ jsx(DatePickerMonthButton, { date }, dateKey(date)))
|
|
584
|
+
}) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
|
|
394
585
|
"aria-hidden": "true",
|
|
395
586
|
className: styles.weekdays,
|
|
396
587
|
"data-slot": "date-picker-weekdays",
|
|
@@ -405,7 +596,7 @@ const DatePickerCalendar = forwardRef(function DatePickerCalendar({ "aria-label"
|
|
|
405
596
|
"data-slot": "date-picker-grid",
|
|
406
597
|
role: "grid",
|
|
407
598
|
children: days.map((date) => /* @__PURE__ */ jsx(DatePickerDay, { date }, dateKey(date)))
|
|
408
|
-
})]
|
|
599
|
+
})] })
|
|
409
600
|
});
|
|
410
601
|
});
|
|
411
602
|
const DatePicker = {
|
|
@@ -421,12 +612,15 @@ const DatePicker = {
|
|
|
421
612
|
Close: DatePickerClose,
|
|
422
613
|
Header: DatePickerHeader,
|
|
423
614
|
Caption: DatePickerCaption,
|
|
615
|
+
MonthSelect: DatePickerMonthSelect,
|
|
616
|
+
YearSelect: DatePickerYearSelect,
|
|
617
|
+
TimeField: DatePickerTimeField,
|
|
424
618
|
Previous: DatePickerPrevious,
|
|
425
619
|
Next: DatePickerNext,
|
|
426
620
|
Day: DatePickerDay,
|
|
427
621
|
Calendar: DatePickerCalendar
|
|
428
622
|
};
|
|
429
623
|
//#endregion
|
|
430
|
-
export { DatePicker, DatePickerCalendar, DatePickerCaption, DatePickerClear, DatePickerClose, DatePickerControl, DatePickerDay, DatePickerHeader, DatePickerLabel, DatePickerNext, DatePickerPopup, DatePickerPortal, DatePickerPositioner, DatePickerPrevious, DatePickerRoot, DatePickerTrigger, DatePickerValue };
|
|
624
|
+
export { DatePicker, DatePickerCalendar, DatePickerCaption, DatePickerClear, DatePickerClose, DatePickerControl, DatePickerDay, DatePickerHeader, DatePickerLabel, DatePickerMonthSelect, DatePickerNext, DatePickerPopup, DatePickerPortal, DatePickerPositioner, DatePickerPrevious, DatePickerRoot, DatePickerTimeField, DatePickerTrigger, DatePickerValue, DatePickerYearSelect };
|
|
431
625
|
|
|
432
626
|
//# sourceMappingURL=date-picker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-picker.js","names":["BasePopover"],"sources":["../../../src/components/date-picker/date-picker.tsx"],"sourcesContent":["\"use client\";\n\nimport { Popover as BasePopover } from \"@base-ui/react/popover\";\nimport {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { ComponentPropsWithoutRef, KeyboardEvent, MouseEvent, ReactNode, Ref } from \"react\";\nimport type { PopoverRoot as BasePopoverRoot } from \"@base-ui/react/popover\";\n\nimport { cx } from \"../../styled-system/css\";\nimport { datePicker } from \"../../styled-system/recipes\";\nimport { withRecipeClassName } from \"../base-ui\";\nimport {\n addDays,\n addMonths,\n createCalendarDate,\n dateKey,\n formatDateLabel,\n formatMonthLabel,\n getCalendarDays,\n getDateRangeLabel,\n getWeekdayLabels,\n isAfterDay,\n isBeforeDay,\n isSameDay,\n startOfMonth,\n toInputDate,\n} from \"./date-utils\";\n\nexport type DatePickerSize = \"sm\" | \"md\" | \"lg\";\n\ninterface DatePickerContextValue {\n canNavigate: (amount: number) => boolean;\n close: () => void;\n dateDisabled: (date: Date) => boolean;\n disabled: boolean;\n focusDate: (date: Date, direction?: number) => void;\n focusedDate: Date;\n formatDate: (date: Date | null) => string;\n labelId: string;\n locale: string;\n month: Date;\n onClear: () => void;\n onSelect: (date: Date) => void;\n placeholder: ReactNode;\n registerDay: (key: string, node: HTMLButtonElement | null) => void;\n selected: Date | null;\n setFocusedDate: (date: Date) => void;\n setMonth: (date: Date) => void;\n size: DatePickerSize;\n styles: ReturnType<typeof datePicker>;\n today: Date;\n triggerId: string;\n weekStartsOn: number;\n}\n\nconst DatePickerContext = createContext<DatePickerContextValue | null>(null);\n\nfunction useDatePickerContext() {\n const context = useContext(DatePickerContext);\n if (!context) {\n throw new Error(\"DatePicker parts must be rendered inside DatePicker.Root.\");\n }\n\n return context;\n}\n\nfunction isSameMonth(left: Date, right: Date) {\n return left.getFullYear() === right.getFullYear() && left.getMonth() === right.getMonth();\n}\n\nfunction composeRefs<T>(first: Ref<T> | undefined, second: (value: T | null) => void) {\n return (value: T | null) => {\n second(value);\n if (typeof first === \"function\") {\n first(value);\n } else if (first) {\n first.current = value;\n }\n };\n}\n\nexport interface DatePickerRootProps extends Omit<BasePopoverRoot.Props, \"children\"> {\n /** Selected value. Use together with `onValueChange` for a controlled picker. */\n value?: Date | null;\n /** Initial selected value for an uncontrolled picker. */\n defaultValue?: Date | null;\n /** Called after a valid day is selected, or when the value is cleared. */\n onValueChange?: (value: Date | null) => void;\n /** Prevents dates before this local calendar day from being selected. */\n minDate?: Date;\n /** Prevents dates after this local calendar day from being selected. */\n maxDate?: Date;\n /** Adds application-specific disabled dates, such as holidays or weekends. */\n isDateDisabled?: (date: Date) => boolean;\n /** Locale used for month, weekday and value formatting. */\n locale?: string;\n /** Called after the visible calendar month changes. */\n onMonthChange?: (month: Date) => void;\n /** First weekday in the calendar, where 0 is Sunday and 1 is Monday. */\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n /** Text shown when no date has been selected. */\n placeholder?: ReactNode;\n /** Shared visual size for the trigger and calendar days. */\n size?: DatePickerSize;\n /** Adds a native hidden input using the `YYYY-MM-DD` representation. */\n name?: string;\n /** Prevents interaction and disables the hidden form input. */\n disabled?: boolean;\n /** Closes the popup after a day is chosen. Defaults to true. */\n closeOnSelect?: boolean;\n children?: ReactNode;\n}\n\nexport function DatePickerRoot({\n children,\n closeOnSelect = true,\n defaultValue = null,\n disabled = false,\n isDateDisabled,\n locale = \"pt-BR\",\n maxDate,\n minDate,\n name,\n onValueChange,\n onMonthChange,\n placeholder = \"Select a date\",\n size = \"md\",\n value: controlledValue,\n weekStartsOn = 0,\n actionsRef: externalActionsRef,\n ...popoverProps\n}: DatePickerRootProps) {\n const [uncontrolledValue, setUncontrolledValue] = useState<Date | null>(defaultValue);\n const selected = controlledValue === undefined ? uncontrolledValue : controlledValue;\n const [month, setMonthState] = useState(() => startOfMonth(selected ?? new Date()));\n const [focusedDate, setFocusedDate] = useState(selected ?? month);\n const previousMonthRef = useRef(month);\n const internalActionsRef = useRef<BasePopoverRoot.Actions | null>(null);\n const dayRefs = useRef(new Map<string, HTMLButtonElement>());\n const labelId = useId();\n const triggerId = useId();\n const today = useMemo(() => new Date(), []);\n const styles = datePicker({ size });\n const minMonth = minDate ? startOfMonth(minDate) : undefined;\n const maxMonth = maxDate ? startOfMonth(maxDate) : undefined;\n\n const clampMonth = useCallback(\n (nextMonth: Date) => {\n const normalized = startOfMonth(nextMonth);\n if (minMonth && isBeforeDay(normalized, minMonth)) return minMonth;\n if (maxMonth && isAfterDay(normalized, maxMonth)) return maxMonth;\n return normalized;\n },\n [maxMonth, minMonth],\n );\n\n const setMonth = useCallback(\n (nextMonth: Date) => {\n const normalized = clampMonth(nextMonth);\n setMonthState((current) => {\n if (isSameMonth(current, normalized)) return current;\n return normalized;\n });\n },\n [clampMonth],\n );\n\n useEffect(() => {\n if (isSameMonth(previousMonthRef.current, month)) return;\n previousMonthRef.current = month;\n onMonthChange?.(month);\n }, [month, onMonthChange]);\n\n useEffect(() => {\n if (!selected) {\n return;\n }\n\n setFocusedDate(selected);\n setMonthState((current) => (isSameMonth(current, selected) ? current : clampMonth(selected)));\n }, [clampMonth, selected]);\n\n const dateDisabled = useCallback(\n (date: Date) =>\n Boolean(\n (minDate && isBeforeDay(date, minDate)) ||\n (maxDate && isAfterDay(date, maxDate)) ||\n isDateDisabled?.(date),\n ),\n [isDateDisabled, maxDate, minDate],\n );\n\n const close = useCallback(() => {\n (externalActionsRef ?? internalActionsRef).current?.close();\n }, [externalActionsRef]);\n\n const onSelect = useCallback(\n (date: Date) => {\n if (disabled || dateDisabled(date)) {\n return;\n }\n\n const nextValue = createCalendarDate(date.getFullYear(), date.getMonth(), date.getDate());\n setUncontrolledValue(nextValue);\n setFocusedDate(nextValue);\n setMonth(startOfMonth(nextValue));\n onValueChange?.(nextValue);\n if (closeOnSelect) {\n close();\n }\n },\n [close, closeOnSelect, dateDisabled, disabled, onValueChange, setMonth],\n );\n\n const onClear = useCallback(() => {\n setUncontrolledValue(null);\n onValueChange?.(null);\n }, [onValueChange]);\n\n const focusDate = useCallback(\n (date: Date, direction = 1) => {\n let nextDate = createCalendarDate(date.getFullYear(), date.getMonth(), date.getDate());\n const step = direction < 0 ? -1 : 1;\n let attempts = 0;\n while (dateDisabled(nextDate) && attempts < 366) {\n nextDate = addDays(nextDate, step);\n attempts += 1;\n }\n\n setFocusedDate(nextDate);\n setMonth(nextDate);\n\n const focusTarget = () => dayRefs.current.get(dateKey(nextDate))?.focus();\n focusTarget();\n queueMicrotask(focusTarget);\n },\n [dateDisabled, setMonth],\n );\n\n const canNavigate = useCallback(\n (amount: number) => {\n const nextMonth = addMonths(month, amount);\n return !(\n (minMonth && isBeforeDay(nextMonth, minMonth)) ||\n (maxMonth && isAfterDay(nextMonth, maxMonth))\n );\n },\n [maxMonth, minMonth, month],\n );\n\n const registerDay = useCallback((key: string, node: HTMLButtonElement | null) => {\n if (node) {\n dayRefs.current.set(key, node);\n } else {\n dayRefs.current.delete(key);\n }\n }, []);\n\n const context: DatePickerContextValue = {\n canNavigate,\n close,\n dateDisabled,\n disabled,\n focusDate,\n focusedDate,\n formatDate: (date) => formatDateLabel(date, locale, String(placeholder)),\n labelId,\n locale,\n month,\n onClear,\n onSelect,\n placeholder,\n registerDay,\n selected,\n setFocusedDate,\n setMonth,\n size,\n styles,\n today: createCalendarDate(today.getFullYear(), today.getMonth(), today.getDate()),\n triggerId,\n weekStartsOn,\n };\n\n return (\n <DatePickerContext.Provider value={context}>\n <BasePopover.Root {...popoverProps} actionsRef={externalActionsRef ?? internalActionsRef}>\n {children}\n </BasePopover.Root>\n {name ? (\n <input disabled={disabled} name={name} type=\"hidden\" value={toInputDate(selected)} />\n ) : null}\n </DatePickerContext.Provider>\n );\n}\n\nexport type DatePickerLabelProps = ComponentPropsWithoutRef<\"label\">;\n\nexport const DatePickerLabel = forwardRef<HTMLLabelElement, DatePickerLabelProps>(\n function DatePickerLabel({ children, className, ...props }, ref) {\n const { labelId, styles, triggerId } = useDatePickerContext();\n\n return (\n <label\n {...props}\n ref={ref}\n className={cx(styles.label, className)}\n data-slot=\"date-picker-label\"\n htmlFor={props.htmlFor ?? triggerId}\n id={props.id ?? labelId}\n >\n {children}\n </label>\n );\n },\n);\n\nexport type DatePickerControlProps = ComponentPropsWithoutRef<\"div\">;\n\nexport const DatePickerControl = forwardRef<HTMLDivElement, DatePickerControlProps>(\n function DatePickerControl({ className, ...props }, ref) {\n const { styles } = useDatePickerContext();\n\n return (\n <div\n {...props}\n ref={ref}\n className={cx(styles.control, className)}\n data-jaci-component=\"date-picker\"\n data-slot=\"date-picker-control\"\n />\n );\n },\n);\n\nexport type DatePickerTriggerProps = ComponentPropsWithoutRef<typeof BasePopover.Trigger>;\n\nexport const DatePickerTrigger = forwardRef<HTMLButtonElement, DatePickerTriggerProps>(\n function DatePickerTrigger({ children, className, disabled, id, ...props }, ref) {\n const { disabled: pickerDisabled, styles, triggerId } = useDatePickerContext();\n\n return (\n <BasePopover.Trigger\n {...props}\n aria-label={props[\"aria-label\"] ?? \"Choose date\"}\n disabled={disabled ?? pickerDisabled}\n id={id ?? triggerId}\n ref={ref}\n className={withRecipeClassName(styles.trigger, className)}\n data-jaci-component=\"date-picker\"\n data-slot=\"date-picker-trigger\"\n >\n {children ?? (\n <>\n <DatePickerValue />\n <span aria-hidden=\"true\">▾</span>\n </>\n )}\n </BasePopover.Trigger>\n );\n },\n);\n\nexport interface DatePickerValueProps extends ComponentPropsWithoutRef<\"span\"> {\n placeholder?: ReactNode;\n}\n\nexport const DatePickerValue = forwardRef<HTMLSpanElement, DatePickerValueProps>(\n function DatePickerValue({ children, className, placeholder, ...props }, ref) {\n const { formatDate, selected, styles } = useDatePickerContext();\n const value = children ?? (selected ? formatDate(selected) : (placeholder ?? \"Select a date\"));\n\n return (\n <span\n {...props}\n ref={ref}\n className={cx(styles.value, className)}\n data-placeholder={selected ? undefined : \"true\"}\n data-slot=\"date-picker-value\"\n >\n {value}\n </span>\n );\n },\n);\n\nexport type DatePickerClearProps = ComponentPropsWithoutRef<\"button\">;\n\nexport const DatePickerClear = forwardRef<HTMLButtonElement, DatePickerClearProps>(\n function DatePickerClear({ children = \"×\", className, disabled, onClick, ...props }, ref) {\n const { close, disabled: pickerDisabled, onClear, selected, styles } = useDatePickerContext();\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n onClear();\n onClick?.(event);\n close();\n };\n\n return (\n <button\n {...props}\n aria-label={props[\"aria-label\"] ?? \"Clear date\"}\n className={cx(styles.clear, className)}\n data-slot=\"date-picker-clear\"\n disabled={disabled || pickerDisabled || !selected}\n onClick={handleClick}\n ref={ref}\n type=\"button\"\n >\n {children}\n </button>\n );\n },\n);\n\nexport type DatePickerPortalProps = ComponentPropsWithoutRef<typeof BasePopover.Portal>;\nexport const DatePickerPortal: typeof BasePopover.Portal = BasePopover.Portal;\n\nexport type DatePickerPositionerProps = ComponentPropsWithoutRef<typeof BasePopover.Positioner>;\n\nexport const DatePickerPositioner = forwardRef<HTMLDivElement, DatePickerPositionerProps>(\n function DatePickerPositioner({ className, ...props }, ref) {\n const { styles } = useDatePickerContext();\n\n return (\n <BasePopover.Positioner\n {...props}\n ref={ref}\n className={withRecipeClassName(styles.positioner, className)}\n data-slot=\"date-picker-positioner\"\n />\n );\n },\n);\n\nexport type DatePickerPopupProps = ComponentPropsWithoutRef<typeof BasePopover.Popup>;\n\nexport const DatePickerPopup = forwardRef<HTMLDivElement, DatePickerPopupProps>(\n function DatePickerPopup({ className, ...props }, ref) {\n const { styles } = useDatePickerContext();\n\n return (\n <BasePopover.Popup\n {...props}\n ref={ref}\n aria-label={props[\"aria-label\"] ?? \"Calendar\"}\n className={withRecipeClassName(styles.popup, className)}\n data-slot=\"date-picker-popup\"\n />\n );\n },\n);\n\nexport type DatePickerCloseProps = ComponentPropsWithoutRef<typeof BasePopover.Close>;\n\nexport const DatePickerClose = forwardRef<HTMLButtonElement, DatePickerCloseProps>(\n function DatePickerClose({ className, ...props }, ref) {\n const { styles } = useDatePickerContext();\n\n return (\n <BasePopover.Close\n {...props}\n ref={ref}\n className={withRecipeClassName(styles.clear, className)}\n data-slot=\"date-picker-close\"\n />\n );\n },\n);\n\nexport type DatePickerHeaderProps = ComponentPropsWithoutRef<\"div\">;\n\nexport const DatePickerHeader = forwardRef<HTMLDivElement, DatePickerHeaderProps>(\n function DatePickerHeader({ className, ...props }, ref) {\n const { styles } = useDatePickerContext();\n\n return (\n <div\n {...props}\n ref={ref}\n className={cx(styles.header, className)}\n data-slot=\"date-picker-header\"\n />\n );\n },\n);\n\nexport type DatePickerCaptionProps = ComponentPropsWithoutRef<\"span\">;\n\nexport const DatePickerCaption = forwardRef<HTMLSpanElement, DatePickerCaptionProps>(\n function DatePickerCaption({ children, className, ...props }, ref) {\n const { locale, month, styles } = useDatePickerContext();\n\n return (\n <span\n {...props}\n ref={ref}\n className={cx(styles.caption, className)}\n data-slot=\"date-picker-caption\"\n >\n {children ?? formatMonthLabel(month, locale)}\n </span>\n );\n },\n);\n\nexport interface DatePickerNavigationProps extends ComponentPropsWithoutRef<\"button\"> {\n amount?: number;\n}\n\nconst DatePickerNavigationButton = forwardRef<HTMLButtonElement, DatePickerNavigationProps>(\n function DatePickerNavigationButton({ amount, children, className, onClick, ...props }, ref) {\n const { canNavigate, month, setMonth, styles } = useDatePickerContext();\n const direction = amount ?? 1;\n const isDisabled = props.disabled || !canNavigate(direction);\n\n return (\n <button\n {...props}\n aria-label={props[\"aria-label\"] ?? (direction < 0 ? \"Previous month\" : \"Next month\")}\n className={cx(styles.navigation, className)}\n data-slot={direction < 0 ? \"date-picker-previous\" : \"date-picker-next\"}\n disabled={isDisabled}\n onClick={(event) => {\n if (!isDisabled) setMonth(addMonths(month, direction));\n onClick?.(event);\n }}\n ref={ref}\n type=\"button\"\n >\n {children ?? (direction < 0 ? \"‹\" : \"›\")}\n </button>\n );\n },\n);\n\nexport const DatePickerPrevious = forwardRef<HTMLButtonElement, DatePickerNavigationProps>(\n function DatePickerPrevious(props, ref) {\n return <DatePickerNavigationButton {...props} amount={-1} ref={ref} />;\n },\n);\n\nexport const DatePickerNext = forwardRef<HTMLButtonElement, DatePickerNavigationProps>(\n function DatePickerNext(props, ref) {\n return <DatePickerNavigationButton {...props} amount={1} ref={ref} />;\n },\n);\n\nexport interface DatePickerDayProps extends Omit<ComponentPropsWithoutRef<\"button\">, \"value\"> {\n date: Date;\n}\n\nexport const DatePickerDay = forwardRef<HTMLButtonElement, DatePickerDayProps>(\n function DatePickerDay(\n { children, className, date, disabled, onClick, onKeyDown, ...props },\n ref,\n ) {\n const {\n dateDisabled,\n disabled: pickerDisabled,\n focusDate,\n focusedDate,\n locale,\n month,\n onSelect,\n registerDay,\n selected,\n styles,\n today,\n } = useDatePickerContext();\n const key = dateKey(date);\n const outsideMonth = !isSameMonth(date, month);\n const isDisabled = disabled || pickerDisabled || dateDisabled(date);\n const isFocused = isSameDay(date, focusedDate);\n const isSelected = isSameDay(date, selected);\n const isToday = isSameDay(date, today);\n const dayRef = composeRefs(ref, (node) => registerDay(key, node));\n\n const moveByKey = (event: KeyboardEvent<HTMLButtonElement>) => {\n if (event.defaultPrevented) {\n return;\n }\n\n let nextDate: Date | undefined;\n switch (event.key) {\n case \"ArrowLeft\":\n nextDate = addDays(date, -1);\n break;\n case \"ArrowRight\":\n nextDate = addDays(date, 1);\n break;\n case \"ArrowUp\":\n nextDate = addDays(date, -7);\n break;\n case \"ArrowDown\":\n nextDate = addDays(date, 7);\n break;\n case \"Home\":\n nextDate = addDays(date, -date.getDay());\n break;\n case \"End\":\n nextDate = addDays(date, 6 - date.getDay());\n break;\n case \"PageUp\":\n nextDate = addMonths(date, event.shiftKey ? -12 : -1);\n break;\n case \"PageDown\":\n nextDate = addMonths(date, event.shiftKey ? 12 : 1);\n break;\n case \"Enter\":\n case \" \":\n if (!isDisabled) {\n event.preventDefault();\n onSelect(date);\n }\n break;\n default:\n break;\n }\n\n if (nextDate) {\n event.preventDefault();\n focusDate(nextDate, nextDate < date ? -1 : 1);\n }\n };\n\n return (\n // biome-ignore lint/a11y/useSemanticElements: A calendar day is an interactive gridcell, not a generic table cell.\n <button\n {...props}\n ref={dayRef}\n aria-label={props[\"aria-label\"] ?? getDateRangeLabel(date, locale)}\n aria-current={isToday ? \"date\" : undefined}\n aria-selected={isSelected}\n className={cx(styles.day, className)}\n data-date={key}\n data-disabled={isDisabled || undefined}\n data-outside-month={outsideMonth || undefined}\n data-selected={isSelected || undefined}\n data-slot=\"date-picker-day\"\n data-today={isToday || undefined}\n disabled={isDisabled}\n onClick={(event) => {\n onSelect(date);\n onClick?.(event);\n }}\n onKeyDown={(event) => {\n moveByKey(event);\n onKeyDown?.(event);\n }}\n role=\"gridcell\"\n tabIndex={isFocused && !isDisabled ? 0 : -1}\n type=\"button\"\n >\n {children ?? date.getDate()}\n </button>\n );\n },\n);\n\nexport interface DatePickerCalendarProps\n extends Omit<ComponentPropsWithoutRef<\"section\">, \"children\"> {\n \"aria-label\"?: string;\n}\n\nexport const DatePickerCalendar = forwardRef<HTMLElement, DatePickerCalendarProps>(\n function DatePickerCalendar({ \"aria-label\": ariaLabel, className, ...props }, ref) {\n const { locale, month, styles, weekStartsOn } = useDatePickerContext();\n const days = useMemo(() => getCalendarDays(month, weekStartsOn), [month, weekStartsOn]);\n const weekdays = useMemo(() => getWeekdayLabels(locale, weekStartsOn), [locale, weekStartsOn]);\n\n return (\n <section\n {...props}\n ref={ref}\n aria-label={ariaLabel ?? formatMonthLabel(month, locale)}\n className={cx(styles.calendar, className)}\n data-slot=\"date-picker-calendar\"\n >\n <div aria-hidden=\"true\" className={styles.weekdays} data-slot=\"date-picker-weekdays\">\n {weekdays.map((weekday) => (\n <span className={styles.weekday} data-slot=\"date-picker-weekday\" key={weekday}>\n {weekday}\n </span>\n ))}\n </div>\n {/* biome-ignore lint/a11y/useSemanticElements: Calendar grids use the WAI-ARIA grid pattern for roving day focus. */}\n <div\n aria-label={formatMonthLabel(month, locale)}\n className={styles.grid}\n data-slot=\"date-picker-grid\"\n role=\"grid\"\n >\n {days.map((date) => (\n <DatePickerDay date={date} key={dateKey(date)} />\n ))}\n </div>\n </section>\n );\n },\n);\n\nexport const DatePicker = {\n Root: DatePickerRoot,\n Label: DatePickerLabel,\n Control: DatePickerControl,\n Trigger: DatePickerTrigger,\n Value: DatePickerValue,\n Clear: DatePickerClear,\n Portal: DatePickerPortal,\n Positioner: DatePickerPositioner,\n Popup: DatePickerPopup,\n Close: DatePickerClose,\n Header: DatePickerHeader,\n Caption: DatePickerCaption,\n Previous: DatePickerPrevious,\n Next: DatePickerNext,\n Day: DatePickerDay,\n Calendar: DatePickerCalendar,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"date-picker.js","names":["BasePopover"],"sources":["../../../src/components/date-picker/date-picker.tsx"],"sourcesContent":["\"use client\";\n\nimport { Popover as BasePopover } from \"@base-ui/react/popover\";\nimport {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { ComponentPropsWithoutRef, KeyboardEvent, MouseEvent, ReactNode, Ref } from \"react\";\nimport type { PopoverRoot as BasePopoverRoot } from \"@base-ui/react/popover\";\n\nimport { cx } from \"../../styled-system/css\";\nimport { datePicker } from \"../../styled-system/recipes\";\nimport { withRecipeClassName } from \"../base-ui\";\nimport {\n addDays,\n addMonths,\n createCalendarDate,\n dateKey,\n formatDateLabel,\n formatMonthLabel,\n getCalendarDays,\n getDateRangeLabel,\n getMonthLabels,\n getWeekdayLabels,\n isAfterDay,\n isBeforeDay,\n isSameDay,\n startOfMonth,\n toInputDate,\n toInputDateTime,\n toInputMonth,\n toTimeInput,\n} from \"./date-utils\";\nimport type { DatePickerGranularity } from \"./date-utils\";\n\nexport type DatePickerSize = \"sm\" | \"md\" | \"lg\";\nexport type { DatePickerGranularity } from \"./date-utils\";\n\nexport interface DatePickerYearRange {\n start: number;\n end: number;\n}\n\ninterface DatePickerContextValue {\n canNavigate: (amount: number) => boolean;\n close: () => void;\n dateDisabled: (date: Date) => boolean;\n granularity: DatePickerGranularity;\n disabled: boolean;\n focusDate: (date: Date, direction?: number) => void;\n focusedDate: Date;\n formatDate: (date: Date | null) => string;\n labelId: string;\n locale: string;\n month: Date;\n monthDisabled: (date: Date) => boolean;\n onClear: () => void;\n onTimeChange: (value: string) => void;\n onSelect: (date: Date) => void;\n selectMonth: (month: number) => void;\n selectYear: (year: number) => void;\n placeholder: ReactNode;\n registerDay: (key: string, node: HTMLButtonElement | null) => void;\n selected: Date | null;\n setFocusedDate: (date: Date) => void;\n setMonth: (date: Date) => void;\n size: DatePickerSize;\n styles: ReturnType<typeof datePicker>;\n today: Date;\n timeMax: string | undefined;\n timeMin: string | undefined;\n triggerId: string;\n weekStartsOn: number;\n yearRange: DatePickerYearRange;\n}\n\nconst DatePickerContext = createContext<DatePickerContextValue | null>(null);\n\nfunction useDatePickerContext() {\n const context = useContext(DatePickerContext);\n if (!context) {\n throw new Error(\"DatePicker parts must be rendered inside DatePicker.Root.\");\n }\n\n return context;\n}\n\nfunction isSameMonth(left: Date, right: Date) {\n return left.getFullYear() === right.getFullYear() && left.getMonth() === right.getMonth();\n}\n\nfunction composeRefs<T>(first: Ref<T> | undefined, second: (value: T | null) => void) {\n return (value: T | null) => {\n second(value);\n if (typeof first === \"function\") {\n first(value);\n } else if (first) {\n first.current = value;\n }\n };\n}\n\nexport interface DatePickerRootProps extends Omit<BasePopoverRoot.Props, \"children\"> {\n /** Selected value. Use together with `onValueChange` for a controlled picker. */\n value?: Date | null;\n /** Initial selected value for an uncontrolled picker. */\n defaultValue?: Date | null;\n /** Called after a valid day, month, or time is selected, or when the value is cleared. */\n onValueChange?: (value: Date | null) => void;\n /** Prevents dates before this local calendar day from being selected. */\n minDate?: Date;\n /** Prevents dates after this local calendar day from being selected. */\n maxDate?: Date;\n /** Adds application-specific disabled dates, such as holidays or weekends. */\n isDateDisabled?: (date: Date) => boolean;\n /** Locale used for month, weekday and value formatting. */\n locale?: string;\n /** Called after the visible calendar month changes. */\n onMonthChange?: (month: Date) => void;\n /** First weekday in the calendar, where 0 is Sunday and 1 is Monday. */\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n /** Text shown when no date has been selected. */\n placeholder?: ReactNode;\n /** Shared visual size for the trigger and calendar days. */\n size?: DatePickerSize;\n /** Controls whether the picker selects days, months, or date and time. */\n granularity?: DatePickerGranularity;\n /** Inclusive range used by the year selector. */\n yearRange?: DatePickerYearRange;\n /** Adds a native hidden input using the representation for the selected granularity. */\n name?: string;\n /** Prevents interaction and disables the hidden form input. */\n disabled?: boolean;\n /** Closes the popup after a value is chosen. Defaults to false for date-time mode and true otherwise. */\n closeOnSelect?: boolean;\n children?: ReactNode;\n}\n\nexport function DatePickerRoot({\n children,\n closeOnSelect: closeOnSelectProp,\n defaultValue = null,\n disabled = false,\n granularity = \"day\",\n isDateDisabled,\n locale = \"pt-BR\",\n maxDate,\n minDate,\n name,\n onValueChange,\n onMonthChange,\n placeholder = \"Select a date\",\n size = \"md\",\n value: controlledValue,\n weekStartsOn = 0,\n yearRange: configuredYearRange,\n actionsRef: externalActionsRef,\n ...popoverProps\n}: DatePickerRootProps) {\n const [uncontrolledValue, setUncontrolledValue] = useState<Date | null>(defaultValue);\n const selected = controlledValue === undefined ? uncontrolledValue : controlledValue;\n const [month, setMonthState] = useState(() => startOfMonth(selected ?? new Date()));\n const [focusedDate, setFocusedDate] = useState(selected ?? month);\n const previousMonthRef = useRef(month);\n const internalActionsRef = useRef<BasePopoverRoot.Actions | null>(null);\n const dayRefs = useRef(new Map<string, HTMLButtonElement>());\n const labelId = useId();\n const triggerId = useId();\n const today = useMemo(() => new Date(), []);\n const styles = datePicker({ size });\n const minMonth = minDate ? startOfMonth(minDate) : undefined;\n const maxMonth = maxDate ? startOfMonth(maxDate) : undefined;\n const closeOnSelect = closeOnSelectProp ?? granularity !== \"date-time\";\n const yearRange = useMemo(() => {\n const defaultStart = today.getFullYear() - 100;\n const defaultEnd = today.getFullYear() + 20;\n const start = configuredYearRange?.start ?? defaultStart;\n const end = configuredYearRange?.end ?? defaultEnd;\n const years = [selected?.getFullYear(), minDate?.getFullYear(), maxDate?.getFullYear()].filter(\n (year): year is number => year !== undefined,\n );\n return {\n end: Math.max(start, end, ...years),\n start: Math.min(start, end, ...years),\n };\n }, [configuredYearRange?.end, configuredYearRange?.start, maxDate, minDate, selected, today]);\n\n const clampMonth = useCallback(\n (nextMonth: Date) => {\n const normalized = startOfMonth(nextMonth);\n if (minMonth && isBeforeDay(normalized, minMonth)) return minMonth;\n if (maxMonth && isAfterDay(normalized, maxMonth)) return maxMonth;\n return normalized;\n },\n [maxMonth, minMonth],\n );\n\n const setMonth = useCallback(\n (nextMonth: Date) => {\n const normalized = clampMonth(nextMonth);\n setMonthState((current) => {\n if (isSameMonth(current, normalized)) return current;\n return normalized;\n });\n },\n [clampMonth],\n );\n\n useEffect(() => {\n if (isSameMonth(previousMonthRef.current, month)) return;\n previousMonthRef.current = month;\n onMonthChange?.(month);\n }, [month, onMonthChange]);\n\n useEffect(() => {\n if (!selected) {\n return;\n }\n\n setFocusedDate(selected);\n setMonthState((current) => (isSameMonth(current, selected) ? current : clampMonth(selected)));\n }, [clampMonth, selected]);\n\n const dateDisabled = useCallback(\n (date: Date) =>\n Boolean(\n (minDate && isBeforeDay(date, minDate)) ||\n (maxDate && isAfterDay(date, maxDate)) ||\n isDateDisabled?.(date),\n ),\n [isDateDisabled, maxDate, minDate],\n );\n\n const close = useCallback(() => {\n (externalActionsRef ?? internalActionsRef).current?.close();\n }, [externalActionsRef]);\n\n const setValue = useCallback(\n (nextValue: Date | null) => {\n setUncontrolledValue(nextValue);\n onValueChange?.(nextValue);\n },\n [onValueChange],\n );\n\n const monthDisabled = useCallback(\n (candidate: Date) => {\n const firstDay = startOfMonth(candidate);\n const lastDay = createCalendarDate(candidate.getFullYear(), candidate.getMonth() + 1, 0);\n return Boolean(\n (minDate && isBeforeDay(lastDay, minDate)) || (maxDate && isAfterDay(firstDay, maxDate)),\n );\n },\n [maxDate, minDate],\n );\n\n const onSelect = useCallback(\n (date: Date) => {\n if (disabled || (granularity === \"month\" ? monthDisabled(date) : dateDisabled(date))) {\n return;\n }\n\n const nextValue = createCalendarDate(\n date.getFullYear(),\n date.getMonth(),\n granularity === \"month\" ? 1 : date.getDate(),\n );\n if (granularity === \"date-time\") {\n nextValue.setHours(selected?.getHours() ?? 12, selected?.getMinutes() ?? 0, 0, 0);\n if (minDate && isSameDay(nextValue, minDate) && nextValue < minDate) {\n nextValue.setHours(minDate.getHours(), minDate.getMinutes(), 0, 0);\n }\n if (maxDate && isSameDay(nextValue, maxDate) && nextValue > maxDate) {\n nextValue.setHours(maxDate.getHours(), maxDate.getMinutes(), 0, 0);\n }\n }\n setValue(nextValue);\n setFocusedDate(nextValue);\n setMonth(startOfMonth(nextValue));\n if (closeOnSelect) {\n close();\n }\n },\n [\n close,\n closeOnSelect,\n dateDisabled,\n disabled,\n granularity,\n maxDate,\n monthDisabled,\n minDate,\n selected,\n setMonth,\n setValue,\n ],\n );\n\n const onClear = useCallback(() => {\n setValue(null);\n }, [setValue]);\n\n const selectMonth = useCallback(\n (monthIndex: number) => {\n const nextMonth = clampMonth(createCalendarDate(month.getFullYear(), monthIndex, 1));\n if (monthDisabled(nextMonth)) return;\n setMonth(nextMonth);\n if (granularity === \"month\") {\n const nextValue = createCalendarDate(nextMonth.getFullYear(), nextMonth.getMonth(), 1);\n setFocusedDate(nextValue);\n setValue(nextValue);\n if (closeOnSelect) close();\n }\n },\n [clampMonth, close, closeOnSelect, granularity, month, monthDisabled, setMonth, setValue],\n );\n\n const selectYear = useCallback(\n (year: number) => {\n const nextMonth = clampMonth(createCalendarDate(year, month.getMonth(), 1));\n if (monthDisabled(nextMonth)) return;\n setMonth(nextMonth);\n if (granularity === \"month\") {\n const nextValue = createCalendarDate(nextMonth.getFullYear(), nextMonth.getMonth(), 1);\n setFocusedDate(nextValue);\n setValue(nextValue);\n if (closeOnSelect) close();\n }\n },\n [clampMonth, close, closeOnSelect, granularity, month, monthDisabled, setMonth, setValue],\n );\n\n const onTimeChange = useCallback(\n (value: string) => {\n const match = value.match(/^(\\d{2}):(\\d{2})$/);\n if (!match) return;\n const hours = Number(match[1]);\n const minutes = Number(match[2]);\n if (hours > 23 || minutes > 59) return;\n const baseDate = selected ?? focusedDate;\n const nextValue = createCalendarDate(\n baseDate.getFullYear(),\n baseDate.getMonth(),\n baseDate.getDate(),\n );\n nextValue.setHours(hours, minutes, 0, 0);\n if (minDate && isSameDay(nextValue, minDate) && nextValue < minDate) return;\n if (maxDate && isSameDay(nextValue, maxDate) && nextValue > maxDate) return;\n setValue(nextValue);\n },\n [focusedDate, maxDate, minDate, selected, setValue],\n );\n\n const focusDate = useCallback(\n (date: Date, direction = 1) => {\n let nextDate = createCalendarDate(date.getFullYear(), date.getMonth(), date.getDate());\n const step = direction < 0 ? -1 : 1;\n let attempts = 0;\n while (dateDisabled(nextDate) && attempts < 366) {\n nextDate = addDays(nextDate, step);\n attempts += 1;\n }\n\n setFocusedDate(nextDate);\n setMonth(nextDate);\n\n const focusTarget = () => dayRefs.current.get(dateKey(nextDate))?.focus();\n focusTarget();\n queueMicrotask(focusTarget);\n },\n [dateDisabled, setMonth],\n );\n\n const canNavigate = useCallback(\n (amount: number) => {\n const nextMonth = addMonths(month, amount);\n return !(\n (minMonth && isBeforeDay(nextMonth, minMonth)) ||\n (maxMonth && isAfterDay(nextMonth, maxMonth))\n );\n },\n [maxMonth, minMonth, month],\n );\n\n const registerDay = useCallback((key: string, node: HTMLButtonElement | null) => {\n if (node) {\n dayRefs.current.set(key, node);\n } else {\n dayRefs.current.delete(key);\n }\n }, []);\n\n const timeMin =\n selected && minDate && isSameDay(selected, minDate) ? toTimeInput(minDate) : undefined;\n const timeMax =\n selected && maxDate && isSameDay(selected, maxDate) ? toTimeInput(maxDate) : undefined;\n\n const context: DatePickerContextValue = {\n canNavigate,\n close,\n dateDisabled,\n granularity,\n disabled,\n focusDate,\n focusedDate,\n formatDate: (date) => formatDateLabel(date, locale, String(placeholder), granularity),\n labelId,\n locale,\n month,\n monthDisabled,\n onClear,\n onTimeChange,\n onSelect,\n selectMonth,\n selectYear,\n placeholder,\n registerDay,\n selected,\n setFocusedDate,\n setMonth,\n size,\n styles,\n today: createCalendarDate(today.getFullYear(), today.getMonth(), today.getDate()),\n timeMax,\n timeMin,\n triggerId,\n weekStartsOn,\n yearRange,\n };\n\n return (\n <DatePickerContext.Provider value={context}>\n <BasePopover.Root {...popoverProps} actionsRef={externalActionsRef ?? internalActionsRef}>\n {children}\n </BasePopover.Root>\n {name ? (\n <input\n disabled={disabled}\n name={name}\n type=\"hidden\"\n value={\n granularity === \"month\"\n ? toInputMonth(selected)\n : granularity === \"date-time\"\n ? toInputDateTime(selected)\n : toInputDate(selected)\n }\n />\n ) : null}\n </DatePickerContext.Provider>\n );\n}\n\nexport type DatePickerLabelProps = ComponentPropsWithoutRef<\"label\">;\n\nexport const DatePickerLabel = forwardRef<HTMLLabelElement, DatePickerLabelProps>(\n function DatePickerLabel({ children, className, ...props }, ref) {\n const { labelId, styles, triggerId } = useDatePickerContext();\n\n return (\n <label\n {...props}\n ref={ref}\n className={cx(styles.label, className)}\n data-slot=\"date-picker-label\"\n htmlFor={props.htmlFor ?? triggerId}\n id={props.id ?? labelId}\n >\n {children}\n </label>\n );\n },\n);\n\nexport type DatePickerControlProps = ComponentPropsWithoutRef<\"div\">;\n\nexport const DatePickerControl = forwardRef<HTMLDivElement, DatePickerControlProps>(\n function DatePickerControl({ className, ...props }, ref) {\n const { styles } = useDatePickerContext();\n\n return (\n <div\n {...props}\n ref={ref}\n className={cx(styles.control, className)}\n data-jaci-component=\"date-picker\"\n data-slot=\"date-picker-control\"\n />\n );\n },\n);\n\nexport type DatePickerTriggerProps = ComponentPropsWithoutRef<typeof BasePopover.Trigger>;\n\nexport const DatePickerTrigger = forwardRef<HTMLButtonElement, DatePickerTriggerProps>(\n function DatePickerTrigger({ children, className, disabled, id, ...props }, ref) {\n const { disabled: pickerDisabled, styles, triggerId } = useDatePickerContext();\n\n return (\n <BasePopover.Trigger\n {...props}\n aria-label={props[\"aria-label\"] ?? \"Choose date\"}\n disabled={disabled ?? pickerDisabled}\n id={id ?? triggerId}\n ref={ref}\n className={withRecipeClassName(styles.trigger, className)}\n data-jaci-component=\"date-picker\"\n data-slot=\"date-picker-trigger\"\n >\n {children ?? (\n <>\n <DatePickerValue />\n <span aria-hidden=\"true\">▾</span>\n </>\n )}\n </BasePopover.Trigger>\n );\n },\n);\n\nexport interface DatePickerValueProps extends ComponentPropsWithoutRef<\"span\"> {\n placeholder?: ReactNode;\n}\n\nexport const DatePickerValue = forwardRef<HTMLSpanElement, DatePickerValueProps>(\n function DatePickerValue({ children, className, placeholder, ...props }, ref) {\n const { formatDate, selected, styles } = useDatePickerContext();\n const value = children ?? (selected ? formatDate(selected) : (placeholder ?? \"Select a date\"));\n\n return (\n <span\n {...props}\n ref={ref}\n className={cx(styles.value, className)}\n data-placeholder={selected ? undefined : \"true\"}\n data-slot=\"date-picker-value\"\n >\n {value}\n </span>\n );\n },\n);\n\nexport type DatePickerClearProps = ComponentPropsWithoutRef<\"button\">;\n\nexport const DatePickerClear = forwardRef<HTMLButtonElement, DatePickerClearProps>(\n function DatePickerClear({ children = \"×\", className, disabled, onClick, ...props }, ref) {\n const { close, disabled: pickerDisabled, onClear, selected, styles } = useDatePickerContext();\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n onClear();\n onClick?.(event);\n close();\n };\n\n return (\n <button\n {...props}\n aria-label={props[\"aria-label\"] ?? \"Clear date\"}\n className={cx(styles.clear, className)}\n data-slot=\"date-picker-clear\"\n disabled={disabled || pickerDisabled || !selected}\n onClick={handleClick}\n ref={ref}\n type=\"button\"\n >\n {children}\n </button>\n );\n },\n);\n\nexport type DatePickerPortalProps = ComponentPropsWithoutRef<typeof BasePopover.Portal>;\nexport const DatePickerPortal: typeof BasePopover.Portal = BasePopover.Portal;\n\nexport type DatePickerPositionerProps = ComponentPropsWithoutRef<typeof BasePopover.Positioner>;\n\nexport const DatePickerPositioner = forwardRef<HTMLDivElement, DatePickerPositionerProps>(\n function DatePickerPositioner({ className, ...props }, ref) {\n const { styles } = useDatePickerContext();\n\n return (\n <BasePopover.Positioner\n {...props}\n ref={ref}\n className={withRecipeClassName(styles.positioner, className)}\n data-slot=\"date-picker-positioner\"\n />\n );\n },\n);\n\nexport type DatePickerPopupProps = ComponentPropsWithoutRef<typeof BasePopover.Popup>;\n\nexport const DatePickerPopup = forwardRef<HTMLDivElement, DatePickerPopupProps>(\n function DatePickerPopup({ className, ...props }, ref) {\n const { styles } = useDatePickerContext();\n\n return (\n <BasePopover.Popup\n {...props}\n ref={ref}\n aria-label={props[\"aria-label\"] ?? \"Calendar\"}\n className={withRecipeClassName(styles.popup, className)}\n data-slot=\"date-picker-popup\"\n />\n );\n },\n);\n\nexport type DatePickerCloseProps = ComponentPropsWithoutRef<typeof BasePopover.Close>;\n\nexport const DatePickerClose = forwardRef<HTMLButtonElement, DatePickerCloseProps>(\n function DatePickerClose({ className, ...props }, ref) {\n const { styles } = useDatePickerContext();\n\n return (\n <BasePopover.Close\n {...props}\n ref={ref}\n className={withRecipeClassName(styles.close, className)}\n data-slot=\"date-picker-close\"\n />\n );\n },\n);\n\nexport type DatePickerHeaderProps = ComponentPropsWithoutRef<\"div\">;\n\nexport const DatePickerHeader = forwardRef<HTMLDivElement, DatePickerHeaderProps>(\n function DatePickerHeader({ className, ...props }, ref) {\n const { styles } = useDatePickerContext();\n\n return (\n <div\n {...props}\n ref={ref}\n className={cx(styles.header, className)}\n data-slot=\"date-picker-header\"\n />\n );\n },\n);\n\nexport type DatePickerCaptionProps = ComponentPropsWithoutRef<\"span\">;\n\nexport const DatePickerCaption = forwardRef<HTMLSpanElement, DatePickerCaptionProps>(\n function DatePickerCaption({ children, className, ...props }, ref) {\n const { locale, month, styles } = useDatePickerContext();\n\n return (\n <span\n {...props}\n ref={ref}\n className={cx(styles.caption, className)}\n data-slot=\"date-picker-caption\"\n >\n {children ?? formatMonthLabel(month, locale)}\n </span>\n );\n },\n);\n\nexport type DatePickerMonthSelectProps = Omit<\n ComponentPropsWithoutRef<\"select\">,\n \"children\" | \"onChange\" | \"value\"\n>;\n\nexport const DatePickerMonthSelect = forwardRef<HTMLSelectElement, DatePickerMonthSelectProps>(\n function DatePickerMonthSelect({ className, ...props }, ref) {\n const { locale, month, monthDisabled, selectMonth, styles } = useDatePickerContext();\n const labels = getMonthLabels(locale);\n\n return (\n <select\n {...props}\n aria-label={props[\"aria-label\"] ?? \"Select month\"}\n className={cx(styles.monthSelect, className)}\n data-slot=\"date-picker-month-select\"\n onChange={(event) => selectMonth(Number(event.currentTarget.value))}\n ref={ref}\n value={month.getMonth()}\n >\n {labels.map((label, monthIndex) => (\n <option\n disabled={monthDisabled(createCalendarDate(month.getFullYear(), monthIndex, 1))}\n key={label}\n value={monthIndex}\n >\n {label}\n </option>\n ))}\n </select>\n );\n },\n);\n\nexport type DatePickerYearSelectProps = Omit<\n ComponentPropsWithoutRef<\"select\">,\n \"children\" | \"onChange\" | \"value\"\n>;\n\nexport const DatePickerYearSelect = forwardRef<HTMLSelectElement, DatePickerYearSelectProps>(\n function DatePickerYearSelect({ className, ...props }, ref) {\n const { month, monthDisabled, selectYear, styles, yearRange } = useDatePickerContext();\n const years = Array.from(\n { length: yearRange.end - yearRange.start + 1 },\n (_, index) => yearRange.start + index,\n );\n\n return (\n <select\n {...props}\n aria-label={props[\"aria-label\"] ?? \"Select year\"}\n className={cx(styles.yearSelect, className)}\n data-slot=\"date-picker-year-select\"\n onChange={(event) => selectYear(Number(event.currentTarget.value))}\n ref={ref}\n value={month.getFullYear()}\n >\n {years.map((year) => (\n <option\n disabled={monthDisabled(createCalendarDate(year, month.getMonth(), 1))}\n key={year}\n value={year}\n >\n {year}\n </option>\n ))}\n </select>\n );\n },\n);\n\nexport type DatePickerTimeFieldProps = Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"onChange\" | \"type\" | \"value\"\n>;\n\nexport const DatePickerTimeField = forwardRef<HTMLInputElement, DatePickerTimeFieldProps>(\n function DatePickerTimeField({ className, ...props }, ref) {\n const { disabled, granularity, onTimeChange, selected, styles, timeMax, timeMin } =\n useDatePickerContext();\n if (granularity !== \"date-time\") return null;\n\n return (\n <input\n {...props}\n aria-label={props[\"aria-label\"] ?? \"Select time\"}\n className={cx(styles.timeField, className)}\n data-slot=\"date-picker-time-field\"\n disabled={disabled || !selected}\n max={timeMax}\n min={timeMin}\n onChange={(event) => onTimeChange(event.currentTarget.value)}\n ref={ref}\n type=\"time\"\n value={toTimeInput(selected)}\n />\n );\n },\n);\n\nexport interface DatePickerNavigationProps extends ComponentPropsWithoutRef<\"button\"> {\n amount?: number;\n}\n\nconst DatePickerNavigationButton = forwardRef<HTMLButtonElement, DatePickerNavigationProps>(\n function DatePickerNavigationButton({ amount, children, className, onClick, ...props }, ref) {\n const { canNavigate, month, setMonth, styles } = useDatePickerContext();\n const direction = amount ?? 1;\n const isDisabled = props.disabled || !canNavigate(direction);\n\n return (\n <button\n {...props}\n aria-label={props[\"aria-label\"] ?? (direction < 0 ? \"Previous month\" : \"Next month\")}\n className={cx(styles.navigation, className)}\n data-slot={direction < 0 ? \"date-picker-previous\" : \"date-picker-next\"}\n disabled={isDisabled}\n onClick={(event) => {\n if (!isDisabled) setMonth(addMonths(month, direction));\n onClick?.(event);\n }}\n ref={ref}\n type=\"button\"\n >\n {children ?? (direction < 0 ? \"‹\" : \"›\")}\n </button>\n );\n },\n);\n\nexport const DatePickerPrevious = forwardRef<HTMLButtonElement, DatePickerNavigationProps>(\n function DatePickerPrevious(props, ref) {\n return <DatePickerNavigationButton {...props} amount={-1} ref={ref} />;\n },\n);\n\nexport const DatePickerNext = forwardRef<HTMLButtonElement, DatePickerNavigationProps>(\n function DatePickerNext(props, ref) {\n return <DatePickerNavigationButton {...props} amount={1} ref={ref} />;\n },\n);\n\nexport interface DatePickerDayProps extends Omit<ComponentPropsWithoutRef<\"button\">, \"value\"> {\n date: Date;\n}\n\nexport const DatePickerDay = forwardRef<HTMLButtonElement, DatePickerDayProps>(\n function DatePickerDay(\n { children, className, date, disabled, onClick, onKeyDown, ...props },\n ref,\n ) {\n const {\n dateDisabled,\n disabled: pickerDisabled,\n focusDate,\n focusedDate,\n locale,\n month,\n onSelect,\n registerDay,\n selected,\n styles,\n today,\n } = useDatePickerContext();\n const key = dateKey(date);\n const outsideMonth = !isSameMonth(date, month);\n const isDisabled = disabled || pickerDisabled || dateDisabled(date);\n const isFocused = isSameDay(date, focusedDate);\n const isSelected = isSameDay(date, selected);\n const isToday = isSameDay(date, today);\n const dayRef = composeRefs(ref, (node) => registerDay(key, node));\n\n const moveByKey = (event: KeyboardEvent<HTMLButtonElement>) => {\n if (event.defaultPrevented) {\n return;\n }\n\n let nextDate: Date | undefined;\n switch (event.key) {\n case \"ArrowLeft\":\n nextDate = addDays(date, -1);\n break;\n case \"ArrowRight\":\n nextDate = addDays(date, 1);\n break;\n case \"ArrowUp\":\n nextDate = addDays(date, -7);\n break;\n case \"ArrowDown\":\n nextDate = addDays(date, 7);\n break;\n case \"Home\":\n nextDate = addDays(date, -date.getDay());\n break;\n case \"End\":\n nextDate = addDays(date, 6 - date.getDay());\n break;\n case \"PageUp\":\n nextDate = addMonths(date, event.shiftKey ? -12 : -1);\n break;\n case \"PageDown\":\n nextDate = addMonths(date, event.shiftKey ? 12 : 1);\n break;\n case \"Enter\":\n case \" \":\n if (!isDisabled) {\n event.preventDefault();\n onSelect(date);\n }\n break;\n default:\n break;\n }\n\n if (nextDate) {\n event.preventDefault();\n focusDate(nextDate, nextDate < date ? -1 : 1);\n }\n };\n\n return (\n // biome-ignore lint/a11y/useSemanticElements: A calendar day is an interactive gridcell, not a generic table cell.\n <button\n {...props}\n ref={dayRef}\n aria-label={props[\"aria-label\"] ?? getDateRangeLabel(date, locale)}\n aria-current={isToday ? \"date\" : undefined}\n aria-selected={isSelected}\n className={cx(styles.day, className)}\n data-date={key}\n data-disabled={isDisabled || undefined}\n data-outside-month={outsideMonth || undefined}\n data-selected={isSelected || undefined}\n data-slot=\"date-picker-day\"\n data-today={isToday || undefined}\n disabled={isDisabled}\n onClick={(event) => {\n onSelect(date);\n onClick?.(event);\n }}\n onKeyDown={(event) => {\n moveByKey(event);\n onKeyDown?.(event);\n }}\n role=\"gridcell\"\n tabIndex={isFocused && !isDisabled ? 0 : -1}\n type=\"button\"\n >\n {children ?? date.getDate()}\n </button>\n );\n },\n);\n\ninterface DatePickerMonthButtonProps {\n date: Date;\n}\n\nconst DatePickerMonthButton = forwardRef<HTMLButtonElement, DatePickerMonthButtonProps>(\n function DatePickerMonthButton({ date }, ref) {\n const { disabled, granularity, locale, monthDisabled, onSelect, selected, styles } =\n useDatePickerContext();\n const isDisabled = disabled || monthDisabled(date);\n const isSelected = granularity === \"month\" && Boolean(selected && isSameMonth(selected, date));\n\n return (\n // biome-ignore lint/a11y/useSemanticElements: Month choices use the calendar gridcell pattern.\n <button\n aria-label={new Intl.DateTimeFormat(locale, { month: \"long\" }).format(date)}\n aria-selected={isSelected}\n className={styles.month}\n data-disabled={isDisabled || undefined}\n data-selected={isSelected || undefined}\n data-slot=\"date-picker-month\"\n disabled={isDisabled}\n onClick={() => onSelect(date)}\n ref={ref}\n role=\"gridcell\"\n type=\"button\"\n >\n {new Intl.DateTimeFormat(locale, { month: \"short\" }).format(date)}\n </button>\n );\n },\n);\n\nexport interface DatePickerCalendarProps\n extends Omit<ComponentPropsWithoutRef<\"section\">, \"children\"> {\n \"aria-label\"?: string;\n}\n\nexport const DatePickerCalendar = forwardRef<HTMLElement, DatePickerCalendarProps>(\n function DatePickerCalendar({ \"aria-label\": ariaLabel, className, ...props }, ref) {\n const { granularity, locale, month, styles, weekStartsOn } = useDatePickerContext();\n const days = useMemo(() => getCalendarDays(month, weekStartsOn), [month, weekStartsOn]);\n const weekdays = useMemo(() => getWeekdayLabels(locale, weekStartsOn), [locale, weekStartsOn]);\n const monthDates = useMemo(\n () =>\n Array.from({ length: 12 }, (_, index) => createCalendarDate(month.getFullYear(), index, 1)),\n [month],\n );\n\n return (\n <section\n {...props}\n ref={ref}\n aria-label={ariaLabel ?? formatMonthLabel(month, locale)}\n className={cx(styles.calendar, className)}\n data-granularity={granularity}\n data-slot=\"date-picker-calendar\"\n >\n {granularity === \"month\" ? (\n // biome-ignore lint/a11y/useSemanticElements: Month selection uses the calendar grid pattern.\n <div\n aria-label={String(month.getFullYear())}\n className={styles.monthGrid}\n data-slot=\"date-picker-month-grid\"\n role=\"grid\"\n >\n {monthDates.map((date) => (\n <DatePickerMonthButton date={date} key={dateKey(date)} />\n ))}\n </div>\n ) : (\n <>\n <div aria-hidden=\"true\" className={styles.weekdays} data-slot=\"date-picker-weekdays\">\n {weekdays.map((weekday) => (\n <span className={styles.weekday} data-slot=\"date-picker-weekday\" key={weekday}>\n {weekday}\n </span>\n ))}\n </div>\n {/* biome-ignore lint/a11y/useSemanticElements: Calendar grids use the WAI-ARIA grid pattern for roving day focus. */}\n <div\n aria-label={formatMonthLabel(month, locale)}\n className={styles.grid}\n data-slot=\"date-picker-grid\"\n role=\"grid\"\n >\n {days.map((date) => (\n <DatePickerDay date={date} key={dateKey(date)} />\n ))}\n </div>\n </>\n )}\n </section>\n );\n },\n);\n\nexport const DatePicker = {\n Root: DatePickerRoot,\n Label: DatePickerLabel,\n Control: DatePickerControl,\n Trigger: DatePickerTrigger,\n Value: DatePickerValue,\n Clear: DatePickerClear,\n Portal: DatePickerPortal,\n Positioner: DatePickerPositioner,\n Popup: DatePickerPopup,\n Close: DatePickerClose,\n Header: DatePickerHeader,\n Caption: DatePickerCaption,\n MonthSelect: DatePickerMonthSelect,\n YearSelect: DatePickerYearSelect,\n TimeField: DatePickerTimeField,\n Previous: DatePickerPrevious,\n Next: DatePickerNext,\n Day: DatePickerDay,\n Calendar: DatePickerCalendar,\n};\n"],"mappings":"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"}
|
|
@@ -25,6 +25,15 @@ function dateKey(date) {
|
|
|
25
25
|
function toInputDate(date) {
|
|
26
26
|
return date ? dateKey(date) : "";
|
|
27
27
|
}
|
|
28
|
+
function toInputMonth(date) {
|
|
29
|
+
return date ? `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}` : "";
|
|
30
|
+
}
|
|
31
|
+
function toInputDateTime(date) {
|
|
32
|
+
if (!date) return "";
|
|
33
|
+
const hours = String(date.getHours()).padStart(2, "0");
|
|
34
|
+
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
35
|
+
return `${dateKey(date)}T${hours}:${minutes}`;
|
|
36
|
+
}
|
|
28
37
|
function isSameDay(left, right) {
|
|
29
38
|
return Boolean(left && right && dateKey(left) === dateKey(right));
|
|
30
39
|
}
|
|
@@ -50,8 +59,25 @@ function formatMonthLabel(date, locale) {
|
|
|
50
59
|
year: "numeric"
|
|
51
60
|
}).format(date);
|
|
52
61
|
}
|
|
53
|
-
function formatDateLabel(date, locale, placeholder) {
|
|
54
|
-
|
|
62
|
+
function formatDateLabel(date, locale, placeholder, granularity = "day") {
|
|
63
|
+
if (!date) return placeholder;
|
|
64
|
+
if (granularity === "month") return new Intl.DateTimeFormat(locale, {
|
|
65
|
+
month: "long",
|
|
66
|
+
year: "numeric"
|
|
67
|
+
}).format(date);
|
|
68
|
+
if (granularity === "date-time") return new Intl.DateTimeFormat(locale, {
|
|
69
|
+
dateStyle: "medium",
|
|
70
|
+
timeStyle: "short"
|
|
71
|
+
}).format(date);
|
|
72
|
+
return new Intl.DateTimeFormat(locale, { dateStyle: "medium" }).format(date);
|
|
73
|
+
}
|
|
74
|
+
function getMonthLabels(locale) {
|
|
75
|
+
const formatter = new Intl.DateTimeFormat(locale, { month: "long" });
|
|
76
|
+
return Array.from({ length: 12 }, (_, month) => formatter.format(createCalendarDate(2024, month, 1)));
|
|
77
|
+
}
|
|
78
|
+
function toTimeInput(date) {
|
|
79
|
+
if (!date) return "";
|
|
80
|
+
return `${String(date.getHours()).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}`;
|
|
55
81
|
}
|
|
56
82
|
function getDateRangeLabel(date, locale) {
|
|
57
83
|
return new Intl.DateTimeFormat(locale, {
|
|
@@ -70,11 +96,15 @@ exports.formatDateLabel = formatDateLabel;
|
|
|
70
96
|
exports.formatMonthLabel = formatMonthLabel;
|
|
71
97
|
exports.getCalendarDays = getCalendarDays;
|
|
72
98
|
exports.getDateRangeLabel = getDateRangeLabel;
|
|
99
|
+
exports.getMonthLabels = getMonthLabels;
|
|
73
100
|
exports.getWeekdayLabels = getWeekdayLabels;
|
|
74
101
|
exports.isAfterDay = isAfterDay;
|
|
75
102
|
exports.isBeforeDay = isBeforeDay;
|
|
76
103
|
exports.isSameDay = isSameDay;
|
|
77
104
|
exports.startOfMonth = startOfMonth;
|
|
78
105
|
exports.toInputDate = toInputDate;
|
|
106
|
+
exports.toInputDateTime = toInputDateTime;
|
|
107
|
+
exports.toInputMonth = toInputMonth;
|
|
108
|
+
exports.toTimeInput = toTimeInput;
|
|
79
109
|
|
|
80
110
|
//# sourceMappingURL=date-utils.cjs.map
|