@bigbinary/neeto-atoms 1.0.59 → 1.0.61
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/dist/{DataTable-BTdSpJfs.js → DataTable-DP06B8C7.js} +140 -124
- package/dist/{DataTable-BTdSpJfs.js.map → DataTable-DP06B8C7.js.map} +1 -1
- package/dist/{DatePicker-kulToqfM.js → DatePicker-mdjh5u40.js} +422 -157
- package/dist/DatePicker-mdjh5u40.js.map +1 -0
- package/dist/{Input-Bxs8n6xp.js → Input-B7twzkUr.js} +5 -3
- package/dist/Input-B7twzkUr.js.map +1 -0
- package/dist/{Pagination-C_X9kgc8.js → Pagination-BRd3WPJ_.js} +15 -4
- package/dist/Pagination-BRd3WPJ_.js.map +1 -0
- package/dist/{Select-BiyQTuiQ.js → Select-Zr8sFnAC.js} +46 -14
- package/dist/Select-Zr8sFnAC.js.map +1 -0
- package/dist/cjs/{DataTable-CCIIXb4B.js → DataTable-CXjAvPHV.js} +140 -124
- package/dist/cjs/{DataTable-CCIIXb4B.js.map → DataTable-CXjAvPHV.js.map} +1 -1
- package/dist/cjs/{DatePicker-BZd4rM2R.js → DatePicker-DpyYPJfR.js} +420 -155
- package/dist/cjs/DatePicker-DpyYPJfR.js.map +1 -0
- package/dist/cjs/{Input-BQh-GS_w.js → Input-Dwl5OhCq.js} +5 -3
- package/dist/cjs/Input-Dwl5OhCq.js.map +1 -0
- package/dist/cjs/{Pagination-DeWfLAq5.js → Pagination-8yFg8xR2.js} +15 -4
- package/dist/cjs/Pagination-8yFg8xR2.js.map +1 -0
- package/dist/cjs/{Select-DC23xcMU.js → Select-BJs-J8fs.js} +45 -13
- package/dist/cjs/Select-BJs-J8fs.js.map +1 -0
- package/dist/cjs/components/DataTable.js +1 -1
- package/dist/cjs/components/DatePicker.js +9 -9
- package/dist/cjs/components/Input.js +1 -1
- package/dist/cjs/components/Pagination.js +2 -1
- package/dist/cjs/components/Pagination.js.map +1 -1
- package/dist/cjs/components/Select.js +2 -2
- package/dist/cjs/components/index.js +15 -15
- package/dist/cjs/formik/ActionBlock.js +10 -4
- package/dist/cjs/formik/ActionBlock.js.map +1 -1
- package/dist/cjs/formik/Input.js +1 -1
- package/dist/cjs/formik/Select.js +2 -2
- package/dist/cjs/formik/index.js +3 -3
- package/dist/cjs/index.js +15 -15
- package/dist/cjs/primitives/Checkbox.js +1 -1
- package/dist/cjs/primitives/Checkbox.js.map +1 -1
- package/dist/cjs/primitives/Combobox.js +14 -2
- package/dist/cjs/primitives/Combobox.js.map +1 -1
- package/dist/cjs/primitives/RadioGroup.js +1 -1
- package/dist/cjs/primitives/RadioGroup.js.map +1 -1
- package/dist/components/DataTable/DataTable.d.ts +1 -1
- package/dist/components/DataTable/types.d.ts +1 -0
- package/dist/components/DataTable.js +1 -1
- package/dist/components/DatePicker/DatePickerField.d.ts +15 -0
- package/dist/components/DatePicker/DatePickerTrigger.d.ts +25 -0
- package/dist/components/DatePicker/RangeCalendar.d.ts +17 -0
- package/dist/components/DatePicker/types.d.ts +3 -3
- package/dist/components/DatePicker/useRangePicker.d.ts +28 -0
- package/dist/components/DatePicker/utils.d.ts +15 -0
- package/dist/components/DatePicker.js +9 -9
- package/dist/components/Input.js +1 -1
- package/dist/components/Pagination/Pagination.d.ts +5 -1
- package/dist/components/Pagination/hooks/usePaginationQueryParams.d.ts +11 -0
- package/dist/components/Pagination.js +2 -1
- package/dist/components/Pagination.js.map +1 -1
- package/dist/components/Select/MultiSelectCombobox.types.d.ts +1 -0
- package/dist/components/Select/MultiSelectDropdown.d.ts +2 -2
- package/dist/components/Select/OptionItem.d.ts +3 -2
- package/dist/components/Select/SelectCombobox.types.d.ts +2 -0
- package/dist/components/Select/hooks/useMultiSelectState.d.ts +3 -1
- package/dist/components/Select/hooks/useSelectState.d.ts +3 -1
- package/dist/components/Select/types.d.ts +7 -0
- package/dist/components/Select.js +2 -2
- package/dist/components/index.js +5 -5
- package/dist/formik/ActionBlock.js +10 -4
- package/dist/formik/ActionBlock.js.map +1 -1
- package/dist/formik/Input.js +1 -1
- package/dist/formik/Select.js +2 -2
- package/dist/formik/index.js +3 -3
- package/dist/index.js +5 -5
- package/dist/primitives/Checkbox.js +1 -1
- package/dist/primitives/Checkbox.js.map +1 -1
- package/dist/primitives/Combobox.d.ts +1 -1
- package/dist/primitives/Combobox.js +14 -2
- package/dist/primitives/Combobox.js.map +1 -1
- package/dist/primitives/RadioGroup.js +1 -1
- package/dist/primitives/RadioGroup.js.map +1 -1
- package/package.json +1 -1
- package/dist/DatePicker-kulToqfM.js.map +0 -1
- package/dist/Input-Bxs8n6xp.js.map +0 -1
- package/dist/Pagination-C_X9kgc8.js.map +0 -1
- package/dist/Select-BiyQTuiQ.js.map +0 -1
- package/dist/cjs/DatePicker-BZd4rM2R.js.map +0 -1
- package/dist/cjs/Input-BQh-GS_w.js.map +0 -1
- package/dist/cjs/Pagination-DeWfLAq5.js.map +0 -1
- package/dist/cjs/Select-DC23xcMU.js.map +0 -1
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { forwardRef,
|
|
2
|
+
import { forwardRef, useState, useCallback, useMemo, useId, useRef, useEffect } from 'react';
|
|
3
3
|
import { Calendar as Calendar$1 } from './primitives/Calendar.js';
|
|
4
|
-
import { Popover, PopoverTrigger,
|
|
5
|
-
import { Field, FieldLabel, FieldContent, FieldError, FieldDescription } from './primitives/Field.js';
|
|
4
|
+
import { PopoverAnchor, Popover, PopoverTrigger, PopoverContent } from './primitives/Popover.js';
|
|
6
5
|
import { c as cn } from './utils-BJnb9o5c.js';
|
|
7
6
|
import { u as useControlledOpen, l as isFixedWidthFormat, m as buildRangeMaskTemplate, d as buildMaskTemplate, b as useOutsideClickClose, e as useCursorRestore, T as TimePickerPanel, j as applyMask, n as dateToTimeValue } from './TimePickerPanel--KDX5QwS.js';
|
|
8
7
|
import pureDayjs from 'dayjs';
|
|
9
8
|
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
|
10
9
|
import { dayjs } from '@bigbinary/neeto-commons-frontend/utils';
|
|
11
10
|
import { Button } from './primitives/Button.js';
|
|
12
|
-
import {
|
|
13
|
-
import { C as ChevronRight } from './chevron-right-DQnrO-ek.js';
|
|
11
|
+
import { Field, FieldLabel, FieldContent, FieldError, FieldDescription } from './primitives/Field.js';
|
|
14
12
|
import { c as createLucideIcon } from './createLucideIcon-C8ycilSN.js';
|
|
15
13
|
import { X } from './x-_o2T3n6D.js';
|
|
14
|
+
import { C as ChevronLeft } from './chevron-left-BDoT8E2-.js';
|
|
15
|
+
import { C as ChevronRight } from './chevron-right-DQnrO-ek.js';
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* @license lucide-react v0.577.0 - ISC
|
|
@@ -86,6 +86,12 @@ const coerceDateValue = (value, type) => {
|
|
|
86
86
|
}
|
|
87
87
|
return toNativeDate(value);
|
|
88
88
|
};
|
|
89
|
+
const getInitialCalendarMonth = (value, defaultValue, type) => {
|
|
90
|
+
const initial = coerceDateValue(value ?? defaultValue, type);
|
|
91
|
+
if (initial instanceof Date) return initial;
|
|
92
|
+
if (Array.isArray(initial) && initial[0] instanceof Date) return initial[0];
|
|
93
|
+
return /* @__PURE__ */ new Date();
|
|
94
|
+
};
|
|
89
95
|
const normalizeToDayjsFormat = (fmt) => fmt.replace(/\byyyy\b/g, "YYYY").replace(/\byy\b/g, "YY").replace(/\bdd\b/g, "DD").replace(/\bd\b/g, "D");
|
|
90
96
|
const normalizeToDateFnsFormat = (fmt) => fmt.replace(/YYYY/g, "yyyy").replace(/YY/g, "yy").replace(/DD/g, "dd").replace(/\bD\b/g, "d");
|
|
91
97
|
const formatDate = (date, formatStr) => {
|
|
@@ -121,11 +127,7 @@ const applyTimeToDate = (date, time) => {
|
|
|
121
127
|
result.setHours(time.hours, time.minutes, time.seconds ?? 0, 0);
|
|
122
128
|
return result;
|
|
123
129
|
};
|
|
124
|
-
const
|
|
125
|
-
const dateStr = pureDayjs(date).format("YYYY-MM-DD HH:mm:ss");
|
|
126
|
-
return dayjs(dateStr).toDate();
|
|
127
|
-
};
|
|
128
|
-
const toDayjs = (date) => dayjs(date);
|
|
130
|
+
const toUserTzDayjs = (date) => dayjs(pureDayjs(date).format("YYYY-MM-DD HH:mm:ss"));
|
|
129
131
|
const getDisplayFormat = (dateFormat, timeFormat, showTime) => {
|
|
130
132
|
const fmt = showTime ? `${dateFormat} ${timeFormat}` : dateFormat;
|
|
131
133
|
return normalizeToDateFnsFormat(fmt);
|
|
@@ -180,6 +182,34 @@ const isYearDisabled = (yearDate, minDate, maxDate) => {
|
|
|
180
182
|
};
|
|
181
183
|
const buildMonth = (year, month) => new Date(year, month, 1);
|
|
182
184
|
const isSameMonth = (a, b) => !!a && a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth();
|
|
185
|
+
const isSameDay = (a, b) => !!a && !!b && a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
186
|
+
const orderRange = (from, to) => {
|
|
187
|
+
if (from && to && from.getTime() > to.getTime()) return [to, from];
|
|
188
|
+
return [from, to];
|
|
189
|
+
};
|
|
190
|
+
const parseGridcellDay = (target) => {
|
|
191
|
+
const el = target;
|
|
192
|
+
const cell = el?.closest('[role="gridcell"][data-day]');
|
|
193
|
+
const dayAttr = cell?.getAttribute("data-day");
|
|
194
|
+
if (!dayAttr) return null;
|
|
195
|
+
const parsed = new Date(dayAttr);
|
|
196
|
+
return Number.isNaN(parsed.getTime()) ? null : parsed;
|
|
197
|
+
};
|
|
198
|
+
const computeRangePreview = ({
|
|
199
|
+
pendingRange,
|
|
200
|
+
committed,
|
|
201
|
+
hoveredDate,
|
|
202
|
+
rangeStep
|
|
203
|
+
}) => {
|
|
204
|
+
let from = pendingRange ? pendingRange[0] : committed?.[0] ?? null;
|
|
205
|
+
let to = pendingRange ? pendingRange[1] : committed?.[1] ?? null;
|
|
206
|
+
if (hoveredDate) {
|
|
207
|
+
if (rangeStep === "from") from = hoveredDate;
|
|
208
|
+
else if (!isSameDay(from, hoveredDate)) to = hoveredDate;
|
|
209
|
+
}
|
|
210
|
+
[from, to] = orderRange(from, to);
|
|
211
|
+
return { from, to };
|
|
212
|
+
};
|
|
183
213
|
const decadeStartFor = (year) => Math.floor(year / 10) * 10;
|
|
184
214
|
|
|
185
215
|
const TIMEZONE_OPTIONS = [
|
|
@@ -243,6 +273,136 @@ const DatePickerFooter = ({
|
|
|
243
273
|
};
|
|
244
274
|
DatePickerFooter.displayName = "DatePickerFooter";
|
|
245
275
|
|
|
276
|
+
const DatePickerField = forwardRef(
|
|
277
|
+
({
|
|
278
|
+
disabled,
|
|
279
|
+
error,
|
|
280
|
+
className,
|
|
281
|
+
label,
|
|
282
|
+
required,
|
|
283
|
+
helpText,
|
|
284
|
+
labelProps,
|
|
285
|
+
errorId,
|
|
286
|
+
helpTextId,
|
|
287
|
+
children
|
|
288
|
+
}, ref) => /* @__PURE__ */ jsxs(
|
|
289
|
+
Field,
|
|
290
|
+
{
|
|
291
|
+
ref,
|
|
292
|
+
"data-disabled": disabled || void 0,
|
|
293
|
+
"data-invalid": !!error || void 0,
|
|
294
|
+
className,
|
|
295
|
+
children: [
|
|
296
|
+
label && /* @__PURE__ */ jsxs(
|
|
297
|
+
FieldLabel,
|
|
298
|
+
{
|
|
299
|
+
...labelProps,
|
|
300
|
+
children: [
|
|
301
|
+
label,
|
|
302
|
+
required && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "text-destructive", children: "*" })
|
|
303
|
+
]
|
|
304
|
+
}
|
|
305
|
+
),
|
|
306
|
+
/* @__PURE__ */ jsxs(FieldContent, { children: [
|
|
307
|
+
children,
|
|
308
|
+
!!error && /* @__PURE__ */ jsx(FieldError, { id: errorId, children: error }),
|
|
309
|
+
helpText && /* @__PURE__ */ jsx(FieldDescription, { id: helpTextId, children: helpText })
|
|
310
|
+
] })
|
|
311
|
+
]
|
|
312
|
+
}
|
|
313
|
+
)
|
|
314
|
+
);
|
|
315
|
+
DatePickerField.displayName = "DatePickerField";
|
|
316
|
+
|
|
317
|
+
const DatePickerTrigger = forwardRef(
|
|
318
|
+
({
|
|
319
|
+
containerRef,
|
|
320
|
+
inputRef,
|
|
321
|
+
disabled,
|
|
322
|
+
error,
|
|
323
|
+
hasField,
|
|
324
|
+
className,
|
|
325
|
+
triggerSizeClass,
|
|
326
|
+
inputSizeClass,
|
|
327
|
+
iconSizeClass,
|
|
328
|
+
label,
|
|
329
|
+
ariaDescribedBy,
|
|
330
|
+
placeholder,
|
|
331
|
+
inputText,
|
|
332
|
+
allowClear,
|
|
333
|
+
timezone,
|
|
334
|
+
onInputChange,
|
|
335
|
+
onInputKeyDown,
|
|
336
|
+
onInputFocus,
|
|
337
|
+
onInputBlur,
|
|
338
|
+
onClear
|
|
339
|
+
}, _ref) => /* @__PURE__ */ jsx(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
340
|
+
"div",
|
|
341
|
+
{
|
|
342
|
+
ref: containerRef,
|
|
343
|
+
className: cn(
|
|
344
|
+
"relative flex w-full cursor-text items-center gap-2 rounded-md border border-input bg-background pe-8 ps-3",
|
|
345
|
+
"focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2",
|
|
346
|
+
disabled && "cursor-not-allowed opacity-50",
|
|
347
|
+
!!error && "border-destructive ring-destructive/20 ring-3",
|
|
348
|
+
triggerSizeClass,
|
|
349
|
+
!hasField && className
|
|
350
|
+
),
|
|
351
|
+
onClick: () => {
|
|
352
|
+
if (disabled) return;
|
|
353
|
+
inputRef.current?.focus();
|
|
354
|
+
},
|
|
355
|
+
children: [
|
|
356
|
+
/* @__PURE__ */ jsx(
|
|
357
|
+
Calendar,
|
|
358
|
+
{
|
|
359
|
+
className: cn("shrink-0 text-muted-foreground", iconSizeClass)
|
|
360
|
+
}
|
|
361
|
+
),
|
|
362
|
+
/* @__PURE__ */ jsx(
|
|
363
|
+
"input",
|
|
364
|
+
{
|
|
365
|
+
ref: inputRef,
|
|
366
|
+
type: "text",
|
|
367
|
+
disabled,
|
|
368
|
+
"aria-label": label || "Pick a date",
|
|
369
|
+
"aria-describedby": ariaDescribedBy,
|
|
370
|
+
"aria-invalid": !!error || void 0,
|
|
371
|
+
placeholder,
|
|
372
|
+
value: inputText,
|
|
373
|
+
onChange: onInputChange,
|
|
374
|
+
onKeyDown: onInputKeyDown,
|
|
375
|
+
onFocus: onInputFocus,
|
|
376
|
+
onBlur: onInputBlur,
|
|
377
|
+
className: cn(
|
|
378
|
+
"min-w-0 flex-1 bg-transparent outline-none placeholder:text-muted-foreground",
|
|
379
|
+
"disabled:cursor-not-allowed",
|
|
380
|
+
inputSizeClass
|
|
381
|
+
)
|
|
382
|
+
}
|
|
383
|
+
),
|
|
384
|
+
timezone && /* @__PURE__ */ jsx("span", { className: "shrink-0 rounded bg-muted px-1.5 py-0.5 text-xs text-muted-foreground", children: timezone.toUpperCase() }),
|
|
385
|
+
allowClear && /* @__PURE__ */ jsx(
|
|
386
|
+
"button",
|
|
387
|
+
{
|
|
388
|
+
type: "button",
|
|
389
|
+
onPointerDown: (e) => e.preventDefault(),
|
|
390
|
+
onClick: onClear,
|
|
391
|
+
className: cn(
|
|
392
|
+
"absolute inset-y-0 end-2 flex items-center text-muted-foreground hover:text-foreground focus:outline-none",
|
|
393
|
+
!(inputText && !disabled) && "invisible"
|
|
394
|
+
),
|
|
395
|
+
"aria-label": "Clear date",
|
|
396
|
+
tabIndex: -1,
|
|
397
|
+
children: /* @__PURE__ */ jsx(X, { className: iconSizeClass })
|
|
398
|
+
}
|
|
399
|
+
)
|
|
400
|
+
]
|
|
401
|
+
}
|
|
402
|
+
) })
|
|
403
|
+
);
|
|
404
|
+
DatePickerTrigger.displayName = "DatePickerTrigger";
|
|
405
|
+
|
|
246
406
|
const MonthPicker = ({
|
|
247
407
|
value,
|
|
248
408
|
displayedYear,
|
|
@@ -303,6 +463,129 @@ const MonthPicker = ({
|
|
|
303
463
|
] });
|
|
304
464
|
};
|
|
305
465
|
|
|
466
|
+
const RangeCalendar = ({
|
|
467
|
+
todayDate,
|
|
468
|
+
weekStartsOn,
|
|
469
|
+
month,
|
|
470
|
+
onMonthChange,
|
|
471
|
+
selected,
|
|
472
|
+
onSelect,
|
|
473
|
+
disabled,
|
|
474
|
+
fromDate,
|
|
475
|
+
toDate,
|
|
476
|
+
onHoverIn,
|
|
477
|
+
onHoverOut
|
|
478
|
+
}) => /* @__PURE__ */ jsx("div", { onMouseOver: onHoverIn, onMouseLeave: onHoverOut, children: /* @__PURE__ */ jsx(
|
|
479
|
+
Calendar$1,
|
|
480
|
+
{
|
|
481
|
+
mode: "range",
|
|
482
|
+
numberOfMonths: 2,
|
|
483
|
+
captionLayout: "dropdown",
|
|
484
|
+
today: todayDate,
|
|
485
|
+
weekStartsOn,
|
|
486
|
+
className: "[&_[data-outside][data-selected=true]]:!bg-transparent [&_[data-outside][data-selected=true]]:after:!bg-transparent [&_[data-outside]_button]:!bg-transparent [&_[data-outside]_button]:!text-muted-foreground",
|
|
487
|
+
month,
|
|
488
|
+
onMonthChange,
|
|
489
|
+
selected,
|
|
490
|
+
onSelect,
|
|
491
|
+
disabled,
|
|
492
|
+
...fromDate && { fromDate },
|
|
493
|
+
...toDate && { toDate }
|
|
494
|
+
}
|
|
495
|
+
) });
|
|
496
|
+
|
|
497
|
+
const useRangePicker = ({
|
|
498
|
+
currentValue,
|
|
499
|
+
showTime,
|
|
500
|
+
needConfirm,
|
|
501
|
+
commitValue,
|
|
502
|
+
setPendingDate,
|
|
503
|
+
setOpen
|
|
504
|
+
}) => {
|
|
505
|
+
const [pendingRange, setPendingRange] = useState(null);
|
|
506
|
+
const [rangeSelectionStep, setRangeSelectionStep] = useState(
|
|
507
|
+
"from"
|
|
508
|
+
);
|
|
509
|
+
const [hoveredDate, setHoveredDate] = useState(null);
|
|
510
|
+
const committed = currentValue ?? null;
|
|
511
|
+
const resetTransientState = useCallback(() => {
|
|
512
|
+
setPendingRange(null);
|
|
513
|
+
setRangeSelectionStep("from");
|
|
514
|
+
setHoveredDate(null);
|
|
515
|
+
}, []);
|
|
516
|
+
const handleRangeSelect = useCallback(
|
|
517
|
+
(_range, triggerDate) => {
|
|
518
|
+
if (!triggerDate) return;
|
|
519
|
+
if (rangeSelectionStep === "from" || !pendingRange?.[0]) {
|
|
520
|
+
const existingTo = pendingRange?.[1] ?? committed?.[1] ?? null;
|
|
521
|
+
const nextTo = existingTo && triggerDate <= existingTo ? existingTo : null;
|
|
522
|
+
setPendingRange([triggerDate, nextTo]);
|
|
523
|
+
setRangeSelectionStep("to");
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
const [from, to] = orderRange(pendingRange[0], triggerDate);
|
|
527
|
+
setRangeSelectionStep("from");
|
|
528
|
+
setPendingRange(null);
|
|
529
|
+
if (showTime || needConfirm) {
|
|
530
|
+
setPendingDate(from);
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
commitValue([from, to]);
|
|
534
|
+
setOpen(false);
|
|
535
|
+
},
|
|
536
|
+
[
|
|
537
|
+
rangeSelectionStep,
|
|
538
|
+
pendingRange,
|
|
539
|
+
committed,
|
|
540
|
+
showTime,
|
|
541
|
+
needConfirm,
|
|
542
|
+
commitValue,
|
|
543
|
+
setPendingDate,
|
|
544
|
+
setOpen
|
|
545
|
+
]
|
|
546
|
+
);
|
|
547
|
+
const handleHoverIn = useCallback(
|
|
548
|
+
(e) => {
|
|
549
|
+
const parsed = parseGridcellDay(e.target);
|
|
550
|
+
if (!parsed) return;
|
|
551
|
+
if (hoveredDate && hoveredDate.getTime() === parsed.getTime()) return;
|
|
552
|
+
setHoveredDate(parsed);
|
|
553
|
+
},
|
|
554
|
+
[hoveredDate]
|
|
555
|
+
);
|
|
556
|
+
const handleHoverOut = useCallback(() => setHoveredDate(null), []);
|
|
557
|
+
const memoizedRangeSelected = useMemo(() => {
|
|
558
|
+
const { from, to } = computeRangePreview({
|
|
559
|
+
pendingRange,
|
|
560
|
+
committed,
|
|
561
|
+
hoveredDate,
|
|
562
|
+
rangeStep: rangeSelectionStep
|
|
563
|
+
});
|
|
564
|
+
if (!from && !to) return void 0;
|
|
565
|
+
return { from: from ?? void 0, to: to ?? void 0 };
|
|
566
|
+
}, [pendingRange, committed, hoveredDate, rangeSelectionStep]);
|
|
567
|
+
const getPreviewParts = useCallback(
|
|
568
|
+
() => computeRangePreview({
|
|
569
|
+
pendingRange,
|
|
570
|
+
committed,
|
|
571
|
+
hoveredDate,
|
|
572
|
+
rangeStep: rangeSelectionStep
|
|
573
|
+
}),
|
|
574
|
+
[pendingRange, committed, hoveredDate, rangeSelectionStep]
|
|
575
|
+
);
|
|
576
|
+
return {
|
|
577
|
+
pendingRange,
|
|
578
|
+
rangeSelectionStep,
|
|
579
|
+
hoveredDate,
|
|
580
|
+
handleRangeSelect,
|
|
581
|
+
handleHoverIn,
|
|
582
|
+
handleHoverOut,
|
|
583
|
+
memoizedRangeSelected,
|
|
584
|
+
getPreviewParts,
|
|
585
|
+
resetTransientState
|
|
586
|
+
};
|
|
587
|
+
};
|
|
588
|
+
|
|
306
589
|
const YearPicker = ({
|
|
307
590
|
value,
|
|
308
591
|
displayedYear,
|
|
@@ -418,14 +701,22 @@ const DatePicker = forwardRef(
|
|
|
418
701
|
coerceDateValue(defaultValue, type) ?? null
|
|
419
702
|
);
|
|
420
703
|
const [calendarMonth, setCalendarMonth] = useState(
|
|
421
|
-
(
|
|
422
|
-
);
|
|
423
|
-
const [rangeSelectionStep, setRangeSelectionStep] = useState(
|
|
424
|
-
"from"
|
|
704
|
+
() => getInitialCalendarMonth(value, defaultValue, type)
|
|
425
705
|
);
|
|
426
706
|
const [pendingDate, setPendingDate] = useState(null);
|
|
427
707
|
const [pendingTime, setPendingTime] = useState(INITIAL_TIME_VALUE);
|
|
428
|
-
const currentValue =
|
|
708
|
+
const currentValue = useMemo(
|
|
709
|
+
() => value !== void 0 ? coerceDateValue(value, type) : internalValue,
|
|
710
|
+
[value, type, internalValue]
|
|
711
|
+
);
|
|
712
|
+
const normalizedMinDate = useMemo(
|
|
713
|
+
() => toNativeDate(minDate) ?? void 0,
|
|
714
|
+
[minDate]
|
|
715
|
+
);
|
|
716
|
+
const normalizedMaxDate = useMemo(
|
|
717
|
+
() => toNativeDate(maxDate) ?? void 0,
|
|
718
|
+
[maxDate]
|
|
719
|
+
);
|
|
429
720
|
const displayFormat = getDisplayFormat(dateFormat, timeFormat, showTime);
|
|
430
721
|
const sizeConfig = SIZE_CONFIG[size];
|
|
431
722
|
const maskEnabled = isFixedWidthFormat(displayFormat);
|
|
@@ -446,13 +737,13 @@ const DatePicker = forwardRef(
|
|
|
446
737
|
const calendarDisabled = useCallback(
|
|
447
738
|
(date) => {
|
|
448
739
|
if (disabledDate?.(date)) return true;
|
|
449
|
-
if (
|
|
740
|
+
if (normalizedMinDate && date < new Date(new Date(normalizedMinDate).setHours(0, 0, 0, 0)))
|
|
450
741
|
return true;
|
|
451
|
-
if (
|
|
742
|
+
if (normalizedMaxDate && date > new Date(new Date(normalizedMaxDate).setHours(23, 59, 59, 999)))
|
|
452
743
|
return true;
|
|
453
744
|
return false;
|
|
454
745
|
},
|
|
455
|
-
[
|
|
746
|
+
[normalizedMinDate, normalizedMaxDate, disabledDate]
|
|
456
747
|
);
|
|
457
748
|
const getDisplayText = useCallback(() => {
|
|
458
749
|
if (type !== "range") {
|
|
@@ -468,36 +759,73 @@ const DatePicker = forwardRef(
|
|
|
468
759
|
const commitValue = (date) => {
|
|
469
760
|
if (date === null) {
|
|
470
761
|
setInternalValue(null);
|
|
471
|
-
|
|
762
|
+
if (type === "range") {
|
|
763
|
+
onChange?.([null, null], ["", ""]);
|
|
764
|
+
} else {
|
|
765
|
+
onChange?.(null, "");
|
|
766
|
+
}
|
|
472
767
|
setInputText("");
|
|
473
768
|
return;
|
|
474
769
|
}
|
|
770
|
+
const toSerializableDayjs = (d) => {
|
|
771
|
+
const userTzDayjs = toUserTzDayjs(d);
|
|
772
|
+
if (showTime) return userTzDayjs;
|
|
773
|
+
return userTzDayjs.hour(12).minute(0).second(0).millisecond(0);
|
|
774
|
+
};
|
|
475
775
|
if (Array.isArray(date)) {
|
|
476
776
|
setInternalValue(date);
|
|
477
|
-
const converted2 = [
|
|
478
|
-
applyTimezone(date[0]),
|
|
479
|
-
applyTimezone(date[1])
|
|
480
|
-
];
|
|
481
777
|
const formatted2 = [
|
|
482
778
|
formatDate(date[0], displayFormat),
|
|
483
779
|
formatDate(date[1], displayFormat)
|
|
484
780
|
];
|
|
485
|
-
onChange?.(
|
|
781
|
+
onChange?.(
|
|
782
|
+
[toSerializableDayjs(date[0]), toSerializableDayjs(date[1])],
|
|
783
|
+
formatted2
|
|
784
|
+
);
|
|
486
785
|
setInputText(`${formatted2[0]} - ${formatted2[1]}`);
|
|
487
786
|
return;
|
|
488
787
|
}
|
|
489
788
|
setInternalValue(date);
|
|
490
|
-
const converted = applyTimezone(date);
|
|
491
789
|
const formatted = formatDate(date, displayFormat);
|
|
492
|
-
onChange?.(
|
|
790
|
+
onChange?.(toSerializableDayjs(date), formatted);
|
|
493
791
|
setInputText(formatted);
|
|
494
792
|
};
|
|
495
|
-
const
|
|
793
|
+
const {
|
|
794
|
+
pendingRange,
|
|
795
|
+
handleRangeSelect,
|
|
796
|
+
handleHoverIn,
|
|
797
|
+
handleHoverOut,
|
|
798
|
+
memoizedRangeSelected,
|
|
799
|
+
getPreviewParts,
|
|
800
|
+
resetTransientState
|
|
801
|
+
} = useRangePicker({
|
|
802
|
+
currentValue,
|
|
803
|
+
showTime,
|
|
804
|
+
needConfirm,
|
|
805
|
+
commitValue,
|
|
806
|
+
setPendingDate,
|
|
807
|
+
setOpen
|
|
808
|
+
});
|
|
809
|
+
useEffect(() => {
|
|
810
|
+
if (type !== "range" || !open) return;
|
|
811
|
+
const { from, to } = getPreviewParts();
|
|
812
|
+
const fromText = from ? formatDate(from, displayFormat) : "";
|
|
813
|
+
const toText = to ? formatDate(to, displayFormat) : "";
|
|
814
|
+
setInputText(fromText || toText ? `${fromText} - ${toText}` : "");
|
|
815
|
+
}, [type, open, getPreviewParts, displayFormat]);
|
|
816
|
+
const parseAndApplyRange = (text, cursorPos) => {
|
|
496
817
|
const parts = text.split(" - ");
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
818
|
+
const separatorIdx = text.indexOf(" - ");
|
|
819
|
+
const editingTo = separatorIdx >= 0 && cursorPos !== null && cursorPos > separatorIdx + 2;
|
|
820
|
+
if (editingTo) {
|
|
821
|
+
const to = parseDate(parts[1] ?? "", displayFormat);
|
|
822
|
+
if (to) setCalendarMonth(to);
|
|
823
|
+
} else {
|
|
824
|
+
if (!isDatePartComplete(parts[0] ?? "", maskEnabled, singleDateLen))
|
|
825
|
+
return;
|
|
826
|
+
const from = parseDate(parts[0] ?? "", displayFormat);
|
|
827
|
+
if (from) setCalendarMonth(from);
|
|
828
|
+
}
|
|
501
829
|
const range = parseRangeText(
|
|
502
830
|
text,
|
|
503
831
|
displayFormat,
|
|
@@ -531,9 +859,20 @@ const DatePicker = forwardRef(
|
|
|
531
859
|
onChange
|
|
532
860
|
]);
|
|
533
861
|
const closePopover = useCallback(() => {
|
|
534
|
-
|
|
862
|
+
if (type === "range" && pendingRange?.[0] && pendingRange?.[1]) {
|
|
863
|
+
commitValue([pendingRange[0], pendingRange[1]]);
|
|
864
|
+
} else {
|
|
865
|
+
commitPendingOnClose();
|
|
866
|
+
}
|
|
867
|
+
resetTransientState();
|
|
535
868
|
setOpen(false);
|
|
536
|
-
}, [
|
|
869
|
+
}, [
|
|
870
|
+
commitPendingOnClose,
|
|
871
|
+
setOpen,
|
|
872
|
+
type,
|
|
873
|
+
pendingRange,
|
|
874
|
+
resetTransientState
|
|
875
|
+
]);
|
|
537
876
|
useOutsideClickClose({
|
|
538
877
|
enabled: open,
|
|
539
878
|
containerRef,
|
|
@@ -542,7 +881,7 @@ const DatePicker = forwardRef(
|
|
|
542
881
|
});
|
|
543
882
|
const openPopover = () => {
|
|
544
883
|
setOpen(true);
|
|
545
|
-
|
|
884
|
+
resetTransientState();
|
|
546
885
|
const dateVal = type === "date" ? currentValue : null;
|
|
547
886
|
if (!dateVal) {
|
|
548
887
|
setPendingDate(null);
|
|
@@ -563,27 +902,6 @@ const DatePicker = forwardRef(
|
|
|
563
902
|
commitValue(selected);
|
|
564
903
|
setOpen(false);
|
|
565
904
|
};
|
|
566
|
-
const handleRangeSelect = (range) => {
|
|
567
|
-
if (!range) return;
|
|
568
|
-
const from = range.from ?? null;
|
|
569
|
-
const to = range.to ?? null;
|
|
570
|
-
if (rangeSelectionStep === "from") {
|
|
571
|
-
setInternalValue([from, null]);
|
|
572
|
-
setRangeSelectionStep("to");
|
|
573
|
-
return;
|
|
574
|
-
}
|
|
575
|
-
setRangeSelectionStep("from");
|
|
576
|
-
if (from && to) {
|
|
577
|
-
if (showTime || needConfirm) {
|
|
578
|
-
setPendingDate(from);
|
|
579
|
-
return;
|
|
580
|
-
}
|
|
581
|
-
commitValue([from, to]);
|
|
582
|
-
setOpen(false);
|
|
583
|
-
return;
|
|
584
|
-
}
|
|
585
|
-
if (from) setInternalValue([from, null]);
|
|
586
|
-
};
|
|
587
905
|
const handleNow = () => {
|
|
588
906
|
const now = toBrowserLocalDate(/* @__PURE__ */ new Date());
|
|
589
907
|
if (showTime || needConfirm) {
|
|
@@ -621,7 +939,7 @@ const DatePicker = forwardRef(
|
|
|
621
939
|
}
|
|
622
940
|
setInputText(text);
|
|
623
941
|
if (type === "range") {
|
|
624
|
-
parseAndApplyRange(text);
|
|
942
|
+
parseAndApplyRange(text, e.target.selectionStart);
|
|
625
943
|
return;
|
|
626
944
|
}
|
|
627
945
|
const isComplete = maskTemplate ? text.length >= maskTemplate.pattern.length : true;
|
|
@@ -712,71 +1030,33 @@ const DatePicker = forwardRef(
|
|
|
712
1030
|
return currentValue ?? void 0;
|
|
713
1031
|
};
|
|
714
1032
|
const triggerContent = /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: trigger ? setOpen : void 0, children: [
|
|
715
|
-
trigger ? /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: trigger }) : /* @__PURE__ */ jsx(
|
|
716
|
-
|
|
1033
|
+
trigger ? /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: trigger }) : /* @__PURE__ */ jsx(
|
|
1034
|
+
DatePickerTrigger,
|
|
717
1035
|
{
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
)
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
ref: inputRef,
|
|
741
|
-
type: "text",
|
|
742
|
-
disabled,
|
|
743
|
-
"aria-label": label || "Pick a date",
|
|
744
|
-
"aria-describedby": ariaDescribedBy,
|
|
745
|
-
"aria-invalid": !!error || void 0,
|
|
746
|
-
placeholder: placeholder ?? defaultPlaceholder,
|
|
747
|
-
value: inputText,
|
|
748
|
-
onChange: handleInputChange,
|
|
749
|
-
onKeyDown: handleInputKeyDown,
|
|
750
|
-
onFocus: () => {
|
|
751
|
-
if (!open) openPopover();
|
|
752
|
-
},
|
|
753
|
-
onBlur: handleInputBlur,
|
|
754
|
-
className: cn(
|
|
755
|
-
"min-w-0 flex-1 bg-transparent outline-none placeholder:text-muted-foreground",
|
|
756
|
-
"disabled:cursor-not-allowed",
|
|
757
|
-
sizeConfig.input
|
|
758
|
-
)
|
|
759
|
-
}
|
|
760
|
-
),
|
|
761
|
-
timezone && /* @__PURE__ */ jsx("span", { className: "shrink-0 rounded bg-muted px-1.5 py-0.5 text-xs text-muted-foreground", children: timezone.toUpperCase() }),
|
|
762
|
-
allowClear && /* @__PURE__ */ jsx(
|
|
763
|
-
"button",
|
|
764
|
-
{
|
|
765
|
-
type: "button",
|
|
766
|
-
onPointerDown: (e) => e.preventDefault(),
|
|
767
|
-
onClick: handleClear,
|
|
768
|
-
className: cn(
|
|
769
|
-
"absolute inset-y-0 end-2 flex items-center text-muted-foreground hover:text-foreground focus:outline-none",
|
|
770
|
-
!(inputText && !disabled) && "invisible"
|
|
771
|
-
),
|
|
772
|
-
"aria-label": "Clear date",
|
|
773
|
-
tabIndex: -1,
|
|
774
|
-
children: /* @__PURE__ */ jsx(X, { className: sizeConfig.icon })
|
|
775
|
-
}
|
|
776
|
-
)
|
|
777
|
-
]
|
|
1036
|
+
containerRef,
|
|
1037
|
+
inputRef,
|
|
1038
|
+
disabled,
|
|
1039
|
+
error,
|
|
1040
|
+
hasField,
|
|
1041
|
+
className,
|
|
1042
|
+
triggerSizeClass: sizeConfig.trigger,
|
|
1043
|
+
inputSizeClass: sizeConfig.input,
|
|
1044
|
+
iconSizeClass: sizeConfig.icon,
|
|
1045
|
+
label,
|
|
1046
|
+
ariaDescribedBy,
|
|
1047
|
+
placeholder: placeholder ?? defaultPlaceholder,
|
|
1048
|
+
inputText,
|
|
1049
|
+
allowClear,
|
|
1050
|
+
timezone,
|
|
1051
|
+
onInputChange: handleInputChange,
|
|
1052
|
+
onInputKeyDown: handleInputKeyDown,
|
|
1053
|
+
onInputFocus: () => {
|
|
1054
|
+
if (!open) openPopover();
|
|
1055
|
+
},
|
|
1056
|
+
onInputBlur: handleInputBlur,
|
|
1057
|
+
onClear: handleClear
|
|
778
1058
|
}
|
|
779
|
-
)
|
|
1059
|
+
),
|
|
780
1060
|
open && /* @__PURE__ */ jsxs(
|
|
781
1061
|
PopoverContent,
|
|
782
1062
|
{
|
|
@@ -799,7 +1079,7 @@ const DatePicker = forwardRef(
|
|
|
799
1079
|
new Date(year, calendarMonth.getMonth(), 1)
|
|
800
1080
|
),
|
|
801
1081
|
onSelect: handleGridPickerSelect,
|
|
802
|
-
isDisabled: (date) => isMonthDisabled(date,
|
|
1082
|
+
isDisabled: (date) => isMonthDisabled(date, normalizedMinDate, normalizedMaxDate)
|
|
803
1083
|
}
|
|
804
1084
|
) : type === "date" && picker === "year" ? /* @__PURE__ */ jsx(
|
|
805
1085
|
YearPicker,
|
|
@@ -808,7 +1088,7 @@ const DatePicker = forwardRef(
|
|
|
808
1088
|
displayedYear: calendarMonth.getFullYear(),
|
|
809
1089
|
onYearChange: (year) => setCalendarMonth(new Date(year, 0, 1)),
|
|
810
1090
|
onSelect: handleGridPickerSelect,
|
|
811
|
-
isDisabled: (date) => isYearDisabled(date,
|
|
1091
|
+
isDisabled: (date) => isYearDisabled(date, normalizedMinDate, normalizedMaxDate)
|
|
812
1092
|
}
|
|
813
1093
|
) : type === "date" ? /* @__PURE__ */ jsx(
|
|
814
1094
|
Calendar$1,
|
|
@@ -824,28 +1104,23 @@ const DatePicker = forwardRef(
|
|
|
824
1104
|
weekStartsOn,
|
|
825
1105
|
classNames: weekRowHoverClassName ? { week: cn("mt-2 flex w-full", weekRowHoverClassName) } : void 0,
|
|
826
1106
|
...weekHighlightProps,
|
|
827
|
-
...
|
|
828
|
-
...
|
|
1107
|
+
...normalizedMinDate && { fromDate: normalizedMinDate },
|
|
1108
|
+
...normalizedMaxDate && { toDate: normalizedMaxDate }
|
|
829
1109
|
}
|
|
830
1110
|
) : /* @__PURE__ */ jsx(
|
|
831
|
-
|
|
1111
|
+
RangeCalendar,
|
|
832
1112
|
{
|
|
833
|
-
|
|
834
|
-
numberOfMonths: 2,
|
|
835
|
-
captionLayout: "dropdown",
|
|
836
|
-
today: todayDate,
|
|
1113
|
+
todayDate,
|
|
837
1114
|
weekStartsOn,
|
|
838
|
-
className: "[&_[data-outside][data-selected=true]]:!bg-transparent [&_[data-outside][data-selected=true]]:after:!bg-transparent [&_[data-outside]_button]:!bg-transparent [&_[data-outside]_button]:!text-muted-foreground",
|
|
839
1115
|
month: calendarMonth,
|
|
840
1116
|
onMonthChange: setCalendarMonth,
|
|
841
|
-
selected:
|
|
842
|
-
from: currentValue[0] ?? void 0,
|
|
843
|
-
to: currentValue[1] ?? void 0
|
|
844
|
-
} : void 0,
|
|
1117
|
+
selected: memoizedRangeSelected,
|
|
845
1118
|
onSelect: handleRangeSelect,
|
|
846
1119
|
disabled: calendarDisabled,
|
|
847
|
-
|
|
848
|
-
|
|
1120
|
+
fromDate: normalizedMinDate,
|
|
1121
|
+
toDate: normalizedMaxDate,
|
|
1122
|
+
onHoverIn: handleHoverIn,
|
|
1123
|
+
onHoverOut: handleHoverOut
|
|
849
1124
|
}
|
|
850
1125
|
),
|
|
851
1126
|
showTime && /* @__PURE__ */ jsx("div", { className: "border-inline-start border-border", children: /* @__PURE__ */ jsx(
|
|
@@ -877,30 +1152,20 @@ const DatePicker = forwardRef(
|
|
|
877
1152
|
if (!hasField) {
|
|
878
1153
|
return /* @__PURE__ */ jsx("div", { ref, className, children: triggerContent });
|
|
879
1154
|
}
|
|
880
|
-
return /* @__PURE__ */
|
|
881
|
-
|
|
1155
|
+
return /* @__PURE__ */ jsx(
|
|
1156
|
+
DatePickerField,
|
|
882
1157
|
{
|
|
883
1158
|
ref,
|
|
884
|
-
|
|
885
|
-
|
|
1159
|
+
disabled,
|
|
1160
|
+
error,
|
|
886
1161
|
className,
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
required && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "text-destructive", children: "*" })
|
|
895
|
-
]
|
|
896
|
-
}
|
|
897
|
-
),
|
|
898
|
-
/* @__PURE__ */ jsxs(FieldContent, { children: [
|
|
899
|
-
triggerContent,
|
|
900
|
-
!!error && /* @__PURE__ */ jsx(FieldError, { id: errorId, children: error }),
|
|
901
|
-
helpText && /* @__PURE__ */ jsx(FieldDescription, { id: helpTextId, children: helpText })
|
|
902
|
-
] })
|
|
903
|
-
]
|
|
1162
|
+
label,
|
|
1163
|
+
required,
|
|
1164
|
+
helpText,
|
|
1165
|
+
labelProps,
|
|
1166
|
+
errorId,
|
|
1167
|
+
helpTextId,
|
|
1168
|
+
children: triggerContent
|
|
904
1169
|
}
|
|
905
1170
|
);
|
|
906
1171
|
}
|
|
@@ -908,4 +1173,4 @@ const DatePicker = forwardRef(
|
|
|
908
1173
|
DatePicker.displayName = "DatePicker";
|
|
909
1174
|
|
|
910
1175
|
export { DatePicker as D };
|
|
911
|
-
//# sourceMappingURL=DatePicker-
|
|
1176
|
+
//# sourceMappingURL=DatePicker-mdjh5u40.js.map
|