@viraui/react 1.0.15 → 1.0.16

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 (68) hide show
  1. package/dist/catalog.json +6 -0
  2. package/dist/components/autocomplete/autocomplete-group.d.ts +12 -0
  3. package/dist/components/autocomplete/autocomplete-group.js +34 -0
  4. package/dist/components/autocomplete/autocomplete-item.d.ts +23 -0
  5. package/dist/components/autocomplete/autocomplete-item.js +37 -0
  6. package/dist/components/autocomplete/autocomplete.css +1 -0
  7. package/dist/components/autocomplete/autocomplete.d.ts +96 -0
  8. package/dist/components/autocomplete/autocomplete.guide.json +95 -0
  9. package/dist/components/autocomplete/autocomplete.js +126 -0
  10. package/dist/components/autocomplete/autocomplete.module.js +31 -0
  11. package/dist/components/autocomplete/index.d.ts +2 -0
  12. package/dist/components/avatar/avatar.css +1 -1
  13. package/dist/components/avatar/avatar.js +1 -1
  14. package/dist/components/avatar-group/avatar-group.js +2 -2
  15. package/dist/components/basic-input/basic-input.js +1 -1
  16. package/dist/components/basic-input/field-label.css +1 -1
  17. package/dist/components/basic-input/field-label.js +1 -2
  18. package/dist/components/button/button-chrome.js +4 -1
  19. package/dist/components/button/button.js +1 -1
  20. package/dist/components/checkbox/checkbox.js +1 -1
  21. package/dist/components/index.d.ts +1 -0
  22. package/dist/components/menu/menu-checkbox-item.d.ts +0 -13
  23. package/dist/components/menu/menu-checkbox-item.js +2 -7
  24. package/dist/components/menu/menu-group.js +4 -7
  25. package/dist/components/menu/menu-indicator-slot.d.ts +3 -7
  26. package/dist/components/menu/menu-indicator-slot.js +15 -21
  27. package/dist/components/menu/menu-item-row.d.ts +2 -4
  28. package/dist/components/menu/menu-item-row.js +15 -17
  29. package/dist/components/menu/menu-item.d.ts +1 -9
  30. package/dist/components/menu/menu-item.js +1 -4
  31. package/dist/components/menu/menu-link-item.d.ts +2 -10
  32. package/dist/components/menu/menu-link-item.js +4 -6
  33. package/dist/components/menu/menu-popup.d.ts +2 -1
  34. package/dist/components/menu/menu-radio-group.js +4 -7
  35. package/dist/components/menu/menu-radio-item.d.ts +0 -13
  36. package/dist/components/menu/menu-radio-item.js +2 -7
  37. package/dist/components/menu/menu-submenu-trigger.d.ts +0 -7
  38. package/dist/components/menu/menu-submenu-trigger.js +2 -7
  39. package/dist/components/menu/menu.css +1 -1
  40. package/dist/components/menu/menu.guide.json +14 -29
  41. package/dist/components/menu/menu.module.js +3 -3
  42. package/dist/components/select/select-group.js +1 -3
  43. package/dist/components/select/select.css +1 -1
  44. package/dist/components/select/select.guide.json +3 -2
  45. package/dist/components/select/select.js +1 -1
  46. package/dist/components/select/select.module.js +1 -3
  47. package/dist/components/spinner/index.d.ts +1 -1
  48. package/dist/components/spinner/spinner.css +1 -1
  49. package/dist/components/spinner/spinner.d.ts +8 -0
  50. package/dist/components/spinner/spinner.guide.json +3 -0
  51. package/dist/components/spinner/spinner.js +22 -20
  52. package/dist/components/spinner/spinner.module.js +2 -7
  53. package/dist/components/spinner/variants/bars.d.ts +2 -0
  54. package/dist/components/spinner/variants/bars.js +134 -0
  55. package/dist/components/spinner/variants/dot-grid.css +1 -0
  56. package/dist/components/spinner/variants/dot-grid.d.ts +2 -0
  57. package/dist/components/spinner/variants/dot-grid.js +57 -0
  58. package/dist/components/spinner/variants/dot-grid.module.js +16 -0
  59. package/dist/components/spinner/variants/dots.d.ts +2 -0
  60. package/dist/components/spinner/variants/dots.js +189 -0
  61. package/dist/components/spinner/variants/index.d.ts +5 -0
  62. package/dist/components/spinner/variants/index.js +16 -0
  63. package/dist/components/tabs/tabs-tab.js +1 -1
  64. package/dist/components/textfield/textfield.guide.json +1 -1
  65. package/dist/components/toast/toast-banner.js +1 -1
  66. package/dist/components/typewriter/typewriter.js +3 -3
  67. package/dist/index.js +4 -3
  68. package/package.json +4 -4
@@ -1,5 +1,4 @@
1
1
  import { clsx } from "../../core/clsx.js";
2
- import { ChromeCheck } from "../../internal/chrome-icons/chrome-icons.js";
3
2
  import { Surface } from "../surface/surface.js";
4
3
  import menu_module_default from "./menu.module.js";
5
4
  import { MenuIndicatorSlot } from "./menu-indicator-slot.js";
@@ -7,7 +6,7 @@ import { MenuItemRow } from "./menu-item-row.js";
7
6
  import { jsx } from "react/jsx-runtime";
8
7
  import { Menu } from "@base-ui/react/menu";
9
8
  //#region src/components/menu/menu-checkbox-item.tsx
10
- var MenuCheckboxItem = ({ addon, addonAlign = "center", children, className, closeOnClick = false, indicator, note, sentiment, ...otherProps }) => /* @__PURE__ */ jsx(Menu.CheckboxItem, {
9
+ var MenuCheckboxItem = ({ addon, children, className, closeOnClick = false, note, sentiment, ...otherProps }) => /* @__PURE__ */ jsx(Menu.CheckboxItem, {
11
10
  ...otherProps,
12
11
  className: clsx(menu_module_default.Item, className),
13
12
  closeOnClick,
@@ -15,12 +14,8 @@ var MenuCheckboxItem = ({ addon, addonAlign = "center", children, className, clo
15
14
  render: /* @__PURE__ */ jsx(Surface, { radius: "auto" }),
16
15
  children: /* @__PURE__ */ jsx(MenuItemRow, {
17
16
  addon,
18
- addonAlign,
19
17
  note,
20
- trailing: /* @__PURE__ */ jsx(MenuIndicatorSlot, {
21
- kind: "checkbox",
22
- children: indicator ?? /* @__PURE__ */ jsx(ChromeCheck, { size: 16 })
23
- }),
18
+ trailing: /* @__PURE__ */ jsx(MenuIndicatorSlot, { kind: "checkbox" }),
24
19
  children
25
20
  })
26
21
  });
@@ -1,21 +1,18 @@
1
- import { clsx } from "../../core/clsx.js";
2
1
  import { Text } from "../text/text.js";
3
2
  import { Stack } from "../stack/stack.js";
4
- import menu_module_default from "./menu.module.js";
5
- import { MenuIndicatorSlot } from "./menu-indicator-slot.js";
6
3
  import { jsx, jsxs } from "react/jsx-runtime";
7
4
  import { Menu } from "@base-ui/react/menu";
8
5
  //#region src/components/menu/menu-group.tsx
9
6
  var MenuGroup = ({ children, className, label, ...otherProps }) => /* @__PURE__ */ jsxs(Menu.Group, {
10
7
  ...otherProps,
11
- className: clsx(menu_module_default.Group, className),
8
+ className,
12
9
  render: /* @__PURE__ */ jsx(Stack, {
13
10
  direction: "column",
14
11
  fillChildren: false,
15
12
  rowGap: "2x-small",
16
13
  vPadding: "2x-small"
17
14
  }),
18
- children: [/* @__PURE__ */ jsxs(Menu.GroupLabel, {
15
+ children: [/* @__PURE__ */ jsx(Menu.GroupLabel, {
19
16
  render: /* @__PURE__ */ jsx(Stack, {
20
17
  columnGap: "small",
21
18
  direction: "row",
@@ -24,12 +21,12 @@ var MenuGroup = ({ children, className, label, ...otherProps }) => /* @__PURE__
24
21
  vAlign: "center",
25
22
  vPadding: ["small", "x-small"]
26
23
  }),
27
- children: [/* @__PURE__ */ jsx(Text, {
24
+ children: /* @__PURE__ */ jsx(Text, {
28
25
  size: "x-small",
29
26
  tone: "muted",
30
27
  weight: "semibold",
31
28
  children: label
32
- }), /* @__PURE__ */ jsx(MenuIndicatorSlot, {})]
29
+ })
33
30
  }), children]
34
31
  });
35
32
  //#endregion
@@ -1,15 +1,11 @@
1
1
  import type * as React from 'react';
2
- export type MenuIndicatorSlotKind = 'spacer' | 'checkbox' | 'radio' | 'chevron';
2
+ export type MenuIndicatorSlotKind = 'checkbox' | 'radio' | 'chevron';
3
3
  export type MenuIndicatorSlotProps = {
4
- children?: React.ReactNode;
5
4
  /**
6
5
  * Trailing footprint kind.
7
- * - `spacer`: empty matching footprint (Item / LinkItem)
8
- * - `checkbox` / `radio`: Base UI indicator with `keepMounted`
6
+ * - `checkbox` / `radio`: Base UI indicator with `keepMounted` + built-in check
9
7
  * - `chevron`: always-visible submenu end chevron
10
- *
11
- * @default 'spacer'
12
8
  */
13
- kind?: MenuIndicatorSlotKind;
9
+ kind: MenuIndicatorSlotKind;
14
10
  };
15
11
  export declare const MenuIndicatorSlot: React.FC<MenuIndicatorSlotProps>;
@@ -1,3 +1,4 @@
1
+ import { ChromeCheck, ChromeChevronEnd } from "../../internal/chrome-icons/chrome-icons.js";
1
2
  import { Stack } from "../stack/stack.js";
2
3
  import menu_module_default from "./menu.module.js";
3
4
  import { jsx } from "react/jsx-runtime";
@@ -10,42 +11,35 @@ var indicatorStackRender = /* @__PURE__ */ jsx(Stack, {
10
11
  inline: true,
11
12
  vAlign: "center"
12
13
  });
13
- var MenuIndicatorSlot = ({ children, kind = "spacer" }) => {
14
+ var checkIcon = /* @__PURE__ */ jsx(ChromeCheck, { size: 16 });
15
+ var chevronIcon = /* @__PURE__ */ jsx(ChromeChevronEnd, { size: 16 });
16
+ var indicatorSlotProps = {
17
+ className: menu_module_default.Indicator,
18
+ "data-grow": "false"
19
+ };
20
+ var MenuIndicatorSlot = ({ kind }) => {
14
21
  if (kind === "checkbox") return /* @__PURE__ */ jsx(Menu.CheckboxItemIndicator, {
15
- className: menu_module_default.Indicator,
16
- "data-grow": "false",
22
+ ...indicatorSlotProps,
17
23
  keepMounted: true,
18
24
  render: indicatorStackRender,
19
- children
25
+ children: checkIcon
20
26
  });
21
27
  if (kind === "radio") return /* @__PURE__ */ jsx(Menu.RadioItemIndicator, {
22
- className: menu_module_default.Indicator,
23
- "data-grow": "false",
28
+ ...indicatorSlotProps,
24
29
  keepMounted: true,
25
30
  render: indicatorStackRender,
26
- children
31
+ children: checkIcon
27
32
  });
28
- if (kind === "chevron") return /* @__PURE__ */ jsx(Stack, {
33
+ return /* @__PURE__ */ jsx(Stack, {
34
+ ...indicatorSlotProps,
29
35
  "aria-hidden": true,
30
- className: menu_module_default.Indicator,
31
- "data-grow": "false",
32
36
  "data-kind": "chevron",
33
37
  "data-shrink": "false",
34
38
  fillChildren: false,
35
39
  hAlign: "center",
36
40
  inline: true,
37
41
  vAlign: "center",
38
- children
39
- });
40
- return /* @__PURE__ */ jsx(Stack, {
41
- "aria-hidden": true,
42
- className: menu_module_default.Indicator,
43
- "data-grow": "false",
44
- "data-shrink": "false",
45
- fillChildren: false,
46
- hAlign: "center",
47
- inline: true,
48
- vAlign: "center"
42
+ children: chevronIcon
49
43
  });
50
44
  };
51
45
  //#endregion
@@ -1,12 +1,10 @@
1
- import { StackProps } from '../stack';
2
1
  import type * as React from 'react';
3
2
  export type MenuItemRowProps = {
4
3
  addon?: React.ReactNode;
5
- addonAlign?: StackProps['vAlign'];
6
4
  children?: React.ReactNode;
7
5
  /**
8
- * Optional muted note (shortcut / secondary label) at the end of the content row,
9
- * immediately before any trailing indicator.
6
+ * Optional muted note (shortcut / secondary label) after the label,
7
+ * before any trailing chevron / check indicator.
10
8
  */
11
9
  note?: React.ReactNode;
12
10
  trailing?: React.ReactNode;
@@ -1,36 +1,34 @@
1
1
  import { Text } from "../text/text.js";
2
2
  import { Stack } from "../stack/stack.js";
3
+ import menu_module_default from "./menu.module.js";
3
4
  import { jsx, jsxs } from "react/jsx-runtime";
4
5
  //#region src/components/menu/menu-item-row.tsx
5
6
  /**
6
7
  * Shared internal row layout for all Menu item kinds (addon + label + optional note + trailing).
7
8
  * Not a public export.
8
9
  */
9
- var MenuItemRow = ({ addon, addonAlign = "center", children, note, trailing }) => /* @__PURE__ */ jsxs(Stack, {
10
- columnGap: "medium",
10
+ var MenuItemRow = ({ addon, children, note, trailing }) => /* @__PURE__ */ jsxs(Stack, {
11
+ columnGap: "small",
12
+ "data-grow": "true",
11
13
  direction: "row",
12
14
  fillChildren: false,
13
15
  hPadding: "small",
14
16
  vPadding: "small",
15
17
  vAlign: "center",
18
+ className: menu_module_default.ItemRow,
16
19
  children: [
17
- /* @__PURE__ */ jsxs(Stack, {
18
- columnGap: "small",
20
+ addon && /* @__PURE__ */ jsx(Stack, {
21
+ "aria-hidden": "true",
22
+ "data-grow": "false",
23
+ "data-shrink": "false",
24
+ children: addon
25
+ }),
26
+ /* @__PURE__ */ jsx(Text, {
19
27
  "data-grow": "true",
20
28
  "data-shrink": "true",
21
- direction: "row",
22
- fillChildren: false,
23
- vAlign: addonAlign,
24
- children: [addon && /* @__PURE__ */ jsx(Stack, {
25
- "aria-hidden": "true",
26
- "data-grow": "false",
27
- "data-shrink": "false",
28
- children: addon
29
- }), /* @__PURE__ */ jsx(Text, {
30
- lineHeight: "small",
31
- size: "small",
32
- children
33
- })]
29
+ lineHeight: "small",
30
+ size: "small",
31
+ children
34
32
  }),
35
33
  note && /* @__PURE__ */ jsx(Text, {
36
34
  whiteSpace: "nowrap",
@@ -1,5 +1,4 @@
1
1
  import { MenuItem as MenuItemPrimitive } from '@base-ui/react/menu';
2
- import { StackProps } from '../stack';
3
2
  import type * as React from 'react';
4
3
  /**
5
4
  * Public Menu.Item props.
@@ -14,14 +13,7 @@ export type MenuItemProps = MenuItemPrimitive.Props & {
14
13
  */
15
14
  addon?: React.ReactNode;
16
15
  /**
17
- * Vertical alignment of the addon relative to the label row.
18
- *
19
- * @default 'center'
20
- */
21
- addonAlign?: StackProps['vAlign'];
22
- /**
23
- * End-aligned secondary text (e.g. keyboard shortcut). Rendered muted `x-small`
24
- * at the end of the row (replaces the empty indicator spacer when set).
16
+ * End-aligned secondary text (e.g. keyboard shortcut). Rendered muted `x-small`.
25
17
  *
26
18
  * @default No note is rendered.
27
19
  */
@@ -1,21 +1,18 @@
1
1
  import { clsx } from "../../core/clsx.js";
2
2
  import { Surface } from "../surface/surface.js";
3
3
  import menu_module_default from "./menu.module.js";
4
- import { MenuIndicatorSlot } from "./menu-indicator-slot.js";
5
4
  import { MenuItemRow } from "./menu-item-row.js";
6
5
  import { jsx } from "react/jsx-runtime";
7
6
  import { Menu } from "@base-ui/react/menu";
8
7
  //#region src/components/menu/menu-item.tsx
9
- var MenuItem = ({ addon, addonAlign = "center", children, className, note, sentiment, ...otherProps }) => /* @__PURE__ */ jsx(Menu.Item, {
8
+ var MenuItem = ({ addon, children, className, note, sentiment, ...otherProps }) => /* @__PURE__ */ jsx(Menu.Item, {
10
9
  ...otherProps,
11
10
  className: clsx(menu_module_default.Item, className),
12
11
  ...sentiment && { "data-sentiment": sentiment },
13
12
  render: /* @__PURE__ */ jsx(Surface, { radius: "auto" }),
14
13
  children: /* @__PURE__ */ jsx(MenuItemRow, {
15
14
  addon,
16
- addonAlign,
17
15
  note,
18
- ...!note && { trailing: /* @__PURE__ */ jsx(MenuIndicatorSlot, {}) },
19
16
  children
20
17
  })
21
18
  });
@@ -1,5 +1,4 @@
1
- import { MenuLinkItem as MenuLinkItemPrimitive } from '@base-ui/react/menu';
2
- import { StackProps } from '../stack';
1
+ import { MenuLinkItem as MenuLinkItemPrimitive } from '@base-ui/react';
3
2
  import type * as React from 'react';
4
3
  /**
5
4
  * Public Menu.LinkItem props.
@@ -14,14 +13,7 @@ export type MenuLinkItemProps = MenuLinkItemPrimitive.Props & {
14
13
  */
15
14
  addon?: React.ReactNode;
16
15
  /**
17
- * Vertical alignment of the addon relative to the label row.
18
- *
19
- * @default 'center'
20
- */
21
- addonAlign?: StackProps['vAlign'];
22
- /**
23
- * End-aligned secondary text (e.g. keyboard shortcut). Rendered muted `x-small`
24
- * at the end of the row (replaces the empty indicator spacer when set).
16
+ * End-aligned secondary text (e.g. keyboard shortcut). Rendered muted `x-small`.
25
17
  *
26
18
  * @default No note is rendered.
27
19
  */
@@ -1,24 +1,22 @@
1
1
  import { clsx } from "../../core/clsx.js";
2
+ import { Stack } from "../stack/stack.js";
2
3
  import { Surface } from "../surface/surface.js";
3
4
  import menu_module_default from "./menu.module.js";
4
- import { MenuIndicatorSlot } from "./menu-indicator-slot.js";
5
5
  import { MenuItemRow } from "./menu-item-row.js";
6
6
  import { jsx } from "react/jsx-runtime";
7
- import { Menu } from "@base-ui/react/menu";
7
+ import { Menu } from "@base-ui/react";
8
8
  //#region src/components/menu/menu-link-item.tsx
9
- var MenuLinkItem = ({ addon, addonAlign = "center", children, className, note, sentiment, ...otherProps }) => /* @__PURE__ */ jsx(Menu.LinkItem, {
9
+ var MenuLinkItem = ({ addon, children, className, note, sentiment, ...otherProps }) => /* @__PURE__ */ jsx(Menu.LinkItem, {
10
10
  ...otherProps,
11
11
  className: clsx(menu_module_default.Item, className),
12
12
  ...sentiment && { "data-sentiment": sentiment },
13
13
  render: /* @__PURE__ */ jsx(Surface, {
14
14
  radius: "auto",
15
- render: /* @__PURE__ */ jsx("a", {})
15
+ render: /* @__PURE__ */ jsx(Stack, { render: /* @__PURE__ */ jsx("a", {}) })
16
16
  }),
17
17
  children: /* @__PURE__ */ jsx(MenuItemRow, {
18
18
  addon,
19
- addonAlign,
20
19
  note,
21
- ...!note && { trailing: /* @__PURE__ */ jsx(MenuIndicatorSlot, {}) },
22
20
  children
23
21
  })
24
22
  });
@@ -6,7 +6,8 @@ type MenuPopupPositionerProps = Omit<MenuPositioner.Props, 'className' | 'style'
6
6
  *
7
7
  * Encapsulates Portal + Positioner + Popup with Elevator + Surface list chrome
8
8
  * (Select-like). Positioning props forward to the Positioner; `sideOffset`
9
- * defaults to `2`.
9
+ * defaults to `2`. RTL placement comes from Base UI `DirectionProvider`;
10
+ * app must also set HTML/`dir` (or `direction`) so portaled CSS inherits RTL.
10
11
  *
11
12
  * @default `sideOffset` is `2`.
12
13
  */
@@ -1,21 +1,18 @@
1
- import { clsx } from "../../core/clsx.js";
2
1
  import { Text } from "../text/text.js";
3
2
  import { Stack } from "../stack/stack.js";
4
- import menu_module_default from "./menu.module.js";
5
- import { MenuIndicatorSlot } from "./menu-indicator-slot.js";
6
3
  import { jsx, jsxs } from "react/jsx-runtime";
7
4
  import { Menu } from "@base-ui/react/menu";
8
5
  //#region src/components/menu/menu-radio-group.tsx
9
6
  var MenuRadioGroup = ({ children, className, label, ...otherProps }) => /* @__PURE__ */ jsxs(Menu.RadioGroup, {
10
7
  ...otherProps,
11
- className: clsx(menu_module_default.Group, className),
8
+ className,
12
9
  render: /* @__PURE__ */ jsx(Stack, {
13
10
  direction: "column",
14
11
  fillChildren: false,
15
12
  rowGap: "2x-small",
16
13
  vPadding: "2x-small"
17
14
  }),
18
- children: [label && /* @__PURE__ */ jsxs(Menu.GroupLabel, {
15
+ children: [label && /* @__PURE__ */ jsx(Menu.GroupLabel, {
19
16
  render: /* @__PURE__ */ jsx(Stack, {
20
17
  columnGap: "small",
21
18
  direction: "row",
@@ -24,12 +21,12 @@ var MenuRadioGroup = ({ children, className, label, ...otherProps }) => /* @__PU
24
21
  vAlign: "center",
25
22
  vPadding: ["small", "small"]
26
23
  }),
27
- children: [/* @__PURE__ */ jsx(Text, {
24
+ children: /* @__PURE__ */ jsx(Text, {
28
25
  size: "x-small",
29
26
  tone: "muted",
30
27
  weight: "semibold",
31
28
  children: label
32
- }), /* @__PURE__ */ jsx(MenuIndicatorSlot, {})]
29
+ })
33
30
  }), children]
34
31
  });
35
32
  //#endregion
@@ -1,5 +1,4 @@
1
1
  import { MenuRadioItem as MenuRadioItemPrimitive } from '@base-ui/react/menu';
2
- import { StackProps } from '../stack';
3
2
  import type * as React from 'react';
4
3
  /**
5
4
  * Public Menu.RadioItem props.
@@ -13,18 +12,6 @@ export type MenuRadioItemProps = MenuRadioItemPrimitive.Props & {
13
12
  * @default No addon is rendered.
14
13
  */
15
14
  addon?: React.ReactNode;
16
- /**
17
- * Vertical alignment of the addon relative to the label row.
18
- *
19
- * @default 'center'
20
- */
21
- addonAlign?: StackProps['vAlign'];
22
- /**
23
- * Custom indicator node when selected.
24
- *
25
- * @default Built-in Check chrome SVG at size 16
26
- */
27
- indicator?: React.ReactNode;
28
15
  /**
29
16
  * End-aligned secondary text (e.g. keyboard shortcut) before the check indicator.
30
17
  * Rendered muted `x-small`.
@@ -1,5 +1,4 @@
1
1
  import { clsx } from "../../core/clsx.js";
2
- import { ChromeCheck } from "../../internal/chrome-icons/chrome-icons.js";
3
2
  import { Surface } from "../surface/surface.js";
4
3
  import menu_module_default from "./menu.module.js";
5
4
  import { MenuIndicatorSlot } from "./menu-indicator-slot.js";
@@ -7,7 +6,7 @@ import { MenuItemRow } from "./menu-item-row.js";
7
6
  import { jsx } from "react/jsx-runtime";
8
7
  import { Menu } from "@base-ui/react/menu";
9
8
  //#region src/components/menu/menu-radio-item.tsx
10
- var MenuRadioItem = ({ addon, addonAlign = "center", children, className, closeOnClick = false, indicator, note, sentiment, ...otherProps }) => /* @__PURE__ */ jsx(Menu.RadioItem, {
9
+ var MenuRadioItem = ({ addon, children, className, closeOnClick = false, note, sentiment, ...otherProps }) => /* @__PURE__ */ jsx(Menu.RadioItem, {
11
10
  ...otherProps,
12
11
  className: clsx(menu_module_default.Item, className),
13
12
  closeOnClick,
@@ -15,12 +14,8 @@ var MenuRadioItem = ({ addon, addonAlign = "center", children, className, closeO
15
14
  render: /* @__PURE__ */ jsx(Surface, { radius: "auto" }),
16
15
  children: /* @__PURE__ */ jsx(MenuItemRow, {
17
16
  addon,
18
- addonAlign,
19
17
  note,
20
- trailing: /* @__PURE__ */ jsx(MenuIndicatorSlot, {
21
- kind: "radio",
22
- children: indicator ?? /* @__PURE__ */ jsx(ChromeCheck, { size: 16 })
23
- }),
18
+ trailing: /* @__PURE__ */ jsx(MenuIndicatorSlot, { kind: "radio" }),
24
19
  children
25
20
  })
26
21
  });
@@ -1,5 +1,4 @@
1
1
  import { MenuSubmenuTrigger as MenuSubmenuTriggerPrimitive } from '@base-ui/react/menu';
2
- import { StackProps } from '../stack';
3
2
  import type * as React from 'react';
4
3
  /**
5
4
  * Public Menu.SubmenuTrigger props.
@@ -13,12 +12,6 @@ export type MenuSubmenuTriggerProps = MenuSubmenuTriggerPrimitive.Props & {
13
12
  * @default No addon is rendered.
14
13
  */
15
14
  addon?: React.ReactNode;
16
- /**
17
- * Vertical alignment of the addon relative to the label row.
18
- *
19
- * @default 'center'
20
- */
21
- addonAlign?: StackProps['vAlign'];
22
15
  /**
23
16
  * Visual sentiment. `destructive` uses highlight-red wash + text.
24
17
  *
@@ -1,5 +1,4 @@
1
1
  import { clsx } from "../../core/clsx.js";
2
- import { ChromeChevronEnd } from "../../internal/chrome-icons/chrome-icons.js";
3
2
  import { Surface } from "../surface/surface.js";
4
3
  import menu_module_default from "./menu.module.js";
5
4
  import { MenuIndicatorSlot } from "./menu-indicator-slot.js";
@@ -7,18 +6,14 @@ import { MenuItemRow } from "./menu-item-row.js";
7
6
  import { jsx } from "react/jsx-runtime";
8
7
  import { Menu } from "@base-ui/react/menu";
9
8
  //#region src/components/menu/menu-submenu-trigger.tsx
10
- var MenuSubmenuTrigger = ({ addon, addonAlign = "center", children, className, sentiment, ...otherProps }) => /* @__PURE__ */ jsx(Menu.SubmenuTrigger, {
9
+ var MenuSubmenuTrigger = ({ addon, children, className, sentiment, ...otherProps }) => /* @__PURE__ */ jsx(Menu.SubmenuTrigger, {
11
10
  ...otherProps,
12
11
  className: clsx(menu_module_default.Item, className),
13
12
  ...sentiment && { "data-sentiment": sentiment },
14
13
  render: /* @__PURE__ */ jsx(Surface, { radius: "auto" }),
15
14
  children: /* @__PURE__ */ jsx(MenuItemRow, {
16
15
  addon,
17
- addonAlign,
18
- trailing: /* @__PURE__ */ jsx(MenuIndicatorSlot, {
19
- kind: "chevron",
20
- children: /* @__PURE__ */ jsx(ChromeChevronEnd, { size: 16 })
21
- }),
16
+ trailing: /* @__PURE__ */ jsx(MenuIndicatorSlot, { kind: "chevron" }),
22
17
  children
23
18
  })
24
19
  });
@@ -1 +1 @@
1
- @layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --__menu-list-appear-offset{syntax:"<length>";inherits:false;initial-value:8px}.viraui__menu-module__MenuPopup_GkrGa{min-inline-size:var(--anchor-width);max-block-size:var(--available-height);scroll-padding-block:var(--space-x-small);color:var(--global-foreground);outline:none;position:relative;overscroll-behavior:contain;transform-origin:var(--transform-origin);transition:opacity var(--duration-instant) var(--easing-entrance),scale var(--duration-instant) var(--easing-entrance),translate var(--duration-instant) var(--easing-entrance);&[data-ending-style],&[data-starting-style]{opacity:0;scale:.96}&[data-side=bottom][data-ending-style],&[data-side=bottom][data-starting-style]{translate:0 calc(var(--__menu-list-appear-offset) * -1)}&[data-side=top][data-ending-style],&[data-side=top][data-starting-style]{translate:0 var(--__menu-list-appear-offset)}&[data-side=inline-start][data-ending-style],&[data-side=inline-start][data-starting-style],&[data-side=left][data-ending-style],&[data-side=left][data-starting-style]{translate:var(--__menu-list-appear-offset) 0}&[data-side=inline-end][data-ending-style],&[data-side=inline-end][data-starting-style],&[data-side=right][data-ending-style],&[data-side=right][data-starting-style]{translate:calc(var(--__menu-list-appear-offset) * -1) 0}&[data-instant=click],&[data-instant=dismiss]{transition:none;scale:1;translate:0;opacity:1}&:focus,&:focus-visible{outline:none}}.viraui__menu-module__Indicator_btL99{min-inline-size:var(--space-medium);min-block-size:var(--space-medium);inline-size:fit-content;block-size:fit-content;color:var(--global-primary);opacity:0;&[data-checked]{opacity:1}&[data-kind=chevron]{opacity:1;color:var(--global-foreground);&:dir(rtl){scale:-1 1}}}.viraui__menu-module__Group_Orz5Y+.viraui__menu-module__Group_Orz5Y{margin-block-start:var(--space-medium)}}@layer viraui.overrides{.viraui__menu-module__Item_9zmEO{cursor:pointer;min-block-size:var(--space-x-large);&:any-link{display:flex}&:not([data-disabled]):hover,&:not([data-disabled])[data-highlighted]{background:var(--global-contrast);@container root not style(--vibrancy-enable: initial){background:oklab(from var(--global-contrast) l a b/12%)}}&:not([data-disabled],:hover)[data-checked]{background:light-dark(oklab(from var(--global-contrast) l a b/8%),oklab(from var(--global-contrast) l a b/5%))}&[data-disabled]{color:var(--global-disabled-foreground);cursor:not-allowed}&[data-sentiment=destructive]{color:var(--highlight-red);outline-color:var(--highlight-red);&:not([data-disabled]):hover,&:not([data-disabled])[data-highlighted]{background:oklab(from var(--highlight-red) l a b/12%)}}}}
1
+ @layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --__menu-list-appear-offset{syntax:"<length>";inherits:false;initial-value:8px}.viraui__menu-module__MenuPopup_GkrGa{min-inline-size:var(--anchor-width);max-block-size:var(--available-height);scroll-padding-block:var(--space-x-small);color:var(--global-foreground);outline:none;position:relative;overscroll-behavior:contain;transform-origin:var(--transform-origin);transition:opacity var(--duration-instant) var(--easing-entrance),scale var(--duration-instant) var(--easing-entrance),translate var(--duration-instant) var(--easing-entrance);&[data-ending-style],&[data-starting-style]{opacity:0;scale:.96}&[data-side=bottom][data-ending-style],&[data-side=bottom][data-starting-style]{translate:0 calc(var(--__menu-list-appear-offset) * -1)}&[data-side=top][data-ending-style],&[data-side=top][data-starting-style]{translate:0 var(--__menu-list-appear-offset)}&[data-side=left][data-ending-style],&[data-side=left][data-starting-style]{translate:var(--__menu-list-appear-offset) 0}&[data-side=right][data-ending-style],&[data-side=right][data-starting-style]{translate:calc(var(--__menu-list-appear-offset) * -1) 0}&[data-side=inline-start][data-ending-style],&[data-side=inline-start][data-starting-style]{translate:var(--__menu-list-appear-offset) 0;&:dir(rtl){translate:calc(var(--__menu-list-appear-offset) * -1) 0}}&[data-side=inline-end][data-ending-style],&[data-side=inline-end][data-starting-style]{translate:calc(var(--__menu-list-appear-offset) * -1) 0;&:dir(rtl){translate:var(--__menu-list-appear-offset) 0}}&[data-instant=click],&[data-instant=dismiss]{transition:none;scale:1;translate:0;opacity:1}&:focus,&:focus-visible{outline:none}}.viraui__menu-module__ItemRow_Be40k{min-block-size:var(--space-x-large)}.viraui__menu-module__Indicator_btL99{min-inline-size:var(--space-small);min-block-size:var(--space-small);inline-size:fit-content;block-size:fit-content;color:var(--global-primary);opacity:0;&[data-checked]{opacity:1}&[data-kind=chevron]{opacity:1;color:var(--global-foreground);&:dir(rtl){scale:-1 1}}}}@layer viraui.overrides{.viraui__menu-module__Item_9zmEO{cursor:pointer;&:not([data-disabled]):hover,&:not([data-disabled])[data-highlighted]{background:var(--global-contrast);@container root not style(--vibrancy-enable: initial){background:oklab(from var(--global-contrast) l a b/12%)}}&:not([data-disabled],:hover)[data-checked]{background:light-dark(oklab(from var(--global-contrast) l a b/8%),oklab(from var(--global-contrast) l a b/5%))}&[data-disabled]{color:var(--global-disabled-foreground);cursor:not-allowed}&[data-sentiment=destructive]{color:var(--highlight-red);outline-color:var(--highlight-red);&:not([data-disabled]):hover,&:not([data-disabled])[data-highlighted]{background:oklab(from var(--highlight-red) l a b/12%)}}}}
@@ -6,36 +6,36 @@
6
6
  "Action menus anchored to a button or icon button",
7
7
  "Nested command lists with checkbox or radio options that stay open on toggle",
8
8
  "Link rows mixed with actions in one menu surface",
9
- "Detached or multi-trigger menus via `Menu.createHandle`"
9
+ "Detached or multi-trigger menus via `Menu.createHandle`",
10
+ "Account / user widgets: `Menu.Trigger` as a Surface chip (avatar + name + email) opening a Popup with a static profile header plus action items"
10
11
  ],
11
12
  "whenNotToUse": [
12
13
  "Page-blocking modal flows (use Dialog)",
13
14
  "Form field single-select from a long list (use Select)",
14
15
  "Context menu or menubar chrome (not in this surface)",
15
- "System-wide transient alerts (use Toast)"
16
+ "System-wide transient alerts (use Toast)",
17
+ "Rich non-menu panels with forms or free layout (use Popover / Dialog — do not wrap Menu in Popover)"
16
18
  ],
17
19
  "accessibility": [
18
- "Give the trigger an accessible name (`Button` label or `aria-label` on IconButton)",
20
+ "Give the trigger an accessible name (`Button` label, visible text in a Surface trigger rendered as `<button>`, or `aria-label` on IconButton)",
19
21
  "Use `Menu.Group` `label` for grouped sections so assistive tech gets a group name",
20
- "Prefer Base UI keyboard navigation; do not trap focus outside the menu pattern"
22
+ "Prefer Base UI keyboard navigation; do not trap focus outside the menu pattern",
23
+ "`Menu.Popup` may include static non-item children (e.g. profile header); keep them non-interactive so focus roving stays on menu items"
21
24
  ],
22
25
  "antiPatterns": [
23
26
  "Expecting `Menu.Arrow`, `Menu.Backdrop`, or public Portal/Positioner/Viewport exports",
24
27
  "Closing checkbox/radio items on click by default when the menu should stay open for multi-toggle",
25
- "Using physical left/right CSS that breaks RTL submenu chevrons"
28
+ "Using physical left/right CSS that breaks RTL submenu chevrons",
29
+ "Expecting RTL item rows / left-opening submenus without Base UI `DirectionProvider direction=\"rtl\"` plus app `dir=\"rtl\"` on a portal ancestor (usually `<html>` / document root — a local wrapper alone does not reach body-mounted popups)",
30
+ "Nesting Menu inside Popover for an account menu — Menu already owns portal, positioning, and listbox keyboard behavior",
31
+ "Putting focusable controls (inputs, nested buttons) in `Menu.Popup` outside `Menu.Item` / `Menu.LinkItem` / checkbox / radio / submenu trigger parts"
26
32
  ],
27
- "related": ["Button", "IconButton", "Select", "Popover", "Tooltip", "Surface", "Stack"],
33
+ "related": ["Avatar", "Button", "IconButton", "Popover", "Select", "Stack", "Surface", "Text", "Tooltip"],
28
34
  "properties": {
29
35
  "react": {
30
36
  "CheckboxItem.addon": {
31
37
  "description": "Decorative leading node rendered before the item label."
32
38
  },
33
- "CheckboxItem.addonAlign": {
34
- "description": "Vertical alignment of the addon relative to the label row."
35
- },
36
- "CheckboxItem.indicator": {
37
- "description": "Custom indicator node when checked."
38
- },
39
39
  "CheckboxItem.note": {
40
40
  "description": "End-aligned secondary text (e.g. keyboard shortcut) before the check indicator. Rendered muted `x-small`."
41
41
  },
@@ -48,11 +48,8 @@
48
48
  "Item.addon": {
49
49
  "description": "Decorative leading node rendered before the item label."
50
50
  },
51
- "Item.addonAlign": {
52
- "description": "Vertical alignment of the addon relative to the label row."
53
- },
54
51
  "Item.note": {
55
- "description": "End-aligned secondary text (e.g. keyboard shortcut). Rendered muted `x-small` at the end of the row (replaces the empty indicator spacer when set)."
52
+ "description": "End-aligned secondary text (e.g. keyboard shortcut). Rendered muted `x-small`."
56
53
  },
57
54
  "Item.sentiment": {
58
55
  "description": "Visual sentiment. `destructive` uses highlight-red wash + text."
@@ -60,11 +57,8 @@
60
57
  "LinkItem.addon": {
61
58
  "description": "Decorative leading node rendered before the item label."
62
59
  },
63
- "LinkItem.addonAlign": {
64
- "description": "Vertical alignment of the addon relative to the label row."
65
- },
66
60
  "LinkItem.note": {
67
- "description": "End-aligned secondary text (e.g. keyboard shortcut). Rendered muted `x-small` at the end of the row (replaces the empty indicator spacer when set)."
61
+ "description": "End-aligned secondary text (e.g. keyboard shortcut). Rendered muted `x-small`."
68
62
  },
69
63
  "LinkItem.sentiment": {
70
64
  "description": "Visual sentiment. `destructive` uses highlight-red wash + text."
@@ -75,12 +69,6 @@
75
69
  "RadioItem.addon": {
76
70
  "description": "Decorative leading node rendered before the item label."
77
71
  },
78
- "RadioItem.addonAlign": {
79
- "description": "Vertical alignment of the addon relative to the label row."
80
- },
81
- "RadioItem.indicator": {
82
- "description": "Custom indicator node when selected."
83
- },
84
72
  "RadioItem.note": {
85
73
  "description": "End-aligned secondary text (e.g. keyboard shortcut) before the check indicator. Rendered muted `x-small`."
86
74
  },
@@ -90,9 +78,6 @@
90
78
  "SubmenuTrigger.addon": {
91
79
  "description": "Decorative leading node rendered before the item label."
92
80
  },
93
- "SubmenuTrigger.addonAlign": {
94
- "description": "Vertical alignment of the addon relative to the label row."
95
- },
96
81
  "SubmenuTrigger.sentiment": {
97
82
  "description": "Visual sentiment. `destructive` uses highlight-red wash + text."
98
83
  }
@@ -1,13 +1,13 @@
1
1
  //#region src/components/menu/menu.module.css
2
2
  var MenuPopup = "viraui__menu-module__MenuPopup_GkrGa";
3
+ var ItemRow = "viraui__menu-module__ItemRow_Be40k";
3
4
  var Indicator = "viraui__menu-module__Indicator_btL99";
4
- var Group = "viraui__menu-module__Group_Orz5Y";
5
5
  var Item = "viraui__menu-module__Item_9zmEO";
6
6
  var menu_module_default = {
7
7
  MenuPopup,
8
+ ItemRow,
8
9
  Indicator,
9
- Group,
10
10
  Item
11
11
  };
12
12
  //#endregion
13
- export { Group, Indicator, Item, MenuPopup, menu_module_default as default };
13
+ export { Indicator, Item, ItemRow, MenuPopup, menu_module_default as default };
@@ -1,7 +1,5 @@
1
- import { clsx } from "../../core/clsx.js";
2
1
  import { Text } from "../text/text.js";
3
2
  import { Stack } from "../stack/stack.js";
4
- import select_module_default from "./select.module.js";
5
3
  import { SelectIndicatorSlot } from "./select-indicator-slot.js";
6
4
  import { jsx, jsxs } from "react/jsx-runtime";
7
5
  import { Select } from "@base-ui/react/select";
@@ -9,7 +7,7 @@ import { Select } from "@base-ui/react/select";
9
7
  function SelectGroup({ children, className, label, ...groupProps }) {
10
8
  return /* @__PURE__ */ jsxs(Select.Group, {
11
9
  ...groupProps,
12
- className: clsx(select_module_default.Group, className),
10
+ className,
13
11
  render: /* @__PURE__ */ jsx(Stack, {
14
12
  direction: "column",
15
13
  fillChildren: false,