@kalyx/react 1.0.0-rc.6 → 1.0.0-rc.8
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 +79 -0
- package/dist/index.cjs +210 -116
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +39 -3
- package/dist/index.d.ts +39 -3
- package/dist/index.js +211 -117
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -82,13 +82,28 @@ interface DatePickerCalendarClassNames {
|
|
|
82
82
|
dayDisabled?: string;
|
|
83
83
|
dayOutsideMonth?: string;
|
|
84
84
|
weekdayHeader?: string;
|
|
85
|
+
/** Header cell at the top of the week-number column. Rendered only when `showWeekNumber` is set. */
|
|
86
|
+
weekNumberHeader?: string;
|
|
87
|
+
/** Each row's week-number cell. Rendered only when `showWeekNumber` is set. */
|
|
88
|
+
weekNumber?: string;
|
|
85
89
|
}
|
|
86
90
|
interface DatePickerCalendarProps extends Omit<HTMLAttributes<HTMLDivElement>, 'role'> {
|
|
87
91
|
classNames?: DatePickerCalendarClassNames;
|
|
88
92
|
/** Called when the title ("January 2026") is clicked. Useful for switching to Month/Year views. */
|
|
89
93
|
onTitleClick?: () => void;
|
|
94
|
+
/**
|
|
95
|
+
* Render an ISO 8601 week-number column on the left of the grid (1–53).
|
|
96
|
+
* The column is a `<th scope="row">`; it doesn't participate in the WAI-ARIA grid
|
|
97
|
+
* data region, so keyboard navigation across the date cells is unaffected.
|
|
98
|
+
*/
|
|
99
|
+
showWeekNumber?: boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Always render 6 weeks (42 cells), even when the month fits in 4 or 5 rows. Useful for
|
|
102
|
+
* popover layouts that need a fixed height across month navigation.
|
|
103
|
+
*/
|
|
104
|
+
fixedWeeks?: boolean;
|
|
90
105
|
}
|
|
91
|
-
declare function DatePickerCalendar({ classNames, onTitleClick, ...props }: DatePickerCalendarProps): react_jsx_runtime.JSX.Element;
|
|
106
|
+
declare function DatePickerCalendar({ classNames, onTitleClick, showWeekNumber, fixedWeeks, ...props }: DatePickerCalendarProps): react_jsx_runtime.JSX.Element;
|
|
92
107
|
|
|
93
108
|
interface DatePickerMonthGridClassNames {
|
|
94
109
|
root?: string;
|
|
@@ -322,6 +337,10 @@ interface RangePickerCalendarClassNames {
|
|
|
322
337
|
dayRangeEnd?: string;
|
|
323
338
|
dayInRange?: string;
|
|
324
339
|
weekdayHeader?: string;
|
|
340
|
+
/** Header cell at the top of the week-number column. Rendered only when `showWeekNumber` is set. */
|
|
341
|
+
weekNumberHeader?: string;
|
|
342
|
+
/** Each row's week-number cell. Rendered only when `showWeekNumber` is set. */
|
|
343
|
+
weekNumber?: string;
|
|
325
344
|
}
|
|
326
345
|
/**
|
|
327
346
|
* Selection mode for the calendar grid.
|
|
@@ -333,8 +352,18 @@ interface RangePickerCalendarProps extends Omit<HTMLAttributes<HTMLDivElement>,
|
|
|
333
352
|
classNames?: RangePickerCalendarClassNames;
|
|
334
353
|
/** @default 'range' */
|
|
335
354
|
selectionMode?: RangePickerCalendarSelectionMode;
|
|
355
|
+
/**
|
|
356
|
+
* Render an ISO 8601 week-number column on the left of the grid (1–53).
|
|
357
|
+
* The column is a `<th scope="row">`; it doesn't participate in the WAI-ARIA grid
|
|
358
|
+
* data region, so keyboard navigation across the date cells is unaffected.
|
|
359
|
+
*/
|
|
360
|
+
showWeekNumber?: boolean;
|
|
361
|
+
/**
|
|
362
|
+
* Always render 6 weeks (42 cells), even when the month fits in 4 or 5 rows.
|
|
363
|
+
*/
|
|
364
|
+
fixedWeeks?: boolean;
|
|
336
365
|
}
|
|
337
|
-
declare function RangePickerCalendar({ classNames, selectionMode, ...props }: RangePickerCalendarProps): react_jsx_runtime.JSX.Element;
|
|
366
|
+
declare function RangePickerCalendar({ classNames, selectionMode, showWeekNumber, fixedWeeks, ...props }: RangePickerCalendarProps): react_jsx_runtime.JSX.Element;
|
|
338
367
|
|
|
339
368
|
/** Predefined preset keys. Custom ranges are also supported. */
|
|
340
369
|
type PresetKey = 'today' | 'yesterday' | 'last7days' | 'last30days' | 'thisWeek' | 'lastWeek' | 'thisMonth' | 'lastMonth' | 'thisYear';
|
|
@@ -466,12 +495,19 @@ interface TimePickerRootProps {
|
|
|
466
495
|
disabled?: boolean;
|
|
467
496
|
/** Read-only */
|
|
468
497
|
readOnly?: boolean;
|
|
498
|
+
/**
|
|
499
|
+
* Programmatic per-slot disable predicate. Returns `true` for any `(hours, minutes)` pair
|
|
500
|
+
* that should be unselectable. Equivalent to react-datepicker's `filterTime`. Use cases:
|
|
501
|
+
* business hours, lunch breaks, blackout slots. Hours are disabled only when the predicate
|
|
502
|
+
* returns `true` for every step within the hour.
|
|
503
|
+
*/
|
|
504
|
+
filterTime?: (hours: number, minutes: number) => boolean;
|
|
469
505
|
/** Override ARIA labels (defaults to English) */
|
|
470
506
|
labels?: Partial<TimePickerLabels>;
|
|
471
507
|
/** Child components */
|
|
472
508
|
children: ReactNode;
|
|
473
509
|
}
|
|
474
|
-
declare function TimePickerRoot({ value: controlledValue, defaultValue, onChange, format, step, withSeconds, displayTimezone, disabled, readOnly, labels: labelsProp, children, }: TimePickerRootProps): react_jsx_runtime.JSX.Element;
|
|
510
|
+
declare function TimePickerRoot({ value: controlledValue, defaultValue, onChange, format, step, withSeconds, displayTimezone, disabled, readOnly, filterTime, labels: labelsProp, children, }: TimePickerRootProps): react_jsx_runtime.JSX.Element;
|
|
475
511
|
|
|
476
512
|
interface TimePickerHourListClassNames {
|
|
477
513
|
root?: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -82,13 +82,28 @@ interface DatePickerCalendarClassNames {
|
|
|
82
82
|
dayDisabled?: string;
|
|
83
83
|
dayOutsideMonth?: string;
|
|
84
84
|
weekdayHeader?: string;
|
|
85
|
+
/** Header cell at the top of the week-number column. Rendered only when `showWeekNumber` is set. */
|
|
86
|
+
weekNumberHeader?: string;
|
|
87
|
+
/** Each row's week-number cell. Rendered only when `showWeekNumber` is set. */
|
|
88
|
+
weekNumber?: string;
|
|
85
89
|
}
|
|
86
90
|
interface DatePickerCalendarProps extends Omit<HTMLAttributes<HTMLDivElement>, 'role'> {
|
|
87
91
|
classNames?: DatePickerCalendarClassNames;
|
|
88
92
|
/** Called when the title ("January 2026") is clicked. Useful for switching to Month/Year views. */
|
|
89
93
|
onTitleClick?: () => void;
|
|
94
|
+
/**
|
|
95
|
+
* Render an ISO 8601 week-number column on the left of the grid (1–53).
|
|
96
|
+
* The column is a `<th scope="row">`; it doesn't participate in the WAI-ARIA grid
|
|
97
|
+
* data region, so keyboard navigation across the date cells is unaffected.
|
|
98
|
+
*/
|
|
99
|
+
showWeekNumber?: boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Always render 6 weeks (42 cells), even when the month fits in 4 or 5 rows. Useful for
|
|
102
|
+
* popover layouts that need a fixed height across month navigation.
|
|
103
|
+
*/
|
|
104
|
+
fixedWeeks?: boolean;
|
|
90
105
|
}
|
|
91
|
-
declare function DatePickerCalendar({ classNames, onTitleClick, ...props }: DatePickerCalendarProps): react_jsx_runtime.JSX.Element;
|
|
106
|
+
declare function DatePickerCalendar({ classNames, onTitleClick, showWeekNumber, fixedWeeks, ...props }: DatePickerCalendarProps): react_jsx_runtime.JSX.Element;
|
|
92
107
|
|
|
93
108
|
interface DatePickerMonthGridClassNames {
|
|
94
109
|
root?: string;
|
|
@@ -322,6 +337,10 @@ interface RangePickerCalendarClassNames {
|
|
|
322
337
|
dayRangeEnd?: string;
|
|
323
338
|
dayInRange?: string;
|
|
324
339
|
weekdayHeader?: string;
|
|
340
|
+
/** Header cell at the top of the week-number column. Rendered only when `showWeekNumber` is set. */
|
|
341
|
+
weekNumberHeader?: string;
|
|
342
|
+
/** Each row's week-number cell. Rendered only when `showWeekNumber` is set. */
|
|
343
|
+
weekNumber?: string;
|
|
325
344
|
}
|
|
326
345
|
/**
|
|
327
346
|
* Selection mode for the calendar grid.
|
|
@@ -333,8 +352,18 @@ interface RangePickerCalendarProps extends Omit<HTMLAttributes<HTMLDivElement>,
|
|
|
333
352
|
classNames?: RangePickerCalendarClassNames;
|
|
334
353
|
/** @default 'range' */
|
|
335
354
|
selectionMode?: RangePickerCalendarSelectionMode;
|
|
355
|
+
/**
|
|
356
|
+
* Render an ISO 8601 week-number column on the left of the grid (1–53).
|
|
357
|
+
* The column is a `<th scope="row">`; it doesn't participate in the WAI-ARIA grid
|
|
358
|
+
* data region, so keyboard navigation across the date cells is unaffected.
|
|
359
|
+
*/
|
|
360
|
+
showWeekNumber?: boolean;
|
|
361
|
+
/**
|
|
362
|
+
* Always render 6 weeks (42 cells), even when the month fits in 4 or 5 rows.
|
|
363
|
+
*/
|
|
364
|
+
fixedWeeks?: boolean;
|
|
336
365
|
}
|
|
337
|
-
declare function RangePickerCalendar({ classNames, selectionMode, ...props }: RangePickerCalendarProps): react_jsx_runtime.JSX.Element;
|
|
366
|
+
declare function RangePickerCalendar({ classNames, selectionMode, showWeekNumber, fixedWeeks, ...props }: RangePickerCalendarProps): react_jsx_runtime.JSX.Element;
|
|
338
367
|
|
|
339
368
|
/** Predefined preset keys. Custom ranges are also supported. */
|
|
340
369
|
type PresetKey = 'today' | 'yesterday' | 'last7days' | 'last30days' | 'thisWeek' | 'lastWeek' | 'thisMonth' | 'lastMonth' | 'thisYear';
|
|
@@ -466,12 +495,19 @@ interface TimePickerRootProps {
|
|
|
466
495
|
disabled?: boolean;
|
|
467
496
|
/** Read-only */
|
|
468
497
|
readOnly?: boolean;
|
|
498
|
+
/**
|
|
499
|
+
* Programmatic per-slot disable predicate. Returns `true` for any `(hours, minutes)` pair
|
|
500
|
+
* that should be unselectable. Equivalent to react-datepicker's `filterTime`. Use cases:
|
|
501
|
+
* business hours, lunch breaks, blackout slots. Hours are disabled only when the predicate
|
|
502
|
+
* returns `true` for every step within the hour.
|
|
503
|
+
*/
|
|
504
|
+
filterTime?: (hours: number, minutes: number) => boolean;
|
|
469
505
|
/** Override ARIA labels (defaults to English) */
|
|
470
506
|
labels?: Partial<TimePickerLabels>;
|
|
471
507
|
/** Child components */
|
|
472
508
|
children: ReactNode;
|
|
473
509
|
}
|
|
474
|
-
declare function TimePickerRoot({ value: controlledValue, defaultValue, onChange, format, step, withSeconds, displayTimezone, disabled, readOnly, labels: labelsProp, children, }: TimePickerRootProps): react_jsx_runtime.JSX.Element;
|
|
510
|
+
declare function TimePickerRoot({ value: controlledValue, defaultValue, onChange, format, step, withSeconds, displayTimezone, disabled, readOnly, filterTime, labels: labelsProp, children, }: TimePickerRootProps): react_jsx_runtime.JSX.Element;
|
|
475
511
|
|
|
476
512
|
interface TimePickerHourListClassNames {
|
|
477
513
|
root?: string;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { createContext, forwardRef, useState, useRef, useCallback, useContext, useId, useMemo, useEffect } from 'react';
|
|
3
|
-
import { parseInputValue, formatTimeString, parseTimeString, getTimeInTimezone, getTime, DateFnsAdapter, DEFAULT_DATEPICKER_LABELS, civilMidnightFromUtcDay, getMonthName, getWeekdayNames, getCalendarDays, formatMonthYear, isDateDisabled, DEFAULT_RANGEPICKER_LABELS, DEFAULT_TIMEPICKER_LABELS, setTimeInTimezone, setTime, to12Hour, to24Hour, generateMinutes, generateHours, formatFullDate } from '@kalyx/core';
|
|
3
|
+
import { parseInputValue, formatTimeString, parseTimeString, getTimeInTimezone, getTime, DateFnsAdapter, DEFAULT_DATEPICKER_LABELS, civilMidnightFromUtcDay, getMonthName, getWeekdayNames, getCalendarDays, formatMonthYear, isDateDisabled, getISOWeekNumber, DEFAULT_RANGEPICKER_LABELS, DEFAULT_TIMEPICKER_LABELS, setTimeInTimezone, setTime, to12Hour, to24Hour, generateMinutes, generateHours, formatFullDate } from '@kalyx/core';
|
|
4
4
|
export { DateFnsAdapter } from '@kalyx/core';
|
|
5
5
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
6
6
|
import { offset, flip, shift, useFloating, autoUpdate } from '@floating-ui/react';
|
|
@@ -464,6 +464,8 @@ var srOnly = {
|
|
|
464
464
|
function DatePickerCalendar({
|
|
465
465
|
classNames,
|
|
466
466
|
onTitleClick,
|
|
467
|
+
showWeekNumber = false,
|
|
468
|
+
fixedWeeks = false,
|
|
467
469
|
...props
|
|
468
470
|
}) {
|
|
469
471
|
const ctx = useDatePickerContext("DatePicker.Calendar");
|
|
@@ -477,10 +479,21 @@ function DatePickerCalendar({
|
|
|
477
479
|
selected: ctx.value,
|
|
478
480
|
focusedDate,
|
|
479
481
|
disabled,
|
|
480
|
-
timezone: displayTimezone
|
|
482
|
+
timezone: displayTimezone,
|
|
483
|
+
fixedWeeks
|
|
481
484
|
}),
|
|
482
|
-
[
|
|
485
|
+
[
|
|
486
|
+
viewMonth,
|
|
487
|
+
adapter,
|
|
488
|
+
weekStartsOn,
|
|
489
|
+
ctx.value,
|
|
490
|
+
focusedDate,
|
|
491
|
+
disabled,
|
|
492
|
+
displayTimezone,
|
|
493
|
+
fixedWeeks
|
|
494
|
+
]
|
|
483
495
|
);
|
|
496
|
+
const thursdayIndex = weekStartsOn === 0 ? 4 : 3;
|
|
484
497
|
const year = adapter.getYear(viewMonth);
|
|
485
498
|
const month = adapter.getMonth(viewMonth);
|
|
486
499
|
const title = formatMonthYear(year, month, locale);
|
|
@@ -621,61 +634,76 @@ function DatePickerCalendar({
|
|
|
621
634
|
className: classNames?.grid,
|
|
622
635
|
onKeyDown: handleKeyDown,
|
|
623
636
|
children: [
|
|
624
|
-
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */
|
|
625
|
-
"th",
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { role: "row", "aria-rowindex": 1, children: [
|
|
638
|
+
showWeekNumber ? /* @__PURE__ */ jsx("th", { scope: "col", "aria-hidden": "true", className: classNames?.weekNumberHeader, children: "#" }) : null,
|
|
639
|
+
weekdays.map((day, colIndex) => /* @__PURE__ */ jsx(
|
|
640
|
+
"th",
|
|
641
|
+
{
|
|
642
|
+
role: "columnheader",
|
|
643
|
+
abbr: day.full,
|
|
644
|
+
scope: "col",
|
|
645
|
+
"aria-colindex": colIndex + 1,
|
|
646
|
+
className: classNames?.weekdayHeader,
|
|
647
|
+
children: day.short
|
|
648
|
+
},
|
|
649
|
+
day.short
|
|
650
|
+
))
|
|
651
|
+
] }) }),
|
|
652
|
+
/* @__PURE__ */ jsx("tbody", { children: weeks.map((week, weekIndex) => /* @__PURE__ */ jsxs(
|
|
637
653
|
"tr",
|
|
638
654
|
{
|
|
639
655
|
role: "row",
|
|
640
656
|
"aria-rowindex": weekIndex + 2,
|
|
641
657
|
className: classNames?.gridRow,
|
|
642
|
-
children:
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
day.isSelected && classNames?.daySelected,
|
|
646
|
-
day.isToday && classNames?.dayToday,
|
|
647
|
-
day.isDisabled && classNames?.dayDisabled,
|
|
648
|
-
!day.isCurrentMonth && classNames?.dayOutsideMonth
|
|
649
|
-
].filter(Boolean).join(" ") || void 0;
|
|
650
|
-
return /* @__PURE__ */ jsx(
|
|
651
|
-
"td",
|
|
658
|
+
children: [
|
|
659
|
+
showWeekNumber ? /* @__PURE__ */ jsx(
|
|
660
|
+
"th",
|
|
652
661
|
{
|
|
653
|
-
|
|
654
|
-
"aria-
|
|
655
|
-
|
|
656
|
-
"
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
662
|
+
scope: "row",
|
|
663
|
+
"aria-hidden": "true",
|
|
664
|
+
className: classNames?.weekNumber,
|
|
665
|
+
"data-week-number": true,
|
|
666
|
+
children: getISOWeekNumber(week[thursdayIndex].isoString)
|
|
667
|
+
}
|
|
668
|
+
) : null,
|
|
669
|
+
week.map((day, colIndex) => {
|
|
670
|
+
const dayClasses = [
|
|
671
|
+
classNames?.day,
|
|
672
|
+
day.isSelected && classNames?.daySelected,
|
|
673
|
+
day.isToday && classNames?.dayToday,
|
|
674
|
+
day.isDisabled && classNames?.dayDisabled,
|
|
675
|
+
!day.isCurrentMonth && classNames?.dayOutsideMonth
|
|
676
|
+
].filter(Boolean).join(" ") || void 0;
|
|
677
|
+
return /* @__PURE__ */ jsx(
|
|
678
|
+
"td",
|
|
679
|
+
{
|
|
680
|
+
role: "gridcell",
|
|
681
|
+
"aria-colindex": colIndex + 1,
|
|
682
|
+
"aria-selected": day.isSelected || void 0,
|
|
683
|
+
"aria-disabled": day.isDisabled || void 0,
|
|
684
|
+
"aria-current": day.isToday ? "date" : void 0,
|
|
685
|
+
className: classNames?.gridCell,
|
|
686
|
+
children: /* @__PURE__ */ jsx(
|
|
687
|
+
"button",
|
|
688
|
+
{
|
|
689
|
+
type: "button",
|
|
690
|
+
tabIndex: day.isFocused ? 0 : -1,
|
|
691
|
+
disabled: day.isDisabled,
|
|
692
|
+
"data-focused": day.isFocused || void 0,
|
|
693
|
+
"data-selected": day.isSelected || void 0,
|
|
694
|
+
"data-today": day.isToday || void 0,
|
|
695
|
+
"data-outside-month": !day.isCurrentMonth || void 0,
|
|
696
|
+
className: dayClasses,
|
|
697
|
+
onClick: () => handleDayClick(day),
|
|
698
|
+
"aria-label": safeFormatFullDate(day.isoString, locale),
|
|
699
|
+
children: day.dayNumber
|
|
700
|
+
}
|
|
701
|
+
)
|
|
702
|
+
},
|
|
703
|
+
day.isoString
|
|
704
|
+
);
|
|
705
|
+
})
|
|
706
|
+
]
|
|
679
707
|
},
|
|
680
708
|
weekIndex
|
|
681
709
|
)) })
|
|
@@ -1338,6 +1366,8 @@ var srOnly2 = {
|
|
|
1338
1366
|
function RangePickerCalendar({
|
|
1339
1367
|
classNames,
|
|
1340
1368
|
selectionMode = "range",
|
|
1369
|
+
showWeekNumber = false,
|
|
1370
|
+
fixedWeeks = false,
|
|
1341
1371
|
...props
|
|
1342
1372
|
}) {
|
|
1343
1373
|
const ctx = useRangePickerContext("RangePicker.Calendar");
|
|
@@ -1363,10 +1393,22 @@ function RangePickerCalendar({
|
|
|
1363
1393
|
disabled,
|
|
1364
1394
|
range: value,
|
|
1365
1395
|
rangeHover: hoverDate,
|
|
1366
|
-
timezone: displayTimezone
|
|
1396
|
+
timezone: displayTimezone,
|
|
1397
|
+
fixedWeeks
|
|
1367
1398
|
}),
|
|
1368
|
-
[
|
|
1399
|
+
[
|
|
1400
|
+
viewMonth,
|
|
1401
|
+
adapter,
|
|
1402
|
+
weekStartsOn,
|
|
1403
|
+
focusedDate,
|
|
1404
|
+
disabled,
|
|
1405
|
+
value,
|
|
1406
|
+
hoverDate,
|
|
1407
|
+
displayTimezone,
|
|
1408
|
+
fixedWeeks
|
|
1409
|
+
]
|
|
1369
1410
|
);
|
|
1411
|
+
const thursdayIndex = weekStartsOn === 0 ? 4 : 3;
|
|
1370
1412
|
const year = adapter.getYear(viewMonth);
|
|
1371
1413
|
const month = adapter.getMonth(viewMonth);
|
|
1372
1414
|
const title = formatMonthYear(year, month, locale);
|
|
@@ -1530,67 +1572,82 @@ function RangePickerCalendar({
|
|
|
1530
1572
|
className: classNames?.grid,
|
|
1531
1573
|
onKeyDown: handleKeyDown,
|
|
1532
1574
|
children: [
|
|
1533
|
-
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */
|
|
1534
|
-
"th",
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1575
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { role: "row", "aria-rowindex": 1, children: [
|
|
1576
|
+
showWeekNumber ? /* @__PURE__ */ jsx("th", { scope: "col", "aria-hidden": "true", className: classNames?.weekNumberHeader, children: "#" }) : null,
|
|
1577
|
+
weekdays.map((day, colIndex) => /* @__PURE__ */ jsx(
|
|
1578
|
+
"th",
|
|
1579
|
+
{
|
|
1580
|
+
role: "columnheader",
|
|
1581
|
+
abbr: day.full,
|
|
1582
|
+
scope: "col",
|
|
1583
|
+
"aria-colindex": colIndex + 1,
|
|
1584
|
+
className: classNames?.weekdayHeader,
|
|
1585
|
+
children: day.short
|
|
1586
|
+
},
|
|
1587
|
+
day.short
|
|
1588
|
+
))
|
|
1589
|
+
] }) }),
|
|
1590
|
+
/* @__PURE__ */ jsx("tbody", { children: weeks.map((week, weekIndex) => /* @__PURE__ */ jsxs(
|
|
1546
1591
|
"tr",
|
|
1547
1592
|
{
|
|
1548
1593
|
role: "row",
|
|
1549
1594
|
"aria-rowindex": weekIndex + 2,
|
|
1550
1595
|
className: classNames?.gridRow,
|
|
1551
|
-
children:
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
day.isRangeStart && classNames?.dayRangeStart,
|
|
1555
|
-
day.isRangeEnd && classNames?.dayRangeEnd,
|
|
1556
|
-
day.isInRange && classNames?.dayInRange,
|
|
1557
|
-
day.isToday && classNames?.dayToday,
|
|
1558
|
-
day.isDisabled && classNames?.dayDisabled,
|
|
1559
|
-
!day.isCurrentMonth && classNames?.dayOutsideMonth
|
|
1560
|
-
].filter(Boolean).join(" ") || void 0;
|
|
1561
|
-
const isSelected = selectionMode === "week" ? day.isRangeStart || day.isRangeEnd || day.isInRange : day.isRangeStart || day.isRangeEnd;
|
|
1562
|
-
return /* @__PURE__ */ jsx(
|
|
1563
|
-
"td",
|
|
1596
|
+
children: [
|
|
1597
|
+
showWeekNumber ? /* @__PURE__ */ jsx(
|
|
1598
|
+
"th",
|
|
1564
1599
|
{
|
|
1565
|
-
|
|
1566
|
-
"aria-
|
|
1567
|
-
|
|
1568
|
-
"
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1600
|
+
scope: "row",
|
|
1601
|
+
"aria-hidden": "true",
|
|
1602
|
+
className: classNames?.weekNumber,
|
|
1603
|
+
"data-week-number": true,
|
|
1604
|
+
children: getISOWeekNumber(week[thursdayIndex].isoString)
|
|
1605
|
+
}
|
|
1606
|
+
) : null,
|
|
1607
|
+
week.map((day, colIndex) => {
|
|
1608
|
+
const dayClasses = [
|
|
1609
|
+
classNames?.day,
|
|
1610
|
+
day.isRangeStart && classNames?.dayRangeStart,
|
|
1611
|
+
day.isRangeEnd && classNames?.dayRangeEnd,
|
|
1612
|
+
day.isInRange && classNames?.dayInRange,
|
|
1613
|
+
day.isToday && classNames?.dayToday,
|
|
1614
|
+
day.isDisabled && classNames?.dayDisabled,
|
|
1615
|
+
!day.isCurrentMonth && classNames?.dayOutsideMonth
|
|
1616
|
+
].filter(Boolean).join(" ") || void 0;
|
|
1617
|
+
const isSelected = selectionMode === "week" ? day.isRangeStart || day.isRangeEnd || day.isInRange : day.isRangeStart || day.isRangeEnd;
|
|
1618
|
+
return /* @__PURE__ */ jsx(
|
|
1619
|
+
"td",
|
|
1620
|
+
{
|
|
1621
|
+
role: "gridcell",
|
|
1622
|
+
"aria-colindex": colIndex + 1,
|
|
1623
|
+
"aria-selected": isSelected || void 0,
|
|
1624
|
+
"aria-disabled": day.isDisabled || void 0,
|
|
1625
|
+
"aria-current": day.isToday ? "date" : void 0,
|
|
1626
|
+
className: classNames?.gridCell,
|
|
1627
|
+
children: /* @__PURE__ */ jsx(
|
|
1628
|
+
"button",
|
|
1629
|
+
{
|
|
1630
|
+
type: "button",
|
|
1631
|
+
tabIndex: day.isFocused ? 0 : -1,
|
|
1632
|
+
disabled: day.isDisabled,
|
|
1633
|
+
"data-focused": day.isFocused || void 0,
|
|
1634
|
+
"data-range-start": day.isRangeStart || void 0,
|
|
1635
|
+
"data-range-end": day.isRangeEnd || void 0,
|
|
1636
|
+
"data-in-range": day.isInRange || void 0,
|
|
1637
|
+
"data-today": day.isToday || void 0,
|
|
1638
|
+
"data-outside-month": !day.isCurrentMonth || void 0,
|
|
1639
|
+
className: dayClasses,
|
|
1640
|
+
onClick: () => handleDayClick(day),
|
|
1641
|
+
onMouseEnter: () => handleDayMouseEnter(day),
|
|
1642
|
+
"aria-label": safeFormatFullDate2(day.isoString, locale),
|
|
1643
|
+
children: day.dayNumber
|
|
1644
|
+
}
|
|
1645
|
+
)
|
|
1646
|
+
},
|
|
1647
|
+
day.isoString
|
|
1648
|
+
);
|
|
1649
|
+
})
|
|
1650
|
+
]
|
|
1594
1651
|
},
|
|
1595
1652
|
weekIndex
|
|
1596
1653
|
)) })
|
|
@@ -1734,6 +1791,7 @@ function TimePickerRoot({
|
|
|
1734
1791
|
displayTimezone,
|
|
1735
1792
|
disabled = false,
|
|
1736
1793
|
readOnly = false,
|
|
1794
|
+
filterTime,
|
|
1737
1795
|
labels: labelsProp,
|
|
1738
1796
|
children
|
|
1739
1797
|
}) {
|
|
@@ -1775,7 +1833,8 @@ function TimePickerRoot({
|
|
|
1775
1833
|
isReadOnly: readOnly,
|
|
1776
1834
|
currentTime,
|
|
1777
1835
|
pickerId,
|
|
1778
|
-
labels: mergedLabels
|
|
1836
|
+
labels: mergedLabels,
|
|
1837
|
+
filterTime
|
|
1779
1838
|
}),
|
|
1780
1839
|
[
|
|
1781
1840
|
currentValue,
|
|
@@ -1788,7 +1847,8 @@ function TimePickerRoot({
|
|
|
1788
1847
|
readOnly,
|
|
1789
1848
|
currentTime,
|
|
1790
1849
|
pickerId,
|
|
1791
|
-
mergedLabels
|
|
1850
|
+
mergedLabels,
|
|
1851
|
+
filterTime
|
|
1792
1852
|
]
|
|
1793
1853
|
);
|
|
1794
1854
|
return /* @__PURE__ */ jsx(TimePickerContext.Provider, { value: contextValue, children });
|
|
@@ -1893,17 +1953,41 @@ function useListboxNavigation({
|
|
|
1893
1953
|
}
|
|
1894
1954
|
function TimePickerHourList({ classNames, ...props }) {
|
|
1895
1955
|
const ctx = useTimePickerContext("TimePicker.HourList");
|
|
1896
|
-
const { format, currentTime, isDisabled, isReadOnly } = ctx;
|
|
1956
|
+
const { format, step, currentTime, isDisabled, isReadOnly, filterTime } = ctx;
|
|
1897
1957
|
const hours = useMemo(() => generateHours(format), [format]);
|
|
1898
1958
|
const selectedHourDisplay = format === "12h" ? to12Hour(currentTime.hours).hours12 : currentTime.hours;
|
|
1899
1959
|
const currentPeriod = format === "12h" ? to12Hour(currentTime.hours).period : null;
|
|
1960
|
+
const fullyDisabledHours24 = useMemo(() => {
|
|
1961
|
+
if (!filterTime) return null;
|
|
1962
|
+
const disabled = /* @__PURE__ */ new Set();
|
|
1963
|
+
for (let h = 0; h < 24; h++) {
|
|
1964
|
+
let allRejected = true;
|
|
1965
|
+
for (let m = 0; m < 60; m += step) {
|
|
1966
|
+
if (!filterTime(h, m)) {
|
|
1967
|
+
allRejected = false;
|
|
1968
|
+
break;
|
|
1969
|
+
}
|
|
1970
|
+
}
|
|
1971
|
+
if (allRejected) disabled.add(h);
|
|
1972
|
+
}
|
|
1973
|
+
return disabled;
|
|
1974
|
+
}, [filterTime, step]);
|
|
1975
|
+
const isHourDisabled = useCallback(
|
|
1976
|
+
(hourDisplay) => {
|
|
1977
|
+
if (!fullyDisabledHours24) return false;
|
|
1978
|
+
const hours24 = format === "12h" && currentPeriod ? to24Hour(hourDisplay, currentPeriod) : hourDisplay;
|
|
1979
|
+
return fullyDisabledHours24.has(hours24);
|
|
1980
|
+
},
|
|
1981
|
+
[fullyDisabledHours24, format, currentPeriod]
|
|
1982
|
+
);
|
|
1900
1983
|
const handleSelect = useCallback(
|
|
1901
1984
|
(hourDisplay) => {
|
|
1902
1985
|
if (isDisabled || isReadOnly) return;
|
|
1986
|
+
if (isHourDisabled(hourDisplay)) return;
|
|
1903
1987
|
const hours24 = format === "12h" && currentPeriod ? to24Hour(hourDisplay, currentPeriod) : hourDisplay;
|
|
1904
1988
|
ctx.setTime({ hours: hours24 });
|
|
1905
1989
|
},
|
|
1906
|
-
[format, currentPeriod, ctx, isDisabled, isReadOnly]
|
|
1990
|
+
[format, currentPeriod, ctx, isDisabled, isReadOnly, isHourDisabled]
|
|
1907
1991
|
);
|
|
1908
1992
|
const { listRef, handleKeyDown } = useListboxNavigation({
|
|
1909
1993
|
items: hours,
|
|
@@ -1921,13 +2005,14 @@ function TimePickerHourList({ classNames, ...props }) {
|
|
|
1921
2005
|
...props,
|
|
1922
2006
|
children: hours.map((hour) => {
|
|
1923
2007
|
const isSelected = hour === selectedHourDisplay;
|
|
2008
|
+
const isHourFullyDisabled = isHourDisabled(hour);
|
|
1924
2009
|
const optionClass = [classNames?.option, isSelected && classNames?.optionSelected].filter(Boolean).join(" ") || void 0;
|
|
1925
2010
|
return /* @__PURE__ */ jsx(
|
|
1926
2011
|
"li",
|
|
1927
2012
|
{
|
|
1928
2013
|
role: "option",
|
|
1929
2014
|
"aria-selected": isSelected,
|
|
1930
|
-
"aria-disabled": isDisabled || void 0,
|
|
2015
|
+
"aria-disabled": isDisabled || isHourFullyDisabled || void 0,
|
|
1931
2016
|
"aria-label": ctx.labels.hourOption(hour),
|
|
1932
2017
|
"data-selected": isSelected || void 0,
|
|
1933
2018
|
tabIndex: isSelected ? 0 : -1,
|
|
@@ -1944,14 +2029,22 @@ function TimePickerHourList({ classNames, ...props }) {
|
|
|
1944
2029
|
}
|
|
1945
2030
|
function TimePickerMinuteList({ classNames, ...props }) {
|
|
1946
2031
|
const ctx = useTimePickerContext("TimePicker.MinuteList");
|
|
1947
|
-
const { step, currentTime, isDisabled, isReadOnly } = ctx;
|
|
2032
|
+
const { step, currentTime, isDisabled, isReadOnly, filterTime } = ctx;
|
|
1948
2033
|
const minutes = useMemo(() => generateMinutes(step), [step]);
|
|
2034
|
+
const isMinuteDisabled = useCallback(
|
|
2035
|
+
(minute) => {
|
|
2036
|
+
if (!filterTime) return false;
|
|
2037
|
+
return filterTime(currentTime.hours, minute);
|
|
2038
|
+
},
|
|
2039
|
+
[filterTime, currentTime.hours]
|
|
2040
|
+
);
|
|
1949
2041
|
const handleSelect = useCallback(
|
|
1950
2042
|
(minute) => {
|
|
1951
2043
|
if (isDisabled || isReadOnly) return;
|
|
2044
|
+
if (isMinuteDisabled(minute)) return;
|
|
1952
2045
|
ctx.setTime({ minutes: minute });
|
|
1953
2046
|
},
|
|
1954
|
-
[ctx, isDisabled, isReadOnly]
|
|
2047
|
+
[ctx, isDisabled, isReadOnly, isMinuteDisabled]
|
|
1955
2048
|
);
|
|
1956
2049
|
const { listRef, handleKeyDown } = useListboxNavigation({
|
|
1957
2050
|
items: minutes,
|
|
@@ -1969,13 +2062,14 @@ function TimePickerMinuteList({ classNames, ...props }) {
|
|
|
1969
2062
|
...props,
|
|
1970
2063
|
children: minutes.map((minute) => {
|
|
1971
2064
|
const isSelected = minute === currentTime.minutes;
|
|
2065
|
+
const isMinuteFullyDisabled = isMinuteDisabled(minute);
|
|
1972
2066
|
const optionClass = [classNames?.option, isSelected && classNames?.optionSelected].filter(Boolean).join(" ") || void 0;
|
|
1973
2067
|
return /* @__PURE__ */ jsx(
|
|
1974
2068
|
"li",
|
|
1975
2069
|
{
|
|
1976
2070
|
role: "option",
|
|
1977
2071
|
"aria-selected": isSelected,
|
|
1978
|
-
"aria-disabled": isDisabled || void 0,
|
|
2072
|
+
"aria-disabled": isDisabled || isMinuteFullyDisabled || void 0,
|
|
1979
2073
|
"aria-label": ctx.labels.minuteOption(minute),
|
|
1980
2074
|
"data-selected": isSelected || void 0,
|
|
1981
2075
|
tabIndex: isSelected ? 0 : -1,
|