@astryxdesign/core 0.7.6-canary.bb18c81 → 0.7.6-canary.df8928a
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/Badge/Badge.d.ts.map +1 -1
- package/dist/Badge/Badge.js +7 -1
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +8 -3
- package/dist/DateInput/TouchDateField.d.ts.map +1 -1
- package/dist/DateInput/TouchDateField.js +8 -3
- package/dist/DateTimeInput/DateTimeInput.d.ts +5 -2
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +19 -11
- package/dist/DateTimeInput/NativeTimeSegment.d.ts.map +1 -1
- package/dist/DateTimeInput/NativeTimeSegment.js +5 -4
- package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
- package/dist/DateTimeInput/TouchDateTimeField.js +4 -3
- package/dist/Drawer/Drawer.d.ts +1 -0
- package/dist/Drawer/Drawer.d.ts.map +1 -1
- package/dist/Drawer/Drawer.js +2 -2
- package/dist/NumberInput/numberParser.d.ts +3 -0
- package/dist/NumberInput/numberParser.d.ts.map +1 -1
- package/dist/NumberInput/numberParser.js +7 -44
- package/dist/TimeInput/TimeInput.d.ts +6 -2
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +21 -14
- package/dist/TimeInput/TouchTimeField.d.ts.map +1 -1
- package/dist/TimeInput/TouchTimeField.js +5 -4
- package/dist/Toast/Toast.d.ts.map +1 -1
- package/dist/Toast/Toast.js +60 -20
- package/dist/astryx.css +1 -0
- package/dist/utils/plainDate.d.ts +2 -0
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +46 -3
- package/dist/utils/timeFormat.d.ts +47 -0
- package/dist/utils/timeFormat.d.ts.map +1 -0
- package/dist/utils/timeFormat.js +240 -0
- package/dist/utils/unicodeDigits.d.ts +20 -0
- package/dist/utils/unicodeDigits.d.ts.map +1 -0
- package/dist/utils/unicodeDigits.js +70 -0
- package/locales/en.json +2 -2
- package/package.json +4 -4
- package/src/Badge/Badge.doc.mjs +1 -1
- package/src/Badge/Badge.tsx +19 -2
- package/src/Badge/__tests__/BadgeLargerText.a11y.chromium.spec.ts +260 -0
- package/src/ComplexSelector/ComplexSelector.test.tsx +37 -0
- package/src/DateInput/DateInput.test.tsx +62 -1
- package/src/DateInput/DateInput.tsx +14 -3
- package/src/DateInput/DateInputTouch.test.tsx +76 -0
- package/src/DateInput/TouchDateField.tsx +14 -3
- package/src/DateTimeInput/DateTimeInput.doc.mjs +10 -8
- package/src/DateTimeInput/DateTimeInput.spec.md +27 -26
- package/src/DateTimeInput/DateTimeInput.test.tsx +20 -0
- package/src/DateTimeInput/DateTimeInput.tsx +31 -13
- package/src/DateTimeInput/NativeTimeSegment.tsx +4 -6
- package/src/DateTimeInput/TouchDateTimeField.tsx +3 -7
- package/src/Drawer/Drawer.test.tsx +13 -0
- package/src/Drawer/Drawer.tsx +8 -2
- package/src/Drawer/__tests__/DrawerNonModalPageScroll.a11y.chromium.spec.ts +267 -0
- package/src/List/ListItem.spec.md +205 -0
- package/src/NumberInput/numberParser.ts +7 -45
- package/src/SideNav/__tests__/SideNavRailMotion.interaction.browser.spec.ts +176 -51
- package/src/TabList/TabList.test.tsx +7 -4
- package/src/TimeInput/NativeTimeInput.test.tsx +17 -0
- package/src/TimeInput/Presentation.test.tsx +21 -0
- package/src/TimeInput/TimeInput.doc.mjs +8 -8
- package/src/TimeInput/TimeInput.spec.md +45 -48
- package/src/TimeInput/TimeInput.test.tsx +76 -0
- package/src/TimeInput/TimeInput.tsx +36 -18
- package/src/TimeInput/TouchTimeField.tsx +4 -6
- package/src/Toast/Toast.spec.md +7 -10
- package/src/Toast/Toast.tsx +104 -36
- package/src/Toast/ToastViewport.test.tsx +144 -0
- package/src/utils/plainDate.test.ts +90 -0
- package/src/utils/plainDate.ts +58 -3
- package/src/utils/timeFormat.test.ts +204 -0
- package/src/utils/timeFormat.ts +314 -0
- package/src/utils/unicodeDigits.test.ts +44 -0
- package/src/utils/unicodeDigits.ts +71 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Badge.d.ts","sourceRoot":"","sources":["../../src/Badge/Badge.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AACrC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAW5C,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"Badge.d.ts","sourceRoot":"","sources":["../../src/Badge/Badge.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AACrC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAW5C,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,SAAS,CAAC;AAwJ7C;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,eAAe,CAAC;AAEjD,MAAM,WAAW,UAAW,SAAQ,SAAS,CAAC,eAAe,CAAC;IAC5D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACjC;;;OAGG;IACH,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB;;OAEG;IACH,KAAK,EAAE,SAAS,CAAC;IAEjB;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,KAAK,CAAC,EACpB,OAAmB,EACnB,KAAK,EACL,IAAI,EACJ,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,UAAU,+BA6CZ;yBAtDe,KAAK"}
|
package/dist/Badge/Badge.js
CHANGED
|
@@ -41,6 +41,10 @@ const styles = {
|
|
|
41
41
|
ks0D6T: "x193iq5w",
|
|
42
42
|
k7Eaqz: "xeuugli",
|
|
43
43
|
$$css: true
|
|
44
|
+
},
|
|
45
|
+
grows: {
|
|
46
|
+
kAzted: "x1tn5z8q",
|
|
47
|
+
$$css: true
|
|
44
48
|
}
|
|
45
49
|
};
|
|
46
50
|
|
|
@@ -182,11 +186,13 @@ export function Badge({
|
|
|
182
186
|
// really cut, reachable by hover and by focus — needs that measurement and
|
|
183
187
|
// a client component, so it is tracked in #5585.
|
|
184
188
|
const labelTitle = typeof label === 'number' ? String(label) : typeof label === 'string' && label.length > 0 ? label : undefined;
|
|
189
|
+
// Whether the label renders anything, which is when the badge grows with it.
|
|
190
|
+
const hasLabel = label !== '' && label != null && typeof label !== 'boolean';
|
|
185
191
|
return /*#__PURE__*/_jsxs("span", {
|
|
186
192
|
ref: ref,
|
|
187
193
|
...mergeProps(themeProps('badge', {
|
|
188
194
|
variant
|
|
189
|
-
}), stylex.props(styles.base, variants[variant], xstyle), className, style),
|
|
195
|
+
}), stylex.props(styles.base, hasLabel && styles.grows, variants[variant], xstyle), className, style),
|
|
190
196
|
title: labelTitle,
|
|
191
197
|
...props,
|
|
192
198
|
children: [icon, /*#__PURE__*/_jsx("span", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DateInput.d.ts","sourceRoot":"","sources":["../../src/DateInput/DateInput.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"DateInput.d.ts","sourceRoot":"","sources":["../../src/DateInput/DateInput.tsx"],"names":[],"mappings":"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"}
|
|
@@ -330,7 +330,7 @@ function PointerDateField({
|
|
|
330
330
|
|
|
331
331
|
// Unified change handler that fires both onChange and changeAction
|
|
332
332
|
const fireChange = useCallback(newValue => {
|
|
333
|
-
if (
|
|
333
|
+
if (isEffectivelyDisabled) {
|
|
334
334
|
return;
|
|
335
335
|
}
|
|
336
336
|
onChange?.(newValue);
|
|
@@ -340,7 +340,7 @@ function PointerDateField({
|
|
|
340
340
|
await changeAction(newValue);
|
|
341
341
|
});
|
|
342
342
|
}
|
|
343
|
-
}, [
|
|
343
|
+
}, [isEffectivelyDisabled, onChange, changeAction, startTransition, setOptimisticValue]);
|
|
344
344
|
|
|
345
345
|
// Handle clear button click
|
|
346
346
|
const handleClear = useCallback(e => {
|
|
@@ -360,10 +360,15 @@ function PointerDateField({
|
|
|
360
360
|
|
|
361
361
|
// Handle date selection from calendar
|
|
362
362
|
const handleDateSelect = useCallback(selectedDate => {
|
|
363
|
+
// An already-open calendar can outlive an enabled owner. Reject the
|
|
364
|
+
// whole selection, including dismissal, so its focused day stays put.
|
|
365
|
+
if (isDisabled) {
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
363
368
|
fireChange(selectedDate);
|
|
364
369
|
setPendingInput(null);
|
|
365
370
|
popover.hide();
|
|
366
|
-
}, [fireChange, popover]);
|
|
371
|
+
}, [isDisabled, fireChange, popover]);
|
|
367
372
|
|
|
368
373
|
// Handle input text change - update immediately if valid and allowed
|
|
369
374
|
const handleInputChange = useCallback(e => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TouchDateField.d.ts","sourceRoot":"","sources":["../../src/DateInput/TouchDateField.tsx"],"names":[],"mappings":"AAgEA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,aAAa,CAAC;AA6ehD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,aAAqB,EACrB,WAAW,EACX,UAAkB,EAClB,UAAkB,EAClB,UAAkB,EAClB,eAAe,EACf,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,SAAiB,EACjB,GAAG,EACH,GAAG,EACH,eAAe,EACf,WAAW,EAAE,oBAAoB,EACjC,IAAI,EAAE,QAAQ,EACd,MAAM,EACN,aAA0B,EAC1B,YAAY,EACZ,QAAgB,EAIhB,cAAc,EAAE,eAAe,EAC/B,YAAY,EAAE,gBAAoB,EAClC,MAAoB,EACpB,KAAK,EACL,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,GAAG,EACH,GAAG,SAAS,EACb,EAAE,cAAc,+
|
|
1
|
+
{"version":3,"file":"TouchDateField.d.ts","sourceRoot":"","sources":["../../src/DateInput/TouchDateField.tsx"],"names":[],"mappings":"AAgEA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,aAAa,CAAC;AA6ehD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,aAAqB,EACrB,WAAW,EACX,UAAkB,EAClB,UAAkB,EAClB,UAAkB,EAClB,eAAe,EACf,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,SAAiB,EACjB,GAAG,EACH,GAAG,EACH,eAAe,EACf,WAAW,EAAE,oBAAoB,EACjC,IAAI,EAAE,QAAQ,EACd,MAAM,EACN,aAA0B,EAC1B,YAAY,EACZ,QAAgB,EAIhB,cAAc,EAAE,eAAe,EAC/B,YAAY,EAAE,gBAAoB,EAClC,MAAoB,EACpB,KAAK,EACL,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,GAAG,EACH,GAAG,SAAS,EACb,EAAE,cAAc,+BAixBhB;yBArzBe,cAAc"}
|
|
@@ -380,7 +380,7 @@ export function TouchDateField({
|
|
|
380
380
|
// literal renders the same shape here and on the desktop control.
|
|
381
381
|
const displayValue = optimisticValue != null && /^\d{4}-\d{2}-\d{2}$/.test(optimisticValue) ? typeof format === 'function' ? format(optimisticValue) : formatSharedDate(plainDateFromISO(optimisticValue), format, locale) : '';
|
|
382
382
|
const fireChange = useCallback(newValue => {
|
|
383
|
-
if (
|
|
383
|
+
if (isEffectivelyDisabled) {
|
|
384
384
|
return;
|
|
385
385
|
}
|
|
386
386
|
onChange?.(newValue);
|
|
@@ -390,7 +390,7 @@ export function TouchDateField({
|
|
|
390
390
|
await changeAction(newValue);
|
|
391
391
|
});
|
|
392
392
|
}
|
|
393
|
-
}, [
|
|
393
|
+
}, [isEffectivelyDisabled, onChange, changeAction, startTransition, setOptimisticValue]);
|
|
394
394
|
const openSheet = useCallback(() => {
|
|
395
395
|
if (!isEffectivelyDisabled) {
|
|
396
396
|
// Always onto the calendar, whatever was showing last time. The wheels
|
|
@@ -447,6 +447,11 @@ export function TouchDateField({
|
|
|
447
447
|
* value is still cleared either way — that half never depends on the range.
|
|
448
448
|
*/
|
|
449
449
|
const handleResetInSheet = useCallback(() => {
|
|
450
|
+
// Disabled: reject the entire reset without closing or moving focus.
|
|
451
|
+
// Busy-only fields keep month navigation; fireChange blocks the clear.
|
|
452
|
+
if (isDisabled) {
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
450
455
|
fireChange(undefined);
|
|
451
456
|
const currentMonth = monthIndexOf(today);
|
|
452
457
|
if (currentMonth < minMonthIndex || currentMonth > maxMonthIndex) {
|
|
@@ -457,7 +462,7 @@ export function TouchDateField({
|
|
|
457
462
|
}
|
|
458
463
|
setMonthIndex(currentMonth);
|
|
459
464
|
scrollerHandleRef.current?.scrollToMonth(currentMonth, 'smooth');
|
|
460
|
-
}, [fireChange, today, monthIndex, minMonthIndex, maxMonthIndex]);
|
|
465
|
+
}, [isDisabled, fireChange, today, monthIndex, minMonthIndex, maxMonthIndex]);
|
|
461
466
|
|
|
462
467
|
// Selection commits on the tap and leaves the sheet up, so a mistake can be
|
|
463
468
|
// corrected in place and a nearby date reconsidered without reopening.
|
|
@@ -112,8 +112,11 @@ export interface DateTimeInputProps extends Omit<FieldInputBaseProps<HTMLInputEl
|
|
|
112
112
|
*/
|
|
113
113
|
hasSeconds?: boolean;
|
|
114
114
|
/**
|
|
115
|
-
* Hour display format.
|
|
116
|
-
*
|
|
115
|
+
* Hour display format: '12h' with the locale's day period, or '24h'.
|
|
116
|
+
* When unset, follows the `InternationalizationProvider` locale's hour
|
|
117
|
+
* cycle (`en-US` 12-hour, `en-GB` 24-hour); a per-user preference rides on
|
|
118
|
+
* the locale tag (`en-US-u-hc-h23`).
|
|
119
|
+
* @default the locale's hour cycle
|
|
117
120
|
*/
|
|
118
121
|
hourFormat?: DateTimeInputHourFormat;
|
|
119
122
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DateTimeInput.d.ts","sourceRoot":"","sources":["../../src/DateTimeInput/DateTimeInput.tsx"],"names":[],"mappings":"AA4CA,OAAO,EAGL,KAAK,WAAW,EAKjB,MAAM,UAAU,CAAC;AAIlB,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"DateTimeInput.d.ts","sourceRoot":"","sources":["../../src/DateTimeInput/DateTimeInput.tsx"],"names":[],"mappings":"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"}
|
|
@@ -34,7 +34,7 @@ import { useTooltip } from "../Tooltip/index.js";
|
|
|
34
34
|
import { useInputContainer } from "../hooks/useInputContainer.js";
|
|
35
35
|
import { useBusyAnnouncement } from "../hooks/useBusyAnnouncement.js";
|
|
36
36
|
import { useInputStatusIcon } from "../hooks/useInputStatusIcon.js";
|
|
37
|
-
import { parseDateInput, parseISOTime,
|
|
37
|
+
import { parseDateInput, parseISOTime, formatISOTime, isTimeInRange, adjustTime, isImeKeyEvent, mergeProps, isFocusDetached } from "../utils/index.js";
|
|
38
38
|
import { chainEventHandlers } from "../utils/chainEventHandlers.js";
|
|
39
39
|
import { joinAriaIDs } from "../utils/inputAria.js";
|
|
40
40
|
import { plainDateFromISO, plainDateToISO, plainDateFormat, DATE_FORMAT_LONG } from "../utils/plainDate.js";
|
|
@@ -46,6 +46,7 @@ import { useSize } from "../SizeContext/SizeContext.js";
|
|
|
46
46
|
import { themeProps } from "../utils/themeProps.js";
|
|
47
47
|
import { focusOutlineStyles } from "../utils/focusOutline.stylex.js";
|
|
48
48
|
import { useLocale, useTranslator } from "../i18n/index.js";
|
|
49
|
+
import { formatLocaleTime, parseLocaleTime, resolveHourFormat } from "../utils/timeFormat.js";
|
|
49
50
|
import { useMergedRefs } from "../hooks/useMergedRefs.js";
|
|
50
51
|
import { useHighlightedOptionScroll } from "../hooks/useHighlightedOptionScroll.js";
|
|
51
52
|
import { NativeDateSegment } from "./NativeDateSegment.js";
|
|
@@ -415,7 +416,7 @@ function PointerDateTimeField({
|
|
|
415
416
|
}
|
|
416
417
|
}
|
|
417
418
|
const nativeTimeValue = nativeTimeDraft ?? valueParts.time;
|
|
418
|
-
const formatDisplayTime =
|
|
419
|
+
const formatDisplayTime = useCallback((time, includeSeconds) => formatLocaleTime(time, locale, hourFormat, includeSeconds), [locale, hourFormat]);
|
|
419
420
|
const timeDisplayValue = useMemo(() => {
|
|
420
421
|
if (timePendingInput !== null) {
|
|
421
422
|
return timePendingInput;
|
|
@@ -426,12 +427,12 @@ function PointerDateTimeField({
|
|
|
426
427
|
if (timePendingInput === null || !timePendingInput.trim()) {
|
|
427
428
|
return true;
|
|
428
429
|
}
|
|
429
|
-
const parsed =
|
|
430
|
+
const parsed = parseLocaleTime(timePendingInput, locale, hasSeconds);
|
|
430
431
|
if (!parsed) {
|
|
431
432
|
return false;
|
|
432
433
|
}
|
|
433
434
|
return isTimeInRange(parsed, timeMin, timeMax);
|
|
434
|
-
}, [timePendingInput, hasSeconds, timeMin, timeMax]);
|
|
435
|
+
}, [timePendingInput, locale, hasSeconds, timeMin, timeMax]);
|
|
435
436
|
const resolvedTimePlaceholder = useMemo(() => {
|
|
436
437
|
if (isTimeFocused && !timeDisplayValue) {
|
|
437
438
|
return hourFormat === '12h' ? t('@astryx.dateTimeInput.timeHint12h') : t('@astryx.dateTimeInput.timeHint24h');
|
|
@@ -817,7 +818,7 @@ function PointerDateTimeField({
|
|
|
817
818
|
}
|
|
818
819
|
const text = e.target.value;
|
|
819
820
|
setTimePendingInput(text);
|
|
820
|
-
const parsed =
|
|
821
|
+
const parsed = parseLocaleTime(text, locale, hasSeconds);
|
|
821
822
|
|
|
822
823
|
// Typing narrows nothing — free-form entry is the contract, and a time
|
|
823
824
|
// between two options must stay reachable. The list instead follows the
|
|
@@ -834,7 +835,7 @@ function PointerDateTimeField({
|
|
|
834
835
|
}
|
|
835
836
|
}
|
|
836
837
|
}
|
|
837
|
-
}, [hasSeconds, timeMin, timeMax, valueParts.time, valueParts.date, fireChange, isEffectivelyDisabled, timePopover.isOpen, closestOptionIndex]);
|
|
838
|
+
}, [locale, hasSeconds, timeMin, timeMax, valueParts.time, valueParts.date, fireChange, isEffectivelyDisabled, timePopover.isOpen, closestOptionIndex]);
|
|
838
839
|
const handleTimeFocus = useCallback(() => {
|
|
839
840
|
// A disabled/busy input stays focusable (via aria-disabled) so its reason
|
|
840
841
|
// is discoverable, but it must not present editing affordances — keep the
|
|
@@ -866,7 +867,7 @@ function PointerDateTimeField({
|
|
|
866
867
|
setTimePendingInput(null);
|
|
867
868
|
return;
|
|
868
869
|
}
|
|
869
|
-
const parsed =
|
|
870
|
+
const parsed = parseLocaleTime(timePendingInput, locale, hasSeconds);
|
|
870
871
|
if (parsed && isTimeInRange(parsed, timeMin, timeMax)) {
|
|
871
872
|
if (parsed !== valueParts.time && valueParts.date) {
|
|
872
873
|
const combined = combineDateTime(valueParts.date, parsed);
|
|
@@ -876,7 +877,7 @@ function PointerDateTimeField({
|
|
|
876
877
|
}
|
|
877
878
|
}
|
|
878
879
|
setTimePendingInput(null);
|
|
879
|
-
}, [timePendingInput, hasSeconds, timeMin, timeMax, valueParts, fireChange, timePopover]);
|
|
880
|
+
}, [timePendingInput, locale, hasSeconds, timeMin, timeMax, valueParts, fireChange, timePopover]);
|
|
880
881
|
const handleTimeKeyDown = useCallback(e => {
|
|
881
882
|
// ArrowUp/ArrowDown step the time and preventDefault; an IME candidate
|
|
882
883
|
// window uses those same arrows to navigate candidates, so guard the
|
|
@@ -934,7 +935,7 @@ function PointerDateTimeField({
|
|
|
934
935
|
// Typed text wins over the highlight. The highlight only tracks
|
|
935
936
|
// the option at or before what was typed, so committing it here
|
|
936
937
|
// would round 1:07 PM down to 1:00 PM and discard the entry.
|
|
937
|
-
const typed = timeHighlightFollowsTypingRef.current && timePendingInput !== null ?
|
|
938
|
+
const typed = timeHighlightFollowsTypingRef.current && timePendingInput !== null ? parseLocaleTime(timePendingInput, locale, hasSeconds) : null;
|
|
938
939
|
const option = timeOptions[activeTimeIndex];
|
|
939
940
|
if (typed) {
|
|
940
941
|
commitTimeOption(typed);
|
|
@@ -975,7 +976,7 @@ function PointerDateTimeField({
|
|
|
975
976
|
}
|
|
976
977
|
}
|
|
977
978
|
}
|
|
978
|
-
}, [valueParts, hasSeconds, timeIncrement, timeMin, timeMax, fireChange, announce, formatDisplayTime, hasTimeOptions, isEffectivelyDisabled, timePopover, timeOptions, activeTimeIndex, timePendingInput, showTimeOptions, commitTimeOption]);
|
|
979
|
+
}, [valueParts, locale, hasSeconds, timeIncrement, timeMin, timeMax, fireChange, announce, formatDisplayTime, hasTimeOptions, isEffectivelyDisabled, timePopover, timeOptions, activeTimeIndex, timePendingInput, showTimeOptions, commitTimeOption]);
|
|
979
980
|
|
|
980
981
|
// --- Clear ---
|
|
981
982
|
const handleClear = useCallback(e => {
|
|
@@ -1304,11 +1305,18 @@ export function DateTimeInput(props) {
|
|
|
1304
1305
|
const isTouch = useMediaQuery(TOUCH_POINTER_QUERY);
|
|
1305
1306
|
useDevWarning('DateTimeInput', '`nativePicker` is deprecated; use `presentation` instead (`touch` → `adaptive-native`, `always` → `native`, `never` → `adaptive-bottom-sheet`). `presentation` wins when both are set.', props.nativePicker !== undefined);
|
|
1306
1307
|
const effective = effectivePickerPresentation(props.presentation, props.nativePicker);
|
|
1308
|
+
const locale = useLocale();
|
|
1307
1309
|
const {
|
|
1308
1310
|
presentation: _presentation,
|
|
1309
1311
|
nativePicker: _nativePicker,
|
|
1310
|
-
...
|
|
1312
|
+
...surfaceProps
|
|
1311
1313
|
} = props;
|
|
1314
|
+
// Every surface gets the resolved hour format, so typed text, the native
|
|
1315
|
+
// field's resting text, preset times, and the sheet wheels agree.
|
|
1316
|
+
const rest = {
|
|
1317
|
+
...surfaceProps,
|
|
1318
|
+
hourFormat: resolveHourFormat(locale, props.hourFormat)
|
|
1319
|
+
};
|
|
1312
1320
|
if (effective === 'native') {
|
|
1313
1321
|
return /*#__PURE__*/_jsx(PointerDateTimeField, {
|
|
1314
1322
|
...rest,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeTimeSegment.d.ts","sourceRoot":"","sources":["../../src/DateTimeInput/NativeTimeSegment.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"NativeTimeSegment.d.ts","sourceRoot":"","sources":["../../src/DateTimeInput/NativeTimeSegment.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,UAAU,CAAC;AAM9C,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAKL,KAAK,aAAa,EACnB,MAAM,UAAU,CAAC;AAoBlB,MAAM,MAAM,sBAAsB,GAAG;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IACtC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,KAAK,IAAI,CAAC;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,GAAG,CAAC,EAAE,aAAa,CAAC;IACpB,GAAG,CAAC,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,KAAK,GAAG,KAAK,CAAC;IAC1B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,kFAAkF;IAClF,mBAAmB,EAAE,OAAO,CAAC;IAC7B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,YAAY,CAAC,EAAE,IAAI,CACjB,mBAAmB,CAAC,gBAAgB,CAAC,EACrC,MAAM,mBAAmB,GAAG,UAAU,GAAG,cAAc,CACxD,CAAC;CACH,CAAC;AAEF,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAAC,EAChC,EAAE,EACF,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,WAAW,EACX,UAAU,EACV,eAAe,EACf,cAAc,EACd,cAAc,EACd,YAAoB,EACpB,GAAG,EACH,GAAG,EACH,UAAU,EACV,qBAAqB,EACrB,mBAAmB,EACnB,qBAAqB,EACrB,MAAM,EACN,UAAU,EACV,eAAe,EACf,YAAY,GACb,EAAE,sBAAsB,+BA4OxB;yBAjQe,iBAAiB"}
|
|
@@ -28,9 +28,10 @@ import { hasEditableDateSegments } from "../DateInput/nativeDateSegments.js";
|
|
|
28
28
|
import { useMediaQuery } from "../hooks/useMediaQuery.js";
|
|
29
29
|
import { useMergedRefs } from "../hooks/useMergedRefs.js";
|
|
30
30
|
import { Icon } from "../Icon/index.js";
|
|
31
|
-
import { useTranslator } from "../i18n/index.js";
|
|
31
|
+
import { useLocale, useTranslator } from "../i18n/index.js";
|
|
32
|
+
import { formatLocaleTime } from "../utils/timeFormat.js";
|
|
32
33
|
import { VisuallyHidden } from "../VisuallyHidden/index.js";
|
|
33
|
-
import { focusOutlineStyles,
|
|
34
|
+
import { focusOutlineStyles, formatISOTime, isTimeInRange, parseISOTime } from "../utils/index.js";
|
|
34
35
|
import { chainEventHandlers } from "../utils/chainEventHandlers.js";
|
|
35
36
|
import { nativePickerSegmentStyles as styles } from "./nativePickerSegmentStyles.js";
|
|
36
37
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
@@ -72,6 +73,7 @@ export function NativeTimeSegment({
|
|
|
72
73
|
...inputProps
|
|
73
74
|
} = controlProps ?? {};
|
|
74
75
|
const t = useTranslator();
|
|
76
|
+
const locale = useLocale();
|
|
75
77
|
const isTouchPointer = useMediaQuery('(pointer: coarse)');
|
|
76
78
|
const internalInputRef = useRef(null);
|
|
77
79
|
const mergedInputRef = useMergedRefs(inputRef, internalInputRef);
|
|
@@ -94,8 +96,7 @@ export function NativeTimeSegment({
|
|
|
94
96
|
}
|
|
95
97
|
const nativeValue = normalizeNativeTime(value) ?? '';
|
|
96
98
|
const isInputValid = rejectedValue === null;
|
|
97
|
-
const
|
|
98
|
-
const overlayText = nativeValue ? formatDisplayTime(nativeValue, false) : placeholder;
|
|
99
|
+
const overlayText = nativeValue ? formatLocaleTime(nativeValue, locale, hourFormat, false) : placeholder;
|
|
99
100
|
const showsOverlay = !!overlayText && !(isFocused && isSegmentEditable);
|
|
100
101
|
const commitValue = useCallback(newValue => {
|
|
101
102
|
if (isEffectivelyDisabled || lastCommitRef.current === newValue) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TouchDateTimeField.d.ts","sourceRoot":"","sources":["../../src/DateTimeInput/TouchDateTimeField.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TouchDateTimeField.d.ts","sourceRoot":"","sources":["../../src/DateTimeInput/TouchDateTimeField.tsx"],"names":[],"mappings":"AA6GA,OAAO,KAAK,EAAC,kBAAkB,EAAoB,MAAM,iBAAiB,CAAC;AAuV3E,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,aAAqB,EACrB,WAAW,EACX,UAAkB,EAClB,UAAkB,EAClB,UAAkB,EAClB,eAAe,EACf,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,SAAiB,EACjB,GAAG,EACH,GAAG,EACH,eAAe,EACf,UAAkB,EAClB,UAAkB,EAElB,aAAa,EAAE,cAAc,EAC7B,kBAAkB,EAAE,mBAAmB,EACvC,QAAgB,EAChB,WAAW,EAAE,oBAAoB,EACjC,eAAe,EAAE,wBAAwB,EACzC,SAAS,EACT,IAAI,EAAE,QAAQ,EACd,MAAM,EACN,YAAY,EAEZ,cAAc,EAAE,eAAe,EAC/B,YAAY,EAAE,gBAAoB,EAClC,KAAK,EACL,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,GAAG,EACH,GAAG,SAAS,EACb,EAAE,kBAAkB,+BA+/BpB;yBAtiCe,kBAAkB"}
|
|
@@ -44,7 +44,8 @@ import { focusOutlineStyles } from "../utils/focusOutline.stylex.js";
|
|
|
44
44
|
import { rtlStyles } from "../utils/rtlStyles.js";
|
|
45
45
|
import { themeProps } from "../utils/themeProps.js";
|
|
46
46
|
import { normalizeDayOfWeek } from "../utils/dateTypes.js";
|
|
47
|
-
import {
|
|
47
|
+
import { formatLocaleTime } from "../utils/timeFormat.js";
|
|
48
|
+
import { formatISOTime, isImeKeyEvent, isRenderable, isTimeInRange, clampTime, mergeProps, parseISOTime } from "../utils/index.js";
|
|
48
49
|
import { chainEventHandlers } from "../utils/chainEventHandlers.js";
|
|
49
50
|
import { joinAriaIDs } from "../utils/inputAria.js";
|
|
50
51
|
import { DATE_FORMAT_LONG, DATE_FORMAT_MONTH_YEAR, DATE_FORMAT_WEEKDAY_ONLY, plainDateFormat, plainDateFromISO, plainDateToday } from "../utils/plainDate.js";
|
|
@@ -417,8 +418,8 @@ export function TouchDateTimeField({
|
|
|
417
418
|
}, [selectedDate, locale]);
|
|
418
419
|
const timeDisplayValue = useMemo(() => {
|
|
419
420
|
const displayTime = normalizedValueTime ?? draftTime;
|
|
420
|
-
return displayTime ? (
|
|
421
|
-
}, [draftTime, normalizedValueTime, hourFormat, hasSeconds]);
|
|
421
|
+
return displayTime ? formatLocaleTime(displayTime, locale, hourFormat, hasSeconds) : '';
|
|
422
|
+
}, [draftTime, normalizedValueTime, locale, hourFormat, hasSeconds]);
|
|
422
423
|
const timeBoundsForDate = useCallback(date => ({
|
|
423
424
|
min: date != null && minParts.date === date && minParts.time ? minParts.time : undefined,
|
|
424
425
|
max: date != null && maxParts.date === date && maxParts.time ? maxParts.time : undefined
|
package/dist/Drawer/Drawer.d.ts
CHANGED
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
* SYNC: When modified, update these files to stay in sync:
|
|
49
49
|
* - /packages/core/src/Drawer/Drawer.doc.mjs (props table, features, usage)
|
|
50
50
|
* - /packages/core/src/Drawer/Drawer.test.tsx (tests for new/changed behavior)
|
|
51
|
+
* - /packages/core/src/Drawer/__tests__/DrawerNonModalPageScroll.a11y.chromium.spec.ts (the page beside a non-modal drawer scrolls)
|
|
51
52
|
* - /packages/core/src/Drawer/Drawer.spec.md (component contract)
|
|
52
53
|
* - /packages/core/src/Drawer/index.ts (exports if types change)
|
|
53
54
|
* - /packages/cli/assets/templates/blocks/components/Drawer/ (showcase blocks)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Drawer.d.ts","sourceRoot":"","sources":["../../src/Drawer/Drawer.tsx"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"Drawer.d.ts","sourceRoot":"","sources":["../../src/Drawer/Drawer.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAEH,OAAO,EAAgC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAEpE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAQ5C,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,WAAW,CAAC;AAgB7C,OAAO,KAAK,EAAC,WAAW,EAAe,MAAM,WAAW,CAAC;AAqMzD,MAAM,WAAW,WAAY,SAAQ,SAAS,CAAC,iBAAiB,CAAC;IAC/D,iDAAiD;IACjD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAEnC;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;;;;;OAMG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAExC;;;;;OAKG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IAEvB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAExB;;;;;OAKG;IACH,YAAY,CAAC,EAAE;QACb;;;;;;WAMG;QACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;KAC/B,CAAC;IAEF;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;OAGG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,MAAM,CAAC,EACrB,MAAM,EACN,YAAY,EACZ,IAAY,EACZ,KAAW,EACX,YAAY,EACZ,KAAK,EACL,QAAe,EACf,OAAgB,EAChB,OAAO,EACP,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,aAAa,EACxB,GAAG,EACH,GAAG,KAAK,EACT,EAAE,WAAW,+BAmLb;yBArMe,MAAM"}
|
package/dist/Drawer/Drawer.js
CHANGED
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
* SYNC: When modified, update these files to stay in sync:
|
|
53
53
|
* - /packages/core/src/Drawer/Drawer.doc.mjs (props table, features, usage)
|
|
54
54
|
* - /packages/core/src/Drawer/Drawer.test.tsx (tests for new/changed behavior)
|
|
55
|
+
* - /packages/core/src/Drawer/__tests__/DrawerNonModalPageScroll.a11y.chromium.spec.ts (the page beside a non-modal drawer scrolls)
|
|
55
56
|
* - /packages/core/src/Drawer/Drawer.spec.md (component contract)
|
|
56
57
|
* - /packages/core/src/Drawer/index.ts (exports if types change)
|
|
57
58
|
* - /packages/cli/assets/templates/blocks/components/Drawer/ (showcase blocks)
|
|
@@ -101,8 +102,7 @@ const styles = {
|
|
|
101
102
|
kXwgrk: "xdt5ytf",
|
|
102
103
|
kWkggS: "x10xzikg",
|
|
103
104
|
kGVxlE: "x1kcpxr7",
|
|
104
|
-
kVQacm: "
|
|
105
|
-
kZeWKH: "xish69e",
|
|
105
|
+
kVQacm: "x7giv3",
|
|
106
106
|
kI3sdo: "x1a2a7pz",
|
|
107
107
|
k87sOh: "x13vifvy",
|
|
108
108
|
krVfgx: "x1ey2m1c",
|
|
@@ -27,6 +27,9 @@
|
|
|
27
27
|
* read off the input: SEPARATOR_CHARS below is a bounded alphabet, the same
|
|
28
28
|
* shape utils/dateParser.ts uses for its `[-/.]` date separators.
|
|
29
29
|
*
|
|
30
|
+
* Digit-script folding is shared with utils/timeFormat.ts through
|
|
31
|
+
* utils/unicodeDigits.ts.
|
|
32
|
+
*
|
|
30
33
|
* SYNC: When modified, update these files to stay in sync:
|
|
31
34
|
* - /packages/core/src/NumberInput/NumberInput.tsx
|
|
32
35
|
* - /packages/core/src/NumberInput/numberParser.test.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"numberParser.d.ts","sourceRoot":"","sources":["../../src/NumberInput/numberParser.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"numberParser.d.ts","sourceRoot":"","sources":["../../src/NumberInput/numberParser.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,SAAS,CAAC;AAwMpC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,MAAM,GACd,MAAM,GAAG,IAAI,CA8Ef;AAaD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAI3E"}
|
|
@@ -29,12 +29,16 @@
|
|
|
29
29
|
* read off the input: SEPARATOR_CHARS below is a bounded alphabet, the same
|
|
30
30
|
* shape utils/dateParser.ts uses for its `[-/.]` date separators.
|
|
31
31
|
*
|
|
32
|
+
* Digit-script folding is shared with utils/timeFormat.ts through
|
|
33
|
+
* utils/unicodeDigits.ts.
|
|
34
|
+
*
|
|
32
35
|
* SYNC: When modified, update these files to stay in sync:
|
|
33
36
|
* - /packages/core/src/NumberInput/NumberInput.tsx
|
|
34
37
|
* - /packages/core/src/NumberInput/numberParser.test.ts
|
|
35
38
|
* - /packages/core/src/NumberInput/numberParser.docblock.test.ts
|
|
36
39
|
*/
|
|
37
40
|
|
|
41
|
+
import { INVISIBLE_CHARS, toAsciiDigits } from "../utils/unicodeDigits.js";
|
|
38
42
|
const symbolsByLocale = new Map();
|
|
39
43
|
function getLocaleNumberSymbols(locale) {
|
|
40
44
|
const key = locale ?? '';
|
|
@@ -63,15 +67,9 @@ function getLocaleNumberSymbols(locale) {
|
|
|
63
67
|
return symbols;
|
|
64
68
|
}
|
|
65
69
|
|
|
66
|
-
// Built at runtime rather than written as
|
|
67
|
-
//
|
|
68
|
-
// enumerated character class, and the copy bundled with Next rejects the
|
|
69
|
-
// General_Category short names, failing the sandbox build. Property escapes are
|
|
70
|
-
// ES2018 and need no transform in any browser this package supports.
|
|
71
|
-
const DECIMAL_DIGIT = new RegExp('\\p{Nd}', 'u');
|
|
70
|
+
// Built at runtime rather than written as a literal: see
|
|
71
|
+
// utils/unicodeDigits.ts (Babel's property-escape transform).
|
|
72
72
|
const CURRENCY = new RegExp('\\p{Sc}', 'u');
|
|
73
|
-
// Zero-width joiners, bidi isolates and the BOM Excel prepends.
|
|
74
|
-
const INVISIBLES = /[\u200B-\u200D\u200E\u200F\u061C\u2066-\u2069\uFEFF]/g;
|
|
75
73
|
// Hyphen last: inside the character class this builds, a leading one would
|
|
76
74
|
// open a range.
|
|
77
75
|
const MINUS_SIGNS = '\u2212\u2012\u2013-';
|
|
@@ -94,41 +92,6 @@ const NUMBER_BODY = new RegExp(`^[0-9${SEPARATOR_CHARS}]+$`);
|
|
|
94
92
|
/** No grouping and at most one full stop: the format `Number()` reads. */
|
|
95
93
|
const MACHINE_NUMBER = /^(?:\d+\.?\d*|\.\d+)$/;
|
|
96
94
|
|
|
97
|
-
/**
|
|
98
|
-
* Value of any Unicode decimal digit. Each digit script lays its ten digits
|
|
99
|
-
* out consecutively, so walking back to the script's zero derives the value
|
|
100
|
-
* for Arabic-Indic, Devanagari, full-width and the rest without shipping a
|
|
101
|
-
* table of them. Returns null in the one shape the walk cannot resolve: two
|
|
102
|
-
* digit blocks adjacent in code space (the mathematical alphanumerics).
|
|
103
|
-
*/
|
|
104
|
-
function digitValue(char) {
|
|
105
|
-
const codePoint = char.codePointAt(0);
|
|
106
|
-
if (codePoint == null) {
|
|
107
|
-
return null;
|
|
108
|
-
}
|
|
109
|
-
for (let zero = codePoint; codePoint - zero < 10; zero--) {
|
|
110
|
-
if (!DECIMAL_DIGIT.test(String.fromCodePoint(zero - 1))) {
|
|
111
|
-
return codePoint - zero;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
return null;
|
|
115
|
-
}
|
|
116
|
-
function toAsciiDigits(text) {
|
|
117
|
-
let out = '';
|
|
118
|
-
for (const char of text) {
|
|
119
|
-
if (!DECIMAL_DIGIT.test(char)) {
|
|
120
|
-
out += char;
|
|
121
|
-
continue;
|
|
122
|
-
}
|
|
123
|
-
const value = digitValue(char);
|
|
124
|
-
if (value == null) {
|
|
125
|
-
return null;
|
|
126
|
-
}
|
|
127
|
-
out += String(value);
|
|
128
|
-
}
|
|
129
|
-
return out;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
95
|
/**
|
|
133
96
|
* Reduce a digits-and-separators string to a plain machine number under one
|
|
134
97
|
* candidate reading, or null when it is not well formed under that reading.
|
|
@@ -259,7 +222,7 @@ function toPlainNumber(core, locale) {
|
|
|
259
222
|
* ```
|
|
260
223
|
*/
|
|
261
224
|
export function parseLocaleNumber(text, locale) {
|
|
262
|
-
const normalized = toAsciiDigits(text.normalize('NFKC').replace(
|
|
225
|
+
const normalized = toAsciiDigits(text.normalize('NFKC').replace(INVISIBLE_CHARS, ''));
|
|
263
226
|
if (normalized == null) {
|
|
264
227
|
return null;
|
|
265
228
|
}
|
|
@@ -121,9 +121,13 @@ export interface TimeInputProps extends Omit<FieldInputBaseProps<HTMLInputElemen
|
|
|
121
121
|
hasAutoFocus?: boolean;
|
|
122
122
|
/**
|
|
123
123
|
* Hour format for display.
|
|
124
|
-
* - '12h': Display as 12-hour with
|
|
124
|
+
* - '12h': Display as 12-hour with the locale's day period (e.g., "2:30 PM")
|
|
125
125
|
* - '24h': Display as 24-hour (e.g., "14:30")
|
|
126
|
-
*
|
|
126
|
+
*
|
|
127
|
+
* When unset, follows the `InternationalizationProvider` locale's hour
|
|
128
|
+
* cycle: `en-US` reads 12-hour, `en-GB` and `de-DE` read 24-hour. A
|
|
129
|
+
* per-user preference rides on the locale tag (`en-US-u-hc-h23`).
|
|
130
|
+
* @default the locale's hour cycle
|
|
127
131
|
*/
|
|
128
132
|
hourFormat?: TimeInputHourFormat;
|
|
129
133
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimeInput.d.ts","sourceRoot":"","sources":["../../src/TimeInput/TimeInput.tsx"],"names":[],"mappings":"AAgCA,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAO3C,OAAO,EAGL,KAAK,WAAW,EAKhB,KAAK,kBAAkB,EACxB,MAAM,UAAU,CAAC;AAIlB,OAAO,EACL,KAAK,aAAa,
|
|
1
|
+
{"version":3,"file":"TimeInput.d.ts","sourceRoot":"","sources":["../../src/TimeInput/TimeInput.tsx"],"names":[],"mappings":"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"}
|
|
@@ -24,7 +24,7 @@ import { Field, InputClearButton, inputWrapperStyles, inputStatusBorderStyles, i
|
|
|
24
24
|
import { Icon } from "../Icon/index.js";
|
|
25
25
|
import { Spinner } from "../Spinner/index.js";
|
|
26
26
|
import { VisuallyHidden } from "../VisuallyHidden/index.js";
|
|
27
|
-
import {
|
|
27
|
+
import { formatISOTime, adjustTime, isImeKeyEvent, isTimeInRange, mergeProps, getInputARIA } from "../utils/index.js";
|
|
28
28
|
import { chainEventHandlers } from "../utils/chainEventHandlers.js";
|
|
29
29
|
import { joinAriaIDs } from "../utils/inputAria.js";
|
|
30
30
|
import { useFieldInputStyling } from "../Field/fieldParts.js";
|
|
@@ -40,7 +40,8 @@ import { InputGroupInternalContext } from "../InputGroup/InputGroupInternalConte
|
|
|
40
40
|
import { groupStyles, inputGroupItemProps } from "../InputGroup/groupStyles.js";
|
|
41
41
|
import { useTooltip } from "../Tooltip/index.js";
|
|
42
42
|
import { themeProps } from "../utils/themeProps.js";
|
|
43
|
-
import { useTranslator } from "../i18n/index.js";
|
|
43
|
+
import { useLocale, useTranslator } from "../i18n/index.js";
|
|
44
|
+
import { formatLocaleTime, parseLocaleTime, resolveHourFormat } from "../utils/timeFormat.js";
|
|
44
45
|
import { useMergedRefs } from "../hooks/useMergedRefs.js";
|
|
45
46
|
import { NativeTimeSegment } from "../DateTimeInput/NativeTimeSegment.js";
|
|
46
47
|
import { TouchTimeField } from "./TouchTimeField.js";
|
|
@@ -146,6 +147,7 @@ function TimeField({
|
|
|
146
147
|
...controlProps
|
|
147
148
|
} = rest;
|
|
148
149
|
const t = useTranslator();
|
|
150
|
+
const locale = useLocale();
|
|
149
151
|
const isEffectivelyRequired = useResolvedRequired({
|
|
150
152
|
isRequired,
|
|
151
153
|
isOptional
|
|
@@ -223,9 +225,7 @@ function TimeField({
|
|
|
223
225
|
// Pending input while user is typing (null = show formatted value)
|
|
224
226
|
const [pendingInput, setPendingInput] = useState(null);
|
|
225
227
|
const [isFocused, setIsFocused] = useState(false);
|
|
226
|
-
|
|
227
|
-
// Format function based on hourFormat
|
|
228
|
-
const formatDisplayTime = hourFormat === '12h' ? formatDisplayTime12h : formatDisplayTime24h;
|
|
228
|
+
const formatDisplayTime = useCallback((time, includeSeconds) => formatLocaleTime(time, locale, hourFormat, includeSeconds), [locale, hourFormat]);
|
|
229
229
|
|
|
230
230
|
// Unified change handler that fires both onChange and changeAction
|
|
231
231
|
const fireChange = useCallback(newValue => {
|
|
@@ -252,21 +252,21 @@ function TimeField({
|
|
|
252
252
|
if (pendingInput === null || !pendingInput.trim()) {
|
|
253
253
|
return true;
|
|
254
254
|
}
|
|
255
|
-
const parsed =
|
|
255
|
+
const parsed = parseLocaleTime(pendingInput, locale, hasSeconds);
|
|
256
256
|
if (!parsed) {
|
|
257
257
|
return false;
|
|
258
258
|
}
|
|
259
259
|
// Also check min/max range
|
|
260
260
|
return isTimeInRange(parsed, min, max);
|
|
261
|
-
}, [pendingInput, hasSeconds, min, max]);
|
|
261
|
+
}, [pendingInput, locale, hasSeconds, min, max]);
|
|
262
262
|
|
|
263
263
|
// Placeholder that shows format hint when focused and empty
|
|
264
264
|
const displayPlaceholder = useMemo(() => {
|
|
265
265
|
if (isFocused && !displayValue) {
|
|
266
|
-
return hourFormat === '12h' ? '
|
|
266
|
+
return hourFormat === '12h' ? t('@astryx.dateTimeInput.timeHint12h') : t('@astryx.dateTimeInput.timeHint24h');
|
|
267
267
|
}
|
|
268
268
|
return placeholder;
|
|
269
|
-
}, [isFocused, displayValue, hourFormat, placeholder]);
|
|
269
|
+
}, [isFocused, displayValue, hourFormat, placeholder, t]);
|
|
270
270
|
|
|
271
271
|
// Handle input text change - update immediately if valid
|
|
272
272
|
const handleInputChange = useCallback(e => {
|
|
@@ -279,11 +279,11 @@ function TimeField({
|
|
|
279
279
|
setPendingInput(newValue);
|
|
280
280
|
|
|
281
281
|
// If the input is valid, update immediately (don't wait for blur)
|
|
282
|
-
const parsed =
|
|
282
|
+
const parsed = parseLocaleTime(newValue, locale, hasSeconds);
|
|
283
283
|
if (parsed && isTimeInRange(parsed, min, max) && parsed !== value) {
|
|
284
284
|
fireChange(parsed);
|
|
285
285
|
}
|
|
286
|
-
}, [hasSeconds, min, max, value, fireChange, isDisabled]);
|
|
286
|
+
}, [locale, hasSeconds, min, max, value, fireChange, isDisabled]);
|
|
287
287
|
|
|
288
288
|
// Handle focus
|
|
289
289
|
const handleFocus = useCallback(() => {
|
|
@@ -315,7 +315,7 @@ function TimeField({
|
|
|
315
315
|
setPendingInput(null);
|
|
316
316
|
return;
|
|
317
317
|
}
|
|
318
|
-
const parsed =
|
|
318
|
+
const parsed = parseLocaleTime(pendingInput, locale, hasSeconds);
|
|
319
319
|
if (parsed && isTimeInRange(parsed, min, max)) {
|
|
320
320
|
// Valid time - update if different
|
|
321
321
|
if (parsed !== value) {
|
|
@@ -324,7 +324,7 @@ function TimeField({
|
|
|
324
324
|
}
|
|
325
325
|
// Clear pending input - display will revert to formatted value
|
|
326
326
|
setPendingInput(null);
|
|
327
|
-
}, [pendingInput, isDisabled, value, fireChange, hasSeconds, min, max]);
|
|
327
|
+
}, [pendingInput, isDisabled, value, fireChange, locale, hasSeconds, min, max]);
|
|
328
328
|
|
|
329
329
|
// Handle keyboard navigation on input
|
|
330
330
|
// Enter in a focused disabled field would submit a surrounding form (FR2).
|
|
@@ -564,11 +564,18 @@ export function TimeInput(props) {
|
|
|
564
564
|
const isTouch = useMediaQuery(TOUCH_POINTER_QUERY);
|
|
565
565
|
useDevWarning('TimeInput', '`nativePicker` is deprecated; use `presentation` instead (`touch` → `adaptive-native`, `always` → `native`, `never` → `text-input`). `presentation` wins when both are set.', props.nativePicker !== undefined);
|
|
566
566
|
const effective = effectiveInputPresentation(props.presentation, props.nativePicker, 'time');
|
|
567
|
+
const locale = useLocale();
|
|
567
568
|
const {
|
|
568
569
|
presentation: _presentation,
|
|
569
570
|
nativePicker: _nativePicker,
|
|
570
|
-
...
|
|
571
|
+
...surfaceProps
|
|
571
572
|
} = props;
|
|
573
|
+
// Every surface gets the resolved hour format, so the typed text, the
|
|
574
|
+
// native field's resting text, and the sheet wheels agree.
|
|
575
|
+
const rest = {
|
|
576
|
+
...surfaceProps,
|
|
577
|
+
hourFormat: resolveHourFormat(locale, props.hourFormat)
|
|
578
|
+
};
|
|
572
579
|
if (effective === 'native') {
|
|
573
580
|
// Deprecated `always` keeps released fallbacks (FR2 legacy); only an
|
|
574
581
|
// explicit `presentation="native"` is forced.
|