@kalyx/react 1.0.0-rc.7 → 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 +29 -0
- package/dist/index.cjs +45 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +45 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -495,12 +495,19 @@ interface TimePickerRootProps {
|
|
|
495
495
|
disabled?: boolean;
|
|
496
496
|
/** Read-only */
|
|
497
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;
|
|
498
505
|
/** Override ARIA labels (defaults to English) */
|
|
499
506
|
labels?: Partial<TimePickerLabels>;
|
|
500
507
|
/** Child components */
|
|
501
508
|
children: ReactNode;
|
|
502
509
|
}
|
|
503
|
-
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;
|
|
504
511
|
|
|
505
512
|
interface TimePickerHourListClassNames {
|
|
506
513
|
root?: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -495,12 +495,19 @@ interface TimePickerRootProps {
|
|
|
495
495
|
disabled?: boolean;
|
|
496
496
|
/** Read-only */
|
|
497
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;
|
|
498
505
|
/** Override ARIA labels (defaults to English) */
|
|
499
506
|
labels?: Partial<TimePickerLabels>;
|
|
500
507
|
/** Child components */
|
|
501
508
|
children: ReactNode;
|
|
502
509
|
}
|
|
503
|
-
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;
|
|
504
511
|
|
|
505
512
|
interface TimePickerHourListClassNames {
|
|
506
513
|
root?: string;
|
package/dist/index.js
CHANGED
|
@@ -1791,6 +1791,7 @@ function TimePickerRoot({
|
|
|
1791
1791
|
displayTimezone,
|
|
1792
1792
|
disabled = false,
|
|
1793
1793
|
readOnly = false,
|
|
1794
|
+
filterTime,
|
|
1794
1795
|
labels: labelsProp,
|
|
1795
1796
|
children
|
|
1796
1797
|
}) {
|
|
@@ -1832,7 +1833,8 @@ function TimePickerRoot({
|
|
|
1832
1833
|
isReadOnly: readOnly,
|
|
1833
1834
|
currentTime,
|
|
1834
1835
|
pickerId,
|
|
1835
|
-
labels: mergedLabels
|
|
1836
|
+
labels: mergedLabels,
|
|
1837
|
+
filterTime
|
|
1836
1838
|
}),
|
|
1837
1839
|
[
|
|
1838
1840
|
currentValue,
|
|
@@ -1845,7 +1847,8 @@ function TimePickerRoot({
|
|
|
1845
1847
|
readOnly,
|
|
1846
1848
|
currentTime,
|
|
1847
1849
|
pickerId,
|
|
1848
|
-
mergedLabels
|
|
1850
|
+
mergedLabels,
|
|
1851
|
+
filterTime
|
|
1849
1852
|
]
|
|
1850
1853
|
);
|
|
1851
1854
|
return /* @__PURE__ */ jsx(TimePickerContext.Provider, { value: contextValue, children });
|
|
@@ -1950,17 +1953,41 @@ function useListboxNavigation({
|
|
|
1950
1953
|
}
|
|
1951
1954
|
function TimePickerHourList({ classNames, ...props }) {
|
|
1952
1955
|
const ctx = useTimePickerContext("TimePicker.HourList");
|
|
1953
|
-
const { format, currentTime, isDisabled, isReadOnly } = ctx;
|
|
1956
|
+
const { format, step, currentTime, isDisabled, isReadOnly, filterTime } = ctx;
|
|
1954
1957
|
const hours = useMemo(() => generateHours(format), [format]);
|
|
1955
1958
|
const selectedHourDisplay = format === "12h" ? to12Hour(currentTime.hours).hours12 : currentTime.hours;
|
|
1956
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
|
+
);
|
|
1957
1983
|
const handleSelect = useCallback(
|
|
1958
1984
|
(hourDisplay) => {
|
|
1959
1985
|
if (isDisabled || isReadOnly) return;
|
|
1986
|
+
if (isHourDisabled(hourDisplay)) return;
|
|
1960
1987
|
const hours24 = format === "12h" && currentPeriod ? to24Hour(hourDisplay, currentPeriod) : hourDisplay;
|
|
1961
1988
|
ctx.setTime({ hours: hours24 });
|
|
1962
1989
|
},
|
|
1963
|
-
[format, currentPeriod, ctx, isDisabled, isReadOnly]
|
|
1990
|
+
[format, currentPeriod, ctx, isDisabled, isReadOnly, isHourDisabled]
|
|
1964
1991
|
);
|
|
1965
1992
|
const { listRef, handleKeyDown } = useListboxNavigation({
|
|
1966
1993
|
items: hours,
|
|
@@ -1978,13 +2005,14 @@ function TimePickerHourList({ classNames, ...props }) {
|
|
|
1978
2005
|
...props,
|
|
1979
2006
|
children: hours.map((hour) => {
|
|
1980
2007
|
const isSelected = hour === selectedHourDisplay;
|
|
2008
|
+
const isHourFullyDisabled = isHourDisabled(hour);
|
|
1981
2009
|
const optionClass = [classNames?.option, isSelected && classNames?.optionSelected].filter(Boolean).join(" ") || void 0;
|
|
1982
2010
|
return /* @__PURE__ */ jsx(
|
|
1983
2011
|
"li",
|
|
1984
2012
|
{
|
|
1985
2013
|
role: "option",
|
|
1986
2014
|
"aria-selected": isSelected,
|
|
1987
|
-
"aria-disabled": isDisabled || void 0,
|
|
2015
|
+
"aria-disabled": isDisabled || isHourFullyDisabled || void 0,
|
|
1988
2016
|
"aria-label": ctx.labels.hourOption(hour),
|
|
1989
2017
|
"data-selected": isSelected || void 0,
|
|
1990
2018
|
tabIndex: isSelected ? 0 : -1,
|
|
@@ -2001,14 +2029,22 @@ function TimePickerHourList({ classNames, ...props }) {
|
|
|
2001
2029
|
}
|
|
2002
2030
|
function TimePickerMinuteList({ classNames, ...props }) {
|
|
2003
2031
|
const ctx = useTimePickerContext("TimePicker.MinuteList");
|
|
2004
|
-
const { step, currentTime, isDisabled, isReadOnly } = ctx;
|
|
2032
|
+
const { step, currentTime, isDisabled, isReadOnly, filterTime } = ctx;
|
|
2005
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
|
+
);
|
|
2006
2041
|
const handleSelect = useCallback(
|
|
2007
2042
|
(minute) => {
|
|
2008
2043
|
if (isDisabled || isReadOnly) return;
|
|
2044
|
+
if (isMinuteDisabled(minute)) return;
|
|
2009
2045
|
ctx.setTime({ minutes: minute });
|
|
2010
2046
|
},
|
|
2011
|
-
[ctx, isDisabled, isReadOnly]
|
|
2047
|
+
[ctx, isDisabled, isReadOnly, isMinuteDisabled]
|
|
2012
2048
|
);
|
|
2013
2049
|
const { listRef, handleKeyDown } = useListboxNavigation({
|
|
2014
2050
|
items: minutes,
|
|
@@ -2026,13 +2062,14 @@ function TimePickerMinuteList({ classNames, ...props }) {
|
|
|
2026
2062
|
...props,
|
|
2027
2063
|
children: minutes.map((minute) => {
|
|
2028
2064
|
const isSelected = minute === currentTime.minutes;
|
|
2065
|
+
const isMinuteFullyDisabled = isMinuteDisabled(minute);
|
|
2029
2066
|
const optionClass = [classNames?.option, isSelected && classNames?.optionSelected].filter(Boolean).join(" ") || void 0;
|
|
2030
2067
|
return /* @__PURE__ */ jsx(
|
|
2031
2068
|
"li",
|
|
2032
2069
|
{
|
|
2033
2070
|
role: "option",
|
|
2034
2071
|
"aria-selected": isSelected,
|
|
2035
|
-
"aria-disabled": isDisabled || void 0,
|
|
2072
|
+
"aria-disabled": isDisabled || isMinuteFullyDisabled || void 0,
|
|
2036
2073
|
"aria-label": ctx.labels.minuteOption(minute),
|
|
2037
2074
|
"data-selected": isSelected || void 0,
|
|
2038
2075
|
tabIndex: isSelected ? 0 : -1,
|