@viraui/react 1.0.13 → 1.0.15

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 (140) hide show
  1. package/dist/catalog.json +10 -4
  2. package/dist/components/accordion/accordion.css +1 -1
  3. package/dist/components/accordion/accordion.guide.json +26 -0
  4. package/dist/components/annotate/annotate.css +1 -1
  5. package/dist/components/annotate/annotate.guide.json +46 -57
  6. package/dist/components/avatar/avatar.css +1 -1
  7. package/dist/components/avatar/avatar.guide.json +22 -10
  8. package/dist/components/avatar/avatar.js +0 -2
  9. package/dist/components/avatar-group/avatar-group.css +1 -7
  10. package/dist/components/avatar-group/avatar-group.guide.json +23 -16
  11. package/dist/components/badge/badge.css +1 -1
  12. package/dist/components/badge/badge.d.ts +1 -1
  13. package/dist/components/badge/badge.guide.json +17 -13
  14. package/dist/components/badge/badge.js +1 -1
  15. package/dist/components/basic-input/basic-input.css +1 -1
  16. package/dist/components/basic-input/field-label.css +1 -1
  17. package/dist/components/basic-input/field-label.js +2 -0
  18. package/dist/components/bleed/bleed.guide.json +9 -6
  19. package/dist/components/button/button-chrome.d.ts +3 -1
  20. package/dist/components/button/button-chrome.js +3 -2
  21. package/dist/components/button/button-link.guide.json +55 -1
  22. package/dist/components/button/button-link.js +1 -0
  23. package/dist/components/button/button.css +1 -1
  24. package/dist/components/button/button.guide.json +27 -7
  25. package/dist/components/button/button.js +1 -0
  26. package/dist/components/checkbox/checkbox.css +1 -1
  27. package/dist/components/checkbox/checkbox.guide.json +40 -1
  28. package/dist/components/checkbox/checkbox.js +2 -2
  29. package/dist/components/checkbox/checkbox.module.js +1 -3
  30. package/dist/components/chip/chip.css +1 -1
  31. package/dist/components/chip/chip.guide.json +23 -6
  32. package/dist/components/chip/chip.js +1 -0
  33. package/dist/components/clamp-text/clamp-text.css +1 -1
  34. package/dist/components/clamp-text/clamp-text.guide.json +9 -0
  35. package/dist/components/dialog/dialog-sheet.js +1 -1
  36. package/dist/components/dialog/dialog.css +1 -1
  37. package/dist/components/dialog/dialog.guide.json +24 -0
  38. package/dist/components/dialog/dialog.module.js +1 -3
  39. package/dist/components/elevator/elevator.guide.json +23 -1
  40. package/dist/components/fieldset/fieldset.guide.json +16 -3
  41. package/dist/components/fieldset/fieldset.js +6 -6
  42. package/dist/components/fit-text/fit-text.css +1 -1
  43. package/dist/components/fit-text/fit-text.guide.json +2 -4
  44. package/dist/components/icon-button/icon-button-link.guide.json +52 -1
  45. package/dist/components/icon-button/icon-button-link.js +2 -2
  46. package/dist/components/icon-button/icon-button.d.ts +1 -1
  47. package/dist/components/icon-button/icon-button.guide.json +48 -3
  48. package/dist/components/icon-button/icon-button.js +2 -2
  49. package/dist/components/index.d.ts +1 -0
  50. package/dist/components/linear-progress/linear-progress.guide.json +16 -5
  51. package/dist/components/linear-progress/linear-progress.js +0 -1
  52. package/dist/components/masonry/masonry.d.ts +1 -1
  53. package/dist/components/masonry/masonry.guide.json +11 -9
  54. package/dist/components/menu/index.d.ts +11 -0
  55. package/dist/components/menu/menu-checkbox-item.d.ts +42 -0
  56. package/dist/components/menu/menu-checkbox-item.js +28 -0
  57. package/dist/components/menu/menu-group.d.ts +12 -0
  58. package/dist/components/menu/menu-group.js +36 -0
  59. package/dist/components/menu/menu-indicator-slot.d.ts +15 -0
  60. package/dist/components/menu/menu-indicator-slot.js +52 -0
  61. package/dist/components/menu/menu-item-row.d.ts +18 -0
  62. package/dist/components/menu/menu-item-row.js +47 -0
  63. package/dist/components/menu/menu-item.d.ts +36 -0
  64. package/dist/components/menu/menu-item.js +23 -0
  65. package/dist/components/menu/menu-link-item.d.ts +36 -0
  66. package/dist/components/menu/menu-link-item.js +26 -0
  67. package/dist/components/menu/menu-popup.d.ts +17 -0
  68. package/dist/components/menu/menu-popup.js +28 -0
  69. package/dist/components/menu/menu-radio-group.d.ts +16 -0
  70. package/dist/components/menu/menu-radio-group.js +36 -0
  71. package/dist/components/menu/menu-radio-item.d.ts +42 -0
  72. package/dist/components/menu/menu-radio-item.js +28 -0
  73. package/dist/components/menu/menu-separator.d.ts +9 -0
  74. package/dist/components/menu/menu-separator.js +15 -0
  75. package/dist/components/menu/menu-submenu-trigger.d.ts +29 -0
  76. package/dist/components/menu/menu-submenu-trigger.js +26 -0
  77. package/dist/components/menu/menu.css +1 -0
  78. package/dist/components/menu/menu.d.ts +58 -0
  79. package/dist/components/menu/menu.guide.json +101 -0
  80. package/dist/components/menu/menu.js +36 -0
  81. package/dist/components/menu/menu.module.js +13 -0
  82. package/dist/components/meter/meter.guide.json +15 -4
  83. package/dist/components/meter/meter.js +0 -1
  84. package/dist/components/popover/popover-sheet.js +1 -1
  85. package/dist/components/popover/popover.guide.json +25 -1
  86. package/dist/components/progressive-blur/progressive-blur.css +1 -1
  87. package/dist/components/progressive-blur/progressive-blur.guide.json +14 -4
  88. package/dist/components/progressive-blur/progressive-blur.js +2 -2
  89. package/dist/components/radio/radio.css +1 -1
  90. package/dist/components/radio/radio.guide.json +34 -1
  91. package/dist/components/radio/radio.js +28 -31
  92. package/dist/components/select/select-group.js +1 -1
  93. package/dist/components/select/select-option.d.ts +1 -1
  94. package/dist/components/select/select-option.js +2 -5
  95. package/dist/components/select/select-separator.js +7 -4
  96. package/dist/components/select/select.css +1 -1
  97. package/dist/components/select/select.guide.json +49 -8
  98. package/dist/components/select/select.js +1 -1
  99. package/dist/components/select/select.module.js +1 -5
  100. package/dist/components/separator/separator.guide.json +28 -1
  101. package/dist/components/shimmer/shimmer.css +1 -1
  102. package/dist/components/shimmer/shimmer.guide.json +19 -16
  103. package/dist/components/skeleton/skeleton.guide.json +24 -31
  104. package/dist/components/slider/slider.guide.json +27 -7
  105. package/dist/components/spinner/spinner.guide.json +5 -4
  106. package/dist/components/stack/stack.guide.json +49 -47
  107. package/dist/components/static-noise/static-noise.guide.json +18 -2
  108. package/dist/components/surface/surface.css +1 -1
  109. package/dist/components/surface/surface.guide.json +41 -48
  110. package/dist/components/switch/switch.css +1 -1
  111. package/dist/components/switch/switch.guide.json +25 -10
  112. package/dist/components/tabs/tabs.guide.json +11 -0
  113. package/dist/components/text/text.css +1 -1
  114. package/dist/components/text/text.guide.json +67 -76
  115. package/dist/components/textarea/textarea.css +1 -1
  116. package/dist/components/textarea/textarea.d.ts +4 -3
  117. package/dist/components/textarea/textarea.guide.json +19 -7
  118. package/dist/components/textfield/textfield.css +1 -1
  119. package/dist/components/textfield/textfield.guide.json +22 -7
  120. package/dist/components/title/title.css +1 -1
  121. package/dist/components/title/title.guide.json +62 -72
  122. package/dist/components/title/title.js +0 -1
  123. package/dist/components/toast/toast.css +1 -1
  124. package/dist/components/toast/toast.guide.json +32 -1
  125. package/dist/components/toggle-button/toggle-button.css +1 -0
  126. package/dist/components/toggle-button/toggle-button.d.ts +7 -0
  127. package/dist/components/toggle-button/toggle-button.guide.json +29 -2
  128. package/dist/components/toggle-button/toggle-button.js +18 -3
  129. package/dist/components/toggle-button/toggle-button.module.js +9 -0
  130. package/dist/components/toggle-group/toggle-group.d.ts +2 -1
  131. package/dist/components/toggle-group/toggle-group.guide.json +2 -3
  132. package/dist/components/tooltip/tooltip.guide.json +8 -1
  133. package/dist/components/typewriter/typewriter.css +1 -1
  134. package/dist/components/typewriter/typewriter.guide.json +27 -5
  135. package/dist/index.js +12 -2
  136. package/dist/internal/chrome-icons/chrome-icons.d.ts +2 -0
  137. package/dist/internal/chrome-icons/chrome-icons.js +7 -1
  138. package/dist/preflight-surface.json +1 -1
  139. package/dist/preflight.css +1 -1
  140. package/package.json +3 -3
@@ -0,0 +1,36 @@
1
+ import { MenuLinkItem as MenuLinkItemPrimitive } from '@base-ui/react/menu';
2
+ import { StackProps } from '../stack';
3
+ import type * as React from 'react';
4
+ /**
5
+ * Public Menu.LinkItem props.
6
+ *
7
+ * @default Base UI pass-through props keep upstream defaults.
8
+ */
9
+ export type MenuLinkItemProps = MenuLinkItemPrimitive.Props & {
10
+ /**
11
+ * Decorative leading node rendered before the item label.
12
+ *
13
+ * @default No addon is rendered.
14
+ */
15
+ 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
+ * 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).
25
+ *
26
+ * @default No note is rendered.
27
+ */
28
+ note?: React.ReactNode;
29
+ /**
30
+ * Visual sentiment. `destructive` uses highlight-red wash + text.
31
+ *
32
+ * @default Neutral item styling.
33
+ */
34
+ sentiment?: 'destructive';
35
+ };
36
+ export declare const MenuLinkItem: React.FC<MenuLinkItemProps>;
@@ -0,0 +1,26 @@
1
+ import { clsx } from "../../core/clsx.js";
2
+ import { Surface } from "../surface/surface.js";
3
+ import menu_module_default from "./menu.module.js";
4
+ import { MenuIndicatorSlot } from "./menu-indicator-slot.js";
5
+ import { MenuItemRow } from "./menu-item-row.js";
6
+ import { jsx } from "react/jsx-runtime";
7
+ import { Menu } from "@base-ui/react/menu";
8
+ //#region src/components/menu/menu-link-item.tsx
9
+ var MenuLinkItem = ({ addon, addonAlign = "center", children, className, note, sentiment, ...otherProps }) => /* @__PURE__ */ jsx(Menu.LinkItem, {
10
+ ...otherProps,
11
+ className: clsx(menu_module_default.Item, className),
12
+ ...sentiment && { "data-sentiment": sentiment },
13
+ render: /* @__PURE__ */ jsx(Surface, {
14
+ radius: "auto",
15
+ render: /* @__PURE__ */ jsx("a", {})
16
+ }),
17
+ children: /* @__PURE__ */ jsx(MenuItemRow, {
18
+ addon,
19
+ addonAlign,
20
+ note,
21
+ ...!note && { trailing: /* @__PURE__ */ jsx(MenuIndicatorSlot, {}) },
22
+ children
23
+ })
24
+ });
25
+ //#endregion
26
+ export { MenuLinkItem };
@@ -0,0 +1,17 @@
1
+ import { MenuPositioner } from '@base-ui/react/menu';
2
+ import type * as React from 'react';
3
+ type MenuPopupPositionerProps = Omit<MenuPositioner.Props, 'className' | 'style' | 'render'>;
4
+ /**
5
+ * Public Menu.Popup props.
6
+ *
7
+ * Encapsulates Portal + Positioner + Popup with Elevator + Surface list chrome
8
+ * (Select-like). Positioning props forward to the Positioner; `sideOffset`
9
+ * defaults to `2`.
10
+ *
11
+ * @default `sideOffset` is `2`.
12
+ */
13
+ export type MenuPopupProps = MenuPopupPositionerProps & {
14
+ children?: React.ReactNode;
15
+ };
16
+ export declare const MenuPopup: React.FC<MenuPopupProps>;
17
+ export {};
@@ -0,0 +1,28 @@
1
+ import { Elevator } from "../elevator/elevator.js";
2
+ import { Surface } from "../surface/surface.js";
3
+ import menu_module_default from "./menu.module.js";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import { Menu } from "@base-ui/react/menu";
6
+ //#region src/components/menu/menu-popup.tsx
7
+ var MenuPopup = ({ children, sideOffset = 2, ...positionerProps }) => /* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(Menu.Positioner, {
8
+ sideOffset,
9
+ ...positionerProps,
10
+ children: /* @__PURE__ */ jsx(Elevator, {
11
+ resting: 1,
12
+ children: /* @__PURE__ */ jsx(Menu.Popup, {
13
+ className: menu_module_default.MenuPopup,
14
+ render: /* @__PURE__ */ jsx(Surface, {
15
+ border: "all",
16
+ color: 1,
17
+ "data-vibrant": true,
18
+ hPadding: "x-small",
19
+ overflow: "auto",
20
+ radius: "medium",
21
+ vPadding: "x-small"
22
+ }),
23
+ children
24
+ })
25
+ })
26
+ }) });
27
+ //#endregion
28
+ export { MenuPopup };
@@ -0,0 +1,16 @@
1
+ import { MenuRadioGroup as MenuRadioGroupPrimitive } from '@base-ui/react/menu';
2
+ import type * as React from 'react';
3
+ /**
4
+ * Public Menu.RadioGroup props.
5
+ *
6
+ * @default No label is rendered.
7
+ */
8
+ export type MenuRadioGroupProps = MenuRadioGroupPrimitive.Props & {
9
+ /**
10
+ * Optional accessible group label rendered with `Menu.GroupLabel`.
11
+ *
12
+ * @default No label is rendered.
13
+ */
14
+ label?: React.ReactNode;
15
+ };
16
+ export declare const MenuRadioGroup: React.FC<MenuRadioGroupProps>;
@@ -0,0 +1,36 @@
1
+ import { clsx } from "../../core/clsx.js";
2
+ import { Text } from "../text/text.js";
3
+ import { Stack } from "../stack/stack.js";
4
+ import menu_module_default from "./menu.module.js";
5
+ import { MenuIndicatorSlot } from "./menu-indicator-slot.js";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { Menu } from "@base-ui/react/menu";
8
+ //#region src/components/menu/menu-radio-group.tsx
9
+ var MenuRadioGroup = ({ children, className, label, ...otherProps }) => /* @__PURE__ */ jsxs(Menu.RadioGroup, {
10
+ ...otherProps,
11
+ className: clsx(menu_module_default.Group, className),
12
+ render: /* @__PURE__ */ jsx(Stack, {
13
+ direction: "column",
14
+ fillChildren: false,
15
+ rowGap: "2x-small",
16
+ vPadding: "2x-small"
17
+ }),
18
+ children: [label && /* @__PURE__ */ jsxs(Menu.GroupLabel, {
19
+ render: /* @__PURE__ */ jsx(Stack, {
20
+ columnGap: "small",
21
+ direction: "row",
22
+ fillChildren: false,
23
+ hPadding: "small",
24
+ vAlign: "center",
25
+ vPadding: ["small", "small"]
26
+ }),
27
+ children: [/* @__PURE__ */ jsx(Text, {
28
+ size: "x-small",
29
+ tone: "muted",
30
+ weight: "semibold",
31
+ children: label
32
+ }), /* @__PURE__ */ jsx(MenuIndicatorSlot, {})]
33
+ }), children]
34
+ });
35
+ //#endregion
36
+ export { MenuRadioGroup };
@@ -0,0 +1,42 @@
1
+ import { MenuRadioItem as MenuRadioItemPrimitive } from '@base-ui/react/menu';
2
+ import { StackProps } from '../stack';
3
+ import type * as React from 'react';
4
+ /**
5
+ * Public Menu.RadioItem props.
6
+ *
7
+ * @default `closeOnClick` is `false`.
8
+ */
9
+ export type MenuRadioItemProps = MenuRadioItemPrimitive.Props & {
10
+ /**
11
+ * Decorative leading node rendered before the item label.
12
+ *
13
+ * @default No addon is rendered.
14
+ */
15
+ 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
+ /**
29
+ * End-aligned secondary text (e.g. keyboard shortcut) before the check indicator.
30
+ * Rendered muted `x-small`.
31
+ *
32
+ * @default No note is rendered.
33
+ */
34
+ note?: React.ReactNode;
35
+ /**
36
+ * Visual sentiment. `destructive` uses highlight-red wash + text.
37
+ *
38
+ * @default Neutral item styling.
39
+ */
40
+ sentiment?: 'destructive';
41
+ };
42
+ export declare const MenuRadioItem: React.FC<MenuRadioItemProps>;
@@ -0,0 +1,28 @@
1
+ import { clsx } from "../../core/clsx.js";
2
+ import { ChromeCheck } from "../../internal/chrome-icons/chrome-icons.js";
3
+ import { Surface } from "../surface/surface.js";
4
+ import menu_module_default from "./menu.module.js";
5
+ import { MenuIndicatorSlot } from "./menu-indicator-slot.js";
6
+ import { MenuItemRow } from "./menu-item-row.js";
7
+ import { jsx } from "react/jsx-runtime";
8
+ import { Menu } from "@base-ui/react/menu";
9
+ //#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, {
11
+ ...otherProps,
12
+ className: clsx(menu_module_default.Item, className),
13
+ closeOnClick,
14
+ ...sentiment && { "data-sentiment": sentiment },
15
+ render: /* @__PURE__ */ jsx(Surface, { radius: "auto" }),
16
+ children: /* @__PURE__ */ jsx(MenuItemRow, {
17
+ addon,
18
+ addonAlign,
19
+ note,
20
+ trailing: /* @__PURE__ */ jsx(MenuIndicatorSlot, {
21
+ kind: "radio",
22
+ children: indicator ?? /* @__PURE__ */ jsx(ChromeCheck, { size: 16 })
23
+ }),
24
+ children
25
+ })
26
+ });
27
+ //#endregion
28
+ export { MenuRadioItem };
@@ -0,0 +1,9 @@
1
+ import { Menu as PrimitiveMenu } from '@base-ui/react/menu';
2
+ import type * as React from 'react';
3
+ /**
4
+ * Public Menu.Separator props.
5
+ *
6
+ * @default `orientation` is `'horizontal'`.
7
+ */
8
+ export type MenuSeparatorProps = React.ComponentProps<typeof PrimitiveMenu.Separator>;
9
+ export declare const MenuSeparator: React.FC<MenuSeparatorProps>;
@@ -0,0 +1,15 @@
1
+ import { Separator } from "../separator/separator.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { Menu } from "@base-ui/react/menu";
4
+ //#region src/components/menu/menu-separator.tsx
5
+ var MenuSeparator = ({ className, orientation = "horizontal", ...otherProps }) => /* @__PURE__ */ jsx(Menu.Separator, {
6
+ render: /* @__PURE__ */ jsx(Separator, {
7
+ vPadding: "x-small",
8
+ hPadding: "x-small"
9
+ }),
10
+ ...otherProps,
11
+ className,
12
+ orientation
13
+ });
14
+ //#endregion
15
+ export { MenuSeparator };
@@ -0,0 +1,29 @@
1
+ import { MenuSubmenuTrigger as MenuSubmenuTriggerPrimitive } from '@base-ui/react/menu';
2
+ import { StackProps } from '../stack';
3
+ import type * as React from 'react';
4
+ /**
5
+ * Public Menu.SubmenuTrigger props.
6
+ *
7
+ * @default Trailing end chevron; RTL mirror via CSS `:dir(rtl)`.
8
+ */
9
+ export type MenuSubmenuTriggerProps = MenuSubmenuTriggerPrimitive.Props & {
10
+ /**
11
+ * Decorative leading node rendered before the item label.
12
+ *
13
+ * @default No addon is rendered.
14
+ */
15
+ 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
+ * Visual sentiment. `destructive` uses highlight-red wash + text.
24
+ *
25
+ * @default Neutral item styling.
26
+ */
27
+ sentiment?: 'destructive';
28
+ };
29
+ export declare const MenuSubmenuTrigger: React.FC<MenuSubmenuTriggerProps>;
@@ -0,0 +1,26 @@
1
+ import { clsx } from "../../core/clsx.js";
2
+ import { ChromeChevronEnd } from "../../internal/chrome-icons/chrome-icons.js";
3
+ import { Surface } from "../surface/surface.js";
4
+ import menu_module_default from "./menu.module.js";
5
+ import { MenuIndicatorSlot } from "./menu-indicator-slot.js";
6
+ import { MenuItemRow } from "./menu-item-row.js";
7
+ import { jsx } from "react/jsx-runtime";
8
+ import { Menu } from "@base-ui/react/menu";
9
+ //#region src/components/menu/menu-submenu-trigger.tsx
10
+ var MenuSubmenuTrigger = ({ addon, addonAlign = "center", children, className, sentiment, ...otherProps }) => /* @__PURE__ */ jsx(Menu.SubmenuTrigger, {
11
+ ...otherProps,
12
+ className: clsx(menu_module_default.Item, className),
13
+ ...sentiment && { "data-sentiment": sentiment },
14
+ render: /* @__PURE__ */ jsx(Surface, { radius: "auto" }),
15
+ children: /* @__PURE__ */ jsx(MenuItemRow, {
16
+ addon,
17
+ addonAlign,
18
+ trailing: /* @__PURE__ */ jsx(MenuIndicatorSlot, {
19
+ kind: "chevron",
20
+ children: /* @__PURE__ */ jsx(ChromeChevronEnd, { size: 16 })
21
+ }),
22
+ children
23
+ })
24
+ });
25
+ //#endregion
26
+ export { MenuSubmenuTrigger };
@@ -0,0 +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%)}}}}
@@ -0,0 +1,58 @@
1
+ import { Menu as PrimitiveMenu, MenuRoot, MenuTrigger as MenuTriggerNamespace } from '@base-ui/react/menu';
2
+ import { MenuCheckboxItem, MenuCheckboxItemProps } from './menu-checkbox-item';
3
+ import { MenuGroup, MenuGroupProps } from './menu-group';
4
+ import { MenuItem, MenuItemProps } from './menu-item';
5
+ import { MenuLinkItem, MenuLinkItemProps } from './menu-link-item';
6
+ import { MenuPopup, MenuPopupProps } from './menu-popup';
7
+ import { MenuRadioGroup, MenuRadioGroupProps } from './menu-radio-group';
8
+ import { MenuRadioItem, MenuRadioItemProps } from './menu-radio-item';
9
+ import { MenuSeparator, MenuSeparatorProps } from './menu-separator';
10
+ import { MenuSubmenuTrigger, MenuSubmenuTriggerProps } from './menu-submenu-trigger';
11
+ import type * as React from 'react';
12
+ /**
13
+ * Public Menu root props.
14
+ *
15
+ * Pass-through to Base UI `Menu.Root`. Supports `open`/`defaultOpen`/`onOpenChange`,
16
+ * `modal`, `triggerId` for controlled activation, and `handle` for detached/multiple
17
+ * triggers. `children` may be a node or a `({ payload }) => ReactNode` render function
18
+ * for per-trigger content.
19
+ *
20
+ * @default Base UI pass-through props keep upstream defaults.
21
+ */
22
+ export type MenuProps = MenuRoot.Props;
23
+ /**
24
+ * Public Menu.Trigger props.
25
+ *
26
+ * Pass-through to Base UI `Menu.Trigger`. Use `render` for the visible control
27
+ * (`Button`, `IconButton`, or another element).
28
+ *
29
+ * @default Base UI pass-through props keep upstream defaults.
30
+ */
31
+ export type MenuTriggerProps = MenuTriggerNamespace.Props;
32
+ /**
33
+ * Public Menu.Submenu props.
34
+ *
35
+ * Pass-through to Base UI `Menu.SubmenuRoot`. Compose `Menu.SubmenuTrigger` and
36
+ * nested `Menu.Popup` as children.
37
+ *
38
+ * @default Base UI pass-through props keep upstream defaults.
39
+ */
40
+ export type MenuSubmenuProps = React.ComponentProps<typeof PrimitiveMenu.SubmenuRoot>;
41
+ export declare const MenuTrigger: PrimitiveMenu.Trigger;
42
+ export declare const MenuSubmenu: typeof PrimitiveMenu.SubmenuRoot;
43
+ type MenuComponent = React.FC<MenuProps> & {
44
+ Trigger: typeof PrimitiveMenu.Trigger;
45
+ Popup: React.FC<MenuPopupProps>;
46
+ Item: React.FC<MenuItemProps>;
47
+ LinkItem: React.FC<MenuLinkItemProps>;
48
+ CheckboxItem: React.FC<MenuCheckboxItemProps>;
49
+ RadioItem: React.FC<MenuRadioItemProps>;
50
+ RadioGroup: React.FC<MenuRadioGroupProps>;
51
+ Group: React.FC<MenuGroupProps>;
52
+ Separator: React.FC<MenuSeparatorProps>;
53
+ Submenu: typeof PrimitiveMenu.SubmenuRoot;
54
+ SubmenuTrigger: React.FC<MenuSubmenuTriggerProps>;
55
+ createHandle: typeof PrimitiveMenu.createHandle;
56
+ };
57
+ export declare const Menu: MenuComponent;
58
+ export { MenuCheckboxItem, MenuGroup, MenuItem, MenuLinkItem, MenuPopup, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuSubmenuTrigger, };
@@ -0,0 +1,101 @@
1
+ {
2
+ "name": "Menu",
3
+ "structure": "<Menu>\n <Menu.Trigger />\n <Menu.Popup>\n <Menu.Item />\n <Menu.LinkItem />\n <Menu.CheckboxItem />\n <Menu.Group label=\"…\">\n <Menu.Item />\n </Menu.Group>\n <Menu.RadioGroup>\n <Menu.RadioItem value=\"…\" />\n </Menu.RadioGroup>\n <Menu.Separator />\n <Menu.Submenu>\n <Menu.SubmenuTrigger />\n <Menu.Popup>…</Menu.Popup>\n </Menu.Submenu>\n </Menu.Popup>\n</Menu>",
4
+ "summary": "Compound menu built on Base UI Menu with `Menu.Trigger`, `Menu.Popup`, unified item rows, groups, checkbox/radio items, nested submenus, destructive sentiment, and `Menu.createHandle` for detached triggers; `Popup` owns Portal + Positioner + Elevator/Surface Select-like list chrome.",
5
+ "whenToUse": [
6
+ "Action menus anchored to a button or icon button",
7
+ "Nested command lists with checkbox or radio options that stay open on toggle",
8
+ "Link rows mixed with actions in one menu surface",
9
+ "Detached or multi-trigger menus via `Menu.createHandle`"
10
+ ],
11
+ "whenNotToUse": [
12
+ "Page-blocking modal flows (use Dialog)",
13
+ "Form field single-select from a long list (use Select)",
14
+ "Context menu or menubar chrome (not in this surface)",
15
+ "System-wide transient alerts (use Toast)"
16
+ ],
17
+ "accessibility": [
18
+ "Give the trigger an accessible name (`Button` label or `aria-label` on IconButton)",
19
+ "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"
21
+ ],
22
+ "antiPatterns": [
23
+ "Expecting `Menu.Arrow`, `Menu.Backdrop`, or public Portal/Positioner/Viewport exports",
24
+ "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"
26
+ ],
27
+ "related": ["Button", "IconButton", "Select", "Popover", "Tooltip", "Surface", "Stack"],
28
+ "properties": {
29
+ "react": {
30
+ "CheckboxItem.addon": {
31
+ "description": "Decorative leading node rendered before the item label."
32
+ },
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
+ "CheckboxItem.note": {
40
+ "description": "End-aligned secondary text (e.g. keyboard shortcut) before the check indicator. Rendered muted `x-small`."
41
+ },
42
+ "CheckboxItem.sentiment": {
43
+ "description": "Visual sentiment. `destructive` uses highlight-red wash + text."
44
+ },
45
+ "Group.label": {
46
+ "description": "Accessible group label rendered with `Menu.GroupLabel`."
47
+ },
48
+ "Item.addon": {
49
+ "description": "Decorative leading node rendered before the item label."
50
+ },
51
+ "Item.addonAlign": {
52
+ "description": "Vertical alignment of the addon relative to the label row."
53
+ },
54
+ "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)."
56
+ },
57
+ "Item.sentiment": {
58
+ "description": "Visual sentiment. `destructive` uses highlight-red wash + text."
59
+ },
60
+ "LinkItem.addon": {
61
+ "description": "Decorative leading node rendered before the item label."
62
+ },
63
+ "LinkItem.addonAlign": {
64
+ "description": "Vertical alignment of the addon relative to the label row."
65
+ },
66
+ "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)."
68
+ },
69
+ "LinkItem.sentiment": {
70
+ "description": "Visual sentiment. `destructive` uses highlight-red wash + text."
71
+ },
72
+ "RadioGroup.label": {
73
+ "description": "Optional accessible group label rendered with `Menu.GroupLabel`."
74
+ },
75
+ "RadioItem.addon": {
76
+ "description": "Decorative leading node rendered before the item label."
77
+ },
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
+ "RadioItem.note": {
85
+ "description": "End-aligned secondary text (e.g. keyboard shortcut) before the check indicator. Rendered muted `x-small`."
86
+ },
87
+ "RadioItem.sentiment": {
88
+ "description": "Visual sentiment. `destructive` uses highlight-red wash + text."
89
+ },
90
+ "SubmenuTrigger.addon": {
91
+ "description": "Decorative leading node rendered before the item label."
92
+ },
93
+ "SubmenuTrigger.addonAlign": {
94
+ "description": "Vertical alignment of the addon relative to the label row."
95
+ },
96
+ "SubmenuTrigger.sentiment": {
97
+ "description": "Visual sentiment. `destructive` uses highlight-red wash + text."
98
+ }
99
+ }
100
+ }
101
+ }
@@ -0,0 +1,36 @@
1
+ import './menu.css';
2
+ import { MenuCheckboxItem } from "./menu-checkbox-item.js";
3
+ import { MenuGroup } from "./menu-group.js";
4
+ import { MenuItem } from "./menu-item.js";
5
+ import { MenuLinkItem } from "./menu-link-item.js";
6
+ import { MenuPopup } from "./menu-popup.js";
7
+ import { MenuRadioGroup } from "./menu-radio-group.js";
8
+ import { MenuRadioItem } from "./menu-radio-item.js";
9
+ import { MenuSeparator } from "./menu-separator.js";
10
+ import { MenuSubmenuTrigger } from "./menu-submenu-trigger.js";
11
+ import { jsx } from "react/jsx-runtime";
12
+ import { Menu } from "@base-ui/react/menu";
13
+ //#region src/components/menu/menu.tsx
14
+ var MenuTrigger = Menu.Trigger;
15
+ var MenuSubmenu = Menu.SubmenuRoot;
16
+ var MenuRootComponent = ({ children, ...otherProps }) => /* @__PURE__ */ jsx(Menu.Root, {
17
+ ...otherProps,
18
+ children
19
+ });
20
+ var { Arrow: _MenuArrow, Backdrop: _MenuBackdrop, Portal: _MenuPortal, Positioner: _MenuPositioner, Popup: _MenuPopup, Viewport: _MenuViewport, CheckboxItemIndicator: _MenuCheckboxItemIndicator, RadioItemIndicator: _MenuRadioItemIndicator, GroupLabel: _MenuGroupLabel } = Menu;
21
+ var Menu$1 = Object.assign(MenuRootComponent, {
22
+ Trigger: Menu.Trigger,
23
+ Popup: MenuPopup,
24
+ Item: MenuItem,
25
+ LinkItem: MenuLinkItem,
26
+ CheckboxItem: MenuCheckboxItem,
27
+ RadioItem: MenuRadioItem,
28
+ RadioGroup: MenuRadioGroup,
29
+ Group: MenuGroup,
30
+ Separator: MenuSeparator,
31
+ Submenu: Menu.SubmenuRoot,
32
+ SubmenuTrigger: MenuSubmenuTrigger,
33
+ createHandle: Menu.createHandle
34
+ });
35
+ //#endregion
36
+ export { Menu$1 as Menu, MenuCheckboxItem, MenuGroup, MenuItem, MenuLinkItem, MenuPopup, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuSubmenu, MenuSubmenuTrigger, MenuTrigger };
@@ -0,0 +1,13 @@
1
+ //#region src/components/menu/menu.module.css
2
+ var MenuPopup = "viraui__menu-module__MenuPopup_GkrGa";
3
+ var Indicator = "viraui__menu-module__Indicator_btL99";
4
+ var Group = "viraui__menu-module__Group_Orz5Y";
5
+ var Item = "viraui__menu-module__Item_9zmEO";
6
+ var menu_module_default = {
7
+ MenuPopup,
8
+ Indicator,
9
+ Group,
10
+ Item
11
+ };
12
+ //#endregion
13
+ export { Group, Indicator, Item, MenuPopup, menu_module_default as default };
@@ -25,15 +25,26 @@
25
25
  ],
26
26
  "related": ["LinearProgress", "Slider", "Text"],
27
27
  "properties": {
28
+ "react": {
29
+ "description": {
30
+ "description": "Static helper copy rendered with `Text` below the meter track."
31
+ },
32
+ "label": {
33
+ "description": "Visible label rendered through `Meter.Label` with shared internal `FieldLabel`."
34
+ },
35
+ "showValue": {
36
+ "description": "Renders the formatted current value via `Meter.Value` and `Text`."
37
+ }
38
+ },
28
39
  "css": {
29
- "track-size": {
30
- "description": "Meter track thickness on the root."
40
+ "indicator-color": {
41
+ "description": "Determinate meter indicator color."
31
42
  },
32
43
  "track-background": {
33
44
  "description": "Meter track background color."
34
45
  },
35
- "indicator-color": {
36
- "description": "Determinate meter indicator color."
46
+ "track-size": {
47
+ "description": "Meter track thickness on the root."
37
48
  }
38
49
  }
39
50
  }
@@ -43,7 +43,6 @@ var Meter$1 = ({ className, description, label, showValue = false, value, ...oth
43
43
  children: /* @__PURE__ */ jsx(Meter.Indicator, { className: meter_module_default.Indicator })
44
44
  }),
45
45
  description && /* @__PURE__ */ jsx(Text, {
46
- className: meter_module_default.Description,
47
46
  size: "small",
48
47
  tone: "muted",
49
48
  children: description
@@ -2,8 +2,8 @@ import { ChromeXmark } from "../../internal/chrome-icons/chrome-icons.js";
2
2
  import { Text } from "../text/text.js";
3
3
  import { Stack } from "../stack/stack.js";
4
4
  import { IconButton } from "../icon-button/icon-button.js";
5
- import popover_module_default from "./popover.module.js";
6
5
  import { Surface } from "../surface/surface.js";
6
+ import popover_module_default from "./popover.module.js";
7
7
  import { Title } from "../title/title.js";
8
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
9
  import { Popover } from "@base-ui/react/popover";
@@ -25,5 +25,29 @@
25
25
  "Rendering heavy or scroll-bound content that belongs in a Dialog",
26
26
  "Expecting `Popover.Arrow` (it is intentionally not exported or rendered)"
27
27
  ],
28
- "related": ["Surface", "Button", "IconButton", "Stack", "Dialog", "Tabs"]
28
+ "related": ["Surface", "Button", "IconButton", "Stack", "Dialog", "Tabs"],
29
+ "properties": {
30
+ "react": {
31
+ "Sheet.description": {
32
+ "description": "Supporting copy announced with the title."
33
+ },
34
+ "Sheet.headerAlign": {
35
+ "description": "Aligns the header content."
36
+ },
37
+ "Sheet.showCloseButton": {
38
+ "description": "Whether to show the built-in flat IconButton close control."
39
+ },
40
+ "Sheet.title": {
41
+ "description": "Accessible popover title rendered as the popup heading."
42
+ },
43
+ "Sheet.unstyled": {
44
+ "description": "Whether to skip the built-in Surface, header, and close chrome and render only the positioning/animation shell (Portal + Positioner + Popup + Viewport)."
45
+ }
46
+ },
47
+ "css": {
48
+ "content-fade-duration": {
49
+ "description": "content fade duration custom property on the component root."
50
+ }
51
+ }
52
+ }
29
53
  }
@@ -1 +1 @@
1
- @layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-progressive-blur-amount{syntax:"<length>";inherits:true;initial-value:16px}.viraui__progressive-blur-module__ProgressiveBlur_eIxTK{pointer-events:none}.viraui__progressive-blur-module__Layer_zbzMS{position:absolute;inset:0;backdrop-filter:blur(calc(var(--vui-progressive-blur-amount) * var(--progressive-blur-factor)));mask-image:var(--progressive-blur-mask-image);.viraui__progressive-blur-module__ProgressiveBlur_eIxTK[data-direction=top] &{--progressive-blur-mask-image:linear-gradient(to top,var(--progressive-blur-mask-gradient))}.viraui__progressive-blur-module__ProgressiveBlur_eIxTK[data-direction=right] &{--progressive-blur-mask-image:linear-gradient(to right,var(--progressive-blur-mask-gradient))}.viraui__progressive-blur-module__ProgressiveBlur_eIxTK[data-direction=bottom] &{--progressive-blur-mask-image:linear-gradient(to bottom,var(--progressive-blur-mask-gradient))}.viraui__progressive-blur-module__ProgressiveBlur_eIxTK[data-direction=left] &{--progressive-blur-mask-image:linear-gradient(to left,var(--progressive-blur-mask-gradient))}}}
1
+ @layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-progressive-blur-amount{syntax:"<length>";inherits:true;initial-value:16px}@property --__progressive-blur-factor{syntax:"<number>";inherits:false;initial-value:1}@property --__progressive-blur-mask-image{syntax:"<image>";inherits:false;initial-value:linear-gradient(#0000,#0000)}@property --__progressive-blur-mask-gradient{syntax:"*";inherits:false;initial-value:#0000}.viraui__progressive-blur-module__ProgressiveBlur_eIxTK{pointer-events:none;&[data-direction=top]{& .viraui__progressive-blur-module__Layer_zbzMS{--__progressive-blur-mask-image:linear-gradient(to top,var(--__progressive-blur-mask-gradient))}}&[data-direction=right]{& .viraui__progressive-blur-module__Layer_zbzMS{--__progressive-blur-mask-image:linear-gradient(to right,var(--__progressive-blur-mask-gradient))}}&[data-direction=bottom]{& .viraui__progressive-blur-module__Layer_zbzMS{--__progressive-blur-mask-image:linear-gradient(to bottom,var(--__progressive-blur-mask-gradient))}}&[data-direction=left]{& .viraui__progressive-blur-module__Layer_zbzMS{--__progressive-blur-mask-image:linear-gradient(to left,var(--__progressive-blur-mask-gradient))}}}.viraui__progressive-blur-module__Layer_zbzMS{position:absolute;inset:0;backdrop-filter:blur(calc(var(--vui-progressive-blur-amount) * var(--__progressive-blur-factor)));mask-image:var(--__progressive-blur-mask-image)}}