@astryxdesign/core 0.7.2 → 0.7.3-canary.06872b4
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/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +19 -24
- 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/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 +12 -14
- 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 +2 -1
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- 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/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +14 -2
- package/dist/astryx.css +4 -2
- 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/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 +35 -8
- package/src/BottomSheet/BottomSheet.spec.md +13 -6
- package/src/BottomSheet/BottomSheetSwitcher.spec.md +121 -51
- 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/ContextMenu/ContextMenu.test.tsx +41 -0
- package/src/DateRangeInput/DateRangeInput.spec.md +13 -13
- 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/DropdownMenuSubMenu.doc.mjs +16 -1
- package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +623 -1
- package/src/DropdownMenu/DropdownMenuSubMenu.tsx +556 -99
- 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/FileInput/FileInput.test.tsx +30 -7
- package/src/FileInput/FileInput.tsx +21 -11
- package/src/Selector/Selector.spec.md +11 -11
- package/src/Selector/Selector.test.tsx +16 -0
- 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 +29 -8
- package/src/Switch/Switch.tsx +13 -14
- 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/TimeInput.doc.mjs +5 -3
- package/src/TimeInput/TimeInput.test.tsx +20 -0
- package/src/TimeInput/TimeInput.tsx +2 -1
- 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/Typeahead/Typeahead.test.tsx +89 -0
- package/src/Typeahead/Typeahead.tsx +15 -2
- package/src/hooks/useMenuPress.ts +45 -7
- package/src/utils/timeParser.test.ts +11 -0
- package/src/utils/timeParser.ts +9 -2
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
* Spinner, and DropdownMenu context + item roles
|
|
10
10
|
* @output Exports DropdownMenuSubMenu — a single menu row that reveals a nested
|
|
11
11
|
* menu of its own children/items: a flyout beside the row, or, on a phone,
|
|
12
|
-
* a drilled-in view in place of the parent rows.
|
|
12
|
+
* a drilled-in view in place of the parent rows. With a header or footer,
|
|
13
|
+
* that surface is a modal dialog rendered into the root's surface host,
|
|
14
|
+
* beside every menu element.
|
|
13
15
|
* @position Sub-component; place inside a DropdownMenu (or ContextMenu)
|
|
14
16
|
* alongside plain items.
|
|
15
17
|
*
|
|
@@ -54,12 +56,13 @@ import * as stylex from '@stylexjs/stylex';
|
|
|
54
56
|
import { Icon, renderIconSlot } from "../Icon/index.js";
|
|
55
57
|
import { Spinner } from "../Spinner/index.js";
|
|
56
58
|
import { MenuRegionsContext } from "./menuRegionsContext.js";
|
|
59
|
+
import { moveRegionsTab } from "./menuRegionStops.js";
|
|
57
60
|
import { Item } from "../Item/index.js";
|
|
58
61
|
import { useLayer } from "../Layer/useLayer.js";
|
|
59
62
|
import { layerAnimations } from "../Layer/layerAnimations.stylex.js";
|
|
60
63
|
import { useListFocus } from "../hooks/useListFocus.js";
|
|
61
64
|
import { useMenuHover } from "../hooks/useMenuHover.js";
|
|
62
|
-
import { isMenuPressActivation, useMenuPress } from "../hooks/useMenuPress.js";
|
|
65
|
+
import { isMenuPressActivation, MENU_PRESS_SURFACE_ATTR, useMenuPress } from "../hooks/useMenuPress.js";
|
|
63
66
|
import { useTypeahead } from "../hooks/useTypeahead.js";
|
|
64
67
|
import { useMenuOverflow } from "./useMenuOverflow.js";
|
|
65
68
|
import { resolveMenuWidth } from "./menuWidth.js";
|
|
@@ -67,11 +70,14 @@ import "../Layer/layerViewportInset.stylex.js";
|
|
|
67
70
|
import { layerViewportInset } from "../Layer/layerViewportInset.stylex.js";
|
|
68
71
|
import "../theme/tokens.stylex.js";
|
|
69
72
|
import { colorVars, spacingVars, radiusVars, durationVars, easeVars, shadowVars, typographyVars, typeScaleVars } from "../theme/tokens.stylex.js";
|
|
70
|
-
import { composeEventHandlers, mergeProps, rtlStyles } from "../utils/index.js";
|
|
73
|
+
import { composeEventHandlers, isImeKeyEvent, isRenderable, mergeProps, rtlStyles } from "../utils/index.js";
|
|
74
|
+
import { focusOutlineStyles } from "../utils/focusOutline.stylex.js";
|
|
75
|
+
import { getInteractionModality } from "../utils/interactionModality.js";
|
|
71
76
|
import { useMergedRefs } from "../hooks/useMergedRefs.js";
|
|
77
|
+
import { useDevWarning } from "../hooks/useDevWarning.js";
|
|
72
78
|
import { themeProps } from "../utils/themeProps.js";
|
|
73
79
|
import { MENU_ITEM_ROLES, MENU_ITEM_SELECTOR, MENU_BOUNDARY_SELECTOR, activateMenuItem } from "./menuItemRoles.js";
|
|
74
|
-
import { DropdownMenuContext, DropdownMenuRootOpenContext, useDropdownMenuContext, useDropdownMenuRootOpen } from "./DropdownMenuContext.js";
|
|
80
|
+
import { DropdownMenuContext, DropdownMenuRootOpenContext, DropdownMenuSurfaceContext, useDropdownMenuContext, useDropdownMenuRootOpen } from "./DropdownMenuContext.js";
|
|
75
81
|
import { focusMenuItemOnHover } from "./menuItemHover.js";
|
|
76
82
|
import { DropdownMenuItem } from "./DropdownMenuItem.js";
|
|
77
83
|
import { useTranslator } from "../i18n/index.js";
|
|
@@ -129,6 +135,21 @@ const _temp = {
|
|
|
129
135
|
"$$css": true
|
|
130
136
|
};
|
|
131
137
|
const flyoutStyles = {
|
|
138
|
+
scrollable: {
|
|
139
|
+
kORKVm: "x1odjw0f",
|
|
140
|
+
kXHlph: "x6ikm8r",
|
|
141
|
+
kZeWKH: "xish69e",
|
|
142
|
+
$$css: true
|
|
143
|
+
},
|
|
144
|
+
touchPinchZoom: {
|
|
145
|
+
kFalU9: "x1j4r261",
|
|
146
|
+
$$css: true
|
|
147
|
+
},
|
|
148
|
+
touchPanYPinchZoom: {
|
|
149
|
+
kFalU9: "xge0x1e",
|
|
150
|
+
kZeWKH: "xish69e",
|
|
151
|
+
$$css: true
|
|
152
|
+
},
|
|
132
153
|
popoverViewport: {
|
|
133
154
|
kB7OPa: "x9f619",
|
|
134
155
|
kskxy: "x1uh1i8a",
|
|
@@ -151,6 +172,94 @@ const flyoutStyles = {
|
|
|
151
172
|
|
|
152
173
|
// The drilled-in list shows in place of the parent rows, inside the parent's
|
|
153
174
|
// own box: no surface, shadow or cap of its own.
|
|
175
|
+
// With a header or footer the sub-menu's surface is a frame holding the
|
|
176
|
+
// header, the sub-menu's own role="menu" element and the footer, in one column
|
|
177
|
+
// under the flyout's block cap: the regions keep their height and the rows
|
|
178
|
+
// shrink and scroll between them.
|
|
179
|
+
// A drilled-in view with a header or footer takes the root menu's place, so
|
|
180
|
+
// it caps where the root does when the root's `menuMaxHeight` lifts the 300px
|
|
181
|
+
// cap; the viewport still bounds it.
|
|
182
|
+
const _temp2 = {
|
|
183
|
+
kskxy: "x1jols5v",
|
|
184
|
+
"$$css": true
|
|
185
|
+
};
|
|
186
|
+
const dynamicRegionStyles = {
|
|
187
|
+
viewMaxHeight: maxHeight => [_temp2, {
|
|
188
|
+
"--x-maxHeight": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(`min(${maxHeight}, ${layerViewportInset.maxBlockSize})`)
|
|
189
|
+
}]
|
|
190
|
+
};
|
|
191
|
+
const regionStyles = {
|
|
192
|
+
frame: {
|
|
193
|
+
kB7OPa: "x9f619",
|
|
194
|
+
k1xSpc: "x78zum5",
|
|
195
|
+
kXwgrk: "xdt5ytf",
|
|
196
|
+
kskxy: "x1uh1i8a",
|
|
197
|
+
"--_dropdown-menu-radius": "x1fcsqxe",
|
|
198
|
+
"--_dropdown-menu-padding": "xgory14",
|
|
199
|
+
kaIpWk: "x1n97fys",
|
|
200
|
+
$$css: true
|
|
201
|
+
},
|
|
202
|
+
menu: {
|
|
203
|
+
kB7OPa: "x9f619",
|
|
204
|
+
k1xSpc: "x78zum5",
|
|
205
|
+
kXwgrk: "xdt5ytf",
|
|
206
|
+
kOIVth: "x1lsbc85",
|
|
207
|
+
kzQI83: "x1iyjqo2",
|
|
208
|
+
kmuXW: "xs83m0k",
|
|
209
|
+
kAzted: "x2lwn1j",
|
|
210
|
+
kmVPX3: "x9epnlk",
|
|
211
|
+
kI3sdo: "x1a2a7pz",
|
|
212
|
+
k7VYTy: "xpdipgo",
|
|
213
|
+
kfSwDN: "x87ps6o",
|
|
214
|
+
$$css: true
|
|
215
|
+
},
|
|
216
|
+
hidden: {
|
|
217
|
+
k1xSpc: "x1s85apg",
|
|
218
|
+
$$css: true
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
/**
|
|
222
|
+
* Close every open flyout with a header or footer whose row sits in `menu`.
|
|
223
|
+
* Such a flyout renders beside the root's menu, not inside the flyout that
|
|
224
|
+
* holds its row, so hiding that flyout does not hide it. Each closes through
|
|
225
|
+
* the popover API, as DropdownMenu closes its flyouts when it hides, so its
|
|
226
|
+
* layer's toggle handling resets its state and reports the close; its own
|
|
227
|
+
* nested flyouts close the same way, innermost first.
|
|
228
|
+
*/
|
|
229
|
+
function hideRegionedFlyoutsIn(menu) {
|
|
230
|
+
if (menu == null) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
const doc = menu.ownerDocument;
|
|
234
|
+
const rows = menu.querySelectorAll('[aria-expanded="true"][aria-controls]');
|
|
235
|
+
for (const row of [...rows].reverse()) {
|
|
236
|
+
const frame = doc.getElementById(row.getAttribute('aria-controls') ?? '');
|
|
237
|
+
if (frame?.getAttribute('data-astryx-submenu-regions') !== 'flyout') {
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
const flyout = frame.closest('[popover]');
|
|
241
|
+
if (flyout == null) {
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
if (typeof flyout.hidePopover === 'function') {
|
|
245
|
+
if (flyout.matches(':popover-open')) {
|
|
246
|
+
flyout.hidePopover();
|
|
247
|
+
}
|
|
248
|
+
} else if (flyout.style.display === 'block') {
|
|
249
|
+
// Without the popover API the layer toggles `display`; mirror it and
|
|
250
|
+
// tell its reconciler, as DropdownMenu's own sweep does.
|
|
251
|
+
flyout.style.display = 'none';
|
|
252
|
+
const toggle = new Event('toggle', {
|
|
253
|
+
bubbles: false
|
|
254
|
+
});
|
|
255
|
+
Object.defineProperty(toggle, 'newState', {
|
|
256
|
+
value: 'closed',
|
|
257
|
+
configurable: true
|
|
258
|
+
});
|
|
259
|
+
flyout.dispatchEvent(toggle);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
154
263
|
|
|
155
264
|
/**
|
|
156
265
|
* A single menu row that reveals a nested flyout of its own items. The row
|
|
@@ -182,6 +291,8 @@ export function DropdownMenuSubMenu(props) {
|
|
|
182
291
|
menuWidth,
|
|
183
292
|
onOpenChange,
|
|
184
293
|
presentation = 'adaptive',
|
|
294
|
+
header,
|
|
295
|
+
footer,
|
|
185
296
|
children,
|
|
186
297
|
xstyle,
|
|
187
298
|
className,
|
|
@@ -200,9 +311,25 @@ export function DropdownMenuSubMenu(props) {
|
|
|
200
311
|
} = props;
|
|
201
312
|
const t = useTranslator();
|
|
202
313
|
const menuCtx = useDropdownMenuContext();
|
|
314
|
+
const rootSurface = use(DropdownMenuSurfaceContext);
|
|
203
315
|
const rootHasRegions = use(MenuRegionsContext);
|
|
204
316
|
const menuSize = menuCtx?.menuSize ?? 'md';
|
|
205
317
|
const canOpen = !isDisabled;
|
|
318
|
+
// With a header or footer the sub-menu's surface holds controls that are not
|
|
319
|
+
// menu items, so it is a modal dialog around the sub-menu's menu, rendered
|
|
320
|
+
// into the root's surface host: outside every menu element. A root that
|
|
321
|
+
// renders no host (no surface context, as in ContextMenu) has nowhere
|
|
322
|
+
// outside its menu to put them, so the sub-menu shows its rows alone there.
|
|
323
|
+
const wantsRegions = isRenderable(header) || isRenderable(footer);
|
|
324
|
+
const rootHostsSurfaces = rootSurface != null;
|
|
325
|
+
const hasRegions = wantsRegions && rootHostsSurfaces;
|
|
326
|
+
const surfaceHost = rootSurface?.host.getElement() ?? null;
|
|
327
|
+
useDevWarning('DropdownMenuSubMenu', 'header and footer show only inside a DropdownMenu; this menu has no place outside its rows for them, so they are not rendered.', wantsRegions && !rootHostsSurfaces);
|
|
328
|
+
const frameId = useId();
|
|
329
|
+
const frameRef = useRef(null);
|
|
330
|
+
const headerRef = useRef(null);
|
|
331
|
+
const footerRef = useRef(null);
|
|
332
|
+
const [isMenuKeyboardFocused, setIsMenuKeyboardFocused] = useState(false);
|
|
206
333
|
const contentId = useId();
|
|
207
334
|
const generatedTriggerId = useId();
|
|
208
335
|
// A caller's `id` names the row; the flyout stays labelled by it.
|
|
@@ -225,17 +352,31 @@ export function DropdownMenuSubMenu(props) {
|
|
|
225
352
|
}) : t('@astryx.dropdownMenu.back');
|
|
226
353
|
const [isFlyoutOpen, setIsFlyoutOpen] = useState(false);
|
|
227
354
|
const isOpen = isDrillIn ? isOnStack : isFlyoutOpen;
|
|
355
|
+
|
|
356
|
+
// Whether focus is anywhere in this flyout's frame, a level nested in it
|
|
357
|
+
// included: React brings a nested level's focus events back here through
|
|
358
|
+
// its portal, where the DOM would not.
|
|
359
|
+
const isFocusInFrameRef = useRef(false);
|
|
360
|
+
// A pointer that left while focus was inside: the flyout closes once focus
|
|
361
|
+
// leaves too.
|
|
362
|
+
const closeWhenFocusLeavesRef = useRef(false);
|
|
228
363
|
const layer = useLayer({
|
|
229
364
|
mode: 'context',
|
|
230
365
|
lightDismiss: false,
|
|
231
366
|
onShow: useCallback(() => {
|
|
367
|
+
closeWhenFocusLeavesRef.current = false;
|
|
232
368
|
setIsFlyoutOpen(true);
|
|
233
369
|
onOpenChange?.(true);
|
|
234
370
|
}, [onOpenChange]),
|
|
235
371
|
onHide: useCallback(() => {
|
|
372
|
+
closeWhenFocusLeavesRef.current = false;
|
|
373
|
+
// Whatever closed this flyout, a flyout with a header or footer opened
|
|
374
|
+
// from one of its rows closes with it: that flyout renders beside the
|
|
375
|
+
// root's menu, not inside this one, so hiding this one leaves it shown.
|
|
376
|
+
hideRegionedFlyoutsIn(triggerRef.current?.ownerDocument.getElementById(contentId) ?? null);
|
|
236
377
|
setIsFlyoutOpen(false);
|
|
237
378
|
onOpenChange?.(false);
|
|
238
|
-
}, [onOpenChange])
|
|
379
|
+
}, [onOpenChange, contentId])
|
|
239
380
|
});
|
|
240
381
|
const showLayer = useCallback(() => {
|
|
241
382
|
if (canOpen) {
|
|
@@ -243,8 +384,42 @@ export function DropdownMenuSubMenu(props) {
|
|
|
243
384
|
}
|
|
244
385
|
}, [canOpen, layer]);
|
|
245
386
|
const hideLayer = useCallback(() => {
|
|
387
|
+
// A pointer leaving a flyout with a header or footer does not close it
|
|
388
|
+
// while focus is inside: what was typed into its field stays.
|
|
389
|
+
if (hasRegions && isFocusInFrameRef.current) {
|
|
390
|
+
closeWhenFocusLeavesRef.current = true;
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
246
393
|
layer.hide();
|
|
394
|
+
}, [layer, hasRegions]);
|
|
395
|
+
const handleFrameFocus = useCallback(() => {
|
|
396
|
+
isFocusInFrameRef.current = true;
|
|
397
|
+
}, []);
|
|
398
|
+
const handleFrameBlur = useCallback(event => {
|
|
399
|
+
isFocusInFrameRef.current = false;
|
|
400
|
+
if (!closeWhenFocusLeavesRef.current) {
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
// Focus moving to another control in the frame keeps it open.
|
|
404
|
+
const next = event.relatedTarget;
|
|
405
|
+
if (next instanceof Node && event.currentTarget.contains(next)) {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
// Focus moving into a level nested in this one (React brings that
|
|
409
|
+
// focus event back through its portal), or moved by the browser itself
|
|
410
|
+
// (an arrow key in a native radio group, whose focus event follows a
|
|
411
|
+
// microtask checkpoint), arrives after this blur: decide in a task of
|
|
412
|
+
// its own, once the move has completed.
|
|
413
|
+
setTimeout(() => {
|
|
414
|
+
if (!isFocusInFrameRef.current && closeWhenFocusLeavesRef.current && triggerRef.current?.isConnected === true) {
|
|
415
|
+
closeWhenFocusLeavesRef.current = false;
|
|
416
|
+
layer.hide();
|
|
417
|
+
}
|
|
418
|
+
}, 0);
|
|
247
419
|
}, [layer]);
|
|
420
|
+
const handleFramePointerEnter = useCallback(() => {
|
|
421
|
+
closeWhenFocusLeavesRef.current = false;
|
|
422
|
+
}, []);
|
|
248
423
|
|
|
249
424
|
// Dedicated roving-focus + typeahead for this flyout level. The boundary
|
|
250
425
|
// selector scopes item collection and key handling to this flyout's own
|
|
@@ -267,8 +442,9 @@ export function DropdownMenuSubMenu(props) {
|
|
|
267
442
|
focusTrigger: true
|
|
268
443
|
})
|
|
269
444
|
});
|
|
270
|
-
// A drilled-in list scrolls with the root menu, not on its own
|
|
271
|
-
|
|
445
|
+
// A drilled-in list scrolls with the root menu, not on its own, unless it
|
|
446
|
+
// has a header or footer: then its rows scroll between them.
|
|
447
|
+
const hasOverflow = useMenuOverflow(menuRef, children, isOpen && (!isDrillIn || hasRegions));
|
|
272
448
|
const typeahead = useTypeahead({
|
|
273
449
|
getItemLabels: () => getItems().map(el => el.textContent),
|
|
274
450
|
onMatch: focusItem,
|
|
@@ -295,10 +471,10 @@ export function DropdownMenuSubMenu(props) {
|
|
|
295
471
|
isOpen: isFlyoutOpen,
|
|
296
472
|
isEnabled: canOpen && !isDrillIn && isRootMenuOpen,
|
|
297
473
|
// The safe triangle toward the flyout's near edge is built from the
|
|
298
|
-
// flyout this component renders, not the hook's own list ref
|
|
299
|
-
|
|
474
|
+
// flyout this component renders, not the hook's own list ref: the
|
|
475
|
+
// frame, with a header or footer.
|
|
476
|
+
flyoutRef: hasRegions ? frameRef : menuRef
|
|
300
477
|
});
|
|
301
|
-
|
|
302
478
|
// Where focus lands once a pushed view shows: the first row after Back for
|
|
303
479
|
// a keyboard open, the list itself for a pointer open; and the row itself
|
|
304
480
|
// once its view is popped.
|
|
@@ -465,14 +641,25 @@ export function DropdownMenuSubMenu(props) {
|
|
|
465
641
|
// only act on our own, letting the deeper level keep ownership. No manual
|
|
466
642
|
// stopPropagation needed — each level self-filters.
|
|
467
643
|
const handleContentKeyDown = useCallback(e => {
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
644
|
+
if (e.key === 'Tab') {
|
|
645
|
+
// With its own header or footer this level is a dialog: Tab walks
|
|
646
|
+
// its regions and its rows as one stop, and wraps. A deeper level
|
|
647
|
+
// has closed itself as the key bubbled up, and the walk continues
|
|
648
|
+
// from this level's rows.
|
|
649
|
+
if (hasRegions) {
|
|
650
|
+
moveRegionsTab(e, menuRef.current, headerRef.current, footerRef.current, !ownsEvent(e));
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
// In a menu with a header or footer above this level, Tab leaves the
|
|
654
|
+
// flyout stack: every open level closes as the key bubbles past it,
|
|
655
|
+
// this one's own rows or a deeper level's, and the level with the
|
|
656
|
+
// regions moves focus on.
|
|
657
|
+
if (rootHasRegions) {
|
|
658
|
+
close({
|
|
659
|
+
focusTrigger: false
|
|
660
|
+
});
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
476
663
|
}
|
|
477
664
|
if (!ownsEvent(e)) {
|
|
478
665
|
return;
|
|
@@ -518,7 +705,28 @@ export function DropdownMenuSubMenu(props) {
|
|
|
518
705
|
return;
|
|
519
706
|
}
|
|
520
707
|
listNavKeyDown(e);
|
|
521
|
-
}, [ownsEvent, close, listNavKeyDown, typeahead, menuRef, rootHasRegions]);
|
|
708
|
+
}, [ownsEvent, close, listNavKeyDown, typeahead, menuRef, rootHasRegions, hasRegions]);
|
|
709
|
+
|
|
710
|
+
// A region keeps its own keys: arrows move a field's caret and letters type.
|
|
711
|
+
// Tab moves on through the dialog's stops, and Escape returns to the row as
|
|
712
|
+
// it does from the rows.
|
|
713
|
+
const handleRegionKeyDown = useCallback(e => {
|
|
714
|
+
if (e.key === 'Tab') {
|
|
715
|
+
moveRegionsTab(e, menuRef.current, headerRef.current, footerRef.current);
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
718
|
+
// An Escape that ends an IME composition belongs to the field, and one a
|
|
719
|
+
// control in the region already handled (a menu it opened closing, a
|
|
720
|
+
// field clearing itself) belongs to that control: either closes nothing
|
|
721
|
+
// here, so one Escape affects one surface.
|
|
722
|
+
if (e.key === 'Escape' && !e.defaultPrevented && !isImeKeyEvent(e.nativeEvent)) {
|
|
723
|
+
e.preventDefault();
|
|
724
|
+
e.stopPropagation();
|
|
725
|
+
close({
|
|
726
|
+
focusTrigger: true
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
}, [menuRef, close]);
|
|
522
730
|
|
|
523
731
|
// Re-provide the menu context so nested items behave exactly like top-level
|
|
524
732
|
// ones. Selecting a leaf item must dismiss the WHOLE stack, not just this
|
|
@@ -569,29 +777,108 @@ export function DropdownMenuSubMenu(props) {
|
|
|
569
777
|
});
|
|
570
778
|
const resolvedMenuWidth = menuWidth ? resolveMenuWidth(menuWidth, layerViewportInset.maxInlineSizeFallback) : null;
|
|
571
779
|
const popoverXstyle = resolvedMenuWidth ? resolvedMenuWidth.property === 'inlineSize' ? flyoutStyles.popoverCustomIntrinsicWidth(resolvedMenuWidth.value) : flyoutStyles.popoverCustomWidth(resolvedMenuWidth.value) : flyoutStyles.popover;
|
|
572
|
-
|
|
780
|
+
|
|
781
|
+
// The flyout is a layer of its own, where layer-scoped contexts reset:
|
|
782
|
+
// nested rows get this level's menu context and the root's surface again.
|
|
783
|
+
const nestedRows = /*#__PURE__*/_jsx(DropdownMenuContext, {
|
|
573
784
|
value: nestedMenuContext,
|
|
574
|
-
children:
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
785
|
+
children: /*#__PURE__*/_jsxs(DropdownMenuSurfaceContext, {
|
|
786
|
+
value: rootSurface,
|
|
787
|
+
children: [isDrillIn && /*#__PURE__*/_jsx(DropdownMenuItem, {
|
|
788
|
+
icon: /*#__PURE__*/_jsx(Icon, {
|
|
789
|
+
icon: "chevronLeft",
|
|
790
|
+
size: "sm",
|
|
791
|
+
color: "secondary",
|
|
792
|
+
xstyle: rtlStyles.mirror
|
|
793
|
+
}),
|
|
794
|
+
label: backLabel,
|
|
795
|
+
hasCloseOnSelect: false,
|
|
796
|
+
onClick: () => close({
|
|
797
|
+
focusTrigger: true
|
|
798
|
+
})
|
|
799
|
+
}), children]
|
|
800
|
+
})
|
|
587
801
|
});
|
|
802
|
+
// A level with its own header or footer tells the levels below it, so Tab
|
|
803
|
+
// from a deeper flyout closes that flyout and this level walks on.
|
|
804
|
+
//
|
|
588
805
|
// Nested rows live in this level's flyout, a layer of their own where the
|
|
589
|
-
// layer-scoped signal resets; re-provide it
|
|
590
|
-
// dies with the root menu
|
|
806
|
+
// layer-scoped signal resets; re-provide it, as whether every level above
|
|
807
|
+
// them is open, so their pending hover intent dies with the root menu or
|
|
808
|
+
// with this level: a hover-open that fired after this level closed would
|
|
809
|
+
// leave a flyout with a header or footer shown beside the root's menu.
|
|
591
810
|
const nestedContent = /*#__PURE__*/_jsx(DropdownMenuRootOpenContext, {
|
|
592
|
-
value: isRootMenuOpen,
|
|
593
|
-
children:
|
|
811
|
+
value: isRootMenuOpen && isOpen,
|
|
812
|
+
children: hasRegions ? /*#__PURE__*/_jsx(MenuRegionsContext, {
|
|
813
|
+
value: true,
|
|
814
|
+
children: nestedRows
|
|
815
|
+
}) : nestedRows
|
|
816
|
+
});
|
|
817
|
+
|
|
818
|
+
// The menu of a sub-menu with a header or footer renders beside the root's
|
|
819
|
+
// menu, outside its DOM: it names the root so the press model counts it as
|
|
820
|
+
// nested there, as a flyout inside the root's menu is. Only this menu does:
|
|
821
|
+
// a picker placed in its header or footer stays its own press root.
|
|
822
|
+
const surfaceOwnerProps = hasRegions && rootSurface != null ? {
|
|
823
|
+
[MENU_PRESS_SURFACE_ATTR]: rootSurface.ownerId
|
|
824
|
+
} : undefined;
|
|
825
|
+
|
|
826
|
+
// With a header or footer, the dialog that holds them and the sub-menu's
|
|
827
|
+
// menu. A drilled-in view is named as its list is, by the row's label; the
|
|
828
|
+
// flyout by the row.
|
|
829
|
+
const renderRegionsFrame = (menuElement, frameProps, surface) => /*#__PURE__*/_jsxs("div", {
|
|
830
|
+
ref: frameRef,
|
|
831
|
+
id: frameId,
|
|
832
|
+
role: "dialog",
|
|
833
|
+
"aria-modal": "true"
|
|
834
|
+
// Read by the root's step-aside rule (a shown view) and by the flyout
|
|
835
|
+
// that holds this row when it closes (an open flyout).
|
|
836
|
+
,
|
|
837
|
+
"data-astryx-submenu-regions": surface,
|
|
838
|
+
...frameProps,
|
|
839
|
+
...(surface === 'flyout' ? {
|
|
840
|
+
onFocus: handleFrameFocus,
|
|
841
|
+
onBlur: handleFrameBlur,
|
|
842
|
+
onPointerEnter: handleFramePointerEnter
|
|
843
|
+
} : undefined),
|
|
844
|
+
...(surface === 'flyout' ?
|
|
845
|
+
// The flyout's frame paints its surface, so the menu target rides
|
|
846
|
+
// on it; a drilled-in view sits inside the root's surface.
|
|
847
|
+
mergeProps(themeProps('dropdown-menu'), {
|
|
848
|
+
className: "x9f619 x78zum5 xdt5ytf x1uh1i8a x1fcsqxe xgory14 x1n97fys xc0b1yq x1prclbq x1i5ehqx x1hc1fzr x19991ni xuedmi6 xlr8y92"
|
|
849
|
+
}) : stylex.props(regionStyles.frame, rootSurface?.menuMaxHeight != null && dynamicRegionStyles.viewMaxHeight(rootSurface.menuMaxHeight), frameProps.hidden === true && regionStyles.hidden)),
|
|
850
|
+
children: [isRenderable(header) && /*#__PURE__*/_jsx("div", {
|
|
851
|
+
ref: headerRef,
|
|
852
|
+
onKeyDown: handleRegionKeyDown,
|
|
853
|
+
...{
|
|
854
|
+
className: "x2lah0s x9epnlk"
|
|
855
|
+
},
|
|
856
|
+
children: header
|
|
857
|
+
}), menuElement, isRenderable(footer) && /*#__PURE__*/_jsx("div", {
|
|
858
|
+
ref: footerRef,
|
|
859
|
+
onKeyDown: handleRegionKeyDown,
|
|
860
|
+
...{
|
|
861
|
+
className: "x2lah0s x9epnlk"
|
|
862
|
+
},
|
|
863
|
+
children: footer
|
|
864
|
+
})]
|
|
594
865
|
});
|
|
866
|
+
// A flyout with a header or footer renders into the root's surface host,
|
|
867
|
+
// beside the root's menu rather than inside it; any other flyout renders
|
|
868
|
+
// in place, inside the menu that holds its row.
|
|
869
|
+
const renderFlyout = flyout => hasRegions && surfaceHost != null ? /*#__PURE__*/createPortal(flyout, surfaceHost) : flyout;
|
|
870
|
+
// Between a header and a footer the rows are one Tab stop, so keyboard focus
|
|
871
|
+
// on the menu element shows the ring the base style otherwise removes.
|
|
872
|
+
const handleMenuFocus = event => {
|
|
873
|
+
if (hasRegions && event.target === event.currentTarget) {
|
|
874
|
+
setIsMenuKeyboardFocused(getInteractionModality() === 'keyboard');
|
|
875
|
+
}
|
|
876
|
+
};
|
|
877
|
+
const handleMenuBlur = event => {
|
|
878
|
+
if (hasRegions && event.target === event.currentTarget) {
|
|
879
|
+
setIsMenuKeyboardFocused(false);
|
|
880
|
+
}
|
|
881
|
+
};
|
|
595
882
|
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
596
883
|
children: [/*#__PURE__*/_jsx(Item
|
|
597
884
|
// Host attributes and handlers first: the row's role, tab stop, popup
|
|
@@ -603,9 +890,9 @@ export function DropdownMenuSubMenu(props) {
|
|
|
603
890
|
id: triggerId,
|
|
604
891
|
role: "menuitem",
|
|
605
892
|
tabIndex: isDisabled ? undefined : -1,
|
|
606
|
-
"aria-haspopup":
|
|
893
|
+
"aria-haspopup": hasRegions ? 'dialog' : 'menu',
|
|
607
894
|
"aria-expanded": isOpen,
|
|
608
|
-
"aria-controls": isOpen ? contentId : undefined,
|
|
895
|
+
"aria-controls": isOpen ? hasRegions ? frameId : contentId : undefined,
|
|
609
896
|
"aria-disabled": isDisabled || undefined,
|
|
610
897
|
"data-testid": testId,
|
|
611
898
|
onMouseEnter: composeEventHandlers(triggerProps.onMouseEnter, onMouseEnter),
|
|
@@ -628,7 +915,32 @@ export function DropdownMenuSubMenu(props) {
|
|
|
628
915
|
className,
|
|
629
916
|
style
|
|
630
917
|
})
|
|
631
|
-
}), activeDrillIn != null ? isOnStack && activeDrillIn.host != null &&
|
|
918
|
+
}), activeDrillIn != null ? isOnStack && activeDrillIn.host != null && (hasRegions ?
|
|
919
|
+
/*#__PURE__*/
|
|
920
|
+
// A view with a header or footer renders beside the root's menu,
|
|
921
|
+
// in its surface host, while the root steps its menu aside.
|
|
922
|
+
createPortal(renderRegionsFrame(/*#__PURE__*/_jsx("div", {
|
|
923
|
+
ref: menuRef,
|
|
924
|
+
id: contentId,
|
|
925
|
+
role: "menu",
|
|
926
|
+
tabIndex: 0,
|
|
927
|
+
"aria-label": stringLabel,
|
|
928
|
+
"aria-labelledby": stringLabel == null ? triggerId : undefined,
|
|
929
|
+
onKeyDown: handleContentKeyDown,
|
|
930
|
+
onFocus: handleMenuFocus,
|
|
931
|
+
onBlur: handleMenuBlur,
|
|
932
|
+
"data-testid": menuDataTestId,
|
|
933
|
+
...menuPress.menuProps,
|
|
934
|
+
...surfaceOwnerProps,
|
|
935
|
+
...stylex.props(regionStyles.menu, hasOverflow && flyoutStyles.scrollable, hasOverflow ? flyoutStyles.touchPanYPinchZoom : flyoutStyles.touchPinchZoom, isMenuKeyboardFocused && focusOutlineStyles.focusVisible),
|
|
936
|
+
children: nestedContent
|
|
937
|
+
}), {
|
|
938
|
+
'aria-label': stringLabel,
|
|
939
|
+
'aria-labelledby': stringLabel == null ? triggerId : undefined,
|
|
940
|
+
// A deeper view shows in its place; this one waits, hidden.
|
|
941
|
+
hidden: !isTopView,
|
|
942
|
+
inert: !isTopView
|
|
943
|
+
}, 'view'), surfaceHost ?? activeDrillIn.host) : /*#__PURE__*/createPortal(/*#__PURE__*/_jsx("div", {
|
|
632
944
|
ref: menuRef,
|
|
633
945
|
id: contentId,
|
|
634
946
|
role: "menu",
|
|
@@ -653,7 +965,28 @@ export function DropdownMenuSubMenu(props) {
|
|
|
653
965
|
}
|
|
654
966
|
}[!!!isTopView << 0],
|
|
655
967
|
children: nestedContent
|
|
656
|
-
}), activeDrillIn.host) : layer.render(/*#__PURE__*/_jsx("div", {
|
|
968
|
+
}), activeDrillIn.host)) : renderFlyout(layer.render(hasRegions ? renderRegionsFrame(/*#__PURE__*/_jsx("div", {
|
|
969
|
+
ref: menuRef,
|
|
970
|
+
id: contentId,
|
|
971
|
+
role: "menu"
|
|
972
|
+
// One Tab stop between the regions.
|
|
973
|
+
,
|
|
974
|
+
tabIndex: 0,
|
|
975
|
+
"aria-labelledby": triggerId,
|
|
976
|
+
onKeyDown: handleContentKeyDown,
|
|
977
|
+
onFocus: handleMenuFocus,
|
|
978
|
+
onBlur: handleMenuBlur,
|
|
979
|
+
"data-testid": menuDataTestId,
|
|
980
|
+
...menuPress.menuProps,
|
|
981
|
+
...surfaceOwnerProps,
|
|
982
|
+
...stylex.props(regionStyles.menu, hasOverflow ? flyoutStyles.touchPanYPinchZoom : flyoutStyles.touchPinchZoom, hasOverflow && flyoutStyles.scrollable, isMenuKeyboardFocused && focusOutlineStyles.focusVisible),
|
|
983
|
+
children: nestedContent
|
|
984
|
+
}), {
|
|
985
|
+
'aria-labelledby': triggerId,
|
|
986
|
+
// Hovering the regions is hovering the flyout.
|
|
987
|
+
onMouseEnter: contentProps.onMouseEnter,
|
|
988
|
+
onMouseLeave: contentProps.onMouseLeave
|
|
989
|
+
}, 'flyout') : /*#__PURE__*/_jsx("div", {
|
|
657
990
|
ref: menuRef,
|
|
658
991
|
id: contentId,
|
|
659
992
|
role: "menu"
|
|
@@ -688,7 +1021,7 @@ export function DropdownMenuSubMenu(props) {
|
|
|
688
1021
|
alignment: 'start',
|
|
689
1022
|
offset: spacingVars['--spacing-1'],
|
|
690
1023
|
xstyle: [flyoutStyles.popoverViewport, popoverXstyle, layerAnimations.end]
|
|
691
|
-
})]
|
|
1024
|
+
}))]
|
|
692
1025
|
});
|
|
693
1026
|
}
|
|
694
1027
|
DropdownMenuSubMenu.displayName = 'DropdownMenuSubMenu';
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* @output `tabbablesIn`, `focusRegionControl`, `moveRegionsTab`: the Tab stops
|
|
5
5
|
* of a header or footer region and the walk through a menu with regions,
|
|
6
6
|
* with a named radio group as one stop
|
|
7
|
-
* @position Internal; DropdownMenu
|
|
8
|
-
*
|
|
7
|
+
* @position Internal; used by DropdownMenu (the root menu's header and footer)
|
|
8
|
+
* and DropdownMenuSubMenu (a sub-menu's header and footer).
|
|
9
9
|
*
|
|
10
10
|
* A menu with a header or footer is a dialog: Tab and Shift+Tab walk the
|
|
11
11
|
* header's controls, the menu as one stop, then the footer's controls, and
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
* @output `tabbablesIn`, `focusRegionControl`, `moveRegionsTab`: the Tab stops
|
|
9
9
|
* of a header or footer region and the walk through a menu with regions,
|
|
10
10
|
* with a named radio group as one stop
|
|
11
|
-
* @position Internal; DropdownMenu
|
|
12
|
-
*
|
|
11
|
+
* @position Internal; used by DropdownMenu (the root menu's header and footer)
|
|
12
|
+
* and DropdownMenuSubMenu (a sub-menu's header and footer).
|
|
13
13
|
*
|
|
14
14
|
* A menu with a header or footer is a dialog: Tab and Shift+Tab walk the
|
|
15
15
|
* header's controls, the menu as one stop, then the footer's controls, and
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileInput.d.ts","sourceRoot":"","sources":["../../src/FileInput/FileInput.tsx"],"names":[],"mappings":"AAuCA,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACxB,MAAM,UAAU,CAAC;AASlB,YAAY,EACV,WAAW,IAAI,eAAe,EAC9B,eAAe,IAAI,mBAAmB,GACvC,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,KAAK,mBAAmB,EAEzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"FileInput.d.ts","sourceRoot":"","sources":["../../src/FileInput/FileInput.tsx"],"names":[],"mappings":"AAuCA,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACxB,MAAM,UAAU,CAAC;AASlB,YAAY,EACV,WAAW,IAAI,eAAe,EAC9B,eAAe,IAAI,mBAAmB,GACvC,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,KAAK,mBAAmB,EAEzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAmP9C,MAAM,WAAW,cAAe,SAAQ,IAAI,CAC1C,mBAAmB,EACnB,UAAU,GAAG,cAAc,GAAG,OAAO,CACtC;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAClC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,KAAK,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;IAC5B;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IAC5B;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,aAAqB,EACrB,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,MAAM,EACN,UAAkB,EAClB,OAAO,EACP,QAAQ,EACR,UAAkB,EAClB,eAAe,EACf,UAAkB,EAClB,SAAiB,EACjB,MAAM,EAAE,UAAU,EAClB,aAA0B,EAC1B,WAAW,EACX,WAAW,EACX,IAAc,EACd,UAAkB,EAClB,YAAY,EACZ,KAAK,EACL,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,GAAG,EACH,EAAE,EAAE,MAAM,EACV,GAAG,SAAS,EACb,EAAE,cAAc,+BAochB;yBAnee,SAAS"}
|
|
@@ -124,7 +124,7 @@ const styles = {
|
|
|
124
124
|
dropzoneDisabled: {
|
|
125
125
|
kkrTdU: "xt0e3qv",
|
|
126
126
|
kSiTet: "xbyyjgo",
|
|
127
|
-
kVAM5u: "xvy26l8",
|
|
127
|
+
kVAM5u: "xvy26l8 x6q1khz",
|
|
128
128
|
$$css: true
|
|
129
129
|
},
|
|
130
130
|
compact: {
|
|
@@ -153,7 +153,7 @@ const styles = {
|
|
|
153
153
|
compactDisabled: {
|
|
154
154
|
kkrTdU: "xt0e3qv",
|
|
155
155
|
kSiTet: "xbyyjgo",
|
|
156
|
-
kVAM5u: "xvy26l8",
|
|
156
|
+
kVAM5u: "xvy26l8 x6q1khz",
|
|
157
157
|
$$css: true
|
|
158
158
|
}
|
|
159
159
|
};
|
|
@@ -526,15 +526,10 @@ export function FileInput({
|
|
|
526
526
|
children: [/*#__PURE__*/_jsx(VisuallyHidden, {
|
|
527
527
|
children: /*#__PURE__*/_jsx("button", {
|
|
528
528
|
type: "button"
|
|
529
|
-
//
|
|
530
|
-
// aria-disabled so the reason is focus-discoverable; opening the
|
|
531
|
-
// picker is still blocked by the isDisabled guards in the handlers.
|
|
532
|
-
// Otherwise the native disabled attribute removes it from the tab
|
|
533
|
-
// order.
|
|
529
|
+
// A disabled trigger keeps its Tab stop (spec:AST-085 FR1).
|
|
534
530
|
,
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
"aria-disabled": showsDisabledMessage ? 'true' : undefined,
|
|
531
|
+
tabIndex: 0,
|
|
532
|
+
"aria-disabled": isDisabled ? 'true' : undefined,
|
|
538
533
|
onClick: handleClick,
|
|
539
534
|
onKeyDown: handleKeyDown
|
|
540
535
|
// aria-label suppresses child content from the accessible name, so
|
|
@@ -556,8 +551,15 @@ export function FileInput({
|
|
|
556
551
|
id: id,
|
|
557
552
|
type: "file",
|
|
558
553
|
accept: accept,
|
|
559
|
-
multiple: isMultiple
|
|
560
|
-
disabled
|
|
554
|
+
multiple: isMultiple
|
|
555
|
+
// Detached from its form while disabled, so selected files are not
|
|
556
|
+
// submitted and `required` does not block submission (FR3).
|
|
557
|
+
,
|
|
558
|
+
form: isDisabled ? '' : undefined
|
|
559
|
+
// A label or description click activates this input directly; cancel
|
|
560
|
+
// it so a disabled input never opens the picker (FR2).
|
|
561
|
+
,
|
|
562
|
+
onClick: isDisabled ? event => event.preventDefault() : rest.onClick,
|
|
561
563
|
onChange: handleInputChange
|
|
562
564
|
// The visually-hidden native input is never focused (tabIndex={-1});
|
|
563
565
|
// its describedby/required/invalid live on the trigger button.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectorOption.d.ts","sourceRoot":"","sources":["../../src/Selector/SelectorOption.tsx"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAErC,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAiB,KAAK,QAAQ,EAAC,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"SelectorOption.d.ts","sourceRoot":"","sources":["../../src/Selector/SelectorOption.tsx"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAErC,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAiB,KAAK,QAAQ,EAAC,MAAM,SAAS,CAAC;AAkBtD,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAE5B;;OAEG;IACH,KAAK,EAAE,SAAS,CAAC;IAEjB;;OAEG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IAExB;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAE9B;;OAEG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;IAEvB;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,KAAK,EACL,WAAW,EACX,MAAM,EACN,UAAU,EACV,MAAM,EACN,SAAS,EACT,KAAK,GACN,EAAE,mBAAmB,+BAoBrB;yBA7Be,cAAc"}
|