@windmorph/react 0.2.3 → 0.2.4

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 (119) hide show
  1. package/dist/components/autocomplete/Autocomplete.d.ts +4 -1
  2. package/dist/components/autocomplete/Autocomplete.js +2 -4
  3. package/dist/components/autocomplete/Autocomplete.js.map +1 -1
  4. package/dist/components/badge/Badge.d.ts +5 -2
  5. package/dist/components/badge/Badge.js +7 -3
  6. package/dist/components/badge/Badge.js.map +1 -1
  7. package/dist/components/button/Button.d.ts +4 -2
  8. package/dist/components/button/Button.js.map +1 -1
  9. package/dist/components/button/ButtonContext.d.ts +1 -1
  10. package/dist/components/button/button-pending.js +2 -4
  11. package/dist/components/button/button-pending.js.map +1 -1
  12. package/dist/{composites → components}/button-group/ButtonGroup.d.ts +4 -4
  13. package/dist/{composites → components}/button-group/ButtonGroup.js +9 -7
  14. package/dist/components/button-group/ButtonGroup.js.map +1 -0
  15. package/dist/{composites → components}/button-group/button-group-styles.d.ts +1 -1
  16. package/dist/{composites → components}/button-group/button-group-styles.js +1 -1
  17. package/dist/{composites → components}/button-group/button-group-styles.js.map +1 -1
  18. package/dist/{composites → components}/button-group/lazy-overflow-menu.js +2 -2
  19. package/dist/components/button-group/lazy-overflow-menu.js.map +1 -0
  20. package/dist/{composites → components}/button-group/overflow-menu-list.js +2 -2
  21. package/dist/components/button-group/overflow-menu-list.js.map +1 -0
  22. package/dist/{composites → components}/button-group/use-overflow.js +1 -1
  23. package/dist/{composites → components}/button-group/use-overflow.js.map +1 -1
  24. package/dist/{composites → components}/button-group/use-press-expansion.js +1 -1
  25. package/dist/{composites → components}/button-group/use-press-expansion.js.map +1 -1
  26. package/dist/components/carousel/Carousel.d.ts +4 -1
  27. package/dist/components/carousel/Carousel.js +2 -4
  28. package/dist/components/carousel/Carousel.js.map +1 -1
  29. package/dist/components/checkbox/checkbox-styles.d.ts +3 -3
  30. package/dist/components/checkbox/checkbox-tokens.d.ts +1 -1
  31. package/dist/components/chip/Chip.d.ts +8 -2
  32. package/dist/components/chip/Chip.js +3 -8
  33. package/dist/components/chip/Chip.js.map +1 -1
  34. package/dist/components/date-picker/DateField.d.ts +4 -1
  35. package/dist/components/date-picker/DateField.js +3 -1
  36. package/dist/components/date-picker/DateField.js.map +1 -1
  37. package/dist/components/date-picker/DatePicker.d.ts +4 -1
  38. package/dist/components/date-picker/DatePicker.js +5 -2
  39. package/dist/components/date-picker/DatePicker.js.map +1 -1
  40. package/dist/components/date-picker/PickerDialog.d.ts +4 -1
  41. package/dist/components/date-picker/PickerDialog.js +3 -1
  42. package/dist/components/date-picker/PickerDialog.js.map +1 -1
  43. package/dist/components/date-picker/date-picker-styles.d.ts +15 -15
  44. package/dist/components/dialog/Dialog.d.ts +5 -2
  45. package/dist/components/dialog/Dialog.js +4 -2
  46. package/dist/components/dialog/Dialog.js.map +1 -1
  47. package/dist/components/icon-button/IconButton.d.ts +4 -2
  48. package/dist/components/icon-button/IconButton.js.map +1 -1
  49. package/dist/components/labels/LabelsProvider.d.ts +35 -0
  50. package/dist/components/labels/LabelsProvider.js +47 -0
  51. package/dist/components/labels/LabelsProvider.js.map +1 -0
  52. package/dist/components/labels/use-labels.d.ts +16 -0
  53. package/dist/components/labels/use-labels.js +42 -0
  54. package/dist/components/labels/use-labels.js.map +1 -0
  55. package/dist/components/menu/Menu.d.ts +4 -1
  56. package/dist/components/menu/Menu.js +7 -10
  57. package/dist/components/menu/Menu.js.map +1 -1
  58. package/dist/components/menu/menu-styles.js +12 -12
  59. package/dist/components/menu/menu-styles.js.map +1 -1
  60. package/dist/components/menu/menu-tokens.js.map +1 -1
  61. package/dist/components/navigation/NavItem.d.ts +1 -1
  62. package/dist/components/navigation/NavItem.js +9 -6
  63. package/dist/components/navigation/NavItem.js.map +1 -1
  64. package/dist/components/pull-to-refresh/PullToRefresh.d.ts +1 -1
  65. package/dist/components/pull-to-refresh/PullToRefresh.js +2 -4
  66. package/dist/components/pull-to-refresh/PullToRefresh.js.map +1 -1
  67. package/dist/components/search/SearchField.d.ts +4 -1
  68. package/dist/components/search/SearchField.js +2 -4
  69. package/dist/components/search/SearchField.js.map +1 -1
  70. package/dist/components/select/Select.d.ts +4 -1
  71. package/dist/components/select/Select.js +2 -4
  72. package/dist/components/select/Select.js.map +1 -1
  73. package/dist/components/sheet/BottomSheet.d.ts +4 -1
  74. package/dist/components/sheet/BottomSheet.js +2 -4
  75. package/dist/components/sheet/BottomSheet.js.map +1 -1
  76. package/dist/components/sheet/SideSheet.d.ts +4 -1
  77. package/dist/components/sheet/SideSheet.js +2 -4
  78. package/dist/components/sheet/SideSheet.js.map +1 -1
  79. package/dist/components/slider/Slider.d.ts +4 -1
  80. package/dist/components/slider/Slider.js +2 -4
  81. package/dist/components/slider/Slider.js.map +1 -1
  82. package/dist/components/snackbar/Snackbar.d.ts +8 -2
  83. package/dist/components/snackbar/Snackbar.js +2 -4
  84. package/dist/components/snackbar/Snackbar.js.map +1 -1
  85. package/dist/components/snackbar/snackbar-tokens.d.ts +1 -1
  86. package/dist/components/split-button/SplitButton.d.ts +4 -1
  87. package/dist/components/split-button/SplitButton.js +4 -2
  88. package/dist/components/split-button/SplitButton.js.map +1 -1
  89. package/dist/components/switch/switch-styles.d.ts +3 -3
  90. package/dist/components/text-field/TextField.d.ts +4 -1
  91. package/dist/components/text-field/TextField.js +2 -4
  92. package/dist/components/text-field/TextField.js.map +1 -1
  93. package/dist/components/time-picker/TimeField.d.ts +24 -2
  94. package/dist/components/time-picker/TimeField.js +40 -12
  95. package/dist/components/time-picker/TimeField.js.map +1 -1
  96. package/dist/components/time-picker/TimeFieldList.js +95 -0
  97. package/dist/components/time-picker/TimeFieldList.js.map +1 -0
  98. package/dist/components/time-picker/TimePicker.d.ts +9 -5
  99. package/dist/components/time-picker/TimePicker.js +5 -2
  100. package/dist/components/time-picker/TimePicker.js.map +1 -1
  101. package/dist/components/time-picker/time-list.js +33 -0
  102. package/dist/components/time-picker/time-list.js.map +1 -0
  103. package/dist/components/tooltip/Tooltip.d.ts +1 -1
  104. package/dist/index.d.ts +40 -38
  105. package/dist/index.js +4 -3
  106. package/dist/primitives.d.ts +7 -4
  107. package/dist/primitives.js +4 -1
  108. package/dist/styles.compiled.css +1 -1
  109. package/dist/utils/use-scroll-keys.d.ts +29 -0
  110. package/dist/utils/use-scroll-keys.js +66 -0
  111. package/dist/utils/use-scroll-keys.js.map +1 -0
  112. package/dist/utils/use-scroll-restoration.d.ts +43 -0
  113. package/dist/utils/use-scroll-restoration.js +173 -0
  114. package/dist/utils/use-scroll-restoration.js.map +1 -0
  115. package/dist/windmorph-labels.d.ts +101 -0
  116. package/package.json +1 -1
  117. package/dist/composites/button-group/ButtonGroup.js.map +0 -1
  118. package/dist/composites/button-group/lazy-overflow-menu.js.map +0 -1
  119. package/dist/composites/button-group/overflow-menu-list.js.map +0 -1
@@ -0,0 +1,47 @@
1
+ "use client";
2
+ import { LabelsContext, defined } from "./use-labels.js";
3
+ import { useContext, useMemo } from "react";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region src/components/labels/LabelsProvider.tsx
6
+ /** One provider's words over another's, per component and per word. */
7
+ function mergeLabels(outer, inner) {
8
+ if (!outer) return inner;
9
+ const merged = { ...outer };
10
+ for (const [component, words] of Object.entries(inner)) merged[component] = {
11
+ ...merged[component],
12
+ ...defined(words)
13
+ };
14
+ return merged;
15
+ }
16
+ /**
17
+ * Sets the words every component below shows or announces by itself ("Close", "Error",
18
+ * "Character count: 0 of 160"), so an app in another language writes them once. Each
19
+ * component uses its English default, then the words of the providers above it (the nearest
20
+ * first, per word), then its own `labels` prop, which always wins.
21
+ *
22
+ * It ships no translations: the words are the app's. Some are functions, which a server
23
+ * component can't pass to a client one, so render it from a client file of the app's.
24
+ *
25
+ * ```tsx
26
+ * 'use client';
27
+ * const words: WindmorphLabels = {
28
+ * TextField: { error: 'Fehler', characterCount: (count, max) => `Zeichen: ${count} von ${max}` },
29
+ * DialogHeader: { close: 'Schließen' },
30
+ * };
31
+ * export const AppLabels = ({ children }: { children: ReactNode }) => (
32
+ * <LabelsProvider labels={words}>{children}</LabelsProvider>
33
+ * );
34
+ * ```
35
+ */
36
+ function LabelsProvider({ labels, children }) {
37
+ const outer = useContext(LabelsContext);
38
+ const merged = useMemo(() => mergeLabels(outer, labels), [outer, labels]);
39
+ return /* @__PURE__ */ jsx(LabelsContext, {
40
+ value: merged,
41
+ children
42
+ });
43
+ }
44
+ //#endregion
45
+ export { LabelsProvider };
46
+
47
+ //# sourceMappingURL=LabelsProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LabelsProvider.js","names":[],"sources":["../../../src/components/labels/LabelsProvider.tsx"],"sourcesContent":["'use client';\n\nimport { useContext, useMemo, type ReactNode } from 'react';\nimport type { WindmorphLabels } from '../../windmorph-labels';\nimport { defined, LabelsContext } from './use-labels';\n\nexport interface LabelsProviderProps {\n /**\n * The words, keyed by component: `{ TextField: { error: '…' }, DialogHeader: { close: '…' } }`.\n * Keep the object the same between renders (a constant, or `useMemo`), so the components\n * below render again only when a word changes.\n */\n labels: WindmorphLabels;\n children?: ReactNode;\n}\n\n/** One provider's words over another's, per component and per word. */\nfunction mergeLabels(outer: WindmorphLabels | null, inner: WindmorphLabels): WindmorphLabels {\n if (!outer) return inner;\n const merged: Record<string, object | undefined> = { ...outer };\n for (const [component, words] of Object.entries(inner)) {\n merged[component] = { ...merged[component], ...defined(words) };\n }\n return merged;\n}\n\n/**\n * Sets the words every component below shows or announces by itself (\"Close\", \"Error\",\n * \"Character count: 0 of 160\"), so an app in another language writes them once. Each\n * component uses its English default, then the words of the providers above it (the nearest\n * first, per word), then its own `labels` prop, which always wins.\n *\n * It ships no translations: the words are the app's. Some are functions, which a server\n * component can't pass to a client one, so render it from a client file of the app's.\n *\n * ```tsx\n * 'use client';\n * const words: WindmorphLabels = {\n * TextField: { error: 'Fehler', characterCount: (count, max) => `Zeichen: ${count} von ${max}` },\n * DialogHeader: { close: 'Schließen' },\n * };\n * export const AppLabels = ({ children }: { children: ReactNode }) => (\n * <LabelsProvider labels={words}>{children}</LabelsProvider>\n * );\n * ```\n */\nexport function LabelsProvider({ labels, children }: LabelsProviderProps) {\n const outer = useContext(LabelsContext);\n const merged = useMemo(() => mergeLabels(outer, labels), [outer, labels]);\n return <LabelsContext value={merged}>{children}</LabelsContext>;\n}\n"],"mappings":";;;;;;AAiBA,SAAS,YAAY,OAA+B,OAAyC;CAC3F,IAAI,CAAC,OAAO,OAAO;CACnB,MAAM,SAA6C,EAAE,GAAG,MAAM;CAC9D,KAAK,MAAM,CAAC,WAAW,UAAU,OAAO,QAAQ,KAAK,GACnD,OAAO,aAAa;EAAE,GAAG,OAAO;EAAY,GAAG,QAAQ,KAAK;CAAE;CAEhE,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,eAAe,EAAE,QAAQ,YAAiC;CACxE,MAAM,QAAQ,WAAW,aAAa;CACtC,MAAM,SAAS,cAAc,YAAY,OAAO,MAAM,GAAG,CAAC,OAAO,MAAM,CAAC;CACxE,OAAO,oBAAC,eAAD;EAAe,OAAO;EAAS;CAAwB,CAAA;AAChE"}
@@ -0,0 +1,16 @@
1
+ import { WindmorphLabels } from "../../windmorph-labels.js";
2
+ //#region src/components/labels/use-labels.d.ts
3
+ /** A component's key in {@link WindmorphLabels}. */
4
+ export type LabelsKey = keyof WindmorphLabels;
5
+ /** The words a key takes: the component's `Partial<…Labels>`. */
6
+ export type LabelsOf<Key extends LabelsKey> = NonNullable<WindmorphLabels[Key]>;
7
+ /**
8
+ * A component's words: its defaults, then the words a `LabelsProvider` above gives `key` (its
9
+ * key in `WindmorphLabels`; one built from another passes that one's key first), then its own
10
+ * `labels`. A word left `undefined` keeps the one below it. The result is the same object
11
+ * until one of the three changes. A component of your own adds its key to `WindmorphLabels` by
12
+ * declaration merging.
13
+ */
14
+ export declare function useLabels<Key extends LabelsKey, Defaults extends Partial<LabelsOf<Key>>>(key: Key | readonly [...LabelsKey[], Key], defaults: Defaults, own: WindmorphLabels[Key]): Defaults & LabelsOf<Key>;
15
+ //#endregion
16
+ //# sourceMappingURL=use-labels.d.ts.map
@@ -0,0 +1,42 @@
1
+ "use client";
2
+ import { createContext, useContext, useMemo } from "react";
3
+ //#region src/components/labels/use-labels.ts
4
+ /** The words of the providers above, already merged; `null` with no provider. */
5
+ const LabelsContext = createContext(null);
6
+ /** An object without its `undefined` values, so a word left `undefined` keeps the one below. */
7
+ function defined(words) {
8
+ if (!words) return {};
9
+ const kept = {};
10
+ for (const key of Object.keys(words)) if (words[key] !== void 0) kept[key] = words[key];
11
+ return kept;
12
+ }
13
+ /**
14
+ * The defaults of a component that works its own out where it uses them (a title that depends
15
+ * on a prop). One object for all of them, so the words stay the same between renders.
16
+ */
17
+ const NO_DEFAULT_LABELS = {};
18
+ /**
19
+ * A component's words: its defaults, then the words a `LabelsProvider` above gives `key` (its
20
+ * key in `WindmorphLabels`; one built from another passes that one's key first), then its own
21
+ * `labels`. A word left `undefined` keeps the one below it. The result is the same object
22
+ * until one of the three changes. A component of your own adds its key to `WindmorphLabels` by
23
+ * declaration merging.
24
+ */
25
+ function useLabels(key, defaults, own) {
26
+ const provided = useContext(LabelsContext);
27
+ const keys = typeof key === "string" ? key : key.join(" ");
28
+ return useMemo(() => {
29
+ const words = { ...defaults };
30
+ if (provided) for (const each of keys.split(" ")) Object.assign(words, defined(provided[each]));
31
+ return Object.assign(words, defined(own));
32
+ }, [
33
+ provided,
34
+ keys,
35
+ defaults,
36
+ own
37
+ ]);
38
+ }
39
+ //#endregion
40
+ export { LabelsContext, NO_DEFAULT_LABELS, defined, useLabels };
41
+
42
+ //# sourceMappingURL=use-labels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-labels.js","names":[],"sources":["../../../src/components/labels/use-labels.ts"],"sourcesContent":["'use client';\n\nimport { createContext, useContext, useMemo } from 'react';\nimport type { WindmorphLabels } from '../../windmorph-labels';\n\n/** A component's key in {@link WindmorphLabels}. */\nexport type LabelsKey = keyof WindmorphLabels;\n\n/** The words a key takes: the component's `Partial<…Labels>`. */\nexport type LabelsOf<Key extends LabelsKey> = NonNullable<WindmorphLabels[Key]>;\n\n/** The words of the providers above, already merged; `null` with no provider. */\nexport const LabelsContext = createContext<WindmorphLabels | null>(null);\n\n/** An object without its `undefined` values, so a word left `undefined` keeps the one below. */\nexport function defined<T extends object>(words: T | undefined): Partial<T> {\n if (!words) return {};\n const kept: Partial<T> = {};\n for (const key of Object.keys(words) as (keyof T)[]) {\n if (words[key] !== undefined) kept[key] = words[key];\n }\n return kept;\n}\n\n/**\n * The defaults of a component that works its own out where it uses them (a title that depends\n * on a prop). One object for all of them, so the words stay the same between renders.\n */\nexport const NO_DEFAULT_LABELS = {};\n\n/**\n * A component's words: its defaults, then the words a `LabelsProvider` above gives `key` (its\n * key in `WindmorphLabels`; one built from another passes that one's key first), then its own\n * `labels`. A word left `undefined` keeps the one below it. The result is the same object\n * until one of the three changes. A component of your own adds its key to `WindmorphLabels` by\n * declaration merging.\n */\nexport function useLabels<Key extends LabelsKey, Defaults extends Partial<LabelsOf<Key>>>(\n key: Key | readonly [...LabelsKey[], Key],\n defaults: Defaults,\n own: WindmorphLabels[Key],\n): Defaults & LabelsOf<Key> {\n const provided = useContext(LabelsContext);\n const keys = typeof key === 'string' ? key : key.join(' ');\n return useMemo(() => {\n const words: Record<string, unknown> = { ...defaults };\n if (provided) {\n for (const each of keys.split(' ') as LabelsKey[]) {\n Object.assign(words, defined(provided[each]));\n }\n }\n return Object.assign(words, defined(own)) as Defaults & LabelsOf<Key>;\n }, [provided, keys, defaults, own]);\n}\n"],"mappings":";;;;AAYA,MAAa,gBAAgB,cAAsC,IAAI;;AAGvE,SAAgB,QAA0B,OAAkC;CAC1E,IAAI,CAAC,OAAO,OAAO,CAAC;CACpB,MAAM,OAAmB,CAAC;CAC1B,KAAK,MAAM,OAAO,OAAO,KAAK,KAAK,GACjC,IAAI,MAAM,SAAS,KAAA,GAAW,KAAK,OAAO,MAAM;CAElD,OAAO;AACT;;;;;AAMA,MAAa,oBAAoB,CAAC;;;;;;;;AASlC,SAAgB,UACd,KACA,UACA,KAC0B;CAC1B,MAAM,WAAW,WAAW,aAAa;CACzC,MAAM,OAAO,OAAO,QAAQ,WAAW,MAAM,IAAI,KAAK,GAAG;CACzD,OAAO,cAAc;EACnB,MAAM,QAAiC,EAAE,GAAG,SAAS;EACrD,IAAI,UACF,KAAK,MAAM,QAAQ,KAAK,MAAM,GAAG,GAC/B,OAAO,OAAO,OAAO,QAAQ,SAAS,KAAK,CAAC;EAGhD,OAAO,OAAO,OAAO,OAAO,QAAQ,GAAG,CAAC;CAC1C,GAAG;EAAC;EAAU;EAAM;EAAU;CAAG,CAAC;AACpC"}
@@ -164,7 +164,10 @@ export interface MenuProps extends Omit<AriaMenuProps<object>, 'children' | 'ite
164
164
  * @default "popover"
165
165
  */
166
166
  presentation?: MenuPresentation;
167
- /** Words the menu shows in a sheet. Set them on the root menu. */
167
+ /**
168
+ * Words the menu shows in a sheet. Set them on the root menu. A {@link LabelsProvider} sets them
169
+ * for the whole app.
170
+ */
168
171
  labels?: Partial<MenuLabels>;
169
172
  /**
170
173
  * Open and close with no motion (M3: "In dense products, such as on desktop, menus can
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { densityAttribute } from "../../tokens/density.js";
3
3
  import { cn } from "../../utils/cn.js";
4
+ import { useLabels } from "../labels/use-labels.js";
4
5
  import { TriggerContext } from "../../primitives/TriggerContext.js";
5
6
  import { useM3Interaction } from "../../primitives/use-m3-interaction.js";
6
7
  import { mergeDataTokens } from "../../utils/merge-data-tokens.js";
@@ -135,7 +136,8 @@ function Menu({ presentation = "popover", instant = false, ...props }) {
135
136
  * The sheet's code loads on first open (or when the trigger is hovered or focused), so a
136
137
  * menu that only opens as a popover doesn't carry it.
137
138
  */
138
- function MenuSheet({ trigger, layout: _layout, placement: _placement, offset: _offset, variant = "standard", labels, className, style, ...props }) {
139
+ function MenuSheet({ trigger, layout: _layout, placement: _placement, offset: _offset, variant = "standard", labels: labelsProp, className, style, ...props }) {
140
+ const labels = useLabels("Menu", DEFAULT_LABELS, labelsProp);
139
141
  const [container, setContainer] = useState(null);
140
142
  const [activeLevel, setActiveLevel] = useState(0);
141
143
  const menuProps = mergeProps(trigger.menuProps, props);
@@ -165,10 +167,7 @@ function MenuSheet({ trigger, layout: _layout, placement: _placement, offset: _o
165
167
  density: props.density,
166
168
  instant: false,
167
169
  sheet: true,
168
- labels: {
169
- ...DEFAULT_LABELS,
170
- ...labels
171
- }
170
+ labels
172
171
  },
173
172
  children: /* @__PURE__ */ jsx(MenuList, {
174
173
  ...menuProps,
@@ -196,7 +195,8 @@ const subscribeToNothing = () => () => {};
196
195
  function toPhysicalPlacement(placement, direction) {
197
196
  return toAriaPlacement(placement, direction === "rtl");
198
197
  }
199
- function MenuPopover({ trigger, instant, isExiting, exitProps, placement = "bottom-start", offset = 0, containerPadding = 12, layout = "divider", variant = "standard", labels, className, style, ...props }) {
198
+ function MenuPopover({ trigger, instant, isExiting, exitProps, placement = "bottom-start", offset = 0, containerPadding = 12, layout = "divider", variant = "standard", labels: labelsProp, className, style, ...props }) {
199
+ const labels = useLabels("Menu", DEFAULT_LABELS, labelsProp);
200
200
  const popoverRef = useRef(null);
201
201
  const [container, setContainer] = useState(null);
202
202
  const setPopover = useCallback((element) => {
@@ -264,10 +264,7 @@ function MenuPopover({ trigger, instant, isExiting, exitProps, placement = "bott
264
264
  density: props.density,
265
265
  instant,
266
266
  sheet: false,
267
- labels: {
268
- ...DEFAULT_LABELS,
269
- ...labels
270
- }
267
+ labels
271
268
  },
272
269
  children: /* @__PURE__ */ jsx(MenuList, {
273
270
  ...mergeProps(trigger.menuProps, props),
@@ -1 +1 @@
1
- {"version":3,"file":"Menu.js","names":["Overlay"],"sources":["../../../src/components/menu/Menu.tsx"],"sourcesContent":["'use client';\n\nimport {\n cloneElement,\n createContext,\n useCallback,\n useContext,\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n useSyncExternalStore,\n type CSSProperties,\n type ElementType,\n type FocusEvent,\n type JSX,\n type Key,\n type ReactElement,\n type ReactNode,\n type Ref,\n type RefObject,\n} from 'react';\nimport {\n DismissButton,\n I18nProvider,\n mergeProps,\n useLocale,\n useMenu,\n useMenuItem,\n useMenuSection,\n useObjectRef,\n usePopover,\n useButton,\n useSubmenuTrigger,\n type AriaMenuItemProps,\n type AriaMenuOptions,\n type AriaMenuProps,\n type AriaPopoverProps,\n type Placement,\n} from 'react-aria';\nimport {\n Item,\n Section,\n useSubmenuTriggerState,\n useTreeState,\n type Node,\n type RootMenuTriggerState,\n type SubmenuTriggerState,\n type TreeState,\n} from 'react-stately';\nimport { localeWithDirection } from '../../primitives/locale-with-direction';\nimport { Overlay } from '../../primitives/Overlay';\nimport { TriggerContext } from '../../primitives/TriggerContext';\nimport { useM3Interaction } from '../../primitives/use-m3-interaction';\nimport { usePresence } from '../../primitives/use-presence';\nimport { densityAttribute, type Density } from '../../tokens/density';\nimport { toAriaPlacement } from '../../utils/placement';\nimport { assertCollectionChildren } from '../../utils/assert-collection-children';\nimport { cn } from '../../utils/cn';\nimport { useTypeaheadDelegate } from '../../utils/typeahead';\nimport { COMPACT_WINDOW, useMediaQuery } from '../date-picker/use-media-query';\nimport { Divider } from '../divider/Divider';\nimport { LazyBottomSheet, usePreloadBottomSheet } from '../sheet/lazy-bottom-sheet';\nimport { BackIcon } from '../sheet/sheet-icons';\nimport { useRevealEntering } from './use-reveal-entering';\nimport { menuOwnWidth, menuStyles, type MenuLayout, type MenuVariant } from './menu-styles';\nimport { MenuTriggerContext, type MenuTriggerContextValue } from './menu-trigger';\n\nexport {\n ContextMenuTrigger,\n MenuTrigger,\n type ContextMenuTriggerProps,\n type MenuTriggerProps,\n} from './menu-trigger';\nimport { mergeDataTokens } from '../../utils/merge-data-tokens';\nimport { splitRootProps, type RootDOMProps } from '../../utils/root-props';\n\nconst CheckIcon = () => (\n <svg viewBox=\"0 -960 960 960\" fill=\"currentColor\">\n <path d=\"M382-240 154-468l57-57 171 171 367-367 57 57-424 424Z\" />\n </svg>\n);\n\n/** Clears the link attributes `useMenuItem` copies from an item's props onto one that isn't a link. */\nconst NOT_A_LINK = {\n href: undefined,\n target: undefined,\n rel: undefined,\n download: undefined,\n ping: undefined,\n referrerPolicy: undefined,\n};\n\n/** The default submenu arrow (Material Symbols `arrow_right`), mirrored in RTL. */\nconst SubmenuIcon = () => (\n <svg viewBox=\"0 -960 960 960\" fill=\"currentColor\" className=\"rtl:-scale-x-100\">\n <path d=\"M400-280v-400l200 200-200 200Z\" />\n </svg>\n);\n\n/** Props of a {@link MenuItem}; the React `key` identifies it for `onAction` and selection. */\nexport interface MenuItemProps {\n /** The label. */\n children: ReactNode;\n /** Plain-text label for typeahead when `children` is not a string. */\n textValue?: string;\n /** Icon before the label. */\n leadingIcon?: ReactNode;\n /** Icon shown while selected (defaults to a check in selectable menus). */\n selectedIcon?: ReactNode;\n /** Second line of text (supporting text), read as part of the item's name after the label. */\n description?: ReactNode;\n /**\n * A badge before the trailing text or icon (M3 anatomy), such as a `Badge` with a count.\n * It's read after the name, as the item's description.\n */\n badge?: ReactNode;\n /** Keyboard shortcut shown at the end, e.g. \"⌘C\", read as the item's description. */\n shortcut?: string;\n /** Icon at the end (an item with a submenu shows an arrow by default). */\n trailingIcon?: ReactNode;\n /**\n * Makes the item a link: a real `<a>` with the item's look, role and keys, so the browser's\n * link menu (open in a new tab, copy or save the link) and modified clicks work. A press,\n * Enter or Space follows it, through a `RouterProvider` (such as `NextRouterProvider`) on a\n * plain click, and closes the menu. A disabled item, or one that opens a submenu, isn't a link.\n */\n href?: string;\n /** A link item's target; `_blank` adds `rel=\"noopener noreferrer\"` unless `rel` is given. */\n target?: string;\n /** A link item's `rel`, e.g. `\"nofollow\"`. */\n rel?: string;\n /** Downloads the link item's file instead of opening it (optionally with a file name). */\n download?: boolean | string;\n /** Accessible name when the label isn't plain text. */\n 'aria-label'?: string;\n /** Classes for the item, merged after `classNames.item`; consumer classes win. */\n className?: string;\n}\n\n/** An item in a `Menu` (a React Stately collection item: identify it with `key`). */\nexport const MenuItem = Item as unknown as (props: MenuItemProps) => JSX.Element;\n\nexport interface MenuGroupProps {\n /** Group label shown above its items. */\n title?: ReactNode;\n /** Accessible name for the group when it has no `title`. */\n 'aria-label'?: string;\n /** `MenuItem`s and `SubmenuTrigger`s. */\n children: ReactElement | ReactElement[];\n}\n\n/**\n * A group of items (a React Stately collection section): set off by dividers in the\n * `divider` layout, its own surface in the `gap` layout.\n */\nexport const MenuGroup = Section as unknown as (props: MenuGroupProps) => JSX.Element;\n\nexport interface SubmenuTriggerProps {\n /** The `MenuItem` that opens the submenu, then the submenu's `Menu`. */\n children: [ReactElement<MenuItemProps>, ReactElement<MenuProps>];\n /** How long (ms) the pointer rests on the item before the submenu opens. @default 200 */\n delay?: number;\n}\n\n/** What a `SubmenuTrigger` adds to its item's collection node. */\ninterface SubmenuItemProps extends MenuItemProps {\n submenu?: ReactElement<MenuProps>;\n submenuDelay?: number;\n /** See {@link CheckableMenuItemProps}. */\n checkable?: boolean;\n}\n\n/**\n * Props of a {@link CheckableMenuItem}, for the library's own menus (not exported from the\n * package): in a selectable menu, `checkable={false}` makes an item a plain action, with the\n * `menuitem` role, no checked state and no check, that closes the menu like any action.\n */\nexport interface CheckableMenuItemProps extends MenuItemProps {\n /** Whether the item can be checked in a selectable menu. @default true */\n checkable?: boolean;\n}\n\n/** A {@link MenuItem} that can opt out of the menu's selection (library-internal). */\nexport const CheckableMenuItem = Item as unknown as (props: CheckableMenuItemProps) => JSX.Element;\n\n/** Only a menu collection reads a `SubmenuTrigger`; rendered on its own it's nothing. */\nfunction SubmenuTriggerElement(): null {\n return null;\n}\n\n/** React Stately builds the item's node from this, with the submenu on its props. */\nSubmenuTriggerElement.getCollectionNode = function* getCollectionNode({\n children: [item, submenu],\n delay,\n}: SubmenuTriggerProps) {\n // `cloneElement` keeps the item's own `key`.\n yield { element: cloneElement(item, { submenu, submenuDelay: delay } as SubmenuItemProps) };\n};\n\n/**\n * Gives a menu item a submenu (M3: \"On web, menus can open submenus\"). It opens beside the\n * item, without covering it, on hover, press, Enter, Space or the arrow key pointing away\n * from the menu (Left in right-to-left), and closes with the opposite arrow or Escape.\n * While it's open, the item shows its active (pressed) layer, and the menu holding focus\n * takes rounder corners than the other one.\n *\n * @example\n * <SubmenuTrigger>\n * <MenuItem key=\"share\">Share</MenuItem>\n * <Menu onAction={(key) => share(key)}>\n * <MenuItem key=\"email\">Email</MenuItem>\n * <MenuItem key=\"link\">Copy link</MenuItem>\n * </Menu>\n * </SubmenuTrigger>\n */\nexport const SubmenuTrigger = SubmenuTriggerElement as unknown as (\n props: SubmenuTriggerProps,\n) => JSX.Element;\n\nexport interface MenuClassNames {\n /**\n * The menu's surface (the `menu` element): its colour, corners, size and the list that\n * scrolls. In a sheet it spans the sheet, without a surface of its own.\n */\n panel?: string;\n /**\n * The bottom sheet the menu opens in (`presentation=\"sheet\"`, or `\"auto\"` on compact\n * windows): the sheet's surface, as its `classNames.panel`.\n */\n sheet?: string;\n /** Each group of items (its own surface in the `gap` layout). */\n group?: string;\n /** Each `MenuGroup`'s heading. */\n heading?: string;\n /** Each item. */\n item?: string;\n /** Each item's leading icon, or the icon marking a selected item. */\n icon?: string;\n /** Each item's `description` line. */\n description?: string;\n /** Each item's keyboard `shortcut`. */\n shortcut?: string;\n /** Each item's trailing icon, including a submenu's arrow. */\n trailingIcon?: string;\n /** The dividers between groups in the `divider` layout. */\n divider?: string;\n}\n\nexport interface MenuProps\n extends\n Omit<\n AriaMenuProps<object>,\n | 'children'\n | 'items'\n | 'onClose'\n | 'autoFocus'\n | 'disallowEmptySelection'\n // The arrow keys always wrap and Escape always closes the menu, as M3's menus do.\n | 'shouldFocusWrap'\n | 'escapeKeyBehavior'\n >,\n Omit<RootDOMProps, keyof AriaMenuProps<object>> {\n /**\n * With `selectionMode`: the last selected item can be deselected, leaving none. `false` keeps\n * at least one item selected. @default true\n */\n deselectable?: boolean;\n /**\n * The keys of items that can't be chosen. They stay focusable, as M3 asks (\"Disabled menu\n * items can receive focus but aren't selectable\").\n */\n disabledKeys?: AriaMenuProps<object>['disabledKeys'];\n /** `MenuItem`s, `MenuGroup`s and `SubmenuTrigger`s. */\n children: ReactNode;\n /** `standard` (surface colours) or `vibrant` (tertiary container). @default \"standard\" */\n variant?: MenuVariant;\n /**\n * How groups are set apart. `divider`: one surface with dividers between groups, which M3\n * recommends on the web and for menus that scroll. `gap`: each group is its own surface,\n * 2px apart; a `gap` menu that has to scroll switches to dividers, since M3 doesn't use\n * gaps in scrolling menus. A submenu takes its parent's layout and variant unless it\n * sets its own.\n * @default \"divider\"\n */\n layout?: MenuLayout;\n /**\n * Web density (M3: \"On web only … Increasing density decreases the top and bottom\n * padding\"): each step down takes 4px off the items' height (44px at 0, 32px at -3) and 2px\n * off the space around dividers. Left out, the menu takes the density of the nearest\n * `ThemeProvider` or `ThemeScope`; a submenu takes its parent menu's. Keep 0 for touch.\n * @default 0\n */\n density?: Density;\n /**\n * Placement relative to the trigger: a side, then optionally the edge to align with\n * (`start` / `end` follow the text direction). A submenu always opens beside its item.\n * @default \"bottom-start\"\n */\n placement?: MenuPlacement;\n /** Gap between the trigger and the menu, in px (a split button's menu sits 4px away). @default 0 */\n offset?: number;\n /**\n * The least space kept between the menu and the window's edges, in px. A split button\n * passes 0, so its menu lines up with the trailing button even at the edge of the screen.\n * @default 12\n */\n containerPadding?: number;\n /**\n * Where the menu opens. `popover`: anchored to its trigger. `sheet`: in a modal bottom\n * sheet. `auto`: a sheet on compact windows (below 600px wide) and a popover on larger\n * ones (M3: \"Consider adapting menus into bottom sheets on small screens\"). Set it on the\n * root menu.\n * @default \"popover\"\n */\n presentation?: MenuPresentation;\n /** Words the menu shows in a sheet. Set them on the root menu. */\n labels?: Partial<MenuLabels>;\n /**\n * Open and close with no motion (M3: \"In dense products, such as on desktop, menus can\n * open instantly to reduce motion\"). Submenus follow their root menu. Popovers only: a menu\n * shown as a bottom sheet (`presentation=\"sheet\"`, or `auto` on a compact window) keeps the\n * sheet's slide, as M3's and Compose's modal bottom sheets always animate; under reduced\n * motion it fades instead.\n * @default false\n */\n instant?: boolean;\n /**\n * Goes with `style` on the menu's outermost element: the box React Aria places against the\n * trigger, or the bottom sheet's outermost element in a sheet. The surface inside keeps\n * its size and its place against the trigger whatever layout class lands here (the box\n * keeps the menu's own width); style it with `classNames.panel`.\n */\n className?: string;\n /** Classes for each part, by slot. */\n classNames?: MenuClassNames;\n /** Goes on the menu's outermost element, with `className`. */\n style?: CSSProperties;\n /** Ref to the menu's list, the `role=\"menu\"` element, in a popover or a sheet. */\n ref?: Ref<HTMLDivElement>;\n}\n\n/** Where a {@link Menu} sits against its trigger: a side, then optionally the edge it aligns with. */\nexport type MenuPlacement =\n | 'top'\n | 'bottom'\n | 'start'\n | 'end'\n | 'top-start'\n | 'top-end'\n | 'bottom-start'\n | 'bottom-end'\n | 'start-top'\n | 'start-bottom'\n | 'end-top'\n | 'end-bottom';\n\n/** Where a {@link Menu} opens. */\nexport type MenuPresentation = 'popover' | 'sheet' | 'auto';\n\n/** Words a {@link Menu} shows. */\nexport interface MenuLabels {\n /**\n * In a sheet, the button above a submenu that goes back to the menu that opened it.\n * @default \"Back\"\n */\n back: string;\n}\n\nconst DEFAULT_LABELS: MenuLabels = { back: 'Back' };\n\n/**\n * M3 Expressive menu: items on one surface with dividers between groups (or on grouped\n * surfaces), standard or vibrant colours, optional single or multiple selection with a\n * selected shape and check, submenus, keyboard navigation and typeahead (React Aria\n * `useMenu`). Must be inside a `MenuTrigger` or `ContextMenuTrigger`; it opens anchored to\n * the trigger in a portal that keeps the surrounding theme and direction.\n *\n * @example\n * <MenuTrigger>\n * <IconButton icon={<MoreIcon />} aria-label=\"More\" />\n * <Menu onAction={(key) => run(key)}>\n * <MenuGroup>\n * <MenuItem key=\"copy\" shortcut=\"⌘C\">Copy</MenuItem>\n * <MenuItem key=\"paste\" shortcut=\"⌘V\">Paste</MenuItem>\n * </MenuGroup>\n * <MenuGroup>\n * <MenuItem key=\"delete\">Delete</MenuItem>\n * </MenuGroup>\n * </Menu>\n * </MenuTrigger>\n */\nexport function Menu({ presentation = 'popover', instant = false, ...props }: MenuProps) {\n const trigger = useContext(MenuTriggerContext);\n if (!trigger) throw new Error('[@windmorph/react] <Menu> must be used inside <MenuTrigger>.');\n const compact = useMediaQuery(COMPACT_WINDOW);\n const presence = usePresence(trigger.state.isOpen);\n const asSheet = presentation === 'sheet' || (presentation === 'auto' && compact);\n usePreloadBottomSheet(trigger.triggerRef, asSheet);\n if (asSheet) return <MenuSheet {...props} trigger={trigger} />;\n // An instant menu leaves at once, without waiting for an exit transition.\n const isPresent = instant ? trigger.state.isOpen : presence.isPresent;\n const isExiting = !instant && presence.isExiting;\n if (!isPresent) return null;\n return (\n <Overlay exiting={isExiting}>\n <MenuPopover\n {...props}\n trigger={trigger}\n instant={instant}\n isExiting={isExiting}\n exitProps={presence.exitProps}\n />\n </Overlay>\n );\n}\n\n/**\n * The menu in a modal bottom sheet (M3: menus can adapt into bottom sheets on small\n * screens). The sheet is a dialog named like the menu; the menu inside keeps its role,\n * keyboard, typeahead and initial focus, and spans the sheet without a surface of its own.\n * The sheet's code loads on first open (or when the trigger is hovered or focused), so a\n * menu that only opens as a popover doesn't carry it.\n */\nfunction MenuSheet({\n trigger,\n layout: _layout,\n placement: _placement,\n offset: _offset,\n variant = 'standard',\n labels,\n className,\n style,\n ...props\n}: Omit<MenuProps, 'presentation' | 'instant'> & { trigger: MenuTriggerContextValue }) {\n const [container, setContainer] = useState<HTMLDivElement | null>(null);\n const [activeLevel, setActiveLevel] = useState(0);\n const menuProps = mergeProps(trigger.menuProps, props);\n const label = menuProps['aria-label'];\n const naming =\n label != null\n ? { 'aria-label': label }\n : { 'aria-labelledby': menuProps['aria-labelledby'] ?? '' };\n return (\n <LazyBottomSheet\n {...naming}\n // A menu sheet opens at its own height (up to the window, the list scrolling inside):\n // at half the window, a short phone left its last items off-screen, where the arrow\n // keys could still move focus.\n skipPartiallyExpanded\n open={trigger.state.isOpen}\n onOpenChange={(open) => (open ? trigger.state.open() : trigger.state.close())}\n className={className}\n style={style}\n classNames={props.classNames?.sheet ? { panel: props.classNames.sheet } : undefined}\n >\n <div ref={setContainer} className={menuStyles().sheetContent()}>\n <TriggerContext value={null}>\n <MenuTreeContext\n value={{\n rootState: trigger.state,\n container,\n activeLevel,\n setActiveLevel,\n layout: 'divider',\n variant,\n density: props.density,\n instant: false,\n sheet: true,\n labels: { ...DEFAULT_LABELS, ...labels },\n }}\n >\n <MenuList\n {...menuProps}\n layout=\"divider\"\n variant={variant}\n level={0}\n embedded\n onClose={trigger.state.close}\n autoFocus={trigger.state.focusStrategy ?? 'first'}\n />\n </MenuTreeContext>\n </TriggerContext>\n </div>\n </LazyBottomSheet>\n );\n}\n\n/** Shared by a menu and its submenus. */\ninterface MenuTreeContextValue {\n rootState: RootMenuTriggerState;\n /** The root popover, which submenus portal into (inside its focus scope, never inert). */\n container: HTMLElement | null;\n /** The level of the menu holding focus (0 is the root menu). */\n activeLevel: number;\n setActiveLevel: (level: number) => void;\n /** What submenus inherit. */\n layout: MenuLayout;\n variant: MenuVariant;\n density: MenuProps['density'];\n /** Submenus open and close with no motion too. */\n instant: boolean;\n /**\n * In a sheet, a submenu takes the sheet's place of the menu that opened it, below a back\n * button, instead of opening beside its item.\n */\n sheet: boolean;\n labels: MenuLabels;\n}\n\nconst MenuTreeContext = createContext<MenuTreeContextValue | null>(null);\n\n/** The menu element an item is rendered in (a submenu's parent). */\nconst MenuListContext = createContext<RefObject<HTMLDivElement | null> | null>(null);\n\nconst subscribeToNothing = () => () => {};\n\n/**\n * React Aria resolves `start` / `end` from its locale context, not the DOM `dir`, so an\n * RTL region without an `I18nProvider` would align the menu to the wrong edge. Resolve\n * them to physical sides from the trigger's computed direction instead.\n */\nfunction toPhysicalPlacement(placement: MenuPlacement, direction: string): Placement {\n return toAriaPlacement(placement, direction === 'rtl');\n}\n\ntype ExitProps = ReturnType<typeof usePresence>['exitProps'];\n\nfunction MenuPopover({\n trigger,\n instant,\n isExiting,\n exitProps,\n placement = 'bottom-start',\n offset = 0,\n containerPadding = 12,\n layout = 'divider',\n variant = 'standard',\n labels,\n className,\n style,\n ...props\n}: Omit<MenuProps, 'presentation' | 'instant'> & {\n trigger: MenuTriggerContextValue;\n instant: boolean;\n isExiting: boolean;\n exitProps: ExitProps;\n}) {\n const popoverRef = useRef<HTMLDivElement>(null);\n const [container, setContainer] = useState<HTMLDivElement | null>(null);\n const setPopover = useCallback((element: HTMLDivElement | null) => {\n popoverRef.current = element;\n setContainer(element);\n }, []);\n const [activeLevel, setActiveLevel] = useState(0);\n // The DOM is the source of truth for direction; read it like an external store.\n const direction = useSyncExternalStore(\n subscribeToNothing,\n () =>\n trigger.triggerRef.current ? getComputedStyle(trigger.triggerRef.current).direction : 'ltr',\n () => 'ltr',\n );\n // Submenus' arrow keys and placement follow the locale's direction: give it the DOM's.\n const { locale, direction: localeDirection } = useLocale();\n const menuLocale =\n direction === localeDirection\n ? locale\n : localeWithDirection(locale, direction === 'rtl' ? 'rtl' : 'ltr');\n const {\n popoverProps,\n underlayProps,\n placement: actualPlacement,\n } = usePopover(\n {\n triggerRef: trigger.triggerRef,\n popoverRef,\n placement: toPhysicalPlacement(placement, direction),\n offset,\n containerPadding,\n },\n trigger.state,\n );\n const revealRef = useRef<HTMLDivElement>(null);\n const entering = useRevealEntering(actualPlacement, revealRef);\n const close = trigger.state.close;\n // Tab moves on from an open menu and closes it and its submenus (the APG menu button\n // pattern). React Aria's focus scope moves focus past the trigger, or back to it when\n // nothing follows; without the close, the menu stayed open with focus outside it. That\n // scope handles Tab on the document's capture phase and stops it, so this listens on the\n // window's, which comes first.\n useEffect(() => {\n const view = container?.ownerDocument.defaultView;\n if (!container || !view) return;\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key !== 'Tab' || event.altKey || event.ctrlKey || event.metaKey) return;\n if (container.contains(container.ownerDocument.activeElement)) close();\n };\n view.addEventListener('keydown', onKeyDown, true);\n return () => view.removeEventListener('keydown', onKeyDown, true);\n }, [container, close]);\n const styles = menuStyles();\n return (\n <>\n <div {...underlayProps} className=\"fixed inset-0\" />\n <div\n {...popoverProps}\n ref={setPopover}\n // React Aria's placement wins over a consumer style's and, through the attribute\n // (styles/utilities.css), over consumer inset classes.\n style={{ ...style, ...popoverProps.style }}\n data-overlay-placement=\"\"\n className={styles.popover({ class: cn(menuOwnWidth, className) })}\n >\n <DismissButton onDismiss={trigger.state.close} />\n <div\n {...exitProps}\n ref={revealRef}\n data-entering={entering || undefined}\n data-exiting={isExiting || undefined}\n data-placement={actualPlacement ?? undefined}\n className={menuStyles({ instant }).reveal()}\n >\n <TriggerContext value={null}>\n <I18nProvider locale={menuLocale}>\n <MenuTreeContext\n value={{\n rootState: trigger.state,\n container,\n activeLevel,\n setActiveLevel,\n layout,\n variant,\n density: props.density,\n instant,\n sheet: false,\n labels: { ...DEFAULT_LABELS, ...labels },\n }}\n >\n <MenuList\n {...mergeProps(trigger.menuProps, props)}\n layout={layout}\n variant={variant}\n level={0}\n onClose={trigger.state.close}\n autoFocus={trigger.state.focusStrategy ?? 'first'}\n />\n </MenuTreeContext>\n </I18nProvider>\n </TriggerContext>\n </div>\n <DismissButton onDismiss={trigger.state.close} />\n </div>\n </>\n );\n}\n\ntype Position = 'only' | 'first' | 'middle' | 'last';\ntype Edges = { top: boolean; bottom: boolean };\n\nconst positionOf = (index: number, count: number): Position =>\n count === 1 ? 'only' : index === 0 ? 'first' : index === count - 1 ? 'last' : 'middle';\n\n/** Which of a group's edges have the outer corners (the others have 8px). */\nconst roundEdges = (position: Position): Edges => ({\n top: position === 'only' || position === 'first',\n bottom: position === 'only' || position === 'last',\n});\n\n/** Sections become groups; runs of loose items between them form implicit groups. */\nfunction toGroups(nodes: Node<object>[]): (Node<object> | Node<object>[])[] {\n const groups: (Node<object> | Node<object>[])[] = [];\n let run: Node<object>[] = [];\n for (const node of nodes) {\n if (node.type === 'section') {\n if (run.length) groups.push(run);\n run = [];\n groups.push(node);\n } else {\n run.push(node);\n }\n }\n if (run.length) groups.push(run);\n return groups;\n}\n\ntype MenuListProps = Omit<\n MenuProps,\n 'placement' | 'layout' | 'variant' | 'presentation' | 'instant' | 'className' | 'style'\n> &\n Pick<AriaMenuOptions<object>, 'onClose' | 'autoFocus' | 'onKeyDown' | 'onKeyUp'> & {\n layout: MenuLayout;\n variant: MenuVariant;\n /** 0 for the root menu, then one more per submenu. */\n level: number;\n listRef?: RefObject<HTMLDivElement | null>;\n /** In a sheet: the list spans it, with no surface of its own. */\n embedded?: boolean;\n };\n\n/**\n * Whether the list has had to scroll, from a `ResizeObserver` (so it's measured only when\n * its size changes). Once true it stays true while the menu is open, so a `gap` menu that\n * switches to dividers can't flip back and forth.\n */\nfunction useHasScrolled(ref: RefObject<HTMLElement | null>, enabled: boolean) {\n const [scrolls, setScrolls] = useState(false);\n useLayoutEffect(() => {\n const element = ref.current;\n if (!enabled || scrolls || !element || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(() => {\n if (element.scrollHeight > element.clientHeight + 1) setScrolls(true);\n });\n observer.observe(element);\n return () => observer.disconnect();\n }, [ref, enabled, scrolls]);\n return scrolls;\n}\n\nfunction MenuList({\n deselectable = true,\n variant,\n layout: requestedLayout,\n density,\n level,\n classNames,\n listRef,\n embedded = false,\n ref: forwardedRef,\n ...allProps\n}: MenuListProps) {\n // The menu list is the menu's root (its `ref` and `id` land there): its DOM attributes too.\n const { root, rest: props } = splitRootProps(allProps);\n // MenuItem / MenuGroup are React Stately Item / Section, so children are a collection.\n assertCollectionChildren(\n props.children,\n 'Menu',\n 'MenuItem, MenuGroup and SubmenuTrigger elements',\n );\n const tree = useContext(MenuTreeContext);\n // M3: \"Disabled menu items can receive focus but aren't selectable.\"\n const state = useTreeState({\n ...(props as AriaMenuProps<object>),\n disallowEmptySelection: !deselectable,\n disabledBehavior: 'selection',\n });\n const ownRef = useObjectRef(forwardedRef);\n const ref = listRef ?? ownRef;\n // M3 keyboard table: \"Letters — Focus moves to the next menu item starting with letter\".\n const keyboardDelegate = useTypeaheadDelegate(state, ref);\n const { menuProps } = useMenu(\n // The arrow keys wrap from the last item to the first and back, as M3's menus and the rest\n // of the library's collections do (APG makes it optional).\n { ...(props as AriaMenuOptions<object>), keyboardDelegate, shouldFocusWrap: true },\n state,\n ref,\n );\n const groups = toGroups([...state.collection]);\n const scrolled = useHasScrolled(ref, requestedLayout === 'gap');\n const layout: MenuLayout = scrolled ? 'divider' : requestedLayout;\n const styles = menuStyles({ variant, layout, embedded });\n // While a submenu is open, the menu holding focus is rounder than the others (M3).\n const submenuOpen = Boolean(tree && tree.rootState.expandedKeysStack.length > 0);\n const shape = !submenuOpen ? undefined : tree?.activeLevel === level ? 'active' : 'inactive';\n const setActive = tree?.setActiveLevel;\n\n return (\n <div\n {...mergeProps(root, menuProps, {\n // Focus events bubble through portals: count only focus inside this menu's element.\n onFocus: (event: FocusEvent<HTMLDivElement>) => {\n if (event.currentTarget.contains(event.target)) setActive?.(level);\n },\n })}\n ref={ref}\n {...densityAttribute(density)}\n data-tokens={mergeDataTokens('md-comp-menus', root)}\n data-variant={variant}\n data-layout={layout}\n data-shape={shape}\n className={styles.menu({ class: classNames?.panel })}\n >\n <MenuListContext value={ref}>\n {groups.map((group, index) => {\n const position = positionOf(index, groups.length);\n // In the divider layout the menu is the surface: its first and last items nest in\n // its corners, and dividers go between groups.\n const edges: Edges =\n layout === 'divider'\n ? { top: index === 0, bottom: index === groups.length - 1 }\n : roundEdges(position);\n const groupStyles = menuStyles({ variant, layout, groupPosition: position, morph: true });\n return (\n <GroupWithDivider\n key={Array.isArray(group) ? group[0]!.key : group.key}\n divider={\n layout === 'divider' && index > 0 ? (\n // A menu's divider is a `separator` between its groups (WAI-ARIA menu).\n <Divider\n decorative={false}\n className={styles.divider({ class: classNames?.divider })}\n />\n ) : null\n }\n >\n {Array.isArray(group) ? (\n <div\n role=\"presentation\"\n className={groupStyles.group({ class: classNames?.group })}\n >\n <MenuItems\n nodes={group}\n state={state}\n variant={variant}\n edges={edges}\n classNames={classNames}\n />\n </div>\n ) : (\n <MenuSection\n section={group}\n state={state}\n variant={variant}\n className={groupStyles.group({ class: classNames?.group })}\n headingClassName={groupStyles.heading({ class: classNames?.heading })}\n edges={edges}\n classNames={classNames}\n />\n )}\n </GroupWithDivider>\n );\n })}\n </MenuListContext>\n </div>\n );\n}\n\nfunction GroupWithDivider({ divider, children }: { divider: ReactNode; children: ReactNode }) {\n return (\n <>\n {divider}\n {children}\n </>\n );\n}\n\nfunction MenuSection({\n section,\n state,\n variant,\n className,\n headingClassName,\n edges,\n classNames,\n}: {\n section: Node<object>;\n state: TreeState<object>;\n variant: MenuVariant;\n className: string;\n headingClassName: string;\n edges: Edges;\n classNames?: MenuClassNames;\n}) {\n const { itemProps, headingProps, groupProps } = useMenuSection({\n heading: section.rendered,\n 'aria-label': section['aria-label'],\n });\n return (\n <div {...itemProps} className={className}>\n {section.rendered && (\n <span {...headingProps} className={headingClassName}>\n {section.rendered}\n </span>\n )}\n <div {...groupProps} className=\"flex flex-col\">\n <MenuItems\n nodes={[...section.childNodes]}\n state={state}\n variant={variant}\n // A heading takes the group's top edge, so the first item doesn't touch it.\n edges={{ ...edges, top: !section.rendered && edges.top }}\n classNames={classNames}\n />\n </div>\n </div>\n );\n}\n\n/**\n * Items nest their corners inside the container's: an item on an outer edge gets the\n * outer corner less the 4px padding, and every other corner is 4px.\n */\nfunction MenuItems({\n nodes,\n state,\n variant,\n edges,\n classNames,\n}: {\n nodes: Node<object>[];\n state: TreeState<object>;\n variant: MenuVariant;\n edges: Edges;\n classNames?: MenuClassNames;\n}) {\n return nodes.map((node, index) => {\n const itemProps: MenuItemViewProps = {\n node,\n state,\n variant,\n top: index === 0 && edges.top ? 'outer' : 'plain',\n bottom: index === nodes.length - 1 && edges.bottom ? 'outer' : 'plain',\n classNames,\n };\n return (node.props as SubmenuItemProps).submenu ? (\n <SubmenuItemView key={node.key} {...itemProps} />\n ) : (\n <MenuItemView key={node.key} {...itemProps} />\n );\n });\n}\n\ninterface MenuItemViewProps {\n node: Node<object>;\n state: TreeState<object>;\n variant: MenuVariant;\n top: 'outer' | 'plain';\n bottom: 'outer' | 'plain';\n classNames?: MenuClassNames;\n /** A submenu trigger's props (from `useSubmenuTrigger`) and ref. */\n triggerProps?: Partial<AriaMenuItemProps>;\n itemRef?: RefObject<HTMLDivElement | null>;\n /** Whether the item's submenu is open (its active state). */\n submenuOpen?: boolean;\n}\n\n/** An item that opens a submenu, and the submenu's popover. */\nfunction SubmenuItemView(props: MenuItemViewProps) {\n const tree = useContext(MenuTreeContext)!;\n const parentMenuRef = useContext(MenuListContext)!;\n const { submenu, submenuDelay } = props.node.props as SubmenuItemProps;\n const submenuState = useSubmenuTriggerState({ triggerKey: props.node.key }, tree.rootState);\n const itemRef = useRef<HTMLDivElement>(null);\n const submenuRef = useRef<HTMLDivElement>(null);\n const { submenuTriggerProps, submenuProps, popoverProps } = useSubmenuTrigger(\n {\n parentMenuRef,\n submenuRef,\n delay: submenuDelay,\n isDisabled: props.state.disabledKeys.has(props.node.key),\n },\n submenuState,\n itemRef,\n );\n // In a sheet a submenu replaces its menu, so hovering an item doesn't open it.\n const { isOpen, onHoverChange, ...triggerProps } = submenuTriggerProps;\n // A sheet's submenu hides the item that opened it, so React Aria's focus on the item when\n // the submenu closes (← or Escape) finds it hidden. Once the menu shows again, the item\n // takes focus back from the closed submenu (or the back button), unless every menu closed.\n const wasOpen = useRef(isOpen);\n useLayoutEffect(() => {\n const closed = wasOpen.current && !isOpen;\n wasOpen.current = isOpen;\n const item = itemRef.current;\n if (!closed || !tree.sheet || !tree.rootState.isOpen || !item) return;\n const active = item.ownerDocument.activeElement;\n if (active == null || active === item.ownerDocument.body) item.focus();\n });\n return (\n <>\n <MenuItemView\n {...props}\n triggerProps={tree.sheet ? triggerProps : { ...triggerProps, onHoverChange }}\n itemRef={itemRef}\n submenuOpen={isOpen}\n />\n {tree.sheet ? (\n <SubmenuSheetPanel\n state={submenuState}\n submenuRef={submenuRef}\n menuProps={submenuProps}\n submenu={submenu!}\n title={props.node.rendered}\n />\n ) : (\n <SubmenuPopover\n state={submenuState}\n triggerRef={itemRef}\n submenuRef={submenuRef}\n menuProps={submenuProps}\n popoverProps={popoverProps}\n submenu={submenu!}\n />\n )}\n </>\n );\n}\n\n/**\n * A submenu in a sheet (M3 adapts menus into bottom sheets on small screens, where there's\n * no room beside an item): it takes the place of the menu that opened it, which the sheet\n * hides while it's open, below a back button and its item's label. ← (→ in right-to-left),\n * Escape and the back button go back. It's portalled into the sheet after its menu, so the\n * sheet's focus scope covers it.\n */\nfunction SubmenuSheetPanel({\n state,\n submenuRef,\n menuProps,\n submenu,\n title,\n}: Pick<SubmenuPopoverProps, 'state' | 'submenuRef' | 'menuProps' | 'submenu'> & {\n title: ReactNode;\n}) {\n const tree = useContext(MenuTreeContext)!;\n if (!state.isOpen || !tree.container) return null;\n const { submenuLevel, ...ariaMenuProps } = menuProps;\n const own = submenu.props;\n const variant = own.variant ?? tree.variant;\n const styles = menuStyles({ variant });\n return (\n <Overlay portalContainer={tree.container} disableFocusManagement>\n <div data-submenu-panel=\"\" className={styles.sheetPanel()}>\n <div className={styles.sheetHeader()}>\n <SheetBackButton\n label={tree.labels.back}\n onPress={() => state.close()}\n className={styles.sheetBack()}\n />\n <span className={styles.sheetTitle()}>{title}</span>\n </div>\n <MenuList\n {...mergeProps(ariaMenuProps, own)}\n listRef={submenuRef}\n layout=\"divider\"\n variant={variant}\n density={own.density ?? tree.density}\n level={submenuLevel + 1}\n embedded\n // However it opened (a touch leaves focus on the item, now hidden), focus moves in.\n autoFocus={state.focusStrategy ?? 'first'}\n />\n </div>\n </Overlay>\n );\n}\n\n/** The back button above a sheet's submenu: 48px, with an outline focus ring. */\nfunction SheetBackButton({\n label,\n onPress,\n className,\n}: {\n label: string;\n onPress: () => void;\n className: string;\n}) {\n const ref = useRef<HTMLButtonElement>(null);\n const { buttonProps, isPressed } = useButton({ onPress, 'aria-label': label }, ref);\n const { interactionProps, dataAttributes } = useM3Interaction({ isPressed }, ref);\n return (\n <button\n {...mergeProps(buttonProps, interactionProps)}\n {...dataAttributes}\n ref={ref}\n className={className}\n >\n <BackIcon />\n </button>\n );\n}\n\ninterface SubmenuPopoverProps {\n state: SubmenuTriggerState;\n triggerRef: RefObject<HTMLDivElement | null>;\n submenuRef: RefObject<HTMLDivElement | null>;\n menuProps: ReturnType<typeof useSubmenuTrigger>['submenuProps'];\n popoverProps: ReturnType<typeof useSubmenuTrigger>['popoverProps'];\n submenu: ReactElement<MenuProps>;\n}\n\nfunction SubmenuPopover(props: SubmenuPopoverProps) {\n const tree = useContext(MenuTreeContext)!;\n const presence = usePresence(props.state.isOpen);\n const isPresent = tree.instant ? props.state.isOpen : presence.isPresent;\n const isExiting = !tree.instant && presence.isExiting;\n const { exitProps } = presence;\n if (!isPresent || !tree.container) return null;\n // Inside the root popover: its focus scope and outside-press handling cover the submenu,\n // and the modal root menu doesn't make it inert.\n return (\n <Overlay portalContainer={tree.container} disableFocusManagement exiting={isExiting}>\n <SubmenuPopoverContent {...props} isExiting={isExiting} exitProps={exitProps} />\n </Overlay>\n );\n}\n\nfunction SubmenuPopoverContent({\n state,\n triggerRef,\n submenuRef,\n menuProps,\n popoverProps,\n submenu,\n isExiting,\n exitProps,\n}: SubmenuPopoverProps & { isExiting: boolean; exitProps: ExitProps }) {\n const tree = useContext(MenuTreeContext)!;\n const popoverRef = useRef<HTMLDivElement>(null);\n const { submenuLevel, ...ariaMenuProps } = menuProps;\n const { popoverProps: positionProps, placement } = usePopover(\n {\n ...popoverProps,\n // React Aria handles this as a submenu's popover (dismissable, non-modal).\n ...({ trigger: 'SubmenuTrigger' } as Partial<AriaPopoverProps>),\n triggerRef,\n popoverRef,\n placement: 'end top',\n // Beside the parent menu (the 4px padding around the item and a 2px gap), with its\n // first item level with the item that opened it.\n offset: 6,\n crossOffset: -4,\n },\n state,\n );\n const revealRef = useRef<HTMLDivElement>(null);\n const entering = useRevealEntering(placement, revealRef);\n const { className, style, ...own } = submenu.props;\n const styles = menuStyles();\n return (\n // `w-max` (`menuOwnWidth`): positioned inside the narrower root popover, it would otherwise shrink to fit\n // what's left of that popover's width and wrap every label. Like the root menu's, the\n // submenu's `className` and `style` go on this outermost element.\n <div\n {...positionProps}\n ref={popoverRef}\n style={{ ...style, ...positionProps.style }}\n data-overlay-placement=\"\"\n className={styles.popover({ class: cn(menuOwnWidth, className) })}\n >\n <div\n {...exitProps}\n ref={revealRef}\n data-entering={entering || undefined}\n data-exiting={isExiting || undefined}\n data-placement={placement ?? undefined}\n className={menuStyles({ instant: tree.instant }).reveal()}\n >\n <MenuList\n {...mergeProps(ariaMenuProps, own)}\n listRef={submenuRef}\n layout={own.layout ?? tree.layout}\n variant={own.variant ?? tree.variant}\n density={own.density ?? tree.density}\n level={submenuLevel + 1}\n />\n </div>\n </div>\n );\n}\n\nfunction MenuItemView({\n node,\n state,\n variant,\n top,\n bottom,\n classNames,\n triggerProps,\n itemRef,\n submenuOpen = false,\n}: MenuItemViewProps) {\n const ownRef = useRef<HTMLElement>(null);\n const ref = itemRef ?? ownRef;\n const props = node.props as SubmenuItemProps;\n const isDisabled = state.disabledKeys.has(node.key);\n // A plain action in a selectable menu (`checkable={false}`) is never checked.\n const selectable = state.selectionManager.selectionMode !== 'none' && props.checkable !== false;\n const plainInSelectable = state.selectionManager.selectionMode !== 'none' && !selectable;\n const multiple = selectable && state.selectionManager.selectionMode === 'multiple';\n const {\n menuItemProps: ariaItemProps,\n keyboardShortcutProps,\n isSelected,\n isPressed,\n } = useMenuItem(\n {\n ...triggerProps,\n key: node.key,\n 'aria-label': props['aria-label'],\n // Disabled items stay focusable (the menu's `disabledBehavior`) but do nothing.\n isDisabled,\n isSelected: plainInSelectable ? false : undefined,\n // M3: multi-select menus stay open until they're dismissed, Enter included; a plain\n // action closes the menu, as in any menu.\n closeOnSelect: multiple ? false : plainInSelectable ? true : undefined,\n },\n state,\n ref,\n );\n const menuItemProps =\n plainInSelectable && !props.submenu\n ? { ...ariaItemProps, role: 'menuitem', 'aria-checked': undefined }\n : ariaItemProps;\n // A link item is a real `<a>`: `useMenuItem` gives it the link's attributes, routes a plain\n // click and closes the menu. A disabled item, or one that opens a submenu, stays a plain\n // element without them, so it can't be followed.\n const link = props.href != null && !isDisabled && !props.submenu;\n // Widened, so the item's ref (an element of either kind) fits both.\n const Root = (link ? 'a' : 'div') as ElementType;\n const linkAttributes = link\n ? { rel: props.rel ?? (props.target === '_blank' ? 'noopener noreferrer' : undefined) }\n : NOT_A_LINK;\n const { interactionProps, dataAttributes } = useM3Interaction(\n { isPressed, isDisabled, isSelected },\n ref,\n );\n const styles = menuStyles({\n variant,\n itemTop: top,\n itemBottom: bottom,\n hasDescription: Boolean(props.description),\n });\n const selectedIcon = props.selectedIcon ?? (selectable ? <CheckIcon /> : null);\n const trailingIcon = props.trailingIcon ?? (props.submenu ? <SubmenuIcon /> : null);\n const badgeId = useId();\n // Named by its content: the label and supporting text in the order they show, each read\n // once. React Aria names it by the label alone and describes it by the supporting text,\n // which leaves visible text out of its name (WCAG 2.5.3), as List options did. The shortcut\n // and the badge are extra information, not the item's label: they stay its description,\n // hidden from the content so they're read once.\n const describedBy =\n [props.shortcut ? keyboardShortcutProps.id : undefined, props.badge ? badgeId : undefined]\n .filter(Boolean)\n .join(' ') || undefined;\n\n return (\n <Root\n {...mergeProps(menuItemProps, interactionProps)}\n {...linkAttributes}\n {...dataAttributes}\n aria-labelledby={undefined}\n aria-describedby={describedBy}\n data-menu-open={submenuOpen || undefined}\n // Each item resolves the menu's tokens, so its selection picks its colours.\n data-tokens={mergeDataTokens('md-comp-menus', menuItemProps)}\n data-variant={variant}\n data-slot=\"item\"\n ref={ref}\n className={styles.item({ class: cn(classNames?.item, props.className) })}\n >\n {props.leadingIcon && selectedIcon ? (\n <span\n aria-hidden=\"true\"\n data-slot=\"leading-icon\"\n className={styles.icon({ class: classNames?.icon })}\n >\n {isSelected ? selectedIcon : props.leadingIcon}\n </span>\n ) : props.leadingIcon ? (\n <span\n aria-hidden=\"true\"\n data-slot=\"leading-icon\"\n className={styles.icon({ class: classNames?.icon })}\n >\n {props.leadingIcon}\n </span>\n ) : selectedIcon ? (\n // No leading icon: the selected icon expands in when selected (Compose).\n <span aria-hidden=\"true\" className={styles.selectedIcon()}>\n <span className={styles.selectedIconInner()}>\n <span className={styles.icon({ class: classNames?.icon })}>{selectedIcon}</span>\n </span>\n </span>\n ) : null}\n <span className={styles.text()}>\n <span>{node.rendered}</span>\n {props.description && (\n <span className={styles.description({ class: classNames?.description })}>\n {props.description}\n </span>\n )}\n </span>\n {props.badge && (\n <span id={badgeId} aria-hidden=\"true\" className={styles.badge()}>\n {props.badge}\n </span>\n )}\n {props.shortcut && (\n <kbd\n {...keyboardShortcutProps}\n aria-hidden=\"true\"\n className={styles.trailing({ class: cn('font-plain', classNames?.shortcut) })}\n >\n {props.shortcut}\n </kbd>\n )}\n {trailingIcon && (\n <span\n aria-hidden=\"true\"\n data-slot=\"trailing-icon\"\n className={styles.trailing({ class: classNames?.trailingIcon })}\n >\n {trailingIcon}\n </span>\n )}\n </Root>\n );\n}\n\nexport type { Key as MenuKey };\n"],"mappings":"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"}
1
+ {"version":3,"file":"Menu.js","names":["Overlay"],"sources":["../../../src/components/menu/Menu.tsx"],"sourcesContent":["'use client';\n\nimport {\n cloneElement,\n createContext,\n useCallback,\n useContext,\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n useSyncExternalStore,\n type CSSProperties,\n type ElementType,\n type FocusEvent,\n type JSX,\n type Key,\n type ReactElement,\n type ReactNode,\n type Ref,\n type RefObject,\n} from 'react';\nimport {\n DismissButton,\n I18nProvider,\n mergeProps,\n useLocale,\n useMenu,\n useMenuItem,\n useMenuSection,\n useObjectRef,\n usePopover,\n useButton,\n useSubmenuTrigger,\n type AriaMenuItemProps,\n type AriaMenuOptions,\n type AriaMenuProps,\n type AriaPopoverProps,\n type Placement,\n} from 'react-aria';\nimport {\n Item,\n Section,\n useSubmenuTriggerState,\n useTreeState,\n type Node,\n type RootMenuTriggerState,\n type SubmenuTriggerState,\n type TreeState,\n} from 'react-stately';\nimport { useLabels } from '../labels/use-labels';\nimport { localeWithDirection } from '../../primitives/locale-with-direction';\nimport { Overlay } from '../../primitives/Overlay';\nimport { TriggerContext } from '../../primitives/TriggerContext';\nimport { useM3Interaction } from '../../primitives/use-m3-interaction';\nimport { usePresence } from '../../primitives/use-presence';\nimport { densityAttribute, type Density } from '../../tokens/density';\nimport { toAriaPlacement } from '../../utils/placement';\nimport { assertCollectionChildren } from '../../utils/assert-collection-children';\nimport { cn } from '../../utils/cn';\nimport { useTypeaheadDelegate } from '../../utils/typeahead';\nimport { COMPACT_WINDOW, useMediaQuery } from '../date-picker/use-media-query';\nimport { Divider } from '../divider/Divider';\nimport { LazyBottomSheet, usePreloadBottomSheet } from '../sheet/lazy-bottom-sheet';\nimport { BackIcon } from '../sheet/sheet-icons';\nimport { useRevealEntering } from './use-reveal-entering';\nimport { menuOwnWidth, menuStyles, type MenuLayout, type MenuVariant } from './menu-styles';\nimport { MenuTriggerContext, type MenuTriggerContextValue } from './menu-trigger';\n\nexport {\n ContextMenuTrigger,\n MenuTrigger,\n type ContextMenuTriggerProps,\n type MenuTriggerProps,\n} from './menu-trigger';\nimport { mergeDataTokens } from '../../utils/merge-data-tokens';\nimport { splitRootProps, type RootDOMProps } from '../../utils/root-props';\n\nconst CheckIcon = () => (\n <svg viewBox=\"0 -960 960 960\" fill=\"currentColor\">\n <path d=\"M382-240 154-468l57-57 171 171 367-367 57 57-424 424Z\" />\n </svg>\n);\n\n/** Clears the link attributes `useMenuItem` copies from an item's props onto one that isn't a link. */\nconst NOT_A_LINK = {\n href: undefined,\n target: undefined,\n rel: undefined,\n download: undefined,\n ping: undefined,\n referrerPolicy: undefined,\n};\n\n/** The default submenu arrow (Material Symbols `arrow_right`), mirrored in RTL. */\nconst SubmenuIcon = () => (\n <svg viewBox=\"0 -960 960 960\" fill=\"currentColor\" className=\"rtl:-scale-x-100\">\n <path d=\"M400-280v-400l200 200-200 200Z\" />\n </svg>\n);\n\n/** Props of a {@link MenuItem}; the React `key` identifies it for `onAction` and selection. */\nexport interface MenuItemProps {\n /** The label. */\n children: ReactNode;\n /** Plain-text label for typeahead when `children` is not a string. */\n textValue?: string;\n /** Icon before the label. */\n leadingIcon?: ReactNode;\n /** Icon shown while selected (defaults to a check in selectable menus). */\n selectedIcon?: ReactNode;\n /** Second line of text (supporting text), read as part of the item's name after the label. */\n description?: ReactNode;\n /**\n * A badge before the trailing text or icon (M3 anatomy), such as a `Badge` with a count.\n * It's read after the name, as the item's description.\n */\n badge?: ReactNode;\n /** Keyboard shortcut shown at the end, e.g. \"⌘C\", read as the item's description. */\n shortcut?: string;\n /** Icon at the end (an item with a submenu shows an arrow by default). */\n trailingIcon?: ReactNode;\n /**\n * Makes the item a link: a real `<a>` with the item's look, role and keys, so the browser's\n * link menu (open in a new tab, copy or save the link) and modified clicks work. A press,\n * Enter or Space follows it, through a `RouterProvider` (such as `NextRouterProvider`) on a\n * plain click, and closes the menu. A disabled item, or one that opens a submenu, isn't a link.\n */\n href?: string;\n /** A link item's target; `_blank` adds `rel=\"noopener noreferrer\"` unless `rel` is given. */\n target?: string;\n /** A link item's `rel`, e.g. `\"nofollow\"`. */\n rel?: string;\n /** Downloads the link item's file instead of opening it (optionally with a file name). */\n download?: boolean | string;\n /** Accessible name when the label isn't plain text. */\n 'aria-label'?: string;\n /** Classes for the item, merged after `classNames.item`; consumer classes win. */\n className?: string;\n}\n\n/** An item in a `Menu` (a React Stately collection item: identify it with `key`). */\nexport const MenuItem = Item as unknown as (props: MenuItemProps) => JSX.Element;\n\nexport interface MenuGroupProps {\n /** Group label shown above its items. */\n title?: ReactNode;\n /** Accessible name for the group when it has no `title`. */\n 'aria-label'?: string;\n /** `MenuItem`s and `SubmenuTrigger`s. */\n children: ReactElement | ReactElement[];\n}\n\n/**\n * A group of items (a React Stately collection section): set off by dividers in the\n * `divider` layout, its own surface in the `gap` layout.\n */\nexport const MenuGroup = Section as unknown as (props: MenuGroupProps) => JSX.Element;\n\nexport interface SubmenuTriggerProps {\n /** The `MenuItem` that opens the submenu, then the submenu's `Menu`. */\n children: [ReactElement<MenuItemProps>, ReactElement<MenuProps>];\n /** How long (ms) the pointer rests on the item before the submenu opens. @default 200 */\n delay?: number;\n}\n\n/** What a `SubmenuTrigger` adds to its item's collection node. */\ninterface SubmenuItemProps extends MenuItemProps {\n submenu?: ReactElement<MenuProps>;\n submenuDelay?: number;\n /** See {@link CheckableMenuItemProps}. */\n checkable?: boolean;\n}\n\n/**\n * Props of a {@link CheckableMenuItem}, for the library's own menus (not exported from the\n * package): in a selectable menu, `checkable={false}` makes an item a plain action, with the\n * `menuitem` role, no checked state and no check, that closes the menu like any action.\n */\nexport interface CheckableMenuItemProps extends MenuItemProps {\n /** Whether the item can be checked in a selectable menu. @default true */\n checkable?: boolean;\n}\n\n/** A {@link MenuItem} that can opt out of the menu's selection (library-internal). */\nexport const CheckableMenuItem = Item as unknown as (props: CheckableMenuItemProps) => JSX.Element;\n\n/** Only a menu collection reads a `SubmenuTrigger`; rendered on its own it's nothing. */\nfunction SubmenuTriggerElement(): null {\n return null;\n}\n\n/** React Stately builds the item's node from this, with the submenu on its props. */\nSubmenuTriggerElement.getCollectionNode = function* getCollectionNode({\n children: [item, submenu],\n delay,\n}: SubmenuTriggerProps) {\n // `cloneElement` keeps the item's own `key`.\n yield { element: cloneElement(item, { submenu, submenuDelay: delay } as SubmenuItemProps) };\n};\n\n/**\n * Gives a menu item a submenu (M3: \"On web, menus can open submenus\"). It opens beside the\n * item, without covering it, on hover, press, Enter, Space or the arrow key pointing away\n * from the menu (Left in right-to-left), and closes with the opposite arrow or Escape.\n * While it's open, the item shows its active (pressed) layer, and the menu holding focus\n * takes rounder corners than the other one.\n *\n * @example\n * <SubmenuTrigger>\n * <MenuItem key=\"share\">Share</MenuItem>\n * <Menu onAction={(key) => share(key)}>\n * <MenuItem key=\"email\">Email</MenuItem>\n * <MenuItem key=\"link\">Copy link</MenuItem>\n * </Menu>\n * </SubmenuTrigger>\n */\nexport const SubmenuTrigger = SubmenuTriggerElement as unknown as (\n props: SubmenuTriggerProps,\n) => JSX.Element;\n\nexport interface MenuClassNames {\n /**\n * The menu's surface (the `menu` element): its colour, corners, size and the list that\n * scrolls. In a sheet it spans the sheet, without a surface of its own.\n */\n panel?: string;\n /**\n * The bottom sheet the menu opens in (`presentation=\"sheet\"`, or `\"auto\"` on compact\n * windows): the sheet's surface, as its `classNames.panel`.\n */\n sheet?: string;\n /** Each group of items (its own surface in the `gap` layout). */\n group?: string;\n /** Each `MenuGroup`'s heading. */\n heading?: string;\n /** Each item. */\n item?: string;\n /** Each item's leading icon, or the icon marking a selected item. */\n icon?: string;\n /** Each item's `description` line. */\n description?: string;\n /** Each item's keyboard `shortcut`. */\n shortcut?: string;\n /** Each item's trailing icon, including a submenu's arrow. */\n trailingIcon?: string;\n /** The dividers between groups in the `divider` layout. */\n divider?: string;\n}\n\nexport interface MenuProps\n extends\n Omit<\n AriaMenuProps<object>,\n | 'children'\n | 'items'\n | 'onClose'\n | 'autoFocus'\n | 'disallowEmptySelection'\n // The arrow keys always wrap and Escape always closes the menu, as M3's menus do.\n | 'shouldFocusWrap'\n | 'escapeKeyBehavior'\n >,\n Omit<RootDOMProps, keyof AriaMenuProps<object>> {\n /**\n * With `selectionMode`: the last selected item can be deselected, leaving none. `false` keeps\n * at least one item selected. @default true\n */\n deselectable?: boolean;\n /**\n * The keys of items that can't be chosen. They stay focusable, as M3 asks (\"Disabled menu\n * items can receive focus but aren't selectable\").\n */\n disabledKeys?: AriaMenuProps<object>['disabledKeys'];\n /** `MenuItem`s, `MenuGroup`s and `SubmenuTrigger`s. */\n children: ReactNode;\n /** `standard` (surface colours) or `vibrant` (tertiary container). @default \"standard\" */\n variant?: MenuVariant;\n /**\n * How groups are set apart. `divider`: one surface with dividers between groups, which M3\n * recommends on the web and for menus that scroll. `gap`: each group is its own surface,\n * 2px apart; a `gap` menu that has to scroll switches to dividers, since M3 doesn't use\n * gaps in scrolling menus. A submenu takes its parent's layout and variant unless it\n * sets its own.\n * @default \"divider\"\n */\n layout?: MenuLayout;\n /**\n * Web density (M3: \"On web only … Increasing density decreases the top and bottom\n * padding\"): each step down takes 4px off the items' height (44px at 0, 32px at -3) and 2px\n * off the space around dividers. Left out, the menu takes the density of the nearest\n * `ThemeProvider` or `ThemeScope`; a submenu takes its parent menu's. Keep 0 for touch.\n * @default 0\n */\n density?: Density;\n /**\n * Placement relative to the trigger: a side, then optionally the edge to align with\n * (`start` / `end` follow the text direction). A submenu always opens beside its item.\n * @default \"bottom-start\"\n */\n placement?: MenuPlacement;\n /** Gap between the trigger and the menu, in px (a split button's menu sits 4px away). @default 0 */\n offset?: number;\n /**\n * The least space kept between the menu and the window's edges, in px. A split button\n * passes 0, so its menu lines up with the trailing button even at the edge of the screen.\n * @default 12\n */\n containerPadding?: number;\n /**\n * Where the menu opens. `popover`: anchored to its trigger. `sheet`: in a modal bottom\n * sheet. `auto`: a sheet on compact windows (below 600px wide) and a popover on larger\n * ones (M3: \"Consider adapting menus into bottom sheets on small screens\"). Set it on the\n * root menu.\n * @default \"popover\"\n */\n presentation?: MenuPresentation;\n /**\n * Words the menu shows in a sheet. Set them on the root menu. A {@link LabelsProvider} sets them\n * for the whole app.\n */\n labels?: Partial<MenuLabels>;\n /**\n * Open and close with no motion (M3: \"In dense products, such as on desktop, menus can\n * open instantly to reduce motion\"). Submenus follow their root menu. Popovers only: a menu\n * shown as a bottom sheet (`presentation=\"sheet\"`, or `auto` on a compact window) keeps the\n * sheet's slide, as M3's and Compose's modal bottom sheets always animate; under reduced\n * motion it fades instead.\n * @default false\n */\n instant?: boolean;\n /**\n * Goes with `style` on the menu's outermost element: the box React Aria places against the\n * trigger, or the bottom sheet's outermost element in a sheet. The surface inside keeps\n * its size and its place against the trigger whatever layout class lands here (the box\n * keeps the menu's own width); style it with `classNames.panel`.\n */\n className?: string;\n /** Classes for each part, by slot. */\n classNames?: MenuClassNames;\n /** Goes on the menu's outermost element, with `className`. */\n style?: CSSProperties;\n /** Ref to the menu's list, the `role=\"menu\"` element, in a popover or a sheet. */\n ref?: Ref<HTMLDivElement>;\n}\n\n/** Where a {@link Menu} sits against its trigger: a side, then optionally the edge it aligns with. */\nexport type MenuPlacement =\n | 'top'\n | 'bottom'\n | 'start'\n | 'end'\n | 'top-start'\n | 'top-end'\n | 'bottom-start'\n | 'bottom-end'\n | 'start-top'\n | 'start-bottom'\n | 'end-top'\n | 'end-bottom';\n\n/** Where a {@link Menu} opens. */\nexport type MenuPresentation = 'popover' | 'sheet' | 'auto';\n\n/** Words a {@link Menu} shows. */\nexport interface MenuLabels {\n /**\n * In a sheet, the button above a submenu that goes back to the menu that opened it.\n * @default \"Back\"\n */\n back: string;\n}\n\nconst DEFAULT_LABELS: MenuLabels = { back: 'Back' };\n\n/**\n * M3 Expressive menu: items on one surface with dividers between groups (or on grouped\n * surfaces), standard or vibrant colours, optional single or multiple selection with a\n * selected shape and check, submenus, keyboard navigation and typeahead (React Aria\n * `useMenu`). Must be inside a `MenuTrigger` or `ContextMenuTrigger`; it opens anchored to\n * the trigger in a portal that keeps the surrounding theme and direction.\n *\n * @example\n * <MenuTrigger>\n * <IconButton icon={<MoreIcon />} aria-label=\"More\" />\n * <Menu onAction={(key) => run(key)}>\n * <MenuGroup>\n * <MenuItem key=\"copy\" shortcut=\"⌘C\">Copy</MenuItem>\n * <MenuItem key=\"paste\" shortcut=\"⌘V\">Paste</MenuItem>\n * </MenuGroup>\n * <MenuGroup>\n * <MenuItem key=\"delete\">Delete</MenuItem>\n * </MenuGroup>\n * </Menu>\n * </MenuTrigger>\n */\nexport function Menu({ presentation = 'popover', instant = false, ...props }: MenuProps) {\n const trigger = useContext(MenuTriggerContext);\n if (!trigger) throw new Error('[@windmorph/react] <Menu> must be used inside <MenuTrigger>.');\n const compact = useMediaQuery(COMPACT_WINDOW);\n const presence = usePresence(trigger.state.isOpen);\n const asSheet = presentation === 'sheet' || (presentation === 'auto' && compact);\n usePreloadBottomSheet(trigger.triggerRef, asSheet);\n if (asSheet) return <MenuSheet {...props} trigger={trigger} />;\n // An instant menu leaves at once, without waiting for an exit transition.\n const isPresent = instant ? trigger.state.isOpen : presence.isPresent;\n const isExiting = !instant && presence.isExiting;\n if (!isPresent) return null;\n return (\n <Overlay exiting={isExiting}>\n <MenuPopover\n {...props}\n trigger={trigger}\n instant={instant}\n isExiting={isExiting}\n exitProps={presence.exitProps}\n />\n </Overlay>\n );\n}\n\n/**\n * The menu in a modal bottom sheet (M3: menus can adapt into bottom sheets on small\n * screens). The sheet is a dialog named like the menu; the menu inside keeps its role,\n * keyboard, typeahead and initial focus, and spans the sheet without a surface of its own.\n * The sheet's code loads on first open (or when the trigger is hovered or focused), so a\n * menu that only opens as a popover doesn't carry it.\n */\nfunction MenuSheet({\n trigger,\n layout: _layout,\n placement: _placement,\n offset: _offset,\n variant = 'standard',\n labels: labelsProp,\n className,\n style,\n ...props\n}: Omit<MenuProps, 'presentation' | 'instant'> & { trigger: MenuTriggerContextValue }) {\n const labels = useLabels('Menu', DEFAULT_LABELS, labelsProp);\n const [container, setContainer] = useState<HTMLDivElement | null>(null);\n const [activeLevel, setActiveLevel] = useState(0);\n const menuProps = mergeProps(trigger.menuProps, props);\n const label = menuProps['aria-label'];\n const naming =\n label != null\n ? { 'aria-label': label }\n : { 'aria-labelledby': menuProps['aria-labelledby'] ?? '' };\n return (\n <LazyBottomSheet\n {...naming}\n // A menu sheet opens at its own height (up to the window, the list scrolling inside):\n // at half the window, a short phone left its last items off-screen, where the arrow\n // keys could still move focus.\n skipPartiallyExpanded\n open={trigger.state.isOpen}\n onOpenChange={(open) => (open ? trigger.state.open() : trigger.state.close())}\n className={className}\n style={style}\n classNames={props.classNames?.sheet ? { panel: props.classNames.sheet } : undefined}\n >\n <div ref={setContainer} className={menuStyles().sheetContent()}>\n <TriggerContext value={null}>\n <MenuTreeContext\n value={{\n rootState: trigger.state,\n container,\n activeLevel,\n setActiveLevel,\n layout: 'divider',\n variant,\n density: props.density,\n instant: false,\n sheet: true,\n labels,\n }}\n >\n <MenuList\n {...menuProps}\n layout=\"divider\"\n variant={variant}\n level={0}\n embedded\n onClose={trigger.state.close}\n autoFocus={trigger.state.focusStrategy ?? 'first'}\n />\n </MenuTreeContext>\n </TriggerContext>\n </div>\n </LazyBottomSheet>\n );\n}\n\n/** Shared by a menu and its submenus. */\ninterface MenuTreeContextValue {\n rootState: RootMenuTriggerState;\n /** The root popover, which submenus portal into (inside its focus scope, never inert). */\n container: HTMLElement | null;\n /** The level of the menu holding focus (0 is the root menu). */\n activeLevel: number;\n setActiveLevel: (level: number) => void;\n /** What submenus inherit. */\n layout: MenuLayout;\n variant: MenuVariant;\n density: MenuProps['density'];\n /** Submenus open and close with no motion too. */\n instant: boolean;\n /**\n * In a sheet, a submenu takes the sheet's place of the menu that opened it, below a back\n * button, instead of opening beside its item.\n */\n sheet: boolean;\n labels: MenuLabels;\n}\n\nconst MenuTreeContext = createContext<MenuTreeContextValue | null>(null);\n\n/** The menu element an item is rendered in (a submenu's parent). */\nconst MenuListContext = createContext<RefObject<HTMLDivElement | null> | null>(null);\n\nconst subscribeToNothing = () => () => {};\n\n/**\n * React Aria resolves `start` / `end` from its locale context, not the DOM `dir`, so an\n * RTL region without an `I18nProvider` would align the menu to the wrong edge. Resolve\n * them to physical sides from the trigger's computed direction instead.\n */\nfunction toPhysicalPlacement(placement: MenuPlacement, direction: string): Placement {\n return toAriaPlacement(placement, direction === 'rtl');\n}\n\ntype ExitProps = ReturnType<typeof usePresence>['exitProps'];\n\nfunction MenuPopover({\n trigger,\n instant,\n isExiting,\n exitProps,\n placement = 'bottom-start',\n offset = 0,\n containerPadding = 12,\n layout = 'divider',\n variant = 'standard',\n labels: labelsProp,\n className,\n style,\n ...props\n}: Omit<MenuProps, 'presentation' | 'instant'> & {\n trigger: MenuTriggerContextValue;\n instant: boolean;\n isExiting: boolean;\n exitProps: ExitProps;\n}) {\n const labels = useLabels('Menu', DEFAULT_LABELS, labelsProp);\n const popoverRef = useRef<HTMLDivElement>(null);\n const [container, setContainer] = useState<HTMLDivElement | null>(null);\n const setPopover = useCallback((element: HTMLDivElement | null) => {\n popoverRef.current = element;\n setContainer(element);\n }, []);\n const [activeLevel, setActiveLevel] = useState(0);\n // The DOM is the source of truth for direction; read it like an external store.\n const direction = useSyncExternalStore(\n subscribeToNothing,\n () =>\n trigger.triggerRef.current ? getComputedStyle(trigger.triggerRef.current).direction : 'ltr',\n () => 'ltr',\n );\n // Submenus' arrow keys and placement follow the locale's direction: give it the DOM's.\n const { locale, direction: localeDirection } = useLocale();\n const menuLocale =\n direction === localeDirection\n ? locale\n : localeWithDirection(locale, direction === 'rtl' ? 'rtl' : 'ltr');\n const {\n popoverProps,\n underlayProps,\n placement: actualPlacement,\n } = usePopover(\n {\n triggerRef: trigger.triggerRef,\n popoverRef,\n placement: toPhysicalPlacement(placement, direction),\n offset,\n containerPadding,\n },\n trigger.state,\n );\n const revealRef = useRef<HTMLDivElement>(null);\n const entering = useRevealEntering(actualPlacement, revealRef);\n const close = trigger.state.close;\n // Tab moves on from an open menu and closes it and its submenus (the APG menu button\n // pattern). React Aria's focus scope moves focus past the trigger, or back to it when\n // nothing follows; without the close, the menu stayed open with focus outside it. That\n // scope handles Tab on the document's capture phase and stops it, so this listens on the\n // window's, which comes first.\n useEffect(() => {\n const view = container?.ownerDocument.defaultView;\n if (!container || !view) return;\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key !== 'Tab' || event.altKey || event.ctrlKey || event.metaKey) return;\n if (container.contains(container.ownerDocument.activeElement)) close();\n };\n view.addEventListener('keydown', onKeyDown, true);\n return () => view.removeEventListener('keydown', onKeyDown, true);\n }, [container, close]);\n const styles = menuStyles();\n return (\n <>\n <div {...underlayProps} className=\"fixed inset-0\" />\n <div\n {...popoverProps}\n ref={setPopover}\n // React Aria's placement wins over a consumer style's and, through the attribute\n // (styles/utilities.css), over consumer inset classes.\n style={{ ...style, ...popoverProps.style }}\n data-overlay-placement=\"\"\n className={styles.popover({ class: cn(menuOwnWidth, className) })}\n >\n <DismissButton onDismiss={trigger.state.close} />\n <div\n {...exitProps}\n ref={revealRef}\n data-entering={entering || undefined}\n data-exiting={isExiting || undefined}\n data-placement={actualPlacement ?? undefined}\n className={menuStyles({ instant }).reveal()}\n >\n <TriggerContext value={null}>\n <I18nProvider locale={menuLocale}>\n <MenuTreeContext\n value={{\n rootState: trigger.state,\n container,\n activeLevel,\n setActiveLevel,\n layout,\n variant,\n density: props.density,\n instant,\n sheet: false,\n labels,\n }}\n >\n <MenuList\n {...mergeProps(trigger.menuProps, props)}\n layout={layout}\n variant={variant}\n level={0}\n onClose={trigger.state.close}\n autoFocus={trigger.state.focusStrategy ?? 'first'}\n />\n </MenuTreeContext>\n </I18nProvider>\n </TriggerContext>\n </div>\n <DismissButton onDismiss={trigger.state.close} />\n </div>\n </>\n );\n}\n\ntype Position = 'only' | 'first' | 'middle' | 'last';\ntype Edges = { top: boolean; bottom: boolean };\n\nconst positionOf = (index: number, count: number): Position =>\n count === 1 ? 'only' : index === 0 ? 'first' : index === count - 1 ? 'last' : 'middle';\n\n/** Which of a group's edges have the outer corners (the others have 8px). */\nconst roundEdges = (position: Position): Edges => ({\n top: position === 'only' || position === 'first',\n bottom: position === 'only' || position === 'last',\n});\n\n/** Sections become groups; runs of loose items between them form implicit groups. */\nfunction toGroups(nodes: Node<object>[]): (Node<object> | Node<object>[])[] {\n const groups: (Node<object> | Node<object>[])[] = [];\n let run: Node<object>[] = [];\n for (const node of nodes) {\n if (node.type === 'section') {\n if (run.length) groups.push(run);\n run = [];\n groups.push(node);\n } else {\n run.push(node);\n }\n }\n if (run.length) groups.push(run);\n return groups;\n}\n\ntype MenuListProps = Omit<\n MenuProps,\n 'placement' | 'layout' | 'variant' | 'presentation' | 'instant' | 'className' | 'style'\n> &\n Pick<AriaMenuOptions<object>, 'onClose' | 'autoFocus' | 'onKeyDown' | 'onKeyUp'> & {\n layout: MenuLayout;\n variant: MenuVariant;\n /** 0 for the root menu, then one more per submenu. */\n level: number;\n listRef?: RefObject<HTMLDivElement | null>;\n /** In a sheet: the list spans it, with no surface of its own. */\n embedded?: boolean;\n };\n\n/**\n * Whether the list has had to scroll, from a `ResizeObserver` (so it's measured only when\n * its size changes). Once true it stays true while the menu is open, so a `gap` menu that\n * switches to dividers can't flip back and forth.\n */\nfunction useHasScrolled(ref: RefObject<HTMLElement | null>, enabled: boolean) {\n const [scrolls, setScrolls] = useState(false);\n useLayoutEffect(() => {\n const element = ref.current;\n if (!enabled || scrolls || !element || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(() => {\n if (element.scrollHeight > element.clientHeight + 1) setScrolls(true);\n });\n observer.observe(element);\n return () => observer.disconnect();\n }, [ref, enabled, scrolls]);\n return scrolls;\n}\n\nfunction MenuList({\n deselectable = true,\n variant,\n layout: requestedLayout,\n density,\n level,\n classNames,\n listRef,\n embedded = false,\n ref: forwardedRef,\n ...allProps\n}: MenuListProps) {\n // The menu list is the menu's root (its `ref` and `id` land there): its DOM attributes too.\n const { root, rest: props } = splitRootProps(allProps);\n // MenuItem / MenuGroup are React Stately Item / Section, so children are a collection.\n assertCollectionChildren(\n props.children,\n 'Menu',\n 'MenuItem, MenuGroup and SubmenuTrigger elements',\n );\n const tree = useContext(MenuTreeContext);\n // M3: \"Disabled menu items can receive focus but aren't selectable.\"\n const state = useTreeState({\n ...(props as AriaMenuProps<object>),\n disallowEmptySelection: !deselectable,\n disabledBehavior: 'selection',\n });\n const ownRef = useObjectRef(forwardedRef);\n const ref = listRef ?? ownRef;\n // M3 keyboard table: \"Letters — Focus moves to the next menu item starting with letter\".\n const keyboardDelegate = useTypeaheadDelegate(state, ref);\n const { menuProps } = useMenu(\n // The arrow keys wrap from the last item to the first and back, as M3's menus and the rest\n // of the library's collections do (APG makes it optional).\n { ...(props as AriaMenuOptions<object>), keyboardDelegate, shouldFocusWrap: true },\n state,\n ref,\n );\n const groups = toGroups([...state.collection]);\n const scrolled = useHasScrolled(ref, requestedLayout === 'gap');\n const layout: MenuLayout = scrolled ? 'divider' : requestedLayout;\n const styles = menuStyles({ variant, layout, embedded });\n // While a submenu is open, the menu holding focus is rounder than the others (M3).\n const submenuOpen = Boolean(tree && tree.rootState.expandedKeysStack.length > 0);\n const shape = !submenuOpen ? undefined : tree?.activeLevel === level ? 'active' : 'inactive';\n const setActive = tree?.setActiveLevel;\n\n return (\n <div\n {...mergeProps(root, menuProps, {\n // Focus events bubble through portals: count only focus inside this menu's element.\n onFocus: (event: FocusEvent<HTMLDivElement>) => {\n if (event.currentTarget.contains(event.target)) setActive?.(level);\n },\n })}\n ref={ref}\n {...densityAttribute(density)}\n data-tokens={mergeDataTokens('md-comp-menus', root)}\n data-variant={variant}\n data-layout={layout}\n data-shape={shape}\n className={styles.menu({ class: classNames?.panel })}\n >\n <MenuListContext value={ref}>\n {groups.map((group, index) => {\n const position = positionOf(index, groups.length);\n // In the divider layout the menu is the surface: its first and last items nest in\n // its corners, and dividers go between groups.\n const edges: Edges =\n layout === 'divider'\n ? { top: index === 0, bottom: index === groups.length - 1 }\n : roundEdges(position);\n const groupStyles = menuStyles({ variant, layout, groupPosition: position, morph: true });\n return (\n <GroupWithDivider\n key={Array.isArray(group) ? group[0]!.key : group.key}\n divider={\n layout === 'divider' && index > 0 ? (\n // A menu's divider is a `separator` between its groups (WAI-ARIA menu).\n <Divider\n decorative={false}\n className={styles.divider({ class: classNames?.divider })}\n />\n ) : null\n }\n >\n {Array.isArray(group) ? (\n <div\n role=\"presentation\"\n className={groupStyles.group({ class: classNames?.group })}\n >\n <MenuItems\n nodes={group}\n state={state}\n variant={variant}\n edges={edges}\n classNames={classNames}\n />\n </div>\n ) : (\n <MenuSection\n section={group}\n state={state}\n variant={variant}\n className={groupStyles.group({ class: classNames?.group })}\n headingClassName={groupStyles.heading({ class: classNames?.heading })}\n edges={edges}\n classNames={classNames}\n />\n )}\n </GroupWithDivider>\n );\n })}\n </MenuListContext>\n </div>\n );\n}\n\nfunction GroupWithDivider({ divider, children }: { divider: ReactNode; children: ReactNode }) {\n return (\n <>\n {divider}\n {children}\n </>\n );\n}\n\nfunction MenuSection({\n section,\n state,\n variant,\n className,\n headingClassName,\n edges,\n classNames,\n}: {\n section: Node<object>;\n state: TreeState<object>;\n variant: MenuVariant;\n className: string;\n headingClassName: string;\n edges: Edges;\n classNames?: MenuClassNames;\n}) {\n const { itemProps, headingProps, groupProps } = useMenuSection({\n heading: section.rendered,\n 'aria-label': section['aria-label'],\n });\n return (\n <div {...itemProps} className={className}>\n {section.rendered && (\n <span {...headingProps} className={headingClassName}>\n {section.rendered}\n </span>\n )}\n <div {...groupProps} className=\"flex flex-col\">\n <MenuItems\n nodes={[...section.childNodes]}\n state={state}\n variant={variant}\n // A heading takes the group's top edge, so the first item doesn't touch it.\n edges={{ ...edges, top: !section.rendered && edges.top }}\n classNames={classNames}\n />\n </div>\n </div>\n );\n}\n\n/**\n * Items nest their corners inside the container's: an item on an outer edge gets the\n * outer corner less the 4px padding, and every other corner is 4px.\n */\nfunction MenuItems({\n nodes,\n state,\n variant,\n edges,\n classNames,\n}: {\n nodes: Node<object>[];\n state: TreeState<object>;\n variant: MenuVariant;\n edges: Edges;\n classNames?: MenuClassNames;\n}) {\n return nodes.map((node, index) => {\n const itemProps: MenuItemViewProps = {\n node,\n state,\n variant,\n top: index === 0 && edges.top ? 'outer' : 'plain',\n bottom: index === nodes.length - 1 && edges.bottom ? 'outer' : 'plain',\n classNames,\n };\n return (node.props as SubmenuItemProps).submenu ? (\n <SubmenuItemView key={node.key} {...itemProps} />\n ) : (\n <MenuItemView key={node.key} {...itemProps} />\n );\n });\n}\n\ninterface MenuItemViewProps {\n node: Node<object>;\n state: TreeState<object>;\n variant: MenuVariant;\n top: 'outer' | 'plain';\n bottom: 'outer' | 'plain';\n classNames?: MenuClassNames;\n /** A submenu trigger's props (from `useSubmenuTrigger`) and ref. */\n triggerProps?: Partial<AriaMenuItemProps>;\n itemRef?: RefObject<HTMLDivElement | null>;\n /** Whether the item's submenu is open (its active state). */\n submenuOpen?: boolean;\n}\n\n/** An item that opens a submenu, and the submenu's popover. */\nfunction SubmenuItemView(props: MenuItemViewProps) {\n const tree = useContext(MenuTreeContext)!;\n const parentMenuRef = useContext(MenuListContext)!;\n const { submenu, submenuDelay } = props.node.props as SubmenuItemProps;\n const submenuState = useSubmenuTriggerState({ triggerKey: props.node.key }, tree.rootState);\n const itemRef = useRef<HTMLDivElement>(null);\n const submenuRef = useRef<HTMLDivElement>(null);\n const { submenuTriggerProps, submenuProps, popoverProps } = useSubmenuTrigger(\n {\n parentMenuRef,\n submenuRef,\n delay: submenuDelay,\n isDisabled: props.state.disabledKeys.has(props.node.key),\n },\n submenuState,\n itemRef,\n );\n // In a sheet a submenu replaces its menu, so hovering an item doesn't open it.\n const { isOpen, onHoverChange, ...triggerProps } = submenuTriggerProps;\n // A sheet's submenu hides the item that opened it, so React Aria's focus on the item when\n // the submenu closes (← or Escape) finds it hidden. Once the menu shows again, the item\n // takes focus back from the closed submenu (or the back button), unless every menu closed.\n const wasOpen = useRef(isOpen);\n useLayoutEffect(() => {\n const closed = wasOpen.current && !isOpen;\n wasOpen.current = isOpen;\n const item = itemRef.current;\n if (!closed || !tree.sheet || !tree.rootState.isOpen || !item) return;\n const active = item.ownerDocument.activeElement;\n if (active == null || active === item.ownerDocument.body) item.focus();\n });\n return (\n <>\n <MenuItemView\n {...props}\n triggerProps={tree.sheet ? triggerProps : { ...triggerProps, onHoverChange }}\n itemRef={itemRef}\n submenuOpen={isOpen}\n />\n {tree.sheet ? (\n <SubmenuSheetPanel\n state={submenuState}\n submenuRef={submenuRef}\n menuProps={submenuProps}\n submenu={submenu!}\n title={props.node.rendered}\n />\n ) : (\n <SubmenuPopover\n state={submenuState}\n triggerRef={itemRef}\n submenuRef={submenuRef}\n menuProps={submenuProps}\n popoverProps={popoverProps}\n submenu={submenu!}\n />\n )}\n </>\n );\n}\n\n/**\n * A submenu in a sheet (M3 adapts menus into bottom sheets on small screens, where there's\n * no room beside an item): it takes the place of the menu that opened it, which the sheet\n * hides while it's open, below a back button and its item's label. ← (→ in right-to-left),\n * Escape and the back button go back. It's portalled into the sheet after its menu, so the\n * sheet's focus scope covers it.\n */\nfunction SubmenuSheetPanel({\n state,\n submenuRef,\n menuProps,\n submenu,\n title,\n}: Pick<SubmenuPopoverProps, 'state' | 'submenuRef' | 'menuProps' | 'submenu'> & {\n title: ReactNode;\n}) {\n const tree = useContext(MenuTreeContext)!;\n if (!state.isOpen || !tree.container) return null;\n const { submenuLevel, ...ariaMenuProps } = menuProps;\n const own = submenu.props;\n const variant = own.variant ?? tree.variant;\n const styles = menuStyles({ variant });\n return (\n <Overlay portalContainer={tree.container} disableFocusManagement>\n <div data-submenu-panel=\"\" className={styles.sheetPanel()}>\n <div className={styles.sheetHeader()}>\n <SheetBackButton\n label={tree.labels.back}\n onPress={() => state.close()}\n className={styles.sheetBack()}\n />\n <span className={styles.sheetTitle()}>{title}</span>\n </div>\n <MenuList\n {...mergeProps(ariaMenuProps, own)}\n listRef={submenuRef}\n layout=\"divider\"\n variant={variant}\n density={own.density ?? tree.density}\n level={submenuLevel + 1}\n embedded\n // However it opened (a touch leaves focus on the item, now hidden), focus moves in.\n autoFocus={state.focusStrategy ?? 'first'}\n />\n </div>\n </Overlay>\n );\n}\n\n/** The back button above a sheet's submenu: 48px, with an outline focus ring. */\nfunction SheetBackButton({\n label,\n onPress,\n className,\n}: {\n label: string;\n onPress: () => void;\n className: string;\n}) {\n const ref = useRef<HTMLButtonElement>(null);\n const { buttonProps, isPressed } = useButton({ onPress, 'aria-label': label }, ref);\n const { interactionProps, dataAttributes } = useM3Interaction({ isPressed }, ref);\n return (\n <button\n {...mergeProps(buttonProps, interactionProps)}\n {...dataAttributes}\n ref={ref}\n className={className}\n >\n <BackIcon />\n </button>\n );\n}\n\ninterface SubmenuPopoverProps {\n state: SubmenuTriggerState;\n triggerRef: RefObject<HTMLDivElement | null>;\n submenuRef: RefObject<HTMLDivElement | null>;\n menuProps: ReturnType<typeof useSubmenuTrigger>['submenuProps'];\n popoverProps: ReturnType<typeof useSubmenuTrigger>['popoverProps'];\n submenu: ReactElement<MenuProps>;\n}\n\nfunction SubmenuPopover(props: SubmenuPopoverProps) {\n const tree = useContext(MenuTreeContext)!;\n const presence = usePresence(props.state.isOpen);\n const isPresent = tree.instant ? props.state.isOpen : presence.isPresent;\n const isExiting = !tree.instant && presence.isExiting;\n const { exitProps } = presence;\n if (!isPresent || !tree.container) return null;\n // Inside the root popover: its focus scope and outside-press handling cover the submenu,\n // and the modal root menu doesn't make it inert.\n return (\n <Overlay portalContainer={tree.container} disableFocusManagement exiting={isExiting}>\n <SubmenuPopoverContent {...props} isExiting={isExiting} exitProps={exitProps} />\n </Overlay>\n );\n}\n\nfunction SubmenuPopoverContent({\n state,\n triggerRef,\n submenuRef,\n menuProps,\n popoverProps,\n submenu,\n isExiting,\n exitProps,\n}: SubmenuPopoverProps & { isExiting: boolean; exitProps: ExitProps }) {\n const tree = useContext(MenuTreeContext)!;\n const popoverRef = useRef<HTMLDivElement>(null);\n const { submenuLevel, ...ariaMenuProps } = menuProps;\n const { popoverProps: positionProps, placement } = usePopover(\n {\n ...popoverProps,\n // React Aria handles this as a submenu's popover (dismissable, non-modal).\n ...({ trigger: 'SubmenuTrigger' } as Partial<AriaPopoverProps>),\n triggerRef,\n popoverRef,\n placement: 'end top',\n // Beside the parent menu (the 4px padding around the item and a 2px gap), with its\n // first item level with the item that opened it.\n offset: 6,\n crossOffset: -4,\n },\n state,\n );\n const revealRef = useRef<HTMLDivElement>(null);\n const entering = useRevealEntering(placement, revealRef);\n const { className, style, ...own } = submenu.props;\n const styles = menuStyles();\n return (\n // `w-max` (`menuOwnWidth`): positioned inside the narrower root popover, it would otherwise shrink to fit\n // what's left of that popover's width and wrap every label. Like the root menu's, the\n // submenu's `className` and `style` go on this outermost element.\n <div\n {...positionProps}\n ref={popoverRef}\n style={{ ...style, ...positionProps.style }}\n data-overlay-placement=\"\"\n className={styles.popover({ class: cn(menuOwnWidth, className) })}\n >\n <div\n {...exitProps}\n ref={revealRef}\n data-entering={entering || undefined}\n data-exiting={isExiting || undefined}\n data-placement={placement ?? undefined}\n className={menuStyles({ instant: tree.instant }).reveal()}\n >\n <MenuList\n {...mergeProps(ariaMenuProps, own)}\n listRef={submenuRef}\n layout={own.layout ?? tree.layout}\n variant={own.variant ?? tree.variant}\n density={own.density ?? tree.density}\n level={submenuLevel + 1}\n />\n </div>\n </div>\n );\n}\n\nfunction MenuItemView({\n node,\n state,\n variant,\n top,\n bottom,\n classNames,\n triggerProps,\n itemRef,\n submenuOpen = false,\n}: MenuItemViewProps) {\n const ownRef = useRef<HTMLElement>(null);\n const ref = itemRef ?? ownRef;\n const props = node.props as SubmenuItemProps;\n const isDisabled = state.disabledKeys.has(node.key);\n // A plain action in a selectable menu (`checkable={false}`) is never checked.\n const selectable = state.selectionManager.selectionMode !== 'none' && props.checkable !== false;\n const plainInSelectable = state.selectionManager.selectionMode !== 'none' && !selectable;\n const multiple = selectable && state.selectionManager.selectionMode === 'multiple';\n const {\n menuItemProps: ariaItemProps,\n keyboardShortcutProps,\n isSelected,\n isPressed,\n } = useMenuItem(\n {\n ...triggerProps,\n key: node.key,\n 'aria-label': props['aria-label'],\n // Disabled items stay focusable (the menu's `disabledBehavior`) but do nothing.\n isDisabled,\n isSelected: plainInSelectable ? false : undefined,\n // M3: multi-select menus stay open until they're dismissed, Enter included; a plain\n // action closes the menu, as in any menu.\n closeOnSelect: multiple ? false : plainInSelectable ? true : undefined,\n },\n state,\n ref,\n );\n const menuItemProps =\n plainInSelectable && !props.submenu\n ? { ...ariaItemProps, role: 'menuitem', 'aria-checked': undefined }\n : ariaItemProps;\n // A link item is a real `<a>`: `useMenuItem` gives it the link's attributes, routes a plain\n // click and closes the menu. A disabled item, or one that opens a submenu, stays a plain\n // element without them, so it can't be followed.\n const link = props.href != null && !isDisabled && !props.submenu;\n // Widened, so the item's ref (an element of either kind) fits both.\n const Root = (link ? 'a' : 'div') as ElementType;\n const linkAttributes = link\n ? { rel: props.rel ?? (props.target === '_blank' ? 'noopener noreferrer' : undefined) }\n : NOT_A_LINK;\n const { interactionProps, dataAttributes } = useM3Interaction(\n { isPressed, isDisabled, isSelected },\n ref,\n );\n const styles = menuStyles({\n variant,\n itemTop: top,\n itemBottom: bottom,\n hasDescription: Boolean(props.description),\n });\n const selectedIcon = props.selectedIcon ?? (selectable ? <CheckIcon /> : null);\n const trailingIcon = props.trailingIcon ?? (props.submenu ? <SubmenuIcon /> : null);\n const badgeId = useId();\n // Named by its content: the label and supporting text in the order they show, each read\n // once. React Aria names it by the label alone and describes it by the supporting text,\n // which leaves visible text out of its name (WCAG 2.5.3), as List options did. The shortcut\n // and the badge are extra information, not the item's label: they stay its description,\n // hidden from the content so they're read once.\n const describedBy =\n [props.shortcut ? keyboardShortcutProps.id : undefined, props.badge ? badgeId : undefined]\n .filter(Boolean)\n .join(' ') || undefined;\n\n return (\n <Root\n {...mergeProps(menuItemProps, interactionProps)}\n {...linkAttributes}\n {...dataAttributes}\n aria-labelledby={undefined}\n aria-describedby={describedBy}\n data-menu-open={submenuOpen || undefined}\n // Each item resolves the menu's tokens, so its selection picks its colours.\n data-tokens={mergeDataTokens('md-comp-menus', menuItemProps)}\n data-variant={variant}\n data-slot=\"item\"\n ref={ref}\n className={styles.item({ class: cn(classNames?.item, props.className) })}\n >\n {props.leadingIcon && selectedIcon ? (\n <span\n aria-hidden=\"true\"\n data-slot=\"leading-icon\"\n className={styles.icon({ class: classNames?.icon })}\n >\n {isSelected ? selectedIcon : props.leadingIcon}\n </span>\n ) : props.leadingIcon ? (\n <span\n aria-hidden=\"true\"\n data-slot=\"leading-icon\"\n className={styles.icon({ class: classNames?.icon })}\n >\n {props.leadingIcon}\n </span>\n ) : selectedIcon ? (\n // No leading icon: the selected icon expands in when selected (Compose).\n <span aria-hidden=\"true\" className={styles.selectedIcon()}>\n <span className={styles.selectedIconInner()}>\n <span className={styles.icon({ class: classNames?.icon })}>{selectedIcon}</span>\n </span>\n </span>\n ) : null}\n <span className={styles.text()}>\n <span>{node.rendered}</span>\n {props.description && (\n <span className={styles.description({ class: classNames?.description })}>\n {props.description}\n </span>\n )}\n </span>\n {props.badge && (\n <span id={badgeId} aria-hidden=\"true\" className={styles.badge()}>\n {props.badge}\n </span>\n )}\n {props.shortcut && (\n <kbd\n {...keyboardShortcutProps}\n aria-hidden=\"true\"\n className={styles.trailing({ class: cn('font-plain', classNames?.shortcut) })}\n >\n {props.shortcut}\n </kbd>\n )}\n {trailingIcon && (\n <span\n aria-hidden=\"true\"\n data-slot=\"trailing-icon\"\n className={styles.trailing({ class: classNames?.trailingIcon })}\n >\n {trailingIcon}\n </span>\n )}\n </Root>\n );\n}\n\nexport type { Key as MenuKey };\n"],"mappings":"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"}
@@ -91,28 +91,28 @@ const menuStyles = tv({
91
91
  standard: {
92
92
  heading: "text-on-surface-variant",
93
93
  item: ["data-disabled:text-on-surface/38", "data-disabled:data-selected:bg-tertiary-container/38 data-disabled:data-selected:text-on-tertiary-container/38"],
94
- icon: "group-data-selected/item:text-on-tertiary-container group-data-disabled/item:text-on-surface/38",
95
- description: "text-on-surface-variant group-data-selected/item:text-on-tertiary-container group-data-disabled/item:text-on-surface/38",
96
- trailing: "group-data-selected/item:text-on-tertiary-container group-data-disabled/item:text-on-surface/38"
94
+ icon: "group-data-selected/item:text-[color:var(--_md-comp-menus-menu-item-selected-label-text-color)] group-data-disabled/item:text-on-surface/38",
95
+ description: "text-on-surface-variant group-data-selected/item:text-[color:var(--_md-comp-menus-menu-item-selected-label-text-color)] group-data-disabled/item:text-on-surface/38",
96
+ trailing: "group-data-selected/item:text-[color:var(--_md-comp-menus-menu-item-selected-label-text-color)] group-data-disabled/item:text-on-surface/38"
97
97
  },
98
98
  vibrant: {
99
99
  heading: "text-on-tertiary-container",
100
100
  item: ["data-disabled:text-on-tertiary-container/38", "data-disabled:data-selected:bg-tertiary/38 data-disabled:data-selected:text-on-tertiary/38"],
101
101
  icon: [
102
102
  "group-data-hovered/item:text-tertiary group-data-focus-visible/item:text-tertiary group-data-pressed/item:text-tertiary",
103
- "group-data-selected/item:text-on-tertiary",
104
- "group-data-selected/item:group-data-hovered/item:text-on-tertiary",
105
- "group-data-selected/item:group-data-focus-visible/item:text-on-tertiary",
106
- "group-data-selected/item:group-data-pressed/item:text-on-tertiary",
103
+ "group-data-selected/item:text-[color:var(--_md-comp-menus-menu-item-selected-label-text-color)]",
104
+ "group-data-selected/item:group-data-hovered/item:text-[color:var(--_md-comp-menus-menu-item-selected-label-text-color)]",
105
+ "group-data-selected/item:group-data-focus-visible/item:text-[color:var(--_md-comp-menus-menu-item-selected-label-text-color)]",
106
+ "group-data-selected/item:group-data-pressed/item:text-[color:var(--_md-comp-menus-menu-item-selected-label-text-color)]",
107
107
  "group-data-disabled/item:text-on-tertiary-container/38"
108
108
  ],
109
- description: "text-on-tertiary-container group-data-selected/item:text-on-tertiary group-data-disabled/item:text-on-tertiary-container/38",
109
+ description: "text-on-tertiary-container group-data-selected/item:text-[color:var(--_md-comp-menus-menu-item-selected-label-text-color)] group-data-disabled/item:text-on-tertiary-container/38",
110
110
  trailing: [
111
111
  "group-data-hovered/item:text-tertiary group-data-focus-visible/item:text-tertiary group-data-pressed/item:text-tertiary",
112
- "group-data-selected/item:text-on-tertiary",
113
- "group-data-selected/item:group-data-hovered/item:text-on-tertiary",
114
- "group-data-selected/item:group-data-focus-visible/item:text-on-tertiary",
115
- "group-data-selected/item:group-data-pressed/item:text-on-tertiary",
112
+ "group-data-selected/item:text-[color:var(--_md-comp-menus-menu-item-selected-label-text-color)]",
113
+ "group-data-selected/item:group-data-hovered/item:text-[color:var(--_md-comp-menus-menu-item-selected-label-text-color)]",
114
+ "group-data-selected/item:group-data-focus-visible/item:text-[color:var(--_md-comp-menus-menu-item-selected-label-text-color)]",
115
+ "group-data-selected/item:group-data-pressed/item:text-[color:var(--_md-comp-menus-menu-item-selected-label-text-color)]",
116
116
  "group-data-disabled/item:text-on-tertiary-container/38"
117
117
  ]
118
118
  }