@astryxdesign/core 0.7.2 → 0.7.3-canary.02f5fe4
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/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheet.js +8 -4
- package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetSwitcher.js +7 -0
- package/dist/Calendar/Calendar.js +3 -2
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +19 -24
- package/dist/ClickableCard/ClickableCard.d.ts +2 -2
- package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
- package/dist/ClickableCard/ClickableCard.js +11 -9
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +11 -1
- package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
- package/dist/ComplexSelector/ComplexSelector.js +23 -5
- package/dist/DateInput/DateInput.d.ts +4 -4
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +27 -20
- package/dist/DateInput/NativeDateField.d.ts.map +1 -1
- package/dist/DateInput/NativeDateField.js +14 -8
- package/dist/DateInput/TouchDateField.d.ts.map +1 -1
- package/dist/DateInput/TouchDateField.js +14 -10
- package/dist/DateRangeInput/DateRangeInput.d.ts +5 -5
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +27 -18
- package/dist/DateTimeInput/DateTimeInput.d.ts +5 -5
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +25 -27
- package/dist/DateTimeInput/NativeDateSegment.d.ts +3 -2
- package/dist/DateTimeInput/NativeDateSegment.d.ts.map +1 -1
- package/dist/DateTimeInput/NativeDateSegment.js +5 -5
- package/dist/DateTimeInput/NativeTimeSegment.d.ts +3 -2
- package/dist/DateTimeInput/NativeTimeSegment.d.ts.map +1 -1
- package/dist/DateTimeInput/NativeTimeSegment.js +5 -5
- package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
- package/dist/DateTimeInput/TouchDateTimeField.js +12 -9
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +9 -4
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +52 -10
- package/dist/DropdownMenu/DropdownMenuContext.d.ts +34 -1
- package/dist/DropdownMenu/DropdownMenuContext.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuContext.js +15 -0
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +21 -2
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuSubMenu.js +375 -42
- package/dist/DropdownMenu/menuRegionStops.d.ts +2 -2
- package/dist/DropdownMenu/menuRegionStops.js +2 -2
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +14 -12
- package/dist/Link/Link.d.ts +2 -3
- package/dist/Link/Link.d.ts.map +1 -1
- package/dist/Link/Link.js +11 -19
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +48 -15
- package/dist/MultiSelector/MultiSelector.d.ts +4 -4
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.disabledFocus.a11y.chromium.spec.d.ts +2 -0
- package/dist/MultiSelector/MultiSelector.disabledFocus.a11y.chromium.spec.d.ts.map +1 -0
- package/dist/MultiSelector/MultiSelector.disabledFocus.a11y.chromium.spec.js +48 -0
- package/dist/MultiSelector/MultiSelector.js +25 -18
- package/dist/Pagination/Pagination.d.ts.map +1 -1
- package/dist/Pagination/Pagination.js +5 -2
- package/dist/Popover/Popover.d.ts.map +1 -1
- package/dist/Popover/Popover.js +8 -4
- package/dist/Selector/Selector.d.ts +4 -4
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +23 -14
- package/dist/Selector/SelectorOption.d.ts.map +1 -1
- package/dist/Selector/SelectorOption.js +1 -0
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +7 -14
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +25 -17
- package/dist/Switch/switch.markers.stylex.d.ts +2 -0
- package/dist/Switch/switch.markers.stylex.d.ts.map +1 -1
- package/dist/Switch/switch.markers.stylex.js +6 -0
- package/dist/TimeInput/TimeInput.d.ts +7 -6
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +37 -20
- package/dist/TimeInput/TouchTimeField.d.ts.map +1 -1
- package/dist/TimeInput/TouchTimeField.js +17 -6
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +41 -8
- package/dist/Token/Token.d.ts.map +1 -1
- package/dist/Token/Token.js +8 -3
- package/dist/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/Tooltip/Tooltip.js +36 -14
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +11 -2
- package/dist/TopNav/TopNav.d.ts.map +1 -1
- package/dist/TopNav/TopNav.js +2 -2
- package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
- package/dist/TopNav/TopNavHeading.js +1 -0
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +8 -3
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +14 -2
- package/dist/astryx.css +8 -2
- package/dist/hooks/useGridFocus.d.ts.map +1 -1
- package/dist/hooks/useGridFocus.js +10 -1
- package/dist/hooks/useMenuPress.d.ts +11 -1
- package/dist/hooks/useMenuPress.d.ts.map +1 -1
- package/dist/hooks/useMenuPress.js +43 -5
- package/dist/utils/disabledInteraction.d.ts +21 -0
- package/dist/utils/disabledInteraction.d.ts.map +1 -0
- package/dist/utils/disabledInteraction.js +33 -0
- package/dist/utils/timeParser.d.ts +4 -0
- package/dist/utils/timeParser.d.ts.map +1 -1
- package/dist/utils/timeParser.js +9 -2
- package/package.json +4 -4
- package/scripts/agent-doc-state.mjs +58 -9
- package/src/Banner/Banner.spec.md +37 -32
- package/src/BottomSheet/BottomSheet.spec.md +34 -54
- package/src/BottomSheet/BottomSheet.test.tsx +29 -0
- package/src/BottomSheet/BottomSheet.tsx +8 -4
- package/src/BottomSheet/BottomSheetSwitcher.spec.md +125 -58
- package/src/BottomSheet/BottomSheetSwitcher.test.tsx +26 -0
- package/src/BottomSheet/BottomSheetSwitcher.tsx +6 -0
- package/src/Calendar/Calendar.test.tsx +68 -24
- package/src/Calendar/Calendar.tsx +2 -1
- package/src/CheckboxInput/CheckboxInput.test.tsx +44 -5
- package/src/CheckboxInput/CheckboxInput.tsx +16 -26
- package/src/CheckboxInput/__tests__/Checkbox.a11y.states.ts +3 -3
- package/src/CheckboxList/CheckboxList.test.tsx +9 -6
- package/src/ClickableCard/ClickableCard.doc.mjs +2 -2
- package/src/ClickableCard/ClickableCard.test.tsx +5 -4
- package/src/ClickableCard/ClickableCard.tsx +9 -9
- package/src/CodeBlock/CodeBlock.highlightStyles.test.tsx +87 -0
- package/src/CodeBlock/CodeBlock.tsx +11 -1
- package/src/ComplexSelector/ComplexSelector.focusableDisabled.test.tsx +76 -0
- package/src/ComplexSelector/ComplexSelector.tsx +21 -4
- package/src/ContextMenu/ContextMenu.test.tsx +41 -0
- package/src/DateInput/DateInput.doc.mjs +9 -8
- package/src/DateInput/DateInput.test.tsx +88 -13
- package/src/DateInput/DateInput.tsx +49 -21
- package/src/DateInput/DateInputTouch.test.tsx +22 -1
- package/src/DateInput/NativeDateField.test.tsx +29 -3
- package/src/DateInput/NativeDateField.tsx +20 -7
- package/src/DateInput/TouchDateField.tsx +24 -9
- package/src/DateRangeInput/DateRangeInput.doc.mjs +6 -5
- package/src/DateRangeInput/DateRangeInput.spec.md +13 -13
- package/src/DateRangeInput/DateRangeInput.test.tsx +82 -16
- package/src/DateRangeInput/DateRangeInput.tsx +40 -20
- package/src/DateTimeInput/DateTimeInput.doc.mjs +9 -8
- package/src/DateTimeInput/DateTimeInput.test.tsx +126 -11
- package/src/DateTimeInput/DateTimeInput.tsx +42 -26
- package/src/DateTimeInput/DateTimeInputTouch.test.tsx +24 -0
- package/src/DateTimeInput/NativeDateSegment.tsx +9 -6
- package/src/DateTimeInput/NativePickerSegments.test.tsx +31 -0
- package/src/DateTimeInput/NativeTimeSegment.tsx +9 -6
- package/src/DateTimeInput/TouchDateTimeField.tsx +22 -7
- package/src/Dialog/Dialog.test.tsx +39 -0
- package/src/Dialog/Dialog.tsx +9 -4
- package/src/DropdownMenu/DropdownMenu.spec.md +33 -2
- package/src/DropdownMenu/DropdownMenu.tsx +79 -8
- package/src/DropdownMenu/DropdownMenuContext.public.test.ts +22 -0
- package/src/DropdownMenu/DropdownMenuContext.tsx +39 -1
- package/src/DropdownMenu/DropdownMenuItem.doc.mjs +66 -7
- package/src/DropdownMenu/DropdownMenuItem.spec.md +209 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +16 -1
- package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +623 -1
- package/src/DropdownMenu/DropdownMenuSubMenu.tsx +556 -99
- package/src/DropdownMenu/__tests__/DropdownMenuItemAudit.a11y.chromium.spec.ts +366 -0
- package/src/DropdownMenu/__tests__/SubMenuHeaderFooter.a11y.chromium.spec.ts +267 -0
- package/src/DropdownMenu/menuRegionStops.ts +2 -2
- package/src/DropdownMenu/modules/useMenuPress.spec.md +9 -0
- package/src/FieldStatus/FieldStatus.spec.md +3 -2
- package/src/FileInput/FileInput.test.tsx +30 -7
- package/src/FileInput/FileInput.tsx +21 -11
- package/src/Link/Link.test.tsx +21 -7
- package/src/Link/Link.tsx +16 -24
- package/src/Link/__tests__/Link.a11y.states.ts +1 -1
- package/src/Markdown/Markdown.rerender.test.tsx +143 -0
- package/src/Markdown/Markdown.tsx +89 -35
- package/src/MultiSelector/MultiSelector.disabledFocus.a11y.chromium.spec.ts +71 -0
- package/src/MultiSelector/MultiSelector.doc.mjs +5 -5
- package/src/MultiSelector/MultiSelector.focusableDisabled.test.tsx +121 -0
- package/src/MultiSelector/MultiSelector.test.tsx +49 -7
- package/src/MultiSelector/MultiSelector.tsx +53 -29
- package/src/Pagination/Pagination.test.tsx +5 -1
- package/src/Pagination/Pagination.tsx +3 -1
- package/src/Popover/Popover.test.tsx +15 -0
- package/src/Popover/Popover.tsx +19 -8
- package/src/PowerSearch/PowerSearchFilterEditor.test.tsx +3 -2
- package/src/PowerSearch/PowerSearchToken.test.tsx +7 -5
- package/src/Selector/Selector.doc.mjs +4 -4
- package/src/Selector/Selector.focusableDisabled.test.tsx +127 -0
- package/src/Selector/Selector.spec.md +11 -11
- package/src/Selector/Selector.test.tsx +64 -6
- package/src/Selector/Selector.tsx +51 -21
- package/src/Selector/SelectorOption.tsx +4 -0
- package/src/SideNav/SideNav.test.tsx +35 -0
- package/src/Slider/Slider.spec.md +11 -11
- package/src/Slider/Slider.test.tsx +3 -3
- package/src/Slider/Slider.tsx +8 -15
- package/src/Switch/Switch.test.tsx +85 -8
- package/src/Switch/Switch.tsx +26 -16
- package/src/Switch/__tests__/Switch.a11y.states.ts +2 -2
- package/src/Switch/switch.markers.stylex.ts +4 -0
- package/src/Table/Table.spec.md +2 -0
- package/src/Table/plugins/infiniteScroll/useTableInfiniteScroll.spec.md +244 -0
- package/src/Table/plugins/selection/useTableSelection.test.tsx +5 -3
- package/src/Table/plugins/virtualization/useTableVirtualization.spec.md +266 -0
- package/src/TimeInput/NativeTimeInput.test.tsx +25 -1
- package/src/TimeInput/Presentation.test.tsx +23 -0
- package/src/TimeInput/TimeInput.doc.mjs +13 -10
- package/src/TimeInput/TimeInput.test.tsx +139 -7
- package/src/TimeInput/TimeInput.tsx +53 -24
- package/src/TimeInput/TouchTimeField.tsx +27 -5
- package/src/Timestamp/Timestamp.doc.mjs +1 -1
- package/src/Timestamp/Timestamp.test.tsx +168 -0
- package/src/Timestamp/Timestamp.tsx +62 -11
- package/src/Token/Token.test.tsx +26 -4
- package/src/Token/Token.tsx +6 -2
- package/src/Tokenizer/Tokenizer.spec.md +28 -28
- package/src/Tooltip/Tooltip.test.tsx +51 -6
- package/src/Tooltip/Tooltip.tsx +41 -18
- package/src/Tooltip/__tests__/Tooltip.a11y.chromium.spec.ts +129 -0
- package/src/Tooltip/__tests__/Tooltip.a11y.renders.tsx +86 -0
- package/src/Tooltip/__tests__/Tooltip.a11y.states.ts +132 -0
- package/src/Tooltip/__tests__/Tooltip.a11y.test.tsx +126 -0
- package/src/Tooltip/__tests__/TooltipHoverBridge.a11y.chromium.spec.ts +74 -0
- package/src/Tooltip/useTooltip.test.tsx +23 -0
- package/src/Tooltip/useTooltip.tsx +22 -9
- package/src/TopNav/TopNav.tsx +11 -1
- package/src/TopNav/TopNavHeading.tsx +1 -0
- package/src/TopNav/__tests__/TopNavMobileLongHeading.a11y.chromium.spec.ts +74 -0
- package/src/TreeList/TreeList.test.tsx +28 -0
- package/src/TreeList/TreeListItem.tsx +6 -2
- package/src/Typeahead/Typeahead.test.tsx +89 -0
- package/src/Typeahead/Typeahead.tsx +15 -2
- package/src/__tests__/DisabledTriggerFocus.a11y.chromium.spec.ts +86 -0
- package/src/hooks/useGridFocus.ts +16 -1
- package/src/hooks/useMenuPress.ts +45 -7
- package/src/utils/disabledInteraction.ts +40 -0
- package/src/utils/timeParser.test.ts +11 -0
- package/src/utils/timeParser.ts +9 -2
|
@@ -49,14 +49,15 @@ export const docs = {
|
|
|
49
49
|
{
|
|
50
50
|
name: 'isDisabled',
|
|
51
51
|
type: 'boolean',
|
|
52
|
-
description:
|
|
52
|
+
description:
|
|
53
|
+
'Disable the input and calendar. The field stays focusable and exposes `aria-disabled`; typing and opening are blocked.',
|
|
53
54
|
default: 'false',
|
|
54
55
|
},
|
|
55
56
|
{
|
|
56
57
|
name: 'disabledMessage',
|
|
57
58
|
type: 'string',
|
|
58
59
|
description:
|
|
59
|
-
'Explains why the input is disabled. With isDisabled, shows a tooltip on hover/keyboard focus
|
|
60
|
+
'Explains why the input is disabled. With isDisabled, shows a tooltip on hover/keyboard focus (activation stays blocked). Use this instead of wrapping a disabled DateInput in Tooltip.',
|
|
60
61
|
},
|
|
61
62
|
{
|
|
62
63
|
name: 'value',
|
|
@@ -275,7 +276,7 @@ export const docs = {
|
|
|
275
276
|
{
|
|
276
277
|
guidance: false,
|
|
277
278
|
description:
|
|
278
|
-
'Wrap a disabled DateInput in Tooltip to explain why it is disabled
|
|
279
|
+
'Wrap a disabled DateInput in Tooltip to explain why it is disabled. Use the disabledMessage prop instead, which ties the reason to the field.',
|
|
279
280
|
},
|
|
280
281
|
],
|
|
281
282
|
anatomy: [
|
|
@@ -368,7 +369,7 @@ export const docsZh = {
|
|
|
368
369
|
{
|
|
369
370
|
guidance: false,
|
|
370
371
|
description:
|
|
371
|
-
'Wrap a disabled DateInput in Tooltip to explain why it is disabled
|
|
372
|
+
'Wrap a disabled DateInput in Tooltip to explain why it is disabled. Use the disabledMessage prop instead, which ties the reason to the field.',
|
|
372
373
|
},
|
|
373
374
|
],
|
|
374
375
|
},
|
|
@@ -400,14 +401,14 @@ export const docsZh = {
|
|
|
400
401
|
{
|
|
401
402
|
name: 'isDisabled',
|
|
402
403
|
type: 'boolean',
|
|
403
|
-
description: '
|
|
404
|
+
description: '禁用输入框和日历。输入框仍可聚焦并暴露 `aria-disabled`,但不能输入或打开日历。',
|
|
404
405
|
default: 'false',
|
|
405
406
|
},
|
|
406
407
|
{
|
|
407
408
|
name: 'disabledMessage',
|
|
408
409
|
type: 'string',
|
|
409
410
|
description:
|
|
410
|
-
'说明输入框为何被禁用。与 isDisabled
|
|
411
|
+
'说明输入框为何被禁用。与 isDisabled 一起使用时,在悬停/键盘聚焦时显示提示(仍阻止输入和激活)。请使用此属性,而不是用 Tooltip 包裹已禁用的 DateInput。',
|
|
411
412
|
},
|
|
412
413
|
{
|
|
413
414
|
name: 'value',
|
|
@@ -621,7 +622,7 @@ export const docsDense = {
|
|
|
621
622
|
{
|
|
622
623
|
guidance: false,
|
|
623
624
|
description:
|
|
624
|
-
'Wrap a disabled DateInput in Tooltip to explain why it is disabled
|
|
625
|
+
'Wrap a disabled DateInput in Tooltip to explain why it is disabled. Use the disabledMessage prop instead, which ties the reason to the field.',
|
|
625
626
|
},
|
|
626
627
|
],
|
|
627
628
|
},
|
|
@@ -633,7 +634,7 @@ export const docsDense = {
|
|
|
633
634
|
isRequired: 'mark field required',
|
|
634
635
|
isDisabled: 'disable input+calendar',
|
|
635
636
|
disabledMessage:
|
|
636
|
-
|
|
637
|
+
"reason shown in a tooltip on hover/focus when disabled; describes the field's focusable controls",
|
|
637
638
|
value: 'selected date YYYY-MM-DD',
|
|
638
639
|
onChange: 'callback on date change',
|
|
639
640
|
changeAction: 'async action after onChange; drives optimistic UI',
|
|
@@ -84,9 +84,14 @@ describe('DateInput', () => {
|
|
|
84
84
|
expect(screen.getByRole('combobox')).not.toHaveAttribute('aria-required');
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
-
it('
|
|
87
|
+
it('keeps a disabled input focusable without native disabled (AST-085 FR1)', () => {
|
|
88
88
|
render(<DateInput label="Date" isDisabled onChange={() => {}} />);
|
|
89
|
-
|
|
89
|
+
const input = screen.getByRole('combobox');
|
|
90
|
+
expect(input).not.toHaveAttribute('disabled');
|
|
91
|
+
expect(input).toHaveAttribute('aria-disabled', 'true');
|
|
92
|
+
expect(input).toHaveAttribute('readonly');
|
|
93
|
+
input.focus();
|
|
94
|
+
expect(input).toHaveFocus();
|
|
90
95
|
});
|
|
91
96
|
|
|
92
97
|
it('is not disabled by default', () => {
|
|
@@ -115,10 +120,16 @@ describe('DateInput', () => {
|
|
|
115
120
|
expect(button).not.toBeDisabled();
|
|
116
121
|
});
|
|
117
122
|
|
|
118
|
-
it('calendar button is disabled when isDisabled is true', () => {
|
|
123
|
+
it('calendar button is focusable-disabled when isDisabled is true', () => {
|
|
119
124
|
render(<DateInput label="Date" isDisabled onChange={() => {}} />);
|
|
120
125
|
const button = getButton('Open calendar');
|
|
121
|
-
expect(button).
|
|
126
|
+
expect(button).not.toHaveAttribute('disabled');
|
|
127
|
+
expect(button).toHaveAttribute('aria-disabled', 'true');
|
|
128
|
+
fireEvent.click(button);
|
|
129
|
+
expect(screen.getByRole('combobox')).toHaveAttribute(
|
|
130
|
+
'aria-expanded',
|
|
131
|
+
'false',
|
|
132
|
+
);
|
|
122
133
|
});
|
|
123
134
|
|
|
124
135
|
it('does not call onChange while typing invalid input', async () => {
|
|
@@ -349,10 +360,15 @@ describe('DateInput', () => {
|
|
|
349
360
|
|
|
350
361
|
// --- P1: Input disabled during isBusy (isLoading) ---
|
|
351
362
|
|
|
352
|
-
it('
|
|
363
|
+
it('blocks input and button without native disabled when isLoading is true', () => {
|
|
353
364
|
render(<DateInput label="Date" isLoading onChange={() => {}} />);
|
|
354
|
-
expect(screen.getByRole('combobox')).
|
|
355
|
-
expect(
|
|
365
|
+
expect(screen.getByRole('combobox')).not.toHaveAttribute('disabled');
|
|
366
|
+
expect(screen.getByRole('combobox')).toHaveAttribute(
|
|
367
|
+
'aria-disabled',
|
|
368
|
+
'true',
|
|
369
|
+
);
|
|
370
|
+
expect(getButton('Open calendar')).not.toHaveAttribute('disabled');
|
|
371
|
+
expect(getButton('Open calendar')).toHaveAttribute('aria-disabled', 'true');
|
|
356
372
|
});
|
|
357
373
|
|
|
358
374
|
it('shows spinner when isLoading is true', () => {
|
|
@@ -526,7 +542,8 @@ describe('DateInput', () => {
|
|
|
526
542
|
render(<DateInput label="Date" isDisabled onChange={() => {}} />);
|
|
527
543
|
|
|
528
544
|
const input = screen.getByRole('combobox');
|
|
529
|
-
expect(input).
|
|
545
|
+
expect(input).toHaveAttribute('aria-disabled', 'true');
|
|
546
|
+
expect(input).not.toHaveAttribute('disabled');
|
|
530
547
|
});
|
|
531
548
|
|
|
532
549
|
// --- P1: aria-busy on input ---
|
|
@@ -818,7 +835,10 @@ describe('DateInput', () => {
|
|
|
818
835
|
expect(input).toHaveAttribute('aria-disabled', 'true');
|
|
819
836
|
expect(input.getAttribute('aria-describedby')).toContain(tooltip.id);
|
|
820
837
|
expect(tooltip).toHaveTextContent('Scheduling is locked');
|
|
821
|
-
expect(getButton('Open calendar')).
|
|
838
|
+
expect(getButton('Open calendar')).toHaveAttribute(
|
|
839
|
+
'aria-disabled',
|
|
840
|
+
'true',
|
|
841
|
+
);
|
|
822
842
|
});
|
|
823
843
|
});
|
|
824
844
|
|
|
@@ -875,6 +895,10 @@ describe('DateInput', () => {
|
|
|
875
895
|
);
|
|
876
896
|
|
|
877
897
|
const tooltip = screen.getByRole('tooltip', h);
|
|
898
|
+
// The calendar button keeps its enabled tab stop (spec:AST-085 FR1),
|
|
899
|
+
// so the input is the second stop.
|
|
900
|
+
await user.tab();
|
|
901
|
+
expect(getButton('Open calendar')).toHaveFocus();
|
|
878
902
|
await user.tab();
|
|
879
903
|
expect(screen.getByRole('combobox')).toHaveFocus();
|
|
880
904
|
await waitFor(() => {
|
|
@@ -908,6 +932,50 @@ describe('DateInput', () => {
|
|
|
908
932
|
expect(input).toHaveAttribute('readonly');
|
|
909
933
|
});
|
|
910
934
|
|
|
935
|
+
it('does not call a caller onClick while disabled (AST-085 FR2)', () => {
|
|
936
|
+
const onClick = vi.fn();
|
|
937
|
+
render(<DateInput label="Date" isDisabled onClick={onClick} />);
|
|
938
|
+
fireEvent.click(screen.getByRole('combobox'));
|
|
939
|
+
expect(onClick).not.toHaveBeenCalled();
|
|
940
|
+
});
|
|
941
|
+
|
|
942
|
+
it('links the reason tooltip from the calendar button too (AST-085 FR5)', () => {
|
|
943
|
+
render(
|
|
944
|
+
<DateInput
|
|
945
|
+
label="Date"
|
|
946
|
+
isDisabled
|
|
947
|
+
disabledMessage="You need the Editor role"
|
|
948
|
+
/>,
|
|
949
|
+
);
|
|
950
|
+
const tooltip = screen.getByRole('tooltip', h);
|
|
951
|
+
expect(
|
|
952
|
+
getButton('Open calendar').getAttribute('aria-describedby'),
|
|
953
|
+
).toContain(tooltip.id);
|
|
954
|
+
});
|
|
955
|
+
|
|
956
|
+
it('drops a draft instead of committing it when the field becomes disabled (AST-085 FR2)', async () => {
|
|
957
|
+
const user = userEvent.setup();
|
|
958
|
+
const onChange = vi.fn();
|
|
959
|
+
const {rerender} = render(
|
|
960
|
+
<DateInput label="Date" value="2026-03-10" onChange={onChange} />,
|
|
961
|
+
);
|
|
962
|
+
const input = screen.getByRole('combobox');
|
|
963
|
+
await user.click(input);
|
|
964
|
+
await user.clear(input);
|
|
965
|
+
rerender(
|
|
966
|
+
<DateInput
|
|
967
|
+
label="Date"
|
|
968
|
+
value="2026-03-10"
|
|
969
|
+
onChange={onChange}
|
|
970
|
+
isDisabled
|
|
971
|
+
/>,
|
|
972
|
+
);
|
|
973
|
+
expect(input).toHaveFocus();
|
|
974
|
+
await user.keyboard('{Enter}');
|
|
975
|
+
await user.tab();
|
|
976
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
977
|
+
});
|
|
978
|
+
|
|
911
979
|
it('links the reason tooltip from the input via aria-describedby', () => {
|
|
912
980
|
render(
|
|
913
981
|
<DateInput
|
|
@@ -941,11 +1009,18 @@ describe('DateInput', () => {
|
|
|
941
1009
|
expect(onChange).not.toHaveBeenCalled();
|
|
942
1010
|
});
|
|
943
1011
|
|
|
944
|
-
it('
|
|
945
|
-
|
|
1012
|
+
it('blocks value changes and opening when disabled without a reason (AST-085 FR1, FR2)', async () => {
|
|
1013
|
+
const user = userEvent.setup();
|
|
1014
|
+
const onChange = vi.fn();
|
|
1015
|
+
render(<DateInput label="Date" onChange={onChange} isDisabled />);
|
|
946
1016
|
const input = screen.getByRole('combobox');
|
|
947
|
-
expect(input).
|
|
948
|
-
|
|
1017
|
+
expect(input).not.toHaveAttribute('disabled');
|
|
1018
|
+
await user.click(input);
|
|
1019
|
+
await user.type(input, '2026-03-15');
|
|
1020
|
+
await user.keyboard('{ArrowDown}');
|
|
1021
|
+
expect(input).toHaveValue('');
|
|
1022
|
+
expect(input).toHaveAttribute('aria-expanded', 'false');
|
|
1023
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
949
1024
|
});
|
|
950
1025
|
});
|
|
951
1026
|
|
|
@@ -79,6 +79,18 @@ import {
|
|
|
79
79
|
import {useDevWarning} from '../hooks/useDevWarning';
|
|
80
80
|
|
|
81
81
|
const styles = stylex.create({
|
|
82
|
+
// The shared disabled style drops the focus ring; restore it while this
|
|
83
|
+
// field's own input holds focus (spec:AST-085 FR6). Defaults repeat it.
|
|
84
|
+
disabledFocusRing: {
|
|
85
|
+
borderColor: {
|
|
86
|
+
default: colorVars['--color-border-emphasized'],
|
|
87
|
+
':has(input:focus)': colorVars['--color-accent'],
|
|
88
|
+
},
|
|
89
|
+
boxShadow: {
|
|
90
|
+
default: 'none',
|
|
91
|
+
':has(input:focus)': `inset 0px 0px 0px 2px ${colorVars['--color-accent-muted']}`,
|
|
92
|
+
},
|
|
93
|
+
},
|
|
82
94
|
iconButton: {
|
|
83
95
|
display: 'flex',
|
|
84
96
|
alignItems: 'center',
|
|
@@ -241,13 +253,13 @@ export interface DateInputProps extends Omit<
|
|
|
241
253
|
|
|
242
254
|
/**
|
|
243
255
|
* Explains why the input is disabled. When set together with
|
|
244
|
-
* `isDisabled`, the
|
|
245
|
-
* keyboard focus, and the field
|
|
256
|
+
* `isDisabled`, the field shows a tooltip with this text on hover and
|
|
257
|
+
* keyboard focus, and the field's focusable controls are described by it,
|
|
246
258
|
* so the reason is discoverable by keyboard and assistive technology.
|
|
247
259
|
* Typing and calendar activation stay blocked.
|
|
248
260
|
*
|
|
249
|
-
* Use this instead of wrapping a disabled input in `Tooltip
|
|
250
|
-
*
|
|
261
|
+
* Use this instead of wrapping a disabled input in `Tooltip`, so the
|
|
262
|
+
* reason is tied to the field.
|
|
251
263
|
*
|
|
252
264
|
* @example
|
|
253
265
|
* ```
|
|
@@ -537,11 +549,11 @@ function PointerDateField({
|
|
|
537
549
|
const isBusy = isLoading || optimisticValue !== value;
|
|
538
550
|
const isEffectivelyDisabled = isDisabled || isBusy;
|
|
539
551
|
|
|
540
|
-
//
|
|
541
|
-
//
|
|
542
|
-
//
|
|
543
|
-
//
|
|
544
|
-
//
|
|
552
|
+
// A disabled or busy field never renders native `disabled` (spec:AST-085
|
|
553
|
+
// FR1): the input and calendar button stay focusable via aria-disabled.
|
|
554
|
+
// Typing is blocked with readOnly and value mutation guards; calendar
|
|
555
|
+
// activation is blocked by the isEffectivelyDisabled guards. The
|
|
556
|
+
// disabled-reason tooltip's listeners attach to the input container. Only
|
|
545
557
|
// the persistent isDisabled state (not the transient busy state) surfaces a
|
|
546
558
|
// reason.
|
|
547
559
|
const showsDisabledMessage = isDisabled && !!disabledMessage;
|
|
@@ -703,8 +715,8 @@ function PointerDateField({
|
|
|
703
715
|
// Handle input text change - update immediately if valid and allowed
|
|
704
716
|
const handleInputChange = useCallback(
|
|
705
717
|
(e: React.ChangeEvent<HTMLInputElement>) => {
|
|
706
|
-
//
|
|
707
|
-
//
|
|
718
|
+
// The input is never natively disabled (spec:AST-085 FR1), so guard
|
|
719
|
+
// value mutation explicitly (readOnly also blocks typing).
|
|
708
720
|
if (isEffectivelyDisabled) {
|
|
709
721
|
return;
|
|
710
722
|
}
|
|
@@ -733,6 +745,11 @@ function PointerDateField({
|
|
|
733
745
|
if (pendingInput === null) {
|
|
734
746
|
return;
|
|
735
747
|
}
|
|
748
|
+
// Disabled or busy: keep the value, drop the draft (spec:AST-085 FR2).
|
|
749
|
+
if (isEffectivelyDisabled) {
|
|
750
|
+
setPendingInput(null);
|
|
751
|
+
return;
|
|
752
|
+
}
|
|
736
753
|
|
|
737
754
|
if (!pendingInput.trim()) {
|
|
738
755
|
if (value !== undefined) {
|
|
@@ -750,7 +767,14 @@ function PointerDateField({
|
|
|
750
767
|
}
|
|
751
768
|
}
|
|
752
769
|
setPendingInput(null);
|
|
753
|
-
}, [
|
|
770
|
+
}, [
|
|
771
|
+
pendingInput,
|
|
772
|
+
isEffectivelyDisabled,
|
|
773
|
+
value,
|
|
774
|
+
fireChange,
|
|
775
|
+
isDateDisabled,
|
|
776
|
+
locale,
|
|
777
|
+
]);
|
|
754
778
|
|
|
755
779
|
// Handle blur - validate, check constraints, and clear pending input
|
|
756
780
|
const handleBlur = useCallback(() => {
|
|
@@ -808,6 +832,7 @@ function PointerDateField({
|
|
|
808
832
|
inputWrapperStyles.base,
|
|
809
833
|
sizeStyles[size],
|
|
810
834
|
isEffectivelyDisabled && inputWrapperStyles.disabled,
|
|
835
|
+
isEffectivelyDisabled && styles.disabledFocusRing,
|
|
811
836
|
status && inputStatusBorderStyles[status.type],
|
|
812
837
|
status &&
|
|
813
838
|
!isEffectivelyDisabled &&
|
|
@@ -823,7 +848,11 @@ function PointerDateField({
|
|
|
823
848
|
<button
|
|
824
849
|
type="button"
|
|
825
850
|
onClick={handleToggle}
|
|
826
|
-
disabled={isEffectivelyDisabled}
|
|
851
|
+
aria-disabled={isEffectivelyDisabled || undefined}
|
|
852
|
+
// A tab stop while disabled too, so it carries the reason (FR5).
|
|
853
|
+
aria-describedby={
|
|
854
|
+
showsDisabledMessage ? disabledMessageTooltip.describedBy : undefined
|
|
855
|
+
}
|
|
827
856
|
aria-label={
|
|
828
857
|
popover.isOpen
|
|
829
858
|
? t('@astryx.dateInput.toggleCalendarClose')
|
|
@@ -858,16 +887,15 @@ function PointerDateField({
|
|
|
858
887
|
value={displayValue}
|
|
859
888
|
onChange={handleInputChange}
|
|
860
889
|
onBlur={chainEventHandlers(handleBlur, onBlurProp)}
|
|
861
|
-
onClick={
|
|
890
|
+
onClick={
|
|
891
|
+
isEffectivelyDisabled
|
|
892
|
+
? undefined
|
|
893
|
+
: chainEventHandlers(handleInputClick, onClickProp)
|
|
894
|
+
}
|
|
862
895
|
onKeyDown={chainEventHandlers(handleInputKeyDown, onKeyDownProp)}
|
|
863
896
|
placeholder={placeholder}
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
// blocked with readOnly and the mutation guards, and calendar
|
|
867
|
-
// activation is blocked by the isEffectivelyDisabled guards.
|
|
868
|
-
disabled={isEffectivelyDisabled && !showsDisabledMessage}
|
|
869
|
-
aria-disabled={showsDisabledMessage ? 'true' : undefined}
|
|
870
|
-
readOnly={showsDisabledMessage || undefined}
|
|
897
|
+
aria-disabled={isEffectivelyDisabled ? 'true' : undefined}
|
|
898
|
+
readOnly={isEffectivelyDisabled || undefined}
|
|
871
899
|
aria-labelledby={
|
|
872
900
|
ariaLabelledByProp != null
|
|
873
901
|
? joinAriaIDs(ariaLabelledBy ?? fieldLabelID, ariaLabelledByProp)
|
|
@@ -554,11 +554,32 @@ describe('DateInput — field parity', () => {
|
|
|
554
554
|
onChange={() => {}}
|
|
555
555
|
/>,
|
|
556
556
|
);
|
|
557
|
-
|
|
557
|
+
// Focusable, never natively disabled (AST-085 FR1), and still inert.
|
|
558
|
+
expect(field()).not.toHaveAttribute('disabled');
|
|
559
|
+
expect(field()).toHaveAttribute('aria-disabled', 'true');
|
|
560
|
+
field().focus();
|
|
561
|
+
expect(field()).toHaveFocus();
|
|
558
562
|
fireEvent.click(field());
|
|
563
|
+
fireEvent.keyDown(field(), {key: 'Enter'});
|
|
564
|
+
expect(field()).toHaveAttribute('aria-expanded', 'false');
|
|
559
565
|
expect(screen.queryByRole('grid')).not.toBeInTheDocument();
|
|
560
566
|
});
|
|
561
567
|
|
|
568
|
+
it('does not call a caller onClick while disabled (AST-085 FR2)', () => {
|
|
569
|
+
const onClick = vi.fn();
|
|
570
|
+
render(
|
|
571
|
+
<DateInput
|
|
572
|
+
nativePicker="never"
|
|
573
|
+
label="Ship date"
|
|
574
|
+
isDisabled
|
|
575
|
+
onClick={onClick}
|
|
576
|
+
onChange={() => {}}
|
|
577
|
+
/>,
|
|
578
|
+
);
|
|
579
|
+
fireEvent.click(field());
|
|
580
|
+
expect(onClick).not.toHaveBeenCalled();
|
|
581
|
+
});
|
|
582
|
+
|
|
562
583
|
it('stays focusable and explains itself when disabled with a reason', () => {
|
|
563
584
|
render(
|
|
564
585
|
<DateInput
|
|
@@ -601,12 +601,38 @@ describe('DateInput nativePicker', () => {
|
|
|
601
601
|
await act(async () => resolveAction());
|
|
602
602
|
});
|
|
603
603
|
|
|
604
|
-
it('
|
|
604
|
+
it('keeps a disabled control focusable and its toggle inert (AST-085 FR1, FR2)', () => {
|
|
605
605
|
stubPointer(true);
|
|
606
606
|
render(<DateInput label="Date" isDisabled onChange={() => {}} />);
|
|
607
607
|
|
|
608
|
-
|
|
609
|
-
expect(
|
|
608
|
+
const input = getInput();
|
|
609
|
+
expect(input).not.toHaveAttribute('disabled');
|
|
610
|
+
expect(input).toHaveAttribute('aria-disabled', 'true');
|
|
611
|
+
expect(input).toHaveAttribute('readonly');
|
|
612
|
+
input.focus();
|
|
613
|
+
expect(input).toHaveFocus();
|
|
614
|
+
const toggle = screen.getByLabelText('Open calendar');
|
|
615
|
+
expect(toggle).not.toHaveAttribute('disabled');
|
|
616
|
+
expect(toggle).toHaveAttribute('aria-disabled', 'true');
|
|
617
|
+
const showPicker = vi.fn();
|
|
618
|
+
Object.defineProperty(input, 'showPicker', {value: showPicker});
|
|
619
|
+
fireEvent.click(toggle);
|
|
620
|
+
expect(showPicker).not.toHaveBeenCalled();
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
it('does not call a caller onClick while disabled (AST-085 FR2)', () => {
|
|
624
|
+
stubPointer(true);
|
|
625
|
+
const onClick = vi.fn();
|
|
626
|
+
render(
|
|
627
|
+
<DateInput
|
|
628
|
+
label="Date"
|
|
629
|
+
isDisabled
|
|
630
|
+
onClick={onClick}
|
|
631
|
+
onChange={() => {}}
|
|
632
|
+
/>,
|
|
633
|
+
);
|
|
634
|
+
fireEvent.click(getInput());
|
|
635
|
+
expect(onClick).not.toHaveBeenCalled();
|
|
610
636
|
});
|
|
611
637
|
|
|
612
638
|
it('ignores a change while disabled', () => {
|
|
@@ -82,6 +82,17 @@ import {
|
|
|
82
82
|
import {chainEventHandlers} from '../utils/chainEventHandlers';
|
|
83
83
|
|
|
84
84
|
const styles = stylex.create({
|
|
85
|
+
// Same as DateInput's: the focus ring for a focused disabled field.
|
|
86
|
+
disabledFocusRing: {
|
|
87
|
+
borderColor: {
|
|
88
|
+
default: colorVars['--color-border-emphasized'],
|
|
89
|
+
':has(input:focus)': colorVars['--color-accent'],
|
|
90
|
+
},
|
|
91
|
+
boxShadow: {
|
|
92
|
+
default: 'none',
|
|
93
|
+
':has(input:focus)': `inset 0px 0px 0px 2px ${colorVars['--color-accent-muted']}`,
|
|
94
|
+
},
|
|
95
|
+
},
|
|
85
96
|
wrapper: {
|
|
86
97
|
gap: spacingVars['--spacing-2'],
|
|
87
98
|
},
|
|
@@ -323,9 +334,10 @@ export function NativeDateField({
|
|
|
323
334
|
// platform picker from its input.
|
|
324
335
|
const isEffectivelyDisabled = isDisabled || isLoading;
|
|
325
336
|
|
|
326
|
-
//
|
|
327
|
-
// disabled
|
|
328
|
-
//
|
|
337
|
+
// Same contract as the other two surfaces: a disabled field never renders
|
|
338
|
+
// native `disabled` (spec:AST-085 FR1); the input stays focusable via
|
|
339
|
+
// aria-disabled and readOnly. The disabled-reason tooltip's listeners
|
|
340
|
+
// attach to the wrapper.
|
|
329
341
|
const showsDisabledMessage = isDisabled && !!disabledMessage;
|
|
330
342
|
const disabledMessageTooltip = useTooltip({
|
|
331
343
|
placement: 'above',
|
|
@@ -582,6 +594,7 @@ export function NativeDateField({
|
|
|
582
594
|
sizeStyles[size],
|
|
583
595
|
styles.wrapper,
|
|
584
596
|
isEffectivelyDisabled && inputWrapperStyles.disabled,
|
|
597
|
+
isEffectivelyDisabled && styles.disabledFocusRing,
|
|
585
598
|
status && inputStatusBorderStyles[status.type],
|
|
586
599
|
status &&
|
|
587
600
|
!isEffectivelyDisabled &&
|
|
@@ -597,7 +610,7 @@ export function NativeDateField({
|
|
|
597
610
|
<button
|
|
598
611
|
type="button"
|
|
599
612
|
onClick={openPicker}
|
|
600
|
-
disabled={isEffectivelyDisabled}
|
|
613
|
+
aria-disabled={isEffectivelyDisabled || undefined}
|
|
601
614
|
aria-label={t('@astryx.dateInput.openCalendar')}
|
|
602
615
|
tabIndex={-1}
|
|
603
616
|
{...stylex.props(
|
|
@@ -615,6 +628,7 @@ export function NativeDateField({
|
|
|
615
628
|
<span {...stylex.props(styles.slot)}>
|
|
616
629
|
<input
|
|
617
630
|
{...controlProps}
|
|
631
|
+
onClick={isEffectivelyDisabled ? undefined : controlProps.onClick}
|
|
618
632
|
ref={mergedInputRef}
|
|
619
633
|
id={id}
|
|
620
634
|
type="date"
|
|
@@ -626,9 +640,8 @@ export function NativeDateField({
|
|
|
626
640
|
onBlur={chainEventHandlers(handleBlur, onBlurProp)}
|
|
627
641
|
min={min}
|
|
628
642
|
max={max}
|
|
629
|
-
disabled={isEffectivelyDisabled
|
|
630
|
-
|
|
631
|
-
readOnly={showsDisabledMessage || undefined}
|
|
643
|
+
aria-disabled={isEffectivelyDisabled ? 'true' : undefined}
|
|
644
|
+
readOnly={isEffectivelyDisabled || undefined}
|
|
632
645
|
aria-labelledby={
|
|
633
646
|
ariaLabelledByProp != null
|
|
634
647
|
? joinAriaIDs(ariaLabelledBy ?? fieldLabelID, ariaLabelledByProp)
|
|
@@ -166,6 +166,17 @@ const sizeStyles = stylex.create({
|
|
|
166
166
|
});
|
|
167
167
|
|
|
168
168
|
const styles = stylex.create({
|
|
169
|
+
// Same as DateInput's: the focus ring for a focused disabled field.
|
|
170
|
+
disabledFocusRing: {
|
|
171
|
+
borderColor: {
|
|
172
|
+
default: colorVars['--color-border-emphasized'],
|
|
173
|
+
':has(input:focus)': colorVars['--color-accent'],
|
|
174
|
+
},
|
|
175
|
+
boxShadow: {
|
|
176
|
+
default: 'none',
|
|
177
|
+
':has(input:focus)': `inset 0px 0px 0px 2px ${colorVars['--color-accent-muted']}`,
|
|
178
|
+
},
|
|
179
|
+
},
|
|
169
180
|
// ---- the closed field ----
|
|
170
181
|
wrapper: {
|
|
171
182
|
gap: spacingVars['--spacing-2'],
|
|
@@ -620,11 +631,11 @@ export function TouchDateField({
|
|
|
620
631
|
const isBusy = isLoading || optimisticValue !== value;
|
|
621
632
|
const isEffectivelyDisabled = isDisabled || isBusy;
|
|
622
633
|
|
|
623
|
-
//
|
|
624
|
-
//
|
|
625
|
-
//
|
|
626
|
-
//
|
|
627
|
-
//
|
|
634
|
+
// Same contract as DateInput: a disabled or busy field never renders native
|
|
635
|
+
// `disabled` (spec:AST-085 FR1); the input stays focusable via
|
|
636
|
+
// aria-disabled. The disabled-reason tooltip's listeners attach to the
|
|
637
|
+
// wrapper. Only the persistent disabled state surfaces a reason, never the
|
|
638
|
+
// transient busy one.
|
|
628
639
|
const showsDisabledMessage = isDisabled && !!disabledMessage;
|
|
629
640
|
const disabledMessageTooltip = useTooltip({
|
|
630
641
|
placement: 'above',
|
|
@@ -1213,6 +1224,7 @@ export function TouchDateField({
|
|
|
1213
1224
|
sizeStyles[size],
|
|
1214
1225
|
styles.wrapper,
|
|
1215
1226
|
isEffectivelyDisabled && inputWrapperStyles.disabled,
|
|
1227
|
+
isEffectivelyDisabled && styles.disabledFocusRing,
|
|
1216
1228
|
status && inputStatusBorderStyles[status.type],
|
|
1217
1229
|
status &&
|
|
1218
1230
|
!isEffectivelyDisabled &&
|
|
@@ -1228,7 +1240,7 @@ export function TouchDateField({
|
|
|
1228
1240
|
<button
|
|
1229
1241
|
type="button"
|
|
1230
1242
|
onClick={openSheet}
|
|
1231
|
-
disabled={isEffectivelyDisabled}
|
|
1243
|
+
aria-disabled={isEffectivelyDisabled || undefined}
|
|
1232
1244
|
aria-label={t('@astryx.dateInput.openCalendar')}
|
|
1233
1245
|
tabIndex={-1}
|
|
1234
1246
|
{...stylex.props(
|
|
@@ -1259,11 +1271,14 @@ export function TouchDateField({
|
|
|
1259
1271
|
readOnly
|
|
1260
1272
|
inputMode="none"
|
|
1261
1273
|
onChange={() => {}}
|
|
1262
|
-
onClick={
|
|
1274
|
+
onClick={
|
|
1275
|
+
isEffectivelyDisabled
|
|
1276
|
+
? undefined
|
|
1277
|
+
: chainEventHandlers(openSheet, onClickProp)
|
|
1278
|
+
}
|
|
1263
1279
|
onKeyDown={chainEventHandlers(handleInputKeyDown, onKeyDownProp)}
|
|
1264
1280
|
placeholder={placeholder}
|
|
1265
|
-
disabled={isEffectivelyDisabled
|
|
1266
|
-
aria-disabled={showsDisabledMessage ? 'true' : undefined}
|
|
1281
|
+
aria-disabled={isEffectivelyDisabled ? 'true' : undefined}
|
|
1267
1282
|
aria-labelledby={
|
|
1268
1283
|
ariaLabelledByProp != null
|
|
1269
1284
|
? joinAriaIDs(ariaLabelledBy ?? fieldLabelID, ariaLabelledByProp)
|
|
@@ -45,14 +45,15 @@ export const docs = {
|
|
|
45
45
|
{
|
|
46
46
|
name: 'isDisabled',
|
|
47
47
|
type: 'boolean',
|
|
48
|
-
description:
|
|
48
|
+
description:
|
|
49
|
+
'Disable the trigger and picker. The trigger stays focusable and exposes `aria-disabled`; opening is blocked.',
|
|
49
50
|
default: 'false',
|
|
50
51
|
},
|
|
51
52
|
{
|
|
52
53
|
name: 'disabledMessage',
|
|
53
54
|
type: 'string',
|
|
54
55
|
description:
|
|
55
|
-
'Explains why the input is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and
|
|
56
|
+
'Explains why the input is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and describes the trigger (activation stays blocked). Use this instead of wrapping a disabled DateRangeInput in Tooltip.',
|
|
56
57
|
},
|
|
57
58
|
{
|
|
58
59
|
name: 'value',
|
|
@@ -240,7 +241,7 @@ export const docs = {
|
|
|
240
241
|
{
|
|
241
242
|
guidance: false,
|
|
242
243
|
description:
|
|
243
|
-
'Wrap a disabled DateRangeInput in Tooltip to explain why it is disabled
|
|
244
|
+
'Wrap a disabled DateRangeInput in Tooltip to explain why it is disabled. Use the disabledMessage prop instead, which ties the reason to the field.',
|
|
244
245
|
},
|
|
245
246
|
],
|
|
246
247
|
anatomy: [
|
|
@@ -344,7 +345,7 @@ export const docsDense = {
|
|
|
344
345
|
{
|
|
345
346
|
guidance: false,
|
|
346
347
|
description:
|
|
347
|
-
'Wrap a disabled DateRangeInput in Tooltip to explain why it is disabled
|
|
348
|
+
'Wrap a disabled DateRangeInput in Tooltip to explain why it is disabled. Use the disabledMessage prop instead, which ties the reason to the field.',
|
|
348
349
|
},
|
|
349
350
|
],
|
|
350
351
|
},
|
|
@@ -356,7 +357,7 @@ export const docsDense = {
|
|
|
356
357
|
isRequired: 'mark field required',
|
|
357
358
|
isDisabled: 'disable trigger+picker',
|
|
358
359
|
disabledMessage:
|
|
359
|
-
'reason shown in a tooltip on hover/focus when disabled;
|
|
360
|
+
'reason shown in a tooltip on hover/focus when disabled; describes the trigger',
|
|
360
361
|
value:
|
|
361
362
|
'selected range {start, end} or null; import DateRange type from @astryxdesign/core/DateRangeInput (do not redeclare)',
|
|
362
363
|
onChange: 'callback on range change; null on clear',
|