@edgeandnode/eds-react 1.0.2 → 1.1.1

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 (103) hide show
  1. package/README.md +32 -7
  2. package/dist/EDSContext.d.ts +2 -2
  3. package/dist/EDSContext.d.ts.map +1 -1
  4. package/dist/EDSContext.js +1 -1
  5. package/dist/EDSContext.js.map +1 -1
  6. package/dist/EDSProvider.d.ts +13 -6
  7. package/dist/EDSProvider.d.ts.map +1 -1
  8. package/dist/EDSProvider.js +48 -63
  9. package/dist/EDSProvider.js.map +1 -1
  10. package/dist/components/Avatar.d.ts +3 -3
  11. package/dist/components/Avatar.d.ts.map +1 -1
  12. package/dist/components/Avatar.js.map +1 -1
  13. package/dist/components/Button.d.ts.map +1 -1
  14. package/dist/components/Button.js +1 -1
  15. package/dist/components/Button.js.map +1 -1
  16. package/dist/components/Card.d.ts +8 -4
  17. package/dist/components/Card.d.ts.map +1 -1
  18. package/dist/components/Card.js +2 -1
  19. package/dist/components/Card.js.map +1 -1
  20. package/dist/components/Keyboard.js +1 -1
  21. package/dist/components/LocalTheme.d.ts +21 -8
  22. package/dist/components/LocalTheme.d.ts.map +1 -1
  23. package/dist/components/LocalTheme.js +10 -4
  24. package/dist/components/LocalTheme.js.map +1 -1
  25. package/dist/components/Menu.parts.d.ts +43 -9
  26. package/dist/components/Menu.parts.d.ts.map +1 -1
  27. package/dist/components/Menu.parts.js +118 -114
  28. package/dist/components/Menu.parts.js.map +1 -1
  29. package/dist/components/Modal.parts.d.ts +1 -1
  30. package/dist/components/Modal.parts.d.ts.map +1 -1
  31. package/dist/components/Modal.parts.js +2 -2
  32. package/dist/components/Modal.parts.js.map +1 -1
  33. package/dist/components/Pane.parts.d.ts +23 -22
  34. package/dist/components/Pane.parts.d.ts.map +1 -1
  35. package/dist/components/Pane.parts.js +3 -3
  36. package/dist/components/Pane.parts.js.map +1 -1
  37. package/dist/components/Prose.d.ts +1 -1
  38. package/dist/components/Prose.d.ts.map +1 -1
  39. package/dist/components/Prose.js +3 -3
  40. package/dist/components/Prose.js.map +1 -1
  41. package/dist/components/Prose.meta.d.ts +5 -0
  42. package/dist/components/Prose.meta.d.ts.map +1 -1
  43. package/dist/components/Prose.meta.js +10 -0
  44. package/dist/components/Prose.meta.js.map +1 -1
  45. package/dist/components/Select.parts.d.ts +8 -3
  46. package/dist/components/Select.parts.d.ts.map +1 -1
  47. package/dist/components/Select.parts.js +26 -17
  48. package/dist/components/Select.parts.js.map +1 -1
  49. package/dist/components/ThemeSwitcher.d.ts +5 -5
  50. package/dist/components/ThemeSwitcher.d.ts.map +1 -1
  51. package/dist/components/ThemeSwitcher.js +5 -4
  52. package/dist/components/ThemeSwitcher.js.map +1 -1
  53. package/dist/components/base/MaybeButtonOrLink.d.ts +7 -5
  54. package/dist/components/base/MaybeButtonOrLink.d.ts.map +1 -1
  55. package/dist/components/base/MaybeButtonOrLink.js +7 -2
  56. package/dist/components/base/MaybeButtonOrLink.js.map +1 -1
  57. package/dist/components/base/Render.d.ts +25 -6
  58. package/dist/components/base/Render.d.ts.map +1 -1
  59. package/dist/components/base/Render.js +4 -3
  60. package/dist/components/base/Render.js.map +1 -1
  61. package/dist/components/base/index.d.ts +1 -1
  62. package/dist/components/base/index.d.ts.map +1 -1
  63. package/dist/components/base/index.js.map +1 -1
  64. package/dist/components/index.d.ts +1 -1
  65. package/dist/components/index.d.ts.map +1 -1
  66. package/dist/components/index.js +1 -1
  67. package/dist/components/index.js.map +1 -1
  68. package/dist/hooks/useEDS.d.ts +16 -8
  69. package/dist/hooks/useEDS.d.ts.map +1 -1
  70. package/dist/hooks/useEDS.js +16 -8
  71. package/dist/hooks/useEDS.js.map +1 -1
  72. package/dist/index.d.ts +2 -1
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +1 -0
  75. package/dist/index.js.map +1 -1
  76. package/dist/theme-persistence.d.ts +18 -0
  77. package/dist/theme-persistence.d.ts.map +1 -0
  78. package/dist/theme-persistence.js +25 -0
  79. package/dist/theme-persistence.js.map +1 -0
  80. package/package.json +20 -20
  81. package/skill/SKILL.md +91 -57
  82. package/skill/references/tokens.md +1 -1
  83. package/src/EDSContext.ts +2 -2
  84. package/src/EDSProvider.tsx +80 -74
  85. package/src/components/Avatar.tsx +5 -3
  86. package/src/components/Button.tsx +4 -0
  87. package/src/components/Card.tsx +14 -8
  88. package/src/components/Keyboard.tsx +1 -1
  89. package/src/components/LocalTheme.tsx +22 -14
  90. package/src/components/Menu.parts.tsx +365 -244
  91. package/src/components/Modal.parts.tsx +8 -1
  92. package/src/components/Pane.parts.tsx +31 -26
  93. package/src/components/Prose.meta.ts +10 -0
  94. package/src/components/Prose.tsx +4 -3
  95. package/src/components/Select.parts.tsx +37 -29
  96. package/src/components/ThemeSwitcher.tsx +11 -13
  97. package/src/components/base/MaybeButtonOrLink.tsx +11 -6
  98. package/src/components/base/Render.tsx +28 -4
  99. package/src/components/base/index.ts +2 -0
  100. package/src/components/index.ts +8 -1
  101. package/src/hooks/useEDS.ts +16 -8
  102. package/src/index.ts +2 -1
  103. package/src/theme-persistence.ts +31 -0
@@ -1,16 +1,29 @@
1
- import type { ComponentProps, ElementType } from 'react';
2
- export interface LocalThemeProps extends ComponentProps<'div'> {
3
- /** @default 'div' */
4
- as?: ElementType | undefined;
1
+ import type { DistributedOmit } from 'type-fest';
2
+ import { type ResolvedTheme } from '../EDSContext.ts';
3
+ import { type AsOrRenderProps, type HTMLElementProps } from './base/Render.tsx';
4
+ export declare namespace LocalThemeProps {
5
+ interface CommonProps extends HTMLElementProps {
6
+ /** The theme to render the content in. */
7
+ theme: ResolvedTheme;
8
+ }
5
9
  }
10
+ export type LocalThemeProps = LocalThemeProps.CommonProps & AsOrRenderProps;
11
+ export type DarkProps = DistributedOmit<LocalThemeProps, 'theme'>;
12
+ export type LightProps = DistributedOmit<LocalThemeProps, 'theme'>;
13
+ /**
14
+ * Renders its content in the given theme, whatever the page's theme is. Unlike switching between
15
+ * `Dark` and `Light`, changing `theme` doesn't remount the content. Components that need to know
16
+ * the theme in JavaScript can read it with `useEDS().activeTheme`.
17
+ */
18
+ export declare function LocalTheme({ theme, ...props }: LocalThemeProps): import("react").JSX.Element;
6
19
  /**
7
20
  * Renders its content in the dark theme, whatever the page's theme is. Components that need to know
8
- * the theme in JavaScript can read it with `useEDS().localTheme`.
21
+ * the theme in JavaScript can read it with `useEDS().activeTheme`.
9
22
  */
10
- export declare function Dark(props: LocalThemeProps): import("react").JSX.Element;
23
+ export declare function Dark(props: DarkProps): import("react").JSX.Element;
11
24
  /**
12
25
  * Renders its content in the light theme, whatever the page's theme is. Components that need to
13
- * know the theme in JavaScript can read it with `useEDS().localTheme`.
26
+ * know the theme in JavaScript can read it with `useEDS().activeTheme`.
14
27
  */
15
- export declare function Light(props: LocalThemeProps): import("react").JSX.Element;
28
+ export declare function Light(props: LightProps): import("react").JSX.Element;
16
29
  //# sourceMappingURL=LocalTheme.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LocalTheme.d.ts","sourceRoot":"","sources":["../../src/components/LocalTheme.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAKxD,MAAM,WAAW,eAAgB,SAAQ,cAAc,CAAC,KAAK,CAAC;IAC5D,qBAAqB;IACrB,EAAE,CAAC,EAAE,WAAW,GAAG,SAAS,CAAA;CAC7B;AAcD;;;GAGG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,eAAe,+BAE1C;AAED;;;GAGG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,eAAe,+BAE3C"}
1
+ {"version":3,"file":"LocalTheme.d.ts","sourceRoot":"","sources":["../../src/components/LocalTheme.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAEhD,OAAO,EAAoC,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAA;AACvF,OAAO,EAAU,KAAK,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEvF,MAAM,CAAC,OAAO,WAAW,eAAe,CAAC;IACvC,UAAU,WAAY,SAAQ,gBAAgB;QAC5C,0CAA0C;QAC1C,KAAK,EAAE,aAAa,CAAA;KACrB;CACF;AAED,MAAM,MAAM,eAAe,GAAG,eAAe,CAAC,WAAW,GAAG,eAAe,CAAA;AAC3E,MAAM,MAAM,SAAS,GAAG,eAAe,CAAC,eAAe,EAAE,OAAO,CAAC,CAAA;AACjE,MAAM,MAAM,UAAU,GAAG,eAAe,CAAC,eAAe,EAAE,OAAO,CAAC,CAAA;AAElE;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,+BAM9D;AAED;;;GAGG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,+BAEpC;AAED;;;GAGG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,+BAEtC"}
@@ -2,19 +2,25 @@
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { mergeProps } from '@base-ui/react';
4
4
  import { LocalThemeContext, THEME_CLASSES } from '../EDSContext.js';
5
- function LocalTheme({ theme, as: Element = 'div', ...props }) {
6
- return (_jsx(LocalThemeContext.Provider, { value: theme, children: _jsx(Element, { ...mergeProps({ className: THEME_CLASSES[theme] }, props) }) }));
5
+ import { Render } from './base/Render.js';
6
+ /**
7
+ * Renders its content in the given theme, whatever the page's theme is. Unlike switching between
8
+ * `Dark` and `Light`, changing `theme` doesn't remount the content. Components that need to know
9
+ * the theme in JavaScript can read it with `useEDS().activeTheme`.
10
+ */
11
+ export function LocalTheme({ theme, ...props }) {
12
+ return (_jsx(LocalThemeContext.Provider, { value: theme, children: _jsx(Render, { ...mergeProps({ className: THEME_CLASSES[theme] }, props) }) }));
7
13
  }
8
14
  /**
9
15
  * Renders its content in the dark theme, whatever the page's theme is. Components that need to know
10
- * the theme in JavaScript can read it with `useEDS().localTheme`.
16
+ * the theme in JavaScript can read it with `useEDS().activeTheme`.
11
17
  */
12
18
  export function Dark(props) {
13
19
  return _jsx(LocalTheme, { theme: "dark", ...props });
14
20
  }
15
21
  /**
16
22
  * Renders its content in the light theme, whatever the page's theme is. Components that need to
17
- * know the theme in JavaScript can read it with `useEDS().localTheme`.
23
+ * know the theme in JavaScript can read it with `useEDS().activeTheme`.
18
24
  */
19
25
  export function Light(props) {
20
26
  return _jsx(LocalTheme, { theme: "light", ...props });
@@ -1 +1 @@
1
- {"version":3,"file":"LocalTheme.js","sourceRoot":"","sources":["../../src/components/LocalTheme.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAGZ,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE3C,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAsB,MAAM,kBAAkB,CAAA;AAOvF,SAAS,UAAU,CAAC,EAClB,KAAK,EACL,EAAE,EAAE,OAAO,GAAG,KAAK,EACnB,GAAG,KAAK,EACmC;IAC3C,OAAO,CACL,KAAC,iBAAiB,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YACtC,KAAC,OAAO,OAAK,UAAU,CAAC,EAAE,SAAS,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,GAAI,GAC5C,CAC9B,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,IAAI,CAAC,KAAsB;IACzC,OAAO,KAAC,UAAU,IAAC,KAAK,EAAC,MAAM,KAAK,KAAK,GAAI,CAAA;AAC/C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,KAAK,CAAC,KAAsB;IAC1C,OAAO,KAAC,UAAU,IAAC,KAAK,EAAC,OAAO,KAAK,KAAK,GAAI,CAAA;AAChD,CAAC"}
1
+ {"version":3,"file":"LocalTheme.js","sourceRoot":"","sources":["../../src/components/LocalTheme.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAG3C,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAsB,MAAM,kBAAkB,CAAA;AACvF,OAAO,EAAE,MAAM,EAA+C,MAAM,kBAAmB,CAAA;AAavF;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,EAAE,KAAK,EAAE,GAAG,KAAK,EAAmB;IAC7D,OAAO,CACL,KAAC,iBAAiB,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YACtC,KAAC,MAAM,OAAK,UAAU,CAAC,EAAE,SAAS,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,GAAI,GAC3C,CAC9B,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,IAAI,CAAC,KAAgB;IACnC,OAAO,KAAC,UAAU,IAAC,KAAK,EAAC,MAAM,KAAK,KAAK,GAAI,CAAA;AAC/C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,KAAK,CAAC,KAAiB;IACrC,OAAO,KAAC,UAAU,IAAC,KAAK,EAAC,OAAO,KAAK,KAAK,GAAI,CAAA;AAChD,CAAC"}
@@ -71,6 +71,36 @@ export declare namespace MenuProps {
71
71
  * @default false
72
72
  */
73
73
  highlightCheckedOnOpen?: boolean | undefined;
74
+ /**
75
+ * Adds `Menu.Search` to the header and filters items by their text (or `label`) as the user
76
+ * types. A custom `header` must include `Menu.Search`, which handles the keyboard navigation.
77
+ * Pass a function to customize matching, or `'manual'` to filter the items yourself (e.g.
78
+ * results from an API). Defaults to `true` if `searchValue` or `onSearchValueChange` is set.
79
+ */
80
+ searchable?: boolean | ((item: {
81
+ label: string;
82
+ searchValue: string;
83
+ }) => boolean) | 'manual' | undefined;
84
+ /** The search query, to control it along with `onSearchValueChange`. */
85
+ searchValue?: string | undefined;
86
+ /**
87
+ * Called when the search query changes, including when it's reset after the menu closes (then
88
+ * `eventDetails.reason` is `'popup-close'`).
89
+ */
90
+ onSearchValueChange?: ((searchValue: string, eventDetails: Menu.FilterProvider.ChangeEventDetails) => void) | undefined;
91
+ /**
92
+ * Shown in a searchable menu when no item matches. A string is rendered in a `Menu.Empty`, and
93
+ * `null` renders nothing.
94
+ *
95
+ * @default <Menu.Empty />
96
+ */
97
+ empty?: ReactNode | undefined;
98
+ /**
99
+ * Marks the items as loading (e.g. search results from an API). In a searchable menu, a
100
+ * `LoadingIcon` also shows in the search input, or in place of the empty state until a search
101
+ * finishes.
102
+ */
103
+ loading?: boolean | undefined;
74
104
  }
75
105
  interface CommonProps extends HTMLProps, OwnProps, EDSComponentProps<typeof MenuMeta> {
76
106
  }
@@ -80,7 +110,7 @@ export declare namespace MenuProps {
80
110
  }
81
111
  }
82
112
  export type MenuProps<T extends OptionValue = OptionValue> = MenuProps.NonRadioProps | MenuProps.RadioProps<T>;
83
- export declare function MenuRoot<T extends OptionValue>({ ref: passedRef, trigger, triggerMode, anchor: passedAnchor, side, gap, align, alignOffset, matchTriggerWidth, matchTriggerHeight, open: controlledOpen, defaultOpen, onOpenChange, header, footer, highlightCheckedOnOpen, label, type, value, defaultValue, onValueChange, children, ...props }: MenuProps<T>): import("react").JSX.Element;
113
+ export declare function MenuRoot<T extends OptionValue>({ ref: passedRef, trigger, triggerMode, anchor: passedAnchor, side, gap, align, alignOffset, matchTriggerWidth, matchTriggerHeight, open: controlledOpen, defaultOpen, onOpenChange, header: passedHeader, footer, highlightCheckedOnOpen, searchable: passedSearchable, searchValue, onSearchValueChange, empty, loading, label, type, value, defaultValue, onValueChange, children, ...props }: MenuProps<T>): import("react").JSX.Element;
84
114
  export declare namespace MenuRoot {
85
115
  var displayName: string;
86
116
  }
@@ -101,6 +131,11 @@ export declare namespace MenuItemProps {
101
131
  interface HTMLProps extends Omit<ComponentProps<'button'>, 'defaultChecked' | 'defaultValue' | 'onChange' | 'type' | 'value'> {
102
132
  }
103
133
  interface OwnProps {
134
+ /**
135
+ * Text that search and typeahead match against. Defaults to the item's rendered text, addons
136
+ * included.
137
+ */
138
+ label?: string | undefined;
104
139
  addonBefore?: AddonValue | undefined;
105
140
  addonAfter?: AddonValue | undefined;
106
141
  disabled?: boolean | undefined;
@@ -142,26 +177,25 @@ export declare namespace MenuItemProps {
142
177
  }
143
178
  }
144
179
  export type MenuItemProps<T extends OptionValue = OptionValue> = MenuItemProps.PlainProps | MenuItemProps.CheckboxProps | MenuItemProps.RadioProps<T>;
145
- export declare function MenuItem<T extends OptionValue>({ ref: passedRef, type: passedType, addonBefore: passedAddonBefore, addonAfter: passedAddonAfter, variant, loading, href, target, checked, defaultChecked, onCheckedChange, value: passedValue, disabled: passedDisabled, children, ...props }: MenuItemProps<T>): import("react").JSX.Element;
180
+ export declare function MenuItem<T extends OptionValue>({ ref: passedRef, type: passedType, label, addonBefore: passedAddonBefore, addonAfter: passedAddonAfter, variant, loading, href, target, checked, defaultChecked, onCheckedChange, value: passedValue, disabled: passedDisabled, children, ...props }: MenuItemProps<T>): import("react").JSX.Element;
146
181
  export declare namespace MenuItem {
147
182
  var displayName: string;
148
183
  }
149
- export interface MenuSearchProps extends Omit<ComponentProps<'input'>, 'children'> {
184
+ export interface MenuSearchProps extends Omit<ComponentProps<'input'>, 'children' | 'value' | 'defaultValue'> {
150
185
  /** @default 'Search' */
151
186
  placeholder?: string | undefined;
152
- value?: string | undefined;
153
- defaultValue?: string | undefined;
154
- onValueChange?: ((value: string) => void) | undefined;
155
187
  }
156
- export declare function MenuSearch({ ref: passedRef, placeholder: passedPlaceholder, value: controlledValue, defaultValue, onValueChange, ...props }: MenuSearchProps): import("react").JSX.Element;
188
+ /** Search input for the `header` of a `searchable` menu, which filters its items. */
189
+ export declare function MenuSearch({ placeholder, ...props }: MenuSearchProps): import("react").JSX.Element;
157
190
  export declare namespace MenuSearch {
158
191
  var displayName: string;
159
192
  }
160
193
  export interface MenuEmptyProps extends ComponentProps<'div'> {
161
194
  }
162
195
  /**
163
- * Renders the standard empty-state treatment for a `Menu` (typically shown when search filters
164
- * yield no results, or when a `Menu` has no items at all). Defaults to `"No results"`.
196
+ * Renders the standard empty-state treatment for a `Menu`, e.g. when it has no items. Searchable
197
+ * menus render it when no item matches (see `empty`). Its text wraps instead of widening the menu.
198
+ * Defaults to `"No results"`.
165
199
  */
166
200
  export declare function MenuEmpty({ children, ...props }: MenuEmptyProps): import("react").JSX.Element;
167
201
  export declare namespace MenuEmpty {
@@ -1 +1 @@
1
- {"version":3,"file":"Menu.parts.d.ts","sourceRoot":"","sources":["../../src/components/Menu.parts.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Menu.parts.d.ts","sourceRoot":"","sources":["../../src/components/Menu.parts.tsx"],"names":[],"mappings":"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"}
@@ -8,7 +8,7 @@ import { useMergedRefs } from '@base-ui/utils/useMergedRefs';
8
8
  import { twToPx } from '@edgeandnode/eds-css';
9
9
  import { ArrowRightInteractiveIcon, ArrowUpRightInteractiveIcon, CaretRightIcon, CheckIcon, LoadingIcon, MagnifyingGlassIcon, XIcon, } from '@edgeandnode/eds-react/icons';
10
10
  import { useAutoValue, useControlled, useCSSPropsPolyfill, useCSSState, useEDS, } from '../hooks/index.js';
11
- import { cn, getCSSPropsAttributes, setInputValue, splitProps, } from '../utils/index.js';
11
+ import { cn, getCSSPropsAttributes, splitProps } from '../utils/index.js';
12
12
  import { renderAddon } from './base/Addon.js';
13
13
  import { ButtonOrLink } from './base/ButtonOrLink.js';
14
14
  import { Portal } from './base/Portal.js';
@@ -17,7 +17,9 @@ import { Button } from './Button.js';
17
17
  import { Checkbox } from './Checkbox.js';
18
18
  import { MenuMeta } from './Menu.meta.js';
19
19
  const MenuTriggerContext = createContext(false);
20
- export function MenuRoot({ ref: passedRef, trigger, triggerMode, anchor: passedAnchor, side, gap, align, alignOffset, matchTriggerWidth, matchTriggerHeight, open: controlledOpen, defaultOpen, onOpenChange, header, footer, highlightCheckedOnOpen, label, type, value, defaultValue, onValueChange, children, ...props }) {
20
+ const MenuSearchableContext = createContext(false);
21
+ const MenuSearchLoadingContext = createContext(false);
22
+ export function MenuRoot({ ref: passedRef, trigger, triggerMode, anchor: passedAnchor, side, gap, align, alignOffset, matchTriggerWidth, matchTriggerHeight, open: controlledOpen, defaultOpen, onOpenChange, header: passedHeader, footer, highlightCheckedOnOpen, searchable: passedSearchable, searchValue, onSearchValueChange, empty, loading, label, type, value, defaultValue, onValueChange, children, ...props }) {
21
23
  const { dirProps, localThemeClass } = useEDS();
22
24
  const isSubmenu = useContext(MenuGroupContext) !== null;
23
25
  const isContextMenu = triggerMode === 'right-click' && !isSubmenu;
@@ -80,35 +82,43 @@ export function MenuRoot({ ref: passedRef, trigger, triggerMode, anchor: passedA
80
82
  capturePointerCoords,
81
83
  });
82
84
  useHighlightCheckedOnOpen(popupRef, open, highlightCheckedOnOpen);
85
+ const searchable = passedSearchable ?? (searchValue !== undefined || onSearchValueChange !== undefined);
86
+ const [onSearchValueChangeAfterClose, reportPendingSearchReset] = useSearchResetAfterClose(onSearchValueChange);
87
+ const header = passedHeader !== undefined ? passedHeader : searchable ? _jsx(MenuSearch, {}) : undefined;
83
88
  return (_jsx("span", { "data-has-trigger": hasTrigger || undefined, className: cn(`root-contents [anchor-scope:all]
84
89
  not-data-has-trigger:**:data-base-ui-focus-guard:hidden`,
85
90
  // Very imperfect workaround for https://bugs.webkit.org/show_bug.cgi?id=301871
86
91
  `safari:root-inline
87
- i:safari:not-data-is-submenu:size-max`), children: _jsxs(MenuRoot, { actionsRef: actionsRef, open: open, onOpenChange: (newOpen) => {
88
- // A menu with no trigger can still be opened/closed by the consumer, but it should not send events
89
- if (hasTrigger)
90
- setOpen(newOpen);
91
- }, ...(!isSubmenu && !isContextMenu && { modal: hasTrigger }), closeParentOnEsc: true, children: [_jsx(MenuTriggerContext.Provider, { value: true, children: renderedTriggerElement ?? (_jsx(MenuInlineFallback, { label: label, portalRef: portalRef, rootProps: props })) }), _jsx(Portal, { children: _jsx("span", { ref: cssPropsPolyfillRef, ...mergeProps({ className: cn('eds-menu invisible! block!', cssPropsClassName) }, cssPropsAttributes, cssPropsPolyfillAttributes, dirProps, props), hidden: undefined }) }), _jsx(Menu.Portal, { container: !hasTrigger
92
- ? portalRef
93
- : /**
94
- * Specifying `document.body` because while it is the default for top-level menus, a submenu
95
- * defaults to using the same portal as its parent, which is not desirable when the parent is
96
- * rendered inline (it can cause the submenu to appear behind other elements).
97
- */
98
- typeof document !== 'undefined'
99
- ? document.body
100
- : undefined,
101
- // Inline menus are portalled in place, so they already inherit the local theme
102
- className: hasTrigger ? localThemeClass : undefined, children: _jsx(Menu.Positioner, { ref: passedRef, anchor: anchor, side: cssProps.side === 'start'
103
- ? 'inline-start'
104
- : cssProps.side === 'end'
105
- ? 'inline-end'
106
- : cssProps.side, sideOffset: twToPx(cssProps.gap), align: cssProps.align, alignOffset: twToPx(cssProps.alignOffset), collisionPadding: 8, collisionAvoidance: {
107
- side: 'flip',
108
- align: 'flip',
109
- fallbackAxisSide: cssProps.side === 'start' || cssProps.side === 'end' ? 'end' : 'none',
110
- }, "data-has-trigger": hasTrigger || undefined, "data-match-trigger-width": cssProps.matchTriggerWidth || undefined, "data-match-trigger-height": cssProps.matchTriggerHeight || undefined, ...mergeProps({
111
- className: cn(`
92
+ i:safari:not-data-is-submenu:size-max`), children: _jsx(MenuFilter, { searchable: searchable, searchValue: searchValue, onSearchValueChange: onSearchValueChangeAfterClose, children: _jsxs(MenuRoot, { actionsRef: actionsRef, open: open, onOpenChange: (newOpen) => {
93
+ if (newOpen)
94
+ reportPendingSearchReset();
95
+ // A menu with no trigger can still be opened/closed by the consumer, but it should not send events
96
+ if (hasTrigger)
97
+ setOpen(newOpen);
98
+ }, onOpenChangeComplete: (newOpen) => {
99
+ if (!newOpen)
100
+ reportPendingSearchReset();
101
+ }, ...(!isSubmenu && !isContextMenu && { modal: hasTrigger }), closeParentOnEsc: true, children: [_jsx(MenuTriggerContext.Provider, { value: true, children: renderedTriggerElement ?? (_jsx(MenuInlineFallback, { label: label, portalRef: portalRef, rootProps: props })) }), _jsx(Portal, { children: _jsx("span", { ref: cssPropsPolyfillRef, ...mergeProps({ className: cn('eds-menu invisible! block!', cssPropsClassName) }, cssPropsAttributes, cssPropsPolyfillAttributes, dirProps, props), hidden: undefined }) }), _jsx(Menu.Portal, { container: !hasTrigger
102
+ ? portalRef
103
+ : /**
104
+ * Specifying `document.body` because while it is the default for top-level menus, a submenu
105
+ * defaults to using the same portal as its parent, which is not desirable when the parent is
106
+ * rendered inline (it can cause the submenu to appear behind other elements).
107
+ */
108
+ typeof document !== 'undefined'
109
+ ? document.body
110
+ : undefined,
111
+ // Inline menus are portalled in place, so they already inherit the local theme
112
+ className: hasTrigger ? localThemeClass : undefined, children: _jsx(Menu.Positioner, { ref: passedRef, anchor: anchor, side: cssProps.side === 'start'
113
+ ? 'inline-start'
114
+ : cssProps.side === 'end'
115
+ ? 'inline-end'
116
+ : cssProps.side, sideOffset: twToPx(cssProps.gap), align: cssProps.align, alignOffset: twToPx(cssProps.alignOffset), collisionPadding: 8, collisionAvoidance: {
117
+ side: 'flip',
118
+ align: 'flip',
119
+ fallbackAxisSide: cssProps.side === 'start' || cssProps.side === 'end' ? 'end' : 'none',
120
+ }, "data-has-trigger": hasTrigger || undefined, "data-match-trigger-width": cssProps.matchTriggerWidth || undefined, "data-match-trigger-height": cssProps.matchTriggerHeight || undefined, ...mergeProps({
121
+ className: cn(`
112
122
  eds-menu root-flex
113
123
  [--available-height-but-not-too-small:max(var(--available-height),--spacing(16))]
114
124
  [anchor-name:--eds-menu]
@@ -127,15 +137,49 @@ export function MenuRoot({ ref: passedRef, trigger, triggerMode, anchor: passedA
127
137
  u:i:data-[match-trigger-width=at-most]:max-w-[min(var(--anchor-width),var(--available-width))]
128
138
  u:i:data-[match-trigger-width=true]:w-(--anchor-width)
129
139
  `, cssPropsClassName),
130
- }, cssPropsAttributes, cssPropsPolyfillAttributes, dirProps, props), render: (renderProps, state) => (_jsxs(_Fragment, { children: [_jsx("div", { ...renderProps, style: hasTrigger ? renderProps.style : undefined }), hasTrigger && state.open && state.anchorHidden && actionsRef.current ? (_jsx(LayoutEffect, { effect: actionsRef.current.close })) : null] })), children: _jsx(Menu.Popup, { ref: popupRef, "data-initial-open": initialOpen.current || undefined, className: "\n flex grow origin-(--transform-origin) flex-col overflow-clip rounded-inherit bg-muted outline-0 transition\n data-ending-style:scale-95\n data-ending-style:opacity-0\n data-starting-style:not-data-initial-open:scale-95\n data-starting-style:not-data-initial-open:opacity-0\n ", onKeyDown: handleMenuPopupKeyDown, children: _jsx(MenuPopupContent, { header: header, footer: footer, children: label !== undefined || type !== undefined ? (type === 'radio' ? (_jsx(MenuGroup, { label: label, type: type, value: value, defaultValue: defaultValue, onValueChange: onValueChange, children: children })) : (_jsx(MenuGroup, { label: label, type: type, children: children }))) : (children) }) }) }) })] }, `${hasTrigger}-${triggerMode}`) }));
140
+ }, cssPropsAttributes, cssPropsPolyfillAttributes, dirProps, props), render: (renderProps, state) => (_jsxs(_Fragment, { children: [_jsx("div", { ...renderProps, style: hasTrigger ? renderProps.style : undefined }), hasTrigger && state.open && state.anchorHidden && actionsRef.current ? (_jsx(LayoutEffect, { effect: actionsRef.current.close })) : null] })), children: _jsx(Menu.Popup, { ref: popupRef, "data-initial-open": initialOpen.current || undefined, className: "\n flex grow origin-(--transform-origin) flex-col overflow-clip rounded-inherit bg-muted outline-0 transition\n data-ending-style:scale-95\n data-ending-style:opacity-0\n data-starting-style:not-data-initial-open:scale-95\n data-starting-style:not-data-initial-open:opacity-0\n ", onKeyDown: handleMenuPopupKeyDown, children: _jsx(MenuPopupContent, { header: header, footer: footer, empty: empty, loading: loading, children: label !== undefined || type !== undefined ? (type === 'radio' ? (_jsx(MenuGroup, { label: label, type: type, value: value, defaultValue: defaultValue, onValueChange: onValueChange, children: children })) : (_jsx(MenuGroup, { label: label, type: type, children: children }))) : (children) }) }) }) })] }, `${hasTrigger}-${triggerMode}`) }) }));
131
141
  }
132
142
  MenuRoot.displayName = 'Menu';
143
+ /** Makes the menu filterable when it's `searchable` (see `MenuProps.OwnProps['searchable']`). */
144
+ function MenuFilter({ searchable, searchValue, onSearchValueChange, children, }) {
145
+ const filter = useMemo(() => searchable === 'manual'
146
+ ? null
147
+ : typeof searchable === 'function'
148
+ ? (label, query) => searchable({ label, searchValue: query })
149
+ : undefined, [searchable]);
150
+ return (_jsx(MenuSearchableContext.Provider, { value: Boolean(searchable), children: searchable ? (_jsx(Menu.FilterProvider, { filter: filter, autoHighlight: true, value: searchValue, onValueChange: onSearchValueChange, children: children })) : (children) }));
151
+ }
133
152
  /**
134
- * Popup chrome: minimum-width spacer, optional header, scrollable items area, optional footer,
135
- * border overlay.
153
+ * Holds back the search reset that Base UI reports as the menu starts closing until it has finished
154
+ * closing (or reopens), so items filtered outside of Base UI (e.g. with `searchable="manual"`)
155
+ * don't change while it animates out. Base UI keeps filtering its own items with the previous query
156
+ * until then too.
136
157
  */
137
- function MenuPopupContent({ header, footer, children, }) {
138
- return (_jsxs(_Fragment, { children: [_jsx("div", { className: "w-58" }), header ? (_jsx("div", { className: "nested/menu-header u:shrink-0 u:border-b u:border-muted u:p-4", children: header })) : null, _jsx("div", { className: "grow scroll-p-8 scrollbar-thin overflow-x-clip overflow-y-auto gradient-mask-y", children: _jsx("div", { className: "overflow-clip p-2", children: _jsxs(MenuGroupContext.Provider, { value: "root", children: [children, _jsx("div", { className: "mt-[calc(-2*(--spacing(2))-1px)] not-preceded-by-peer/menu-group:hidden" })] }) }) }), footer ? (_jsx("div", { className: "nested/menu-footer u:shrink-0 u:border-t u:border-muted u:p-4", children: footer })) : null, _jsx("div", { className: "pointer-events-none absolute inset-0 rounded-inherit border border-muted" })] }));
158
+ function useSearchResetAfterClose(onSearchValueChange) {
159
+ const pendingResetRef = useRef(null);
160
+ const onSearchValueChangeAfterClose = onSearchValueChange &&
161
+ ((searchValue, eventDetails) => {
162
+ if (eventDetails.reason === 'popup-close') {
163
+ pendingResetRef.current = () => onSearchValueChange(searchValue, eventDetails);
164
+ }
165
+ else {
166
+ onSearchValueChange(searchValue, eventDetails);
167
+ }
168
+ });
169
+ const reportPendingReset = () => {
170
+ pendingResetRef.current?.();
171
+ pendingResetRef.current = null;
172
+ };
173
+ return [onSearchValueChangeAfterClose, reportPendingReset];
174
+ }
175
+ /**
176
+ * Popup chrome: minimum-width spacer, optional header, scrollable items area (with a searchable
177
+ * menu's empty state), optional footer, border overlay.
178
+ */
179
+ function MenuPopupContent({ header, footer, empty, loading = false, children, }) {
180
+ const searchable = useContext(MenuSearchableContext);
181
+ const [emptyShowsLoading, setEmptyShowsLoading] = useState(false);
182
+ return (_jsxs(_Fragment, { children: [_jsx("div", { className: "w-58" }), header ? (_jsx("div", { className: "nested/menu-header u:shrink-0 u:border-b u:border-muted u:p-4", children: _jsx(MenuSearchLoadingContext.Provider, { value: loading && !emptyShowsLoading, children: header }) })) : null, _jsx("div", { className: "grow scroll-p-8 scrollbar-thin overflow-x-clip overflow-y-auto gradient-mask-y", children: _jsxs("div", { className: "overflow-clip p-2", children: [searchable ? (_jsx(Menu.Empty, { children: _jsx(MenuEmptyContent, { empty: empty, loading: loading, onLoadingShownChange: setEmptyShowsLoading }) })) : null, _jsx(Menu.List, { "aria-busy": loading || undefined, className: "outline-0", children: _jsx(MenuGroupContext.Provider, { value: "root", children: children }) })] }) }), footer ? (_jsx("div", { className: "nested/menu-footer u:shrink-0 u:border-t u:border-muted u:p-4", children: footer })) : null, _jsx("div", { className: "pointer-events-none absolute inset-0 rounded-inherit border border-muted" })] }));
139
183
  }
140
184
  /**
141
185
  * Resolves the anchor `Menu.Positioner` should point at, and returns a pointer-capture handler for
@@ -232,9 +276,28 @@ function renderMenuTriggerElement({ trigger, triggerMode, triggerRef, isSubmenu,
232
276
  return (_jsx(Menu.Trigger, { ref: triggerRef, openOnHover: triggerMode === 'hover', "data-open-on-hover": triggerMode === 'hover' || undefined, className: "\n u:inherit-position\n u:i:open:data-open-on-hover:state-hover\n u:iii:open:not-data-open-on-hover:state-active\n ", onPointerDown: capturePointerCoords, onPointerEnter: capturePointerCoords, render: renderTrigger }));
233
277
  }
234
278
  }
279
+ /**
280
+ * The content of a searchable menu's `Menu.Empty`, which Base UI only renders while no item
281
+ * matches. Until a search finishes, `empty` would be premature, so `loading` shows a `LoadingIcon`
282
+ * instead (rather than in the search input).
283
+ */
284
+ function MenuEmptyContent({ empty, loading, onLoadingShownChange, }) {
285
+ const [searchFinished, setSearchFinished] = useState(!loading);
286
+ if (!loading && !searchFinished)
287
+ setSearchFinished(true);
288
+ useLayoutEffect(() => {
289
+ onLoadingShownChange(!searchFinished);
290
+ return () => onLoadingShownChange(false);
291
+ }, [searchFinished, onLoadingShownChange]);
292
+ if (!searchFinished) {
293
+ return (_jsx(MenuEmpty, { children: _jsx("span", { className: "flex h-lh items-center justify-center", children: _jsx(LoadingIcon, {}) }) }));
294
+ }
295
+ return empty === undefined || typeof empty === 'string' ? _jsx(MenuEmpty, { children: empty }) : empty;
296
+ }
235
297
  /**
236
298
  * Focus the `[data-checked]` item on open so Base UI's composite syncs its active index to it (Base
237
- * UI has no `initialActiveIndex` API).
299
+ * UI has no `initialActiveIndex` API). In a searchable menu, typing then moves focus back to the
300
+ * search input.
238
301
  */
239
302
  function useHighlightCheckedOnOpen(popupRef, open, enabled) {
240
303
  useEffect(() => {
@@ -252,19 +315,12 @@ function useHighlightCheckedOnOpen(popupRef, open, enabled) {
252
315
  highlightedItem === checkedItem) {
253
316
  return;
254
317
  }
255
- const searchInput = popup.querySelector('input[type="search"]');
256
- const searchWasFocused = searchInput !== null && document.activeElement === searchInput;
257
318
  checkedItem.focus({ preventScroll: false });
258
- if (searchWasFocused)
259
- searchInput.focus({ preventScroll: true });
260
319
  });
261
320
  return () => cancelAnimationFrame(frameId);
262
321
  }, [popupRef, open, enabled]);
263
322
  }
264
- /**
265
- * Keydown handler for `Menu.Popup`. Handles Shift + Tab escaping the popup and inline-search-input
266
- * / composite-item coordination.
267
- */
323
+ /** Keydown handler for `Menu.Popup`. Handles Shift + Tab escaping the popup. */
268
324
  function handleMenuPopupKeyDown(event) {
269
325
  /**
270
326
  * Ensure Shift + Tab doesn't close the menu if there is a previous focusable element that is not
@@ -292,54 +348,6 @@ function handleMenuPopupKeyDown(event) {
292
348
  if ((previousElement && !previousElementIsMenuItem) ||
293
349
  (!activeElementIsMenuItem && previousElementIsMenuItem)) {
294
350
  event.preventBaseUIHandler();
295
- return;
296
- }
297
- }
298
- // If there is a search input in the menu...
299
- const searchInput = event.currentTarget.querySelector('input[type="search"]');
300
- if (searchInput instanceof HTMLInputElement) {
301
- // If the user typed some text, ensure it goes in the input instead of Base UI focusing the item that matches
302
- if ((event.key.length === 1 && event.key !== ' ') ||
303
- event.key === 'Backspace' ||
304
- event.key === 'ArrowLeft' ||
305
- event.key === 'ArrowRight') {
306
- event.preventBaseUIHandler();
307
- searchInput.focus();
308
- }
309
- else {
310
- const searchInputIsFocused = document.activeElement === searchInput;
311
- const menuItems = [...event.currentTarget.querySelectorAll('.eds-menu-item')];
312
- const highlightedMenuItem = menuItems.find((item) => item.matches('[data-highlighted]'));
313
- /**
314
- * If the user pressed the down arrow while the search input is focused and there is a single
315
- * menu item in the results, move the focus to it because it may already be highlighted, which
316
- * would prevent Base UI from focusing it.
317
- */
318
- if (event.key === 'ArrowDown' && searchInputIsFocused && menuItems.length === 1) {
319
- event.preventBaseUIHandler();
320
- menuItems[0].focus();
321
- }
322
- // Inversely, if the user pressed the up arrow and the focus is on the only menu item, move it back to the search input
323
- else if (event.key === 'ArrowUp' &&
324
- menuItems.length === 1 &&
325
- document.activeElement === menuItems[0]) {
326
- event.preventDefault();
327
- searchInput.focus();
328
- }
329
- // If the user pressed Enter while the search input is focused and a menu item is highlighted, select it
330
- else if (event.key === 'Enter' && searchInputIsFocused && highlightedMenuItem) {
331
- highlightedMenuItem.focus();
332
- window.setTimeout(() => {
333
- highlightedMenuItem.dispatchEvent(new KeyboardEvent('keydown', {
334
- key: 'Enter',
335
- code: 'Enter',
336
- keyCode: 13,
337
- which: 13,
338
- bubbles: true,
339
- cancelable: true,
340
- }));
341
- }, 0);
342
- }
343
351
  }
344
352
  }
345
353
  }
@@ -355,10 +363,12 @@ export function MenuGroup({ label, type = 'plain', value, defaultValue, onValueC
355
363
  if (isNested) {
356
364
  throw new Error(`[Menu] Groups cannot be nested, make sure you're not using \`Menu.Group\` in a \`Menu\` with a \`label\` and/or \`type\` prop (implicit group)`);
357
365
  }
358
- return (_jsx(MenuGroupContext.Provider, { value: menuGroupContextValue, children: _jsxs(Menu.Group, { ...mergeProps({ className: cn('peer/menu-group u:-m-2 u:mb-2 u:border-b u:border-muted u:p-2') }, props), render: type === 'radio' ? (_jsx(Menu.RadioGroup, { value: value, defaultValue: defaultValue, onValueChange: onValueChange })) : (_jsx("div", {})), children: [label ? (_jsx(Menu.GroupLabel, { className: "truncate p-2 text-12 text-muted", children: label })) : null, children] }) }));
366
+ return (_jsx(MenuGroupContext.Provider, { value: menuGroupContextValue, children: _jsxs(Menu.Group, { ...mergeProps({
367
+ className: cn('u:-m-2 u:border-muted u:p-2 u:has-[~:not([hidden]):not(:empty)]:mb-2 u:has-[~:not([hidden]):not(:empty)]:border-b'),
368
+ }, props), render: type === 'radio' ? (_jsx(Menu.RadioGroup, { value: value, defaultValue: defaultValue, onValueChange: onValueChange })) : (_jsx("div", {})), children: [label ? (_jsx(Menu.GroupLabel, { className: "truncate p-2 text-12 text-muted", children: label })) : null, children] }) }));
359
369
  }
360
370
  MenuGroup.displayName = 'Menu.Group';
361
- export function MenuItem({ ref: passedRef, type: passedType, addonBefore: passedAddonBefore, addonAfter: passedAddonAfter, variant, loading, href, target, checked, defaultChecked, onCheckedChange, value: passedValue, disabled: passedDisabled, children, ...props }) {
371
+ export function MenuItem({ ref: passedRef, type: passedType, label, addonBefore: passedAddonBefore, addonAfter: passedAddonAfter, variant, loading, href, target, checked, defaultChecked, onCheckedChange, value: passedValue, disabled: passedDisabled, children, ...props }) {
362
372
  const elementRef = useRef(null);
363
373
  const elementPassedRef = useMergedRefs(elementRef, passedRef);
364
374
  const autoValue = useAutoValue(children);
@@ -427,18 +437,18 @@ export function MenuItem({ ref: passedRef, type: passedType, addonBefore: passed
427
437
  ...props,
428
438
  };
429
439
  if (type === 'submenu-trigger') {
430
- return _jsx(Menu.SubmenuTrigger, { nativeButton: true, disabled: disabled, render: renderItem(baseProps) });
440
+ return (_jsx(Menu.SubmenuTrigger, { nativeButton: true, label: label, disabled: disabled, render: renderItem(baseProps) }));
431
441
  }
432
442
  if (type === 'checkbox') {
433
- return (_jsx(CheckboxItem, { ...baseProps, nativeButton: true, checked: checked, defaultChecked: defaultChecked, onCheckedChange: onCheckedChange, disabled: disabled, render: renderItem }));
443
+ return (_jsx(CheckboxItem, { ...baseProps, nativeButton: true, label: label, checked: checked, defaultChecked: defaultChecked, onCheckedChange: onCheckedChange, disabled: disabled, render: renderItem }));
434
444
  }
435
445
  if (type === 'radio') {
436
- return (_jsx(Menu.RadioItem, { ...baseProps, nativeButton: true, closeOnClick: true, value: passedValue !== undefined ? passedValue : autoValue, disabled: disabled, render: renderItem }));
446
+ return (_jsx(Menu.RadioItem, { ...baseProps, nativeButton: true, closeOnClick: true, label: label, value: passedValue !== undefined ? passedValue : autoValue, disabled: disabled, render: renderItem }));
437
447
  }
438
448
  if (href !== undefined) {
439
- return (_jsx(Menu.LinkItem, { ...baseProps, closeOnClick: true, href: href, target: target, render: renderItem, children: children }));
449
+ return (_jsx(Menu.LinkItem, { ...baseProps, closeOnClick: true, label: label, href: href, target: target, render: renderItem, children: children }));
440
450
  }
441
- return _jsx(Menu.Item, { ...baseProps, nativeButton: true, disabled: disabled, render: renderItem });
451
+ return (_jsx(Menu.Item, { ...baseProps, nativeButton: true, label: label, disabled: disabled, render: renderItem }));
442
452
  }
443
453
  MenuItem.displayName = 'Menu.Item';
444
454
  function MenuItemAddon({ children, ...props }) {
@@ -446,30 +456,24 @@ function MenuItemAddon({ children, ...props }) {
446
456
  className: cn('eds-addon root-flex items-center justify-center u:h-(--eds-addon-size) u:min-w-(--eds-addon-size) u:shrink-0 u:addon-medium'),
447
457
  }, props), children: children }));
448
458
  }
449
- export function MenuSearch({ ref: passedRef, placeholder: passedPlaceholder, value: controlledValue, defaultValue, onValueChange, ...props }) {
450
- const inputRef = useRef(null);
451
- const inputPassedRef = useMergedRefs(inputRef, passedRef);
452
- const placeholder = passedPlaceholder ?? 'Search';
453
- const [value, setValue] = useControlled(controlledValue, defaultValue ?? '', onValueChange);
459
+ /** Search input for the `header` of a `searchable` menu, which filters its items. */
460
+ export function MenuSearch({ placeholder = 'Search', ...props }) {
461
+ if (!useContext(MenuSearchableContext)) {
462
+ throw new Error('[Menu] `Menu.Search` must be used in a `searchable` menu');
463
+ }
464
+ const loading = useContext(MenuSearchLoadingContext);
454
465
  const { rootProps, nestedProps } = splitProps(props);
455
- return (_jsxs("div", { ...mergeProps({ className: cn('root-flex items-center u:-m-4 u:text-14 u:text-default') }, rootProps), children: [_jsx(MagnifyingGlassIcon, { alt: "", className: "absolute inset-y-0 inset-s-3.5 my-auto size-3.5" }), _jsx("input", { ref: inputPassedRef, type: "search", placeholder: placeholder, "aria-label": placeholder, value: value, ...mergeProps({
456
- className: cn('peer -mb-px h-10 w-0 grow ps-8.5 outline-0'),
457
- onChange: (event) => setValue(event.target.value),
458
- }, nestedProps) }), _jsx("div", { className: "me-1.5 flex size-7 shrink-0 items-center justify-center peer-placeholder-shown:hidden", children: _jsx(Button, { variant: "naked", size: "xsmall", tabIndex: -1, onClick: () => {
459
- const input = inputRef.current;
460
- if (!input)
461
- return;
462
- setInputValue(input, '');
463
- input.focus();
464
- }, className: "h-full", children: _jsx(XIcon, { alt: "Clear" }) }) })] }));
466
+ return (_jsxs("div", { ...mergeProps({ className: cn('root-flex items-center u:-m-4 u:text-14 u:text-default') }, rootProps), children: [loading ? (_jsx(LoadingIcon, { className: "absolute inset-y-0 inset-s-3.5 my-auto size-3.5" })) : (_jsx(MagnifyingGlassIcon, { alt: "", className: "absolute inset-y-0 inset-s-3.5 my-auto size-3.5" })), _jsx(Menu.Input, { placeholder: placeholder, "aria-label": placeholder, ...mergeProps({ className: cn('peer -mb-px h-10 w-0 grow ps-8.5 outline-0') }, nestedProps) }), _jsx("div", { className: "me-1.5 flex size-7 shrink-0 items-center justify-center peer-placeholder-shown:hidden", children: _jsx(Menu.Clear, { "aria-hidden": false, render: _jsx(Button, { variant: "naked", size: "xsmall", className: "h-full" }), children: _jsx(XIcon, { alt: "Clear" }) }) })] }));
465
467
  }
466
468
  MenuSearch.displayName = 'Menu.Search';
467
469
  /**
468
- * Renders the standard empty-state treatment for a `Menu` (typically shown when search filters
469
- * yield no results, or when a `Menu` has no items at all). Defaults to `"No results"`.
470
+ * Renders the standard empty-state treatment for a `Menu`, e.g. when it has no items. Searchable
471
+ * menus render it when no item matches (see `empty`). Its text wraps instead of widening the menu.
472
+ * Defaults to `"No results"`.
470
473
  */
471
474
  export function MenuEmpty({ children = 'No results', ...props }) {
472
- return (_jsx("div", { ...mergeProps({ className: cn('p-2 u:text-16 u:text-muted') }, props), children: children }));
475
+ // `contain-inline-size` keeps the text from widening a menu that sizes to fit its content
476
+ return (_jsx("div", { ...mergeProps({ className: cn('p-2 contain-inline-size u:text-16 u:text-muted') }, props), children: children }));
473
477
  }
474
478
  MenuEmpty.displayName = 'Menu.Empty';
475
479
  /**