@astryxdesign/core 0.7.3-canary.b74cf21 → 0.7.3-canary.cb489ff

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.
Files changed (77) hide show
  1. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  2. package/dist/CheckboxInput/CheckboxInput.js +19 -24
  3. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  4. package/dist/DropdownMenu/DropdownMenu.js +52 -10
  5. package/dist/DropdownMenu/DropdownMenuContext.d.ts +34 -1
  6. package/dist/DropdownMenu/DropdownMenuContext.d.ts.map +1 -1
  7. package/dist/DropdownMenu/DropdownMenuContext.js +15 -0
  8. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +21 -2
  9. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  10. package/dist/DropdownMenu/DropdownMenuSubMenu.js +375 -42
  11. package/dist/DropdownMenu/menuRegionStops.d.ts +2 -2
  12. package/dist/DropdownMenu/menuRegionStops.js +2 -2
  13. package/dist/FileInput/FileInput.d.ts.map +1 -1
  14. package/dist/FileInput/FileInput.js +14 -12
  15. package/dist/Slider/Slider.d.ts.map +1 -1
  16. package/dist/Slider/Slider.js +7 -14
  17. package/dist/Switch/Switch.d.ts.map +1 -1
  18. package/dist/Switch/Switch.js +12 -14
  19. package/dist/Switch/switch.markers.stylex.d.ts +2 -0
  20. package/dist/Switch/switch.markers.stylex.d.ts.map +1 -1
  21. package/dist/Switch/switch.markers.stylex.js +6 -0
  22. package/dist/TimeInput/TimeInput.d.ts +2 -1
  23. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  24. package/dist/Tooltip/Tooltip.d.ts.map +1 -1
  25. package/dist/Tooltip/Tooltip.js +36 -14
  26. package/dist/TopNav/TopNav.d.ts.map +1 -1
  27. package/dist/TopNav/TopNav.js +2 -2
  28. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  29. package/dist/TopNav/TopNavHeading.js +1 -0
  30. package/dist/astryx.css +3 -2
  31. package/dist/hooks/useMenuPress.d.ts +11 -1
  32. package/dist/hooks/useMenuPress.d.ts.map +1 -1
  33. package/dist/hooks/useMenuPress.js +43 -5
  34. package/dist/utils/timeParser.d.ts +4 -0
  35. package/dist/utils/timeParser.d.ts.map +1 -1
  36. package/dist/utils/timeParser.js +9 -2
  37. package/package.json +3 -3
  38. package/src/CheckboxInput/CheckboxInput.test.tsx +44 -5
  39. package/src/CheckboxInput/CheckboxInput.tsx +16 -26
  40. package/src/CheckboxInput/__tests__/Checkbox.a11y.states.ts +3 -3
  41. package/src/CheckboxList/CheckboxList.test.tsx +9 -6
  42. package/src/ContextMenu/ContextMenu.test.tsx +41 -0
  43. package/src/DropdownMenu/DropdownMenu.spec.md +33 -2
  44. package/src/DropdownMenu/DropdownMenu.tsx +79 -8
  45. package/src/DropdownMenu/DropdownMenuContext.public.test.ts +22 -0
  46. package/src/DropdownMenu/DropdownMenuContext.tsx +39 -1
  47. package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +16 -1
  48. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +623 -1
  49. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +556 -99
  50. package/src/DropdownMenu/__tests__/SubMenuHeaderFooter.a11y.chromium.spec.ts +267 -0
  51. package/src/DropdownMenu/menuRegionStops.ts +2 -2
  52. package/src/DropdownMenu/modules/useMenuPress.spec.md +9 -0
  53. package/src/FileInput/FileInput.test.tsx +30 -7
  54. package/src/FileInput/FileInput.tsx +21 -11
  55. package/src/SideNav/SideNav.test.tsx +35 -0
  56. package/src/Slider/Slider.test.tsx +3 -3
  57. package/src/Slider/Slider.tsx +8 -15
  58. package/src/Switch/Switch.test.tsx +29 -8
  59. package/src/Switch/Switch.tsx +13 -14
  60. package/src/Switch/__tests__/Switch.a11y.states.ts +2 -2
  61. package/src/Switch/switch.markers.stylex.ts +4 -0
  62. package/src/Table/plugins/selection/useTableSelection.test.tsx +5 -3
  63. package/src/TimeInput/TimeInput.doc.mjs +5 -3
  64. package/src/TimeInput/TimeInput.test.tsx +20 -0
  65. package/src/TimeInput/TimeInput.tsx +2 -1
  66. package/src/Tooltip/Tooltip.test.tsx +51 -6
  67. package/src/Tooltip/Tooltip.tsx +41 -18
  68. package/src/Tooltip/__tests__/Tooltip.a11y.chromium.spec.ts +129 -0
  69. package/src/Tooltip/__tests__/Tooltip.a11y.renders.tsx +86 -0
  70. package/src/Tooltip/__tests__/Tooltip.a11y.states.ts +132 -0
  71. package/src/Tooltip/__tests__/Tooltip.a11y.test.tsx +126 -0
  72. package/src/TopNav/TopNav.tsx +11 -1
  73. package/src/TopNav/TopNavHeading.tsx +1 -0
  74. package/src/TopNav/__tests__/TopNavMobileLongHeading.a11y.chromium.spec.ts +74 -0
  75. package/src/hooks/useMenuPress.ts +45 -7
  76. package/src/utils/timeParser.test.ts +11 -0
  77. package/src/utils/timeParser.ts +9 -2
@@ -1 +1 @@
1
- {"version":3,"file":"CheckboxInput.d.ts","sourceRoot":"","sources":["../../src/CheckboxInput/CheckboxInput.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CheckboxInput.d.ts","sourceRoot":"","sources":["../../src/CheckboxInput/CheckboxInput.tsx"],"names":[],"mappings":"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"}
@@ -15,7 +15,7 @@
15
15
  * - /apps/storybook/stories/CheckboxInput.stories.tsx (storybook stories)
16
16
  * - /packages/cli/assets/templates/blocks/components/CheckboxInput/ (showcase blocks)
17
17
  */
18
- import { useId, useCallback, use, useOptimistic, useRef, useTransition } from 'react';
18
+ import { useId, useCallback, useOptimistic, useRef, useTransition } from 'react';
19
19
  import * as stylex from '@stylexjs/stylex';
20
20
  import "../theme/tokens.stylex.js";
21
21
  import { colorVars, spacingVars, radiusVars, typographyVars, typeScaleVars, fontWeightVars } from "../theme/tokens.stylex.js";
@@ -32,7 +32,6 @@ import { usePressFeedback } from "../hooks/usePressFeedback.js";
32
32
  import { useResolvedRequired } from "../hooks/useResolvedRequired.js";
33
33
  import { useIndicator } from "../Indicator/index.js";
34
34
  import { themeProps } from "../utils/themeProps.js";
35
- import { CheckboxListContext } from "../CheckboxList/CheckboxListContext.js";
36
35
  import { useMergedRefs } from "../hooks/useMergedRefs.js";
37
36
 
38
37
  // The touch press's paint, declared by the shared overlay styles on the
@@ -177,18 +176,10 @@ export function CheckboxInput({
177
176
  const [optimisticValue, setOptimisticValue] = useOptimistic(value);
178
177
  const isBusy = isLoading || optimisticValue !== value;
179
178
 
180
- // Disabled-reason tooltip. Disabled controls swallow pointer events, so the
181
- // tooltip listeners attach to the checkbox row (which already exists) and the
182
- // native checkbox stays perceivable via aria-disabled instead of the disabled
183
- // attribute. Value mutation is blocked by the isDisabled guard in onChange.
179
+ // A disabled checkbox stays focusable via aria-disabled instead of the
180
+ // native disabled attribute (spec:AST-085 FR1). Value mutation is blocked by
181
+ // the click and onChange guards on the input.
184
182
  const showsDisabledMessage = isDisabled && !!disabledMessage;
185
- // Keep the native checkbox focusable via aria-disabled either when it renders
186
- // its own reason tooltip, or when it sits in a CheckboxList whose whole-group
187
- // `disabledMessage` (shown on the group container) needs each checkbox to
188
- // stay keyboard-perceivable. The group signals this through context rather
189
- // than a public prop.
190
- const checkboxListContext = use(CheckboxListContext);
191
- const isFocusableDisabled = isDisabled && (showsDisabledMessage || (checkboxListContext?.hasDisabledMessage ?? false));
192
183
  const disabledMessageTooltip = useTooltip({
193
184
  placement: 'above',
194
185
  // The container row is not naturally focusable; focusin bubbles up from the
@@ -206,7 +197,7 @@ export function CheckboxInput({
206
197
  const indicatorRef = useRef(null);
207
198
  const {
208
199
  focusProps
209
- } = useIndicatorFocusRing(indicatorRef, isDisabled);
200
+ } = useIndicatorFocusRing(indicatorRef);
210
201
  const isIndeterminate = optimisticValue === 'indeterminate';
211
202
  const isChecked = optimisticValue === true;
212
203
 
@@ -272,24 +263,28 @@ export function CheckboxInput({
272
263
  ref: useMergedRefs(ref, indeterminateRef, disabledMessageTooltip.positionRef),
273
264
  id: id,
274
265
  type: "checkbox"
275
- // Withhold the name while disabled: with a disabledMessage the
276
- // input stays focusable (not natively disabled), and a disabled
277
- // control must not submit.
266
+ // Withhold the name while disabled: the input stays focusable (not
267
+ // natively disabled), and a disabled control must not submit.
278
268
  ,
279
269
  name: isDisabled ? undefined : htmlName,
280
- checked: isChecked
281
- // With a disabledMessage the checkbox keeps focusability via
282
- // aria-disabled so the reason is focus-discoverable; toggling is
283
- // still blocked by the isDisabled guard in onChange below.
270
+ checked: isChecked,
271
+ "aria-disabled": isDisabled ? 'true' : undefined
272
+ // Detached from its form while disabled, so it neither submits nor
273
+ // blocks submission through `required` (spec:AST-085 FR3).
284
274
  ,
285
- disabled: isDisabled && !isFocusableDisabled,
286
- "aria-disabled": isFocusableDisabled ? 'true' : undefined,
287
- form: isFocusableDisabled ? '' : undefined,
275
+ form: isDisabled ? '' : undefined
276
+ // Native `disabled` suppressed onClick (FR2); preventDefault here
277
+ // would desync React's controlled checked state.
278
+ ,
279
+ onClick: isDisabled ? undefined : rest.onClick,
288
280
  readOnly: isReadOnly,
289
281
  required: isRequired,
290
282
  "aria-required": isEffectivelyRequired ? 'true' : undefined,
291
283
  onChange: e => {
292
284
  if (isDisabled || isBusy || isReadOnly) {
285
+ // Activation clears the native mixed state; React restores
286
+ // only `checked`, so restore `indeterminate` too.
287
+ e.target.indeterminate = isIndeterminate;
293
288
  return;
294
289
  }
295
290
  const checked = e.target.checked;
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownMenu.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenu.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DropdownMenu.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenu.tsx"],"names":[],"mappings":"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"}
@@ -42,7 +42,7 @@ import { Heading } from "../Heading/index.js";
42
42
  import { Icon } from "../Icon/index.js";
43
43
  import { renderDropdownItems } from "./renderDropdownItems.js";
44
44
  import { MENU_ITEM_ROLES, MENU_ITEM_SELECTOR, MENU_BOUNDARY_SELECTOR, activateMenuItem } from "./menuItemRoles.js";
45
- import { DropdownMenuContext, DropdownMenuRootOpenContext } from "./DropdownMenuContext.js";
45
+ import { DropdownMenuContext, DropdownMenuRootOpenContext, DropdownMenuSurfaceContext } from "./DropdownMenuContext.js";
46
46
  import { useIsomorphicLayoutEffect } from "../hooks/useIsomorphicLayoutEffect.js";
47
47
  import { useListFocus } from "../hooks/useListFocus.js";
48
48
  import { useMenuPress } from "../hooks/useMenuPress.js";
@@ -76,6 +76,13 @@ const MENU_BLOCK_CAP = '300px';
76
76
  const MENU_MAX_BLOCK_SIZE = `min(${MENU_BLOCK_CAP}, ${layerViewportInset.maxBlockSize})`;
77
77
  const MENU_MAX_BLOCK_SIZE_FALLBACK = `min(${MENU_BLOCK_CAP}, ${layerViewportInset.maxBlockSizeFallback})`;
78
78
  const MENU_TRIGGER_OPEN_BACKGROUND = `linear-gradient(${colorVars['--color-overlay-pressed']}, ${colorVars['--color-overlay-pressed']})`;
79
+
80
+ // A sub-menu's drilled-in view with a header or footer renders in the surface
81
+ // host that follows the menu, as the frame marked
82
+ // `data-astryx-submenu-regions="view"` (hidden while a deeper view shows).
83
+ // While one shows, the menu and its header and footer step aside. The rule
84
+ // reads that from the DOM, so no state mirrors which view shows.
85
+ const STEPS_ASIDE_FOR_VIEW = ':has(~ * > [data-astryx-submenu-regions="view"]:not([hidden]))';
79
86
  const _temp = {
80
87
  kzqmXN: "x1uyokj7",
81
88
  "$$css": true
@@ -92,7 +99,7 @@ const styles = {
92
99
  },
93
100
  dropdown: {
94
101
  kB7OPa: "x9f619",
95
- k1xSpc: "x78zum5",
102
+ k1xSpc: "x78zum5 x1ab7gxt",
96
103
  kXwgrk: "xdt5ytf",
97
104
  kOIVth: "x1lsbc85",
98
105
  kI3sdo: "x1a2a7pz",
@@ -1098,6 +1105,21 @@ function DropdownMenuPopover({
1098
1105
  drillIn,
1099
1106
  wrapContent
1100
1107
  } = useMenuDrillIn(isOpen);
1108
+ // The surface host is owned through a ref. State keeps only a key that
1109
+ // changes whenever a host element attaches, the host included when it
1110
+ // moves (a header or footer coming or going), so sub-menus re-render into
1111
+ // the element that is mounted.
1112
+ const surfaceHostRef = useRef(null);
1113
+ const [surfaceHostKey, setSurfaceHostKey] = useState(0);
1114
+ const attachSurfaceHost = useCallback(node => {
1115
+ surfaceHostRef.current = node;
1116
+ if (node != null) {
1117
+ setSurfaceHostKey(key => key + 1);
1118
+ }
1119
+ }, []);
1120
+ const surfaceHost = useMemo(() => ({
1121
+ getElement: () => surfaceHostKey > 0 ? surfaceHostRef.current : null
1122
+ }), [surfaceHostKey]);
1101
1123
  const resolvedMaxHeight = menuMaxHeight == null ? null : `${menuMaxHeight}px`;
1102
1124
  // Context for compound items
1103
1125
  const contextValue = useMemo(() => ({
@@ -1106,31 +1128,48 @@ function DropdownMenuPopover({
1106
1128
  drillIn,
1107
1129
  menuLabel
1108
1130
  }), [closeMenu, menuSize, drillIn, menuLabel]);
1131
+ // What a sub-menu with a header or footer needs, on an internal context.
1132
+ const surfaceValue = useMemo(() => ({
1133
+ host: surfaceHost,
1134
+ ownerId: menuId,
1135
+ menuMaxHeight: resolvedMaxHeight ?? undefined
1136
+ }), [surfaceHost, menuId, resolvedMaxHeight]);
1109
1137
 
1110
1138
  // Resolve menu content: data-driven items become components
1111
1139
  const menuContent = wrapContent(props.items !== undefined ? renderDropdownItems(items) : children);
1112
1140
  const hasOverflow = useMenuOverflow(listRef, menuContent, popover.isOpen);
1113
1141
 
1114
1142
  // The header and footer sit beside the menu inside the popover, never inside
1115
- // the role="menu" element: a menu holds only its rows.
1143
+ // the role="menu" element: a menu holds only its rows. The surface host
1144
+ // follows the menu, so a sub-menu with a header or footer renders beside the
1145
+ // menu too; while such a sub-menu's drilled-in view shows there, the menu and
1146
+ // the regions step aside (STEPS_ASIDE_FOR_VIEW).
1147
+ const surfaceHostElement = /*#__PURE__*/_jsx("div", {
1148
+ ref: attachSurfaceHost,
1149
+ ...{
1150
+ className: "xjp7ctv"
1151
+ }
1152
+ });
1116
1153
  const renderWithRegions = menu => hasRegions ? /*#__PURE__*/_jsxs("div", {
1117
1154
  ...stylex.props(styles.regionsFrame, resolvedMaxHeight != null && dynamicStyles.menuMaxHeight(resolvedMaxHeight)),
1118
1155
  children: [isRenderable(header) && /*#__PURE__*/_jsx("div", {
1119
1156
  ref: headerRef,
1120
1157
  onKeyDown: handleRegionKeyDown,
1121
1158
  ...{
1122
- className: "x2lah0s x9epnlk"
1159
+ className: "x2lah0s x9epnlk x1ab7gxt"
1123
1160
  },
1124
1161
  children: header
1125
1162
  }), menu, isRenderable(footer) && /*#__PURE__*/_jsx("div", {
1126
1163
  ref: footerRef,
1127
1164
  onKeyDown: handleRegionKeyDown,
1128
1165
  ...{
1129
- className: "x2lah0s x9epnlk"
1166
+ className: "x2lah0s x9epnlk x1ab7gxt"
1130
1167
  },
1131
1168
  children: footer
1132
- })]
1133
- }) : menu;
1169
+ }), surfaceHostElement]
1170
+ }) : /*#__PURE__*/_jsxs(_Fragment, {
1171
+ children: [menu, surfaceHostElement]
1172
+ });
1134
1173
  const triggerProps = {
1135
1174
  ref: el => {
1136
1175
  buttonRef.current = el;
@@ -1228,9 +1267,12 @@ function DropdownMenuPopover({
1228
1267
  value: hasRegions,
1229
1268
  children: /*#__PURE__*/_jsx(DropdownMenuContext, {
1230
1269
  value: contextValue,
1231
- children: /*#__PURE__*/_jsx(DropdownMenuRootOpenContext, {
1232
- value: isOpen,
1233
- children: menuContent
1270
+ children: /*#__PURE__*/_jsx(DropdownMenuSurfaceContext, {
1271
+ value: surfaceValue,
1272
+ children: /*#__PURE__*/_jsx(DropdownMenuRootOpenContext, {
1273
+ value: isOpen,
1274
+ children: menuContent
1275
+ })
1234
1276
  })
1235
1277
  })
1236
1278
  })
@@ -25,7 +25,10 @@ export interface DropdownMenuDrillIn {
25
25
  viewStack: ReadonlyArray<string>;
26
26
  /** The element a shown view renders its rows into (a portal target). */
27
27
  host: HTMLElement | null;
28
- /** Show a sub-menu's view in place of the current rows. */
28
+ /**
29
+ * Show a sub-menu's view in place of the current rows. A view with a header
30
+ * or footer renders into the root's surface host instead of `host`.
31
+ */
29
32
  push: (viewId: string) => void;
30
33
  /** Return to the rows the shown view replaced. */
31
34
  pop: () => void;
@@ -43,6 +46,36 @@ export interface DropdownMenuContextValue {
43
46
  */
44
47
  menuLabel?: string;
45
48
  }
49
+ /**
50
+ * The root's surface host. The root owns the element through a ref; this
51
+ * object is new whenever a new element attaches, so a sub-menu re-renders
52
+ * into it.
53
+ */
54
+ export interface DropdownMenuSurfaceHost {
55
+ /** The host element, or `null` before it attaches. */
56
+ getElement: () => HTMLElement | null;
57
+ }
58
+ /** What a sub-menu with a header or footer needs from the root. Internal. */
59
+ export interface DropdownMenuSurfaceValue {
60
+ /**
61
+ * An element inside the root's popover but outside every `role="menu"`
62
+ * element, where such a sub-menu renders its surface (its flyout layer, or
63
+ * its drilled-in view, while which the root's menu and regions step aside).
64
+ */
65
+ host: DropdownMenuSurfaceHost;
66
+ /**
67
+ * The root menu's `id`, which a sub-menu's menu in the host names so the
68
+ * press model counts it, and only it, as nested in the root.
69
+ */
70
+ ownerId: string;
71
+ /** The root's resolved `menuMaxHeight`, which a drilled-in view caps at. */
72
+ menuMaxHeight?: string;
73
+ }
74
+ /**
75
+ * The root's surface; `null` under a root with none (ContextMenu). Internal,
76
+ * off the public menu context, and layer-scoped, so each flyout re-provides it.
77
+ */
78
+ export declare const DropdownMenuSurfaceContext: import("react").Context<DropdownMenuSurfaceValue | null>;
46
79
  /**
47
80
  * Whether the root menu of this layer tree is open; internal companion to
48
81
  * `DropdownMenuContext`, on its own unexported context so the public
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownMenuContext.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenuContext.tsx"],"names":[],"mappings":"AAmBA,uDAAuD;AACvD,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAElD;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,cAAc,EAAE,OAAO,CAAC;IACxB,4EAA4E;IAC5E,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACjC,wEAAwE;IACxE,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IACzB,2DAA2D;IAC3D,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,kDAAkD;IAClD,GAAG,EAAE,MAAM,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC,uEAAuE;IACvE,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,yCAAyC;IACzC,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,sEAAsE;IACtE,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B,yCAEjC,CAAC;AAGR;;;;GAIG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAEjD;AAED,eAAO,MAAM,mBAAmB,0DACiC,CAAC;AAGlE;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,wBAAwB,GAAG,IAAI,CAExE;AAMD,MAAM,WAAW,kCAAkC;IACjD,iDAAiD;IACjD,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,uEAAuE;IACvE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,qEAAqE;IACrE,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,eAAO,MAAM,6BAA6B,oEACsB,CAAC;AAGjE;;;GAGG;AACH,wBAAgB,gCAAgC,IAAI,kCAAkC,GAAG,IAAI,CAE5F"}
1
+ {"version":3,"file":"DropdownMenuContext.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenuContext.tsx"],"names":[],"mappings":"AAmBA,uDAAuD;AACvD,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAElD;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,cAAc,EAAE,OAAO,CAAC;IACxB,4EAA4E;IAC5E,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACjC,wEAAwE;IACxE,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IACzB;;;OAGG;IACH,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,kDAAkD;IAClD,GAAG,EAAE,MAAM,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC,uEAAuE;IACvE,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,yCAAyC;IACzC,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,sEAAsE;IACtE,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,sDAAsD;IACtD,UAAU,EAAE,MAAM,WAAW,GAAG,IAAI,CAAC;CACtC;AAED,6EAA6E;AAC7E,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,IAAI,EAAE,uBAAuB,CAAC;IAC9B;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,eAAO,MAAM,0BAA0B,0DAC0B,CAAC;AAGlE;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B,yCAEjC,CAAC;AAGR;;;;GAIG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAEjD;AAED,eAAO,MAAM,mBAAmB,0DACiC,CAAC;AAGlE;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,wBAAwB,GAAG,IAAI,CAExE;AAMD,MAAM,WAAW,kCAAkC;IACjD,iDAAiD;IACjD,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,uEAAuE;IACvE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,qEAAqE;IACrE,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,eAAO,MAAM,6BAA6B,oEACsB,CAAC;AAGjE;;;GAGG;AACH,wBAAgB,gCAAgC,IAAI,kCAAkC,GAAG,IAAI,CAE5F"}
@@ -32,6 +32,21 @@ import { createLayerScopedContext } from "../Layer/layerScopedContext.js";
32
32
  * @internal
33
33
  */
34
34
 
35
+ /**
36
+ * The root's surface host. The root owns the element through a ref; this
37
+ * object is new whenever a new element attaches, so a sub-menu re-renders
38
+ * into it.
39
+ */
40
+
41
+ /** What a sub-menu with a header or footer needs from the root. Internal. */
42
+
43
+ /**
44
+ * The root's surface; `null` under a root with none (ContextMenu). Internal,
45
+ * off the public menu context, and layer-scoped, so each flyout re-provides it.
46
+ */
47
+ export const DropdownMenuSurfaceContext = createLayerScopedContext(null);
48
+ DropdownMenuSurfaceContext.displayName = 'DropdownMenuSurfaceContext';
49
+
35
50
  /**
36
51
  * Whether the root menu of this layer tree is open; internal companion to
37
52
  * `DropdownMenuContext`, on its own unexported context so the public
@@ -5,7 +5,9 @@
5
5
  * Spinner, and DropdownMenu context + item roles
6
6
  * @output Exports DropdownMenuSubMenu — a single menu row that reveals a nested
7
7
  * menu of its own children/items: a flyout beside the row, or, on a phone,
8
- * a drilled-in view in place of the parent rows.
8
+ * a drilled-in view in place of the parent rows. With a header or footer,
9
+ * that surface is a modal dialog rendered into the root's surface host,
10
+ * beside every menu element.
9
11
  * @position Sub-component; place inside a DropdownMenu (or ContextMenu)
10
12
  * alongside plain items.
11
13
  *
@@ -83,13 +85,30 @@ interface DropdownMenuSubMenuBaseProps extends Omit<BaseProps, 'role' | 'tabInde
83
85
  * 'adaptive'
84
86
  */
85
87
  presentation?: DropdownMenuSubMenuPresentation;
88
+ /**
89
+ * Content above the sub-menu's rows: a field that filters them, say. Like
90
+ * the root menu's `header`, it sits beside the sub-menu's `role="menu"`
91
+ * element, never inside it, and keeps its own keys and presses. With a
92
+ * header or footer the sub-menu's surface (the flyout, or the drilled-in
93
+ * view on a phone) is a modal dialog named by the row: the row says
94
+ * `aria-haspopup="dialog"`, Tab and Shift+Tab walk the header's controls,
95
+ * the rows as one stop and the footer's controls and wrap, and Escape
96
+ * returns to the row. A pointer leaving the flyout does not close it while
97
+ * focus is inside. A `ContextMenu` does not show it.
98
+ */
99
+ header?: ReactNode;
100
+ /**
101
+ * Content below the sub-menu's rows: a door to where the options are
102
+ * managed, say. Same rules as `header`.
103
+ */
104
+ footer?: ReactNode;
86
105
  /** Test id for the trigger row. */
87
106
  'data-testid'?: string;
88
107
  /** Test id for the flyout menu. */
89
108
  menuDataTestId?: string;
90
109
  /**
91
110
  * Ref forwarded to the trigger row — the element carrying `role="menuitem"`
92
- * and `aria-haspopup="menu"`.
111
+ * and `aria-haspopup="menu"` (`"dialog"` with a header or footer).
93
112
  */
94
113
  ref?: React.Ref<HTMLElement>;
95
114
  }
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownMenuSubMenu.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenuSubMenu.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,OAAO,KAAK,EAAE,EASZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf,OAAO,EAAuB,KAAK,QAAQ,EAAC,MAAM,SAAS,CAAC;AA0B5D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AA4J5C,MAAM,MAAM,+BAA+B,GACzC,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAC;AAErC,UAAU,4BAA6B,SAAQ,IAAI,CACjD,SAAS,EACT,MAAM,GAAG,UAAU,CACpB;IACC,2DAA2D;IAC3D,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC5B,8CAA8C;IAC9C,KAAK,EAAE,SAAS,CAAC;IACjB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,8CAA8C;IAC9C,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,+BAA+B,CAAC;IAC/C,mCAAmC;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mCAAmC;IACnC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,wBAAyB,SAAQ,4BAA4B;IAC5E;;;;;;;;OAQG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,wBAAwB,GAC9B,SAAS,CA4kBX;yBA9kBe,mBAAmB"}
1
+ {"version":3,"file":"DropdownMenuSubMenu.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenuSubMenu.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,OAAO,KAAK,EAAE,EASZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf,OAAO,EAAuB,KAAK,QAAQ,EAAC,MAAM,SAAS,CAAC;AAwC5D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AA6N5C,MAAM,MAAM,+BAA+B,GACzC,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAC;AAErC,UAAU,4BAA6B,SAAQ,IAAI,CACjD,SAAS,EACT,MAAM,GAAG,UAAU,CACpB;IACC,2DAA2D;IAC3D,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC5B,8CAA8C;IAC9C,KAAK,EAAE,SAAS,CAAC;IACjB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,8CAA8C;IAC9C,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,+BAA+B,CAAC;IAC/C;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,mCAAmC;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mCAAmC;IACnC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,wBAAyB,SAAQ,4BAA4B;IAC5E;;;;;;;;OAQG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AA6CD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,wBAAwB,GAC9B,SAAS,CAw4BX;yBA14Be,mBAAmB"}