@nuvui/date-picker 0.0.0-stage → 0.1.1
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/LICENSE +21 -0
- package/README.md +36 -2
- package/dist/components/calendar/calendar.cjs +163 -0
- package/dist/components/calendar/calendar.d.cts +17 -0
- package/dist/components/calendar/calendar.d.ts +17 -0
- package/dist/components/calendar/calendar.js +163 -0
- package/dist/components/calendar/index.cjs +3 -0
- package/dist/components/calendar/index.d.cts +2 -0
- package/dist/components/calendar/index.d.ts +2 -0
- package/dist/components/calendar/index.js +2 -0
- package/dist/components/date-picker/date-picker.cjs +340 -0
- package/dist/components/date-picker/date-picker.d.cts +169 -0
- package/dist/components/date-picker/date-picker.d.ts +169 -0
- package/dist/components/date-picker/date-picker.js +339 -0
- package/dist/components/date-picker/index.cjs +4 -0
- package/dist/components/date-picker/index.d.cts +2 -0
- package/dist/components/date-picker/index.d.ts +2 -0
- package/dist/components/date-picker/index.js +2 -0
- package/dist/components/date-picker/popup.cjs +43 -0
- package/dist/components/date-picker/popup.js +43 -0
- package/dist/css/calendar.css +291 -0
- package/dist/css/date-picker.css +24 -0
- package/dist/index.cjs +13 -0
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +4 -0
- package/dist/locale.cjs +9 -0
- package/dist/locale.d.cts +1 -0
- package/dist/locale.d.ts +1 -0
- package/dist/locale.js +1 -0
- package/dist/styles.css +314 -0
- package/dist/utils/cx.cjs +6 -0
- package/dist/utils/cx.js +6 -0
- package/dist/utils/dates.cjs +59 -0
- package/dist/utils/dates.js +54 -0
- package/dist/utils/use-controlled.cjs +31 -0
- package/dist/utils/use-controlled.js +31 -0
- package/dist/utils/use-date-text.cjs +83 -0
- package/dist/utils/use-date-text.js +83 -0
- package/dist/utils/use-is-phone.cjs +18 -0
- package/dist/utils/use-is-phone.js +18 -0
- package/package.json +118 -3
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const require_cx = require("../../utils/cx.cjs");
|
|
3
|
+
const require_calendar = require("../calendar/calendar.cjs");
|
|
4
|
+
const require_dates = require("../../utils/dates.cjs");
|
|
5
|
+
const require_use_controlled = require("../../utils/use-controlled.cjs");
|
|
6
|
+
const require_use_date_text = require("../../utils/use-date-text.cjs");
|
|
7
|
+
const require_use_is_phone = require("../../utils/use-is-phone.cjs");
|
|
8
|
+
const require_popup = require("./popup.cjs");
|
|
9
|
+
let react = require("react");
|
|
10
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
11
|
+
let _nuvui_react_input = require("@nuvui/react/input");
|
|
12
|
+
let _nuvui_react_input_group = require("@nuvui/react/input-group");
|
|
13
|
+
let _nuvui_react_popover = require("@nuvui/react/popover");
|
|
14
|
+
//#region src/components/date-picker/date-picker.tsx
|
|
15
|
+
function CalendarIcon() {
|
|
16
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
17
|
+
"aria-hidden": "true",
|
|
18
|
+
viewBox: "0 0 16 16",
|
|
19
|
+
width: "16",
|
|
20
|
+
height: "16",
|
|
21
|
+
fill: "none",
|
|
22
|
+
stroke: "currentColor",
|
|
23
|
+
strokeWidth: "1.5",
|
|
24
|
+
strokeLinecap: "round",
|
|
25
|
+
strokeLinejoin: "round",
|
|
26
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
|
|
27
|
+
x: "2.5",
|
|
28
|
+
y: "3.5",
|
|
29
|
+
width: "11",
|
|
30
|
+
height: "10",
|
|
31
|
+
rx: "1.5"
|
|
32
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M2.5 6.5h11M5.5 2v3m5-3v3" })]
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function hint(format, locale) {
|
|
36
|
+
return (format === "P" ? require_dates.shortPattern(locale) : format).toLowerCase();
|
|
37
|
+
}
|
|
38
|
+
function useFormReset(input, onReset) {
|
|
39
|
+
const latest = (0, react.useRef)(onReset);
|
|
40
|
+
latest.current = onReset;
|
|
41
|
+
(0, react.useEffect)(() => {
|
|
42
|
+
const form = input.current?.form;
|
|
43
|
+
if (!form) return;
|
|
44
|
+
const reset = () => latest.current();
|
|
45
|
+
form.addEventListener("reset", reset);
|
|
46
|
+
return () => form.removeEventListener("reset", reset);
|
|
47
|
+
}, [input]);
|
|
48
|
+
}
|
|
49
|
+
function useMergedRef(outer, inner) {
|
|
50
|
+
return (0, react.useCallback)((node) => {
|
|
51
|
+
for (const ref of [outer, inner]) if (typeof ref === "function") ref(node);
|
|
52
|
+
else if (ref) ref.current = node;
|
|
53
|
+
}, [outer, inner]);
|
|
54
|
+
}
|
|
55
|
+
function openWithAltDown(event, open) {
|
|
56
|
+
if (event.key === "ArrowDown" && event.altKey) {
|
|
57
|
+
event.preventDefault();
|
|
58
|
+
open();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const DatePicker = (0, react.forwardRef)(function DatePicker({ value: valueProp, defaultValue = null, onValueChange, open: openProp, defaultOpen = false, onOpenChange, min, max, disabledDates, locale, weekStartsOn, timeZone, format = "P", invalidMessage = "Enter a valid date.", calendarLabel = "Choose date", title = "Choose date", closeLabel = "Close", calendar, name, form, container, className, style, disabled, readOnly, placeholder, onBlur, onKeyDown, "aria-invalid": ariaInvalid, ...props }, ref) {
|
|
62
|
+
const [value, setValue] = require_use_controlled.useControlled(valueProp !== void 0, valueProp ?? null, defaultValue, onValueChange);
|
|
63
|
+
const [open, setOpen] = require_use_controlled.useControlled(openProp !== void 0, openProp ?? false, defaultOpen, onOpenChange);
|
|
64
|
+
const phone = require_use_is_phone.useIsPhone();
|
|
65
|
+
const input = (0, react.useRef)(null);
|
|
66
|
+
const trigger = (0, react.useRef)(null);
|
|
67
|
+
const matchers = (0, react.useMemo)(() => require_dates.disabledDays(min, max, disabledDates, timeZone), [
|
|
68
|
+
min,
|
|
69
|
+
max,
|
|
70
|
+
disabledDates,
|
|
71
|
+
timeZone
|
|
72
|
+
]);
|
|
73
|
+
const field = require_use_date_text.useDateText({
|
|
74
|
+
value,
|
|
75
|
+
onCommit: setValue,
|
|
76
|
+
problem: (date) => require_dates.isDisabled(date, matchers) ? invalidMessage : void 0,
|
|
77
|
+
invalidMessage,
|
|
78
|
+
pattern: format,
|
|
79
|
+
locale,
|
|
80
|
+
timeZone,
|
|
81
|
+
input
|
|
82
|
+
});
|
|
83
|
+
useFormReset(input, () => {
|
|
84
|
+
field.clearDraft();
|
|
85
|
+
setValue(defaultValue);
|
|
86
|
+
});
|
|
87
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_nuvui_react_popover.Popover, {
|
|
88
|
+
open: open && !phone,
|
|
89
|
+
onOpenChange: setOpen,
|
|
90
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_nuvui_react_popover.PopoverAnchor, {
|
|
91
|
+
asChild: true,
|
|
92
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_nuvui_react_input_group.InputGroup, {
|
|
93
|
+
className: require_cx.cx("nuv-date-picker", className),
|
|
94
|
+
style,
|
|
95
|
+
children: [
|
|
96
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_nuvui_react_input.Input, {
|
|
97
|
+
ref: useMergedRef(ref, input),
|
|
98
|
+
autoComplete: "off",
|
|
99
|
+
placeholder: placeholder ?? hint(format, locale),
|
|
100
|
+
disabled,
|
|
101
|
+
readOnly,
|
|
102
|
+
"aria-invalid": field.error ? true : ariaInvalid,
|
|
103
|
+
...props,
|
|
104
|
+
value: field.text,
|
|
105
|
+
onChange: field.onChange,
|
|
106
|
+
onBlur: (event) => {
|
|
107
|
+
field.onBlur();
|
|
108
|
+
onBlur?.(event);
|
|
109
|
+
},
|
|
110
|
+
onKeyDown: (event) => {
|
|
111
|
+
onKeyDown?.(event);
|
|
112
|
+
if (event.defaultPrevented) return;
|
|
113
|
+
field.onKeyDown(event);
|
|
114
|
+
if (!disabled && !readOnly) openWithAltDown(event, () => setOpen(true));
|
|
115
|
+
}
|
|
116
|
+
}),
|
|
117
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_nuvui_react_popover.PopoverTrigger, {
|
|
118
|
+
asChild: true,
|
|
119
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_nuvui_react_input_group.InputGroupButton, {
|
|
120
|
+
ref: trigger,
|
|
121
|
+
className: "nuv-date-picker__button",
|
|
122
|
+
"aria-label": value ? `${calendarLabel}, ${require_dates.formatDate(value, "PPPP", locale, timeZone)}` : calendarLabel,
|
|
123
|
+
disabled: disabled || readOnly,
|
|
124
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CalendarIcon, {})
|
|
125
|
+
})
|
|
126
|
+
}),
|
|
127
|
+
name ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
128
|
+
type: "hidden",
|
|
129
|
+
name,
|
|
130
|
+
form,
|
|
131
|
+
value: require_dates.isoDate(value ?? void 0, timeZone),
|
|
132
|
+
disabled
|
|
133
|
+
}) : null
|
|
134
|
+
]
|
|
135
|
+
})
|
|
136
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_popup.Popup, {
|
|
137
|
+
open,
|
|
138
|
+
onOpenChange: setOpen,
|
|
139
|
+
phone,
|
|
140
|
+
title,
|
|
141
|
+
closeLabel,
|
|
142
|
+
container,
|
|
143
|
+
trigger,
|
|
144
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_calendar.Calendar, {
|
|
145
|
+
...calendar,
|
|
146
|
+
mode: "single",
|
|
147
|
+
required: true,
|
|
148
|
+
selected: value ?? void 0,
|
|
149
|
+
onSelect: (date) => {
|
|
150
|
+
field.clearDraft();
|
|
151
|
+
setValue(date);
|
|
152
|
+
setOpen(false);
|
|
153
|
+
},
|
|
154
|
+
defaultMonth: value ?? calendar?.defaultMonth,
|
|
155
|
+
startMonth: min,
|
|
156
|
+
endMonth: max,
|
|
157
|
+
disabled: matchers,
|
|
158
|
+
locale,
|
|
159
|
+
weekStartsOn,
|
|
160
|
+
timeZone
|
|
161
|
+
})
|
|
162
|
+
})]
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
function before(a, b, timeZone) {
|
|
166
|
+
return require_dates.isoDate(a, timeZone) < require_dates.isoDate(b, timeZone);
|
|
167
|
+
}
|
|
168
|
+
const DateRangePicker = (0, react.forwardRef)(function DateRangePicker({ value: valueProp, defaultValue = null, onValueChange, open: openProp, defaultOpen = false, onOpenChange, min, max, disabledDates, locale, weekStartsOn, timeZone, format = "P", invalidMessage = "Enter a valid date.", orderMessage = "The end date is before the start date.", calendarLabel = "Choose dates", title = "Choose dates", closeLabel = "Close", startLabel = "Start date", endLabel = "End date", numberOfMonths = 2, calendar, startName, endName, form, container, className, style, disabled, readOnly, required, placeholder, id, onBlur, onKeyDown, "aria-invalid": ariaInvalid, "aria-labelledby": ariaLabelledBy, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, ...props }, ref) {
|
|
169
|
+
const [value, setValue] = require_use_controlled.useControlled(valueProp !== void 0, valueProp ?? null, defaultValue, onValueChange);
|
|
170
|
+
const [open, setOpen] = require_use_controlled.useControlled(openProp !== void 0, openProp ?? false, defaultOpen, onOpenChange);
|
|
171
|
+
const phone = require_use_is_phone.useIsPhone();
|
|
172
|
+
const startInput = (0, react.useRef)(null);
|
|
173
|
+
const endInput = (0, react.useRef)(null);
|
|
174
|
+
const trigger = (0, react.useRef)(null);
|
|
175
|
+
const from = value?.from ?? null;
|
|
176
|
+
const to = value?.to ?? null;
|
|
177
|
+
const matchers = (0, react.useMemo)(() => require_dates.disabledDays(min, max, disabledDates, timeZone), [
|
|
178
|
+
min,
|
|
179
|
+
max,
|
|
180
|
+
disabledDates,
|
|
181
|
+
timeZone
|
|
182
|
+
]);
|
|
183
|
+
function setRange(nextFrom, nextTo) {
|
|
184
|
+
setValue(nextFrom || nextTo ? {
|
|
185
|
+
from: nextFrom ?? void 0,
|
|
186
|
+
to: nextTo ?? void 0
|
|
187
|
+
} : null);
|
|
188
|
+
}
|
|
189
|
+
const start = require_use_date_text.useDateText({
|
|
190
|
+
value: from,
|
|
191
|
+
onCommit: (date) => setRange(date, to),
|
|
192
|
+
problem: (date) => {
|
|
193
|
+
if (require_dates.isDisabled(date, matchers)) return invalidMessage;
|
|
194
|
+
return to && before(to, date, timeZone) ? orderMessage : void 0;
|
|
195
|
+
},
|
|
196
|
+
invalidMessage,
|
|
197
|
+
pattern: format,
|
|
198
|
+
locale,
|
|
199
|
+
timeZone,
|
|
200
|
+
input: startInput
|
|
201
|
+
});
|
|
202
|
+
const end = require_use_date_text.useDateText({
|
|
203
|
+
value: to,
|
|
204
|
+
onCommit: (date) => setRange(from, date),
|
|
205
|
+
problem: (date) => {
|
|
206
|
+
if (require_dates.isDisabled(date, matchers)) return invalidMessage;
|
|
207
|
+
return from && before(date, from, timeZone) ? orderMessage : void 0;
|
|
208
|
+
},
|
|
209
|
+
invalidMessage,
|
|
210
|
+
pattern: format,
|
|
211
|
+
locale,
|
|
212
|
+
timeZone,
|
|
213
|
+
input: endInput
|
|
214
|
+
});
|
|
215
|
+
useFormReset(startInput, () => {
|
|
216
|
+
start.clearDraft();
|
|
217
|
+
end.clearDraft();
|
|
218
|
+
setValue(defaultValue);
|
|
219
|
+
});
|
|
220
|
+
const shared = {
|
|
221
|
+
autoComplete: "off",
|
|
222
|
+
placeholder: placeholder ?? hint(format, locale),
|
|
223
|
+
disabled,
|
|
224
|
+
readOnly,
|
|
225
|
+
required,
|
|
226
|
+
"aria-describedby": ariaDescribedBy,
|
|
227
|
+
...props
|
|
228
|
+
};
|
|
229
|
+
function keyDown(event, field) {
|
|
230
|
+
onKeyDown?.(event);
|
|
231
|
+
if (event.defaultPrevented) return;
|
|
232
|
+
field.onKeyDown(event);
|
|
233
|
+
if (!disabled && !readOnly) openWithAltDown(event, () => setOpen(true));
|
|
234
|
+
}
|
|
235
|
+
const picked = [from, to].filter((date) => date !== null).map((date) => require_dates.formatDate(date, "PPPP", locale, timeZone)).join(", ");
|
|
236
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_nuvui_react_popover.Popover, {
|
|
237
|
+
open: open && !phone,
|
|
238
|
+
onOpenChange: setOpen,
|
|
239
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_nuvui_react_popover.PopoverAnchor, {
|
|
240
|
+
asChild: true,
|
|
241
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_nuvui_react_input_group.InputGroup, {
|
|
242
|
+
role: "group",
|
|
243
|
+
"aria-labelledby": ariaLabelledBy,
|
|
244
|
+
"aria-label": ariaLabel,
|
|
245
|
+
className: require_cx.cx("nuv-date-picker nuv-date-picker--range", className),
|
|
246
|
+
style,
|
|
247
|
+
children: [
|
|
248
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_nuvui_react_input.Input, {
|
|
249
|
+
ref: useMergedRef(ref, startInput),
|
|
250
|
+
id,
|
|
251
|
+
"aria-label": startLabel,
|
|
252
|
+
"aria-invalid": start.error ? true : ariaInvalid,
|
|
253
|
+
...shared,
|
|
254
|
+
value: start.text,
|
|
255
|
+
onChange: start.onChange,
|
|
256
|
+
onBlur: (event) => {
|
|
257
|
+
start.onBlur();
|
|
258
|
+
onBlur?.(event);
|
|
259
|
+
},
|
|
260
|
+
onKeyDown: (event) => keyDown(event, start)
|
|
261
|
+
}),
|
|
262
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
263
|
+
"aria-hidden": "true",
|
|
264
|
+
className: "nuv-date-picker__separator",
|
|
265
|
+
children: "–"
|
|
266
|
+
}),
|
|
267
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_nuvui_react_input.Input, {
|
|
268
|
+
ref: endInput,
|
|
269
|
+
"aria-label": endLabel,
|
|
270
|
+
"aria-invalid": end.error ? true : ariaInvalid,
|
|
271
|
+
...shared,
|
|
272
|
+
value: end.text,
|
|
273
|
+
onChange: end.onChange,
|
|
274
|
+
onBlur: (event) => {
|
|
275
|
+
end.onBlur();
|
|
276
|
+
onBlur?.(event);
|
|
277
|
+
},
|
|
278
|
+
onKeyDown: (event) => keyDown(event, end)
|
|
279
|
+
}),
|
|
280
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_nuvui_react_popover.PopoverTrigger, {
|
|
281
|
+
asChild: true,
|
|
282
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_nuvui_react_input_group.InputGroupButton, {
|
|
283
|
+
ref: trigger,
|
|
284
|
+
className: "nuv-date-picker__button",
|
|
285
|
+
"aria-label": picked ? `${calendarLabel}, ${picked}` : calendarLabel,
|
|
286
|
+
disabled: disabled || readOnly,
|
|
287
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CalendarIcon, {})
|
|
288
|
+
})
|
|
289
|
+
}),
|
|
290
|
+
startName ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
291
|
+
type: "hidden",
|
|
292
|
+
name: startName,
|
|
293
|
+
form,
|
|
294
|
+
value: require_dates.isoDate(from ?? void 0, timeZone),
|
|
295
|
+
disabled
|
|
296
|
+
}) : null,
|
|
297
|
+
endName ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
298
|
+
type: "hidden",
|
|
299
|
+
name: endName,
|
|
300
|
+
form,
|
|
301
|
+
value: require_dates.isoDate(to ?? void 0, timeZone),
|
|
302
|
+
disabled
|
|
303
|
+
}) : null
|
|
304
|
+
]
|
|
305
|
+
})
|
|
306
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_popup.Popup, {
|
|
307
|
+
open,
|
|
308
|
+
onOpenChange: setOpen,
|
|
309
|
+
phone,
|
|
310
|
+
title,
|
|
311
|
+
closeLabel,
|
|
312
|
+
container,
|
|
313
|
+
trigger,
|
|
314
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_calendar.Calendar, {
|
|
315
|
+
numberOfMonths: phone ? 1 : numberOfMonths,
|
|
316
|
+
...calendar,
|
|
317
|
+
mode: "range",
|
|
318
|
+
required: true,
|
|
319
|
+
resetOnSelect: true,
|
|
320
|
+
selected: value ?? void 0,
|
|
321
|
+
onSelect: (range) => {
|
|
322
|
+
start.clearDraft();
|
|
323
|
+
end.clearDraft();
|
|
324
|
+
setValue(range);
|
|
325
|
+
if (range.from && range.to) setOpen(false);
|
|
326
|
+
},
|
|
327
|
+
defaultMonth: from ?? calendar?.defaultMonth,
|
|
328
|
+
startMonth: min,
|
|
329
|
+
endMonth: max,
|
|
330
|
+
disabled: matchers,
|
|
331
|
+
locale,
|
|
332
|
+
weekStartsOn,
|
|
333
|
+
timeZone
|
|
334
|
+
})
|
|
335
|
+
})]
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
//#endregion
|
|
339
|
+
exports.DatePicker = DatePicker;
|
|
340
|
+
exports.DateRangePicker = DateRangePicker;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { CalendarLocale } from "../calendar/calendar.cjs";
|
|
2
|
+
import { DateRange, Matcher, PropsBase, PropsRange } from "react-day-picker";
|
|
3
|
+
import { InputHTMLAttributes } from "react";
|
|
4
|
+
//#region src/components/date-picker/date-picker.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* The calendar's own options, for the ones the picker doesn't set itself:
|
|
7
|
+
* `captionLayout`, `showWeekNumber`, `labels` and the rest.
|
|
8
|
+
*/
|
|
9
|
+
export type DatePickerCalendarProps = Omit<PropsBase, "mode" | "required" | "disabled" | "locale" | "timeZone" | "weekStartsOn" | "startMonth" | "endMonth" | "animate" | "autoFocus" | "dir">;
|
|
10
|
+
/**
|
|
11
|
+
* The same for a range, with the three options only a range has: the
|
|
12
|
+
* fewest and the most days it may span, and whether it may run across a
|
|
13
|
+
* day that can't be picked.
|
|
14
|
+
*/
|
|
15
|
+
export type DateRangePickerCalendarProps = DatePickerCalendarProps & Pick<PropsRange, "min" | "max" | "excludeDisabled">;
|
|
16
|
+
type InputProps = Omit<InputHTMLAttributes<HTMLInputElement>, "value" | "defaultValue" | "onChange" | "min" | "max" | "type" | "name" | "form" | "children">;
|
|
17
|
+
interface SharedProps {
|
|
18
|
+
/**
|
|
19
|
+
* Whether the calendar is open. Use it with `onOpenChange`.
|
|
20
|
+
*/
|
|
21
|
+
open?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Whether the calendar starts out open.
|
|
24
|
+
* @default false
|
|
25
|
+
*/
|
|
26
|
+
defaultOpen?: boolean;
|
|
27
|
+
/** Called when the calendar opens or closes. */
|
|
28
|
+
onOpenChange?: (open: boolean) => void;
|
|
29
|
+
/** The earliest day that can be picked or typed. */
|
|
30
|
+
min?: Date;
|
|
31
|
+
/** The latest day that can be picked or typed. */
|
|
32
|
+
max?: Date;
|
|
33
|
+
/**
|
|
34
|
+
* Days that can't be picked or typed: a date, a list of them, a range,
|
|
35
|
+
* `{ dayOfWeek: [0, 6] }` for weekends, or a function that's given a date.
|
|
36
|
+
*/
|
|
37
|
+
disabledDates?: Matcher | Matcher[];
|
|
38
|
+
/**
|
|
39
|
+
* The language of the calendar, and the order a typed date is read in.
|
|
40
|
+
* Take one from `@nuvui/date-picker/locale`.
|
|
41
|
+
* @default enUS
|
|
42
|
+
*/
|
|
43
|
+
locale?: CalendarLocale;
|
|
44
|
+
/**
|
|
45
|
+
* The day a week starts on, from 0 for Sunday. Left out, it's the
|
|
46
|
+
* locale's.
|
|
47
|
+
*/
|
|
48
|
+
weekStartsOn?: PropsBase["weekStartsOn"];
|
|
49
|
+
/**
|
|
50
|
+
* The time zone the days are in, as an IANA name such as
|
|
51
|
+
* `"Asia/Tokyo"`. Left out, it's the browser's. Dates are then handed
|
|
52
|
+
* back as `TZDate`s.
|
|
53
|
+
*/
|
|
54
|
+
timeZone?: string;
|
|
55
|
+
/**
|
|
56
|
+
* The pattern a typed date is read and written in, in date-fns' tokens.
|
|
57
|
+
* `"P"` is the locale's own short date, `MM/dd/yyyy` in the United
|
|
58
|
+
* States.
|
|
59
|
+
* @default "P"
|
|
60
|
+
*/
|
|
61
|
+
format?: string;
|
|
62
|
+
/**
|
|
63
|
+
* What the browser is told when the text isn't a date, or is one that
|
|
64
|
+
* can't be picked. It's shown when a form with the field is submitted.
|
|
65
|
+
* @default "Enter a valid date."
|
|
66
|
+
*/
|
|
67
|
+
invalidMessage?: string;
|
|
68
|
+
/**
|
|
69
|
+
* Accessible name of the button that opens the calendar. The picked date
|
|
70
|
+
* is read after it.
|
|
71
|
+
* @default "Choose date"
|
|
72
|
+
*/
|
|
73
|
+
calendarLabel?: string;
|
|
74
|
+
/**
|
|
75
|
+
* Accessible name of the calendar's panel, and the heading of the sheet
|
|
76
|
+
* it opens in on a phone.
|
|
77
|
+
* @default "Choose date"
|
|
78
|
+
*/
|
|
79
|
+
title?: string;
|
|
80
|
+
/**
|
|
81
|
+
* Accessible name of the sheet's close button.
|
|
82
|
+
* @default "Close"
|
|
83
|
+
*/
|
|
84
|
+
closeLabel?: string;
|
|
85
|
+
/**
|
|
86
|
+
* The `id` of the form the value belongs to, when the field is outside
|
|
87
|
+
* it.
|
|
88
|
+
*/
|
|
89
|
+
form?: string;
|
|
90
|
+
/**
|
|
91
|
+
* The element the calendar is rendered into. Set this when it should pick
|
|
92
|
+
* up a `data-theme` from a section of the page.
|
|
93
|
+
* @default document.body
|
|
94
|
+
*/
|
|
95
|
+
container?: Element | DocumentFragment | null;
|
|
96
|
+
}
|
|
97
|
+
export interface DatePickerOwnProps extends SharedProps {
|
|
98
|
+
/**
|
|
99
|
+
* The picked date, or `null` for none. Use it with `onValueChange`.
|
|
100
|
+
*/
|
|
101
|
+
value?: Date | null;
|
|
102
|
+
/** The date picked to begin with. */
|
|
103
|
+
defaultValue?: Date | null;
|
|
104
|
+
/** Called with the new date when one is picked or typed. */
|
|
105
|
+
onValueChange?: (date: Date | null) => void;
|
|
106
|
+
/**
|
|
107
|
+
* The name the date is submitted under, as `yyyy-MM-dd`. Without one,
|
|
108
|
+
* nothing is submitted.
|
|
109
|
+
*/
|
|
110
|
+
name?: string;
|
|
111
|
+
/**
|
|
112
|
+
* More of the calendar's own options, such as `captionLayout` and
|
|
113
|
+
* `showWeekNumber`.
|
|
114
|
+
*/
|
|
115
|
+
calendar?: DatePickerCalendarProps;
|
|
116
|
+
}
|
|
117
|
+
export interface DatePickerProps extends DatePickerOwnProps, InputProps {}
|
|
118
|
+
export declare const DatePicker: import("react").ForwardRefExoticComponent<DatePickerProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
119
|
+
export interface DateRangePickerOwnProps extends SharedProps {
|
|
120
|
+
/**
|
|
121
|
+
* The picked range, or `null` for none. Use it with `onValueChange`.
|
|
122
|
+
*/
|
|
123
|
+
value?: DateRange | null;
|
|
124
|
+
/** The range picked to begin with. */
|
|
125
|
+
defaultValue?: DateRange | null;
|
|
126
|
+
/**
|
|
127
|
+
* Called with the new range when a day is picked or typed. While only
|
|
128
|
+
* the first day has been chosen, `to` is `undefined`.
|
|
129
|
+
*/
|
|
130
|
+
onValueChange?: (range: DateRange | null) => void;
|
|
131
|
+
/**
|
|
132
|
+
* The name the first day is submitted under, as `yyyy-MM-dd`.
|
|
133
|
+
*/
|
|
134
|
+
startName?: string;
|
|
135
|
+
/** The name the last day is submitted under, as `yyyy-MM-dd`. */
|
|
136
|
+
endName?: string;
|
|
137
|
+
/**
|
|
138
|
+
* Accessible name of the field for the first day.
|
|
139
|
+
* @default "Start date"
|
|
140
|
+
*/
|
|
141
|
+
startLabel?: string;
|
|
142
|
+
/**
|
|
143
|
+
* Accessible name of the field for the last day.
|
|
144
|
+
* @default "End date"
|
|
145
|
+
*/
|
|
146
|
+
endLabel?: string;
|
|
147
|
+
/**
|
|
148
|
+
* What the browser is told when the last day comes before the first.
|
|
149
|
+
* @default "The end date is before the start date."
|
|
150
|
+
*/
|
|
151
|
+
orderMessage?: string;
|
|
152
|
+
/**
|
|
153
|
+
* How many months the calendar shows side by side. On a phone it's
|
|
154
|
+
* always one.
|
|
155
|
+
* @default 2
|
|
156
|
+
*/
|
|
157
|
+
numberOfMonths?: number;
|
|
158
|
+
/**
|
|
159
|
+
* More of the calendar's own options. `min` and `max` here are the
|
|
160
|
+
* fewest and the most days the range may span.
|
|
161
|
+
*/
|
|
162
|
+
calendar?: DateRangePickerCalendarProps;
|
|
163
|
+
}
|
|
164
|
+
export interface DateRangePickerProps extends DateRangePickerOwnProps, Omit<InputProps, "placeholder"> {
|
|
165
|
+
/** The hint in both fields. Left out, it's the pattern. */
|
|
166
|
+
placeholder?: string;
|
|
167
|
+
}
|
|
168
|
+
export declare const DateRangePicker: import("react").ForwardRefExoticComponent<DateRangePickerProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
169
|
+
//#endregion
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { CalendarLocale } from "../calendar/calendar.js";
|
|
2
|
+
import { InputHTMLAttributes } from "react";
|
|
3
|
+
import { DateRange, Matcher, PropsBase, PropsRange } from "react-day-picker";
|
|
4
|
+
//#region src/components/date-picker/date-picker.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* The calendar's own options, for the ones the picker doesn't set itself:
|
|
7
|
+
* `captionLayout`, `showWeekNumber`, `labels` and the rest.
|
|
8
|
+
*/
|
|
9
|
+
export type DatePickerCalendarProps = Omit<PropsBase, "mode" | "required" | "disabled" | "locale" | "timeZone" | "weekStartsOn" | "startMonth" | "endMonth" | "animate" | "autoFocus" | "dir">;
|
|
10
|
+
/**
|
|
11
|
+
* The same for a range, with the three options only a range has: the
|
|
12
|
+
* fewest and the most days it may span, and whether it may run across a
|
|
13
|
+
* day that can't be picked.
|
|
14
|
+
*/
|
|
15
|
+
export type DateRangePickerCalendarProps = DatePickerCalendarProps & Pick<PropsRange, "min" | "max" | "excludeDisabled">;
|
|
16
|
+
type InputProps = Omit<InputHTMLAttributes<HTMLInputElement>, "value" | "defaultValue" | "onChange" | "min" | "max" | "type" | "name" | "form" | "children">;
|
|
17
|
+
interface SharedProps {
|
|
18
|
+
/**
|
|
19
|
+
* Whether the calendar is open. Use it with `onOpenChange`.
|
|
20
|
+
*/
|
|
21
|
+
open?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Whether the calendar starts out open.
|
|
24
|
+
* @default false
|
|
25
|
+
*/
|
|
26
|
+
defaultOpen?: boolean;
|
|
27
|
+
/** Called when the calendar opens or closes. */
|
|
28
|
+
onOpenChange?: (open: boolean) => void;
|
|
29
|
+
/** The earliest day that can be picked or typed. */
|
|
30
|
+
min?: Date;
|
|
31
|
+
/** The latest day that can be picked or typed. */
|
|
32
|
+
max?: Date;
|
|
33
|
+
/**
|
|
34
|
+
* Days that can't be picked or typed: a date, a list of them, a range,
|
|
35
|
+
* `{ dayOfWeek: [0, 6] }` for weekends, or a function that's given a date.
|
|
36
|
+
*/
|
|
37
|
+
disabledDates?: Matcher | Matcher[];
|
|
38
|
+
/**
|
|
39
|
+
* The language of the calendar, and the order a typed date is read in.
|
|
40
|
+
* Take one from `@nuvui/date-picker/locale`.
|
|
41
|
+
* @default enUS
|
|
42
|
+
*/
|
|
43
|
+
locale?: CalendarLocale;
|
|
44
|
+
/**
|
|
45
|
+
* The day a week starts on, from 0 for Sunday. Left out, it's the
|
|
46
|
+
* locale's.
|
|
47
|
+
*/
|
|
48
|
+
weekStartsOn?: PropsBase["weekStartsOn"];
|
|
49
|
+
/**
|
|
50
|
+
* The time zone the days are in, as an IANA name such as
|
|
51
|
+
* `"Asia/Tokyo"`. Left out, it's the browser's. Dates are then handed
|
|
52
|
+
* back as `TZDate`s.
|
|
53
|
+
*/
|
|
54
|
+
timeZone?: string;
|
|
55
|
+
/**
|
|
56
|
+
* The pattern a typed date is read and written in, in date-fns' tokens.
|
|
57
|
+
* `"P"` is the locale's own short date, `MM/dd/yyyy` in the United
|
|
58
|
+
* States.
|
|
59
|
+
* @default "P"
|
|
60
|
+
*/
|
|
61
|
+
format?: string;
|
|
62
|
+
/**
|
|
63
|
+
* What the browser is told when the text isn't a date, or is one that
|
|
64
|
+
* can't be picked. It's shown when a form with the field is submitted.
|
|
65
|
+
* @default "Enter a valid date."
|
|
66
|
+
*/
|
|
67
|
+
invalidMessage?: string;
|
|
68
|
+
/**
|
|
69
|
+
* Accessible name of the button that opens the calendar. The picked date
|
|
70
|
+
* is read after it.
|
|
71
|
+
* @default "Choose date"
|
|
72
|
+
*/
|
|
73
|
+
calendarLabel?: string;
|
|
74
|
+
/**
|
|
75
|
+
* Accessible name of the calendar's panel, and the heading of the sheet
|
|
76
|
+
* it opens in on a phone.
|
|
77
|
+
* @default "Choose date"
|
|
78
|
+
*/
|
|
79
|
+
title?: string;
|
|
80
|
+
/**
|
|
81
|
+
* Accessible name of the sheet's close button.
|
|
82
|
+
* @default "Close"
|
|
83
|
+
*/
|
|
84
|
+
closeLabel?: string;
|
|
85
|
+
/**
|
|
86
|
+
* The `id` of the form the value belongs to, when the field is outside
|
|
87
|
+
* it.
|
|
88
|
+
*/
|
|
89
|
+
form?: string;
|
|
90
|
+
/**
|
|
91
|
+
* The element the calendar is rendered into. Set this when it should pick
|
|
92
|
+
* up a `data-theme` from a section of the page.
|
|
93
|
+
* @default document.body
|
|
94
|
+
*/
|
|
95
|
+
container?: Element | DocumentFragment | null;
|
|
96
|
+
}
|
|
97
|
+
export interface DatePickerOwnProps extends SharedProps {
|
|
98
|
+
/**
|
|
99
|
+
* The picked date, or `null` for none. Use it with `onValueChange`.
|
|
100
|
+
*/
|
|
101
|
+
value?: Date | null;
|
|
102
|
+
/** The date picked to begin with. */
|
|
103
|
+
defaultValue?: Date | null;
|
|
104
|
+
/** Called with the new date when one is picked or typed. */
|
|
105
|
+
onValueChange?: (date: Date | null) => void;
|
|
106
|
+
/**
|
|
107
|
+
* The name the date is submitted under, as `yyyy-MM-dd`. Without one,
|
|
108
|
+
* nothing is submitted.
|
|
109
|
+
*/
|
|
110
|
+
name?: string;
|
|
111
|
+
/**
|
|
112
|
+
* More of the calendar's own options, such as `captionLayout` and
|
|
113
|
+
* `showWeekNumber`.
|
|
114
|
+
*/
|
|
115
|
+
calendar?: DatePickerCalendarProps;
|
|
116
|
+
}
|
|
117
|
+
export interface DatePickerProps extends DatePickerOwnProps, InputProps {}
|
|
118
|
+
export declare const DatePicker: import("react").ForwardRefExoticComponent<DatePickerProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
119
|
+
export interface DateRangePickerOwnProps extends SharedProps {
|
|
120
|
+
/**
|
|
121
|
+
* The picked range, or `null` for none. Use it with `onValueChange`.
|
|
122
|
+
*/
|
|
123
|
+
value?: DateRange | null;
|
|
124
|
+
/** The range picked to begin with. */
|
|
125
|
+
defaultValue?: DateRange | null;
|
|
126
|
+
/**
|
|
127
|
+
* Called with the new range when a day is picked or typed. While only
|
|
128
|
+
* the first day has been chosen, `to` is `undefined`.
|
|
129
|
+
*/
|
|
130
|
+
onValueChange?: (range: DateRange | null) => void;
|
|
131
|
+
/**
|
|
132
|
+
* The name the first day is submitted under, as `yyyy-MM-dd`.
|
|
133
|
+
*/
|
|
134
|
+
startName?: string;
|
|
135
|
+
/** The name the last day is submitted under, as `yyyy-MM-dd`. */
|
|
136
|
+
endName?: string;
|
|
137
|
+
/**
|
|
138
|
+
* Accessible name of the field for the first day.
|
|
139
|
+
* @default "Start date"
|
|
140
|
+
*/
|
|
141
|
+
startLabel?: string;
|
|
142
|
+
/**
|
|
143
|
+
* Accessible name of the field for the last day.
|
|
144
|
+
* @default "End date"
|
|
145
|
+
*/
|
|
146
|
+
endLabel?: string;
|
|
147
|
+
/**
|
|
148
|
+
* What the browser is told when the last day comes before the first.
|
|
149
|
+
* @default "The end date is before the start date."
|
|
150
|
+
*/
|
|
151
|
+
orderMessage?: string;
|
|
152
|
+
/**
|
|
153
|
+
* How many months the calendar shows side by side. On a phone it's
|
|
154
|
+
* always one.
|
|
155
|
+
* @default 2
|
|
156
|
+
*/
|
|
157
|
+
numberOfMonths?: number;
|
|
158
|
+
/**
|
|
159
|
+
* More of the calendar's own options. `min` and `max` here are the
|
|
160
|
+
* fewest and the most days the range may span.
|
|
161
|
+
*/
|
|
162
|
+
calendar?: DateRangePickerCalendarProps;
|
|
163
|
+
}
|
|
164
|
+
export interface DateRangePickerProps extends DateRangePickerOwnProps, Omit<InputProps, "placeholder"> {
|
|
165
|
+
/** The hint in both fields. Left out, it's the pattern. */
|
|
166
|
+
placeholder?: string;
|
|
167
|
+
}
|
|
168
|
+
export declare const DateRangePicker: import("react").ForwardRefExoticComponent<DateRangePickerProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
169
|
+
//#endregion
|