@viraui/react 2026.0.8 → 2026.0.10
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.
- package/dist/catalog.json +2 -2
- package/dist/components/accordion/accordion-item.d.ts +7 -0
- package/dist/components/accordion/accordion-item.js +7 -1
- package/dist/components/accordion/accordion.css +1 -1
- package/dist/components/accordion/accordion.guide.json +9 -0
- package/dist/components/autocomplete/autocomplete.guide.json +1 -0
- package/dist/components/avatar/avatar.guide.json +1 -0
- package/dist/components/button/button.guide.json +1 -0
- package/dist/components/checkbox/checkbox.guide.json +1 -0
- package/dist/components/dialog/dialog.guide.json +1 -0
- package/dist/components/fieldset/fieldset.guide.json +1 -0
- package/dist/components/linear-progress/linear-progress.guide.json +1 -0
- package/dist/components/menu/menu.guide.json +1 -0
- package/dist/components/meter/meter.guide.json +1 -0
- package/dist/components/popover/popover.guide.json +1 -0
- package/dist/components/radio/radio.guide.json +1 -0
- package/dist/components/select/select.guide.json +4 -1
- package/dist/components/slider/slider.guide.json +1 -0
- package/dist/components/stack/stack.css +1 -1
- package/dist/components/stack/stack.d.ts +12 -0
- package/dist/components/stack/stack.guide.json +7 -3
- package/dist/components/stack/stack.js +2 -1
- package/dist/components/surface/surface.css +1 -1
- package/dist/components/surface/surface.d.ts +12 -0
- package/dist/components/surface/surface.guide.json +5 -2
- package/dist/components/surface/surface.js +2 -1
- package/dist/components/switch/switch.guide.json +1 -0
- package/dist/components/tabs/tabs.guide.json +1 -0
- package/dist/components/textarea/textarea.guide.json +1 -0
- package/dist/components/textfield/textfield.guide.json +1 -0
- package/dist/components/toast/toast.guide.json +1 -0
- package/dist/components/toggle-button/toggle-button.guide.json +1 -0
- package/dist/components/toggle-group/toggle-group.guide.json +1 -0
- package/dist/components/tooltip/tooltip.guide.json +1 -0
- package/package.json +2 -2
package/dist/catalog.json
CHANGED
|
@@ -185,7 +185,7 @@
|
|
|
185
185
|
{
|
|
186
186
|
"id": "stack",
|
|
187
187
|
"name": "Stack",
|
|
188
|
-
"summary": "Flex layout primitive for arranging children with token spacing, alignment, and padding;
|
|
188
|
+
"summary": "Flex layout primitive for arranging children with token spacing, alignment, and padding; optionally enables a named CSS container query context (`stack`) via `enableContainer`.",
|
|
189
189
|
"guidePath": "./components/stack/stack.guide.json"
|
|
190
190
|
},
|
|
191
191
|
{
|
|
@@ -197,7 +197,7 @@
|
|
|
197
197
|
{
|
|
198
198
|
"id": "surface",
|
|
199
199
|
"name": "Surface",
|
|
200
|
-
"summary": "Presentational container with token background, optional border, radius, and padding; nested surfaces use radius=\"auto\" for concentric corners;
|
|
200
|
+
"summary": "Presentational container with token background, optional border, radius, and padding; nested surfaces use radius=\"auto\" for concentric corners; optionally enables a named CSS container query context (`surface`) via `enableContainer`.",
|
|
201
201
|
"guidePath": "./components/surface/surface.guide.json"
|
|
202
202
|
},
|
|
203
203
|
{
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AccordionItem } from '@base-ui/react/accordion';
|
|
2
2
|
import { SurfaceProps } from '../surface';
|
|
3
|
+
import { ThemeTypes } from '@viraui/foundation/vira/types';
|
|
3
4
|
import type * as React from 'react';
|
|
4
5
|
/**
|
|
5
6
|
* Public Accordion.Item props.
|
|
@@ -54,5 +55,11 @@ export type AccordionItemProps = AccordionItem.Props & {
|
|
|
54
55
|
* @default 1
|
|
55
56
|
*/
|
|
56
57
|
color?: SurfaceProps['color'];
|
|
58
|
+
/**
|
|
59
|
+
* Corner radius token for the wrapping `Surface` island edges when `useSurface` is `true`.
|
|
60
|
+
*
|
|
61
|
+
* @default medium
|
|
62
|
+
*/
|
|
63
|
+
radius?: ThemeTypes['radius'];
|
|
57
64
|
};
|
|
58
65
|
export declare const AccordionItemComponent: React.FC<AccordionItemProps>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { clsx } from "../../core/clsx.js";
|
|
2
|
+
import { resolveThemeValue } from "../../core/theme/resolve-theme-value.js";
|
|
2
3
|
import { ChromeMinus, ChromePlus } from "../../internal/chrome-icons/chrome-icons.js";
|
|
3
4
|
import accordion_module_default from "./accordion.module.js";
|
|
4
5
|
import { Text } from "../text/text.js";
|
|
@@ -7,8 +8,12 @@ import { Surface } from "../surface/surface.js";
|
|
|
7
8
|
import { Accordion } from "@base-ui/react/accordion";
|
|
8
9
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
10
|
//#region src/components/accordion/accordion-item.tsx
|
|
10
|
-
var AccordionItemComponent = ({ children, className, color = 1, iconClosed = /* @__PURE__ */ jsx(ChromePlus, { size: 16 }), iconOpen = /* @__PURE__ */ jsx(ChromeMinus, { size: 16 }), iconPosition = "end", trigger, useSurface = true, ...otherProps }) => {
|
|
11
|
+
var AccordionItemComponent = ({ children, className, color = 1, iconClosed = /* @__PURE__ */ jsx(ChromePlus, { size: 16 }), iconOpen = /* @__PURE__ */ jsx(ChromeMinus, { size: 16 }), iconPosition = "end", radius, style, trigger, useSurface = true, ...otherProps }) => {
|
|
11
12
|
const iconAtStart = iconPosition === "start";
|
|
13
|
+
const dynamicStyle = {
|
|
14
|
+
...radius != null && { "--vui-accordion-radius": resolveThemeValue(radius, "radius", "var(--radius-medium)") },
|
|
15
|
+
...style
|
|
16
|
+
};
|
|
12
17
|
const triggerIcon = /* @__PURE__ */ jsxs("span", {
|
|
13
18
|
"aria-hidden": true,
|
|
14
19
|
className: accordion_module_default.IconSlot,
|
|
@@ -23,6 +28,7 @@ var AccordionItemComponent = ({ children, className, color = 1, iconClosed = /*
|
|
|
23
28
|
return /* @__PURE__ */ jsxs(Accordion.Item, {
|
|
24
29
|
className: clsx(accordion_module_default.Item, className),
|
|
25
30
|
"data-use-surface": useSurface ? "true" : "false",
|
|
31
|
+
style: dynamicStyle,
|
|
26
32
|
...useSurface && { render: /* @__PURE__ */ jsx(Surface, {
|
|
27
33
|
border: "all",
|
|
28
34
|
color
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-accordion-island-gap{syntax:"<length>";inherits:true;initial-value:0}@property --
|
|
1
|
+
@layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-accordion-island-gap{syntax:"<length>";inherits:true;initial-value:0}@property --vui-accordion-radius{syntax:"<length-percentage>";inherits:true;initial-value:0}.viraui__accordion-module__Accordion_wFOlN{--vui-accordion-island-gap:var(--space-medium);--vui-accordion-radius:var(--radius-medium);inline-size:100%;&:dir(rtl) .viraui__accordion-module__Trigger_4HzIb[data-stack-direction=row-reverse]{direction:ltr;flex-direction:row}}.viraui__accordion-module__Trigger_4HzIb{inline-size:100%;border:0;background:#0000;cursor:pointer;text-align:start;color:inherit;&:focus-visible{outline-offset:-4px}&[data-disabled]{cursor:not-allowed;opacity:.5}.viraui__accordion-module__Item_66o2x[data-use-surface=true] &{&:focus-visible{border-radius:var(--radius-large);outline-offset:-4px}}}.viraui__accordion-module__IconSlot_AVQq3{position:relative;flex-shrink:0;inline-size:1rem;block-size:1rem}.viraui__accordion-module__Icon_qdu2v{position:absolute;inset:0;display:grid;place-items:center;transition:opacity var(--duration-fast) var(--easing-standard),rotate var(--duration-fast) var(--easing-standard);&:first-of-type{opacity:1;rotate:0deg}&:last-of-type{opacity:0;rotate:-90deg}.viraui__accordion-module__Trigger_4HzIb[data-panel-open] &:first-of-type{opacity:0;rotate:90deg}.viraui__accordion-module__Trigger_4HzIb[data-panel-open] &:last-of-type{opacity:1;rotate:0deg}@media (prefers-reduced-motion:reduce){transition:none}}.viraui__accordion-module__Panel_U1Ofk{block-size:var(--accordion-panel-height);overflow:hidden;transition:block-size var(--duration-fast) var(--easing-standard);&[data-ending-style],&[data-starting-style]{block-size:0}@media (prefers-reduced-motion:reduce){transition:none}}}@layer viraui.overrides{.viraui__accordion-module__Item_66o2x{inline-size:100%;transition:margin var(--duration-fast) var(--easing-standard),background var(--duration-fast) var(--easing-standard),border-radius var(--duration-fast) var(--easing-standard);&[data-use-surface=true]{--vui-surface-border-radius-top-left:0;--vui-surface-border-radius-top-right:0;--vui-surface-border-radius-bottom-right:0;--vui-surface-border-radius-bottom-left:0;&:not([data-open]){--vui-surface-background:#0000}&:not([data-open])+&:not([data-open]),&[data-open]+&[data-open]{border-top-width:0}&:first-child,&:not([data-open])+&[data-open],&[data-open]+&:not([data-open]){--vui-surface-border-radius-top-left:var(--vui-accordion-radius);--vui-surface-border-radius-top-right:var(--vui-accordion-radius)}&:last-child,&:not([data-open]):has(+&[data-open]),&[data-open]:has(+&:not([data-open])){--vui-surface-border-radius-bottom-left:var(--vui-accordion-radius);--vui-surface-border-radius-bottom-right:var(--vui-accordion-radius)}&:not(:last-child):not([data-open]):has(+&[data-open]),&:not(:last-child)[data-open]:has(+&:not([data-open])){margin-block-end:var(--vui-accordion-island-gap)}}.viraui__accordion-module__Accordion_wFOlN[data-islands=false] &[data-use-surface=true]{&:not(:first-child){border-top-width:0}&:not([data-open])+&[data-open],&[data-open]+&:not([data-open]){--vui-surface-border-radius-top-left:0;--vui-surface-border-radius-top-right:0}&:not([data-open]):has(+&[data-open]),&[data-open]:has(+&:not([data-open])){--vui-surface-border-radius-bottom-left:0;--vui-surface-border-radius-bottom-right:0}&:not(:last-child):not([data-open]):has(+&[data-open]),&:not(:last-child)[data-open]:has(+&:not([data-open])){margin-block-end:0}}}}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "Accordion",
|
|
3
|
+
"baseUIApi": "https://base-ui.com/react/components/accordion#api-reference",
|
|
3
4
|
"structure": "<Accordion>\n <Accordion.Item trigger=\"…\">…</Accordion.Item>\n</Accordion>",
|
|
4
5
|
"summary": "Collapsible sections grouped into open/closed blocks with optional Surface wrapping, shared corner radius, and background on open items.",
|
|
5
6
|
"whenToUse": [
|
|
@@ -41,6 +42,10 @@
|
|
|
41
42
|
"Item.iconPosition": {
|
|
42
43
|
"description": "Side of the trigger label where the expand/collapse icon is rendered."
|
|
43
44
|
},
|
|
45
|
+
"Item.radius": {
|
|
46
|
+
"description": "Corner radius token for the wrapping Surface island edges when useSurface is true.",
|
|
47
|
+
"refCss": "radius"
|
|
48
|
+
},
|
|
44
49
|
"Item.trigger": {
|
|
45
50
|
"description": "Visible trigger label rendered inside the accordion header button."
|
|
46
51
|
},
|
|
@@ -51,6 +56,10 @@
|
|
|
51
56
|
"css": {
|
|
52
57
|
"island-gap": {
|
|
53
58
|
"description": "Gap between separated Surface islands when islands={true}."
|
|
59
|
+
},
|
|
60
|
+
"radius": {
|
|
61
|
+
"description": "Corner radius for Surface island block edges when useSurface is true.",
|
|
62
|
+
"refReact": "Item.radius"
|
|
54
63
|
}
|
|
55
64
|
}
|
|
56
65
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "Autocomplete",
|
|
3
|
+
"baseUIApi": "https://base-ui.com/react/components/autocomplete#api-reference",
|
|
3
4
|
"structure": "<Autocomplete>\n <Autocomplete.Item value=\"…\">…</Autocomplete.Item>\n <Autocomplete.Group label=\"…\" items={[…]}>\n <Autocomplete.Collection>\n {(item) => <Autocomplete.Item value={item}>…</Autocomplete.Item>}\n </Autocomplete.Collection>\n </Autocomplete.Group>\n</Autocomplete>",
|
|
4
5
|
"summary": "Field-wrapped free-form suggest input with Textfield chrome and Select-like popup list.",
|
|
5
6
|
"whenToUse": [
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "Dialog",
|
|
3
|
+
"baseUIApi": "https://base-ui.com/react/components/drawer#api-reference",
|
|
3
4
|
"structure": "<Dialog>\n <Dialog.Trigger />\n <Dialog.Sheet title=\"…\">…</Dialog.Sheet>\n</Dialog>",
|
|
4
5
|
"summary": "Compound drawer sheet with `Dialog.Trigger`, `Dialog.Sheet`, `Dialog.Close`, and Base UI pass-through `Dialog.Provider`, `Dialog.Indent`, and `Dialog.IndentBackground` for app-shell indent effects.",
|
|
5
6
|
"whenToUse": [
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "LinearProgress",
|
|
3
|
+
"baseUIApi": "https://base-ui.com/react/components/progress#api-reference",
|
|
3
4
|
"structure": "<LinearProgress value={40} />",
|
|
4
5
|
"summary": "Shows determinate or indeterminate progress for a task in a compact horizontal track.",
|
|
5
6
|
"whenToUse": [
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "Menu",
|
|
3
|
+
"baseUIApi": "https://base-ui.com/react/components/menu#api-reference",
|
|
3
4
|
"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
5
|
"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
6
|
"whenToUse": [
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "Popover",
|
|
3
|
+
"baseUIApi": "https://base-ui.com/react/components/popover#api-reference",
|
|
3
4
|
"structure": "<Popover>\n <Popover.Trigger />\n <Popover.Sheet title=\"…\">…</Popover.Sheet>\n</Popover>",
|
|
4
5
|
"summary": "Compound popover built on Base UI Popover with `Popover.Trigger`, `Popover.Sheet`, `Popover.Close`, `Popover.Title`, `Popover.Description`, and `Popover.createHandle` for detached and multiple triggers; `Sheet` encapsulates Portal + Positioner + Popup + Viewport + Title + Description and animates position, size, and content between triggers; `Sheet` with `unstyled` skips the built-in Surface and header so the consumer composes the popup chrome, including `Popover.Title` and `Popover.Description`.",
|
|
5
6
|
"whenToUse": [
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "Radio",
|
|
3
|
+
"baseUIApi": "https://base-ui.com/react/components/radio#api-reference",
|
|
3
4
|
"structure": "<RadioGroup>\n <Radio value=\"…\" label=\"…\" />\n</RadioGroup>",
|
|
4
5
|
"summary": "Mutually exclusive choice within a RadioGroup, with optional per-option label and helper text.",
|
|
5
6
|
"whenToUse": [
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "Select",
|
|
3
|
+
"baseUIApi": "https://base-ui.com/react/components/select#api-reference",
|
|
3
4
|
"structure": "<Select>\n <Select.Option value=\"…\">…</Select.Option>\n <Select.Group label=\"…\">\n <Select.Option value=\"…\">…</Select.Option>\n </Select.Group>\n <Select.Separator />\n</Select>",
|
|
4
5
|
"summary": "Field-wrapped single-select dropdown with grouped options and field copy.",
|
|
5
6
|
"whenToUse": [
|
|
@@ -23,7 +24,9 @@
|
|
|
23
24
|
"antiPatterns": [
|
|
24
25
|
"Expecting multi-select or combobox behavior",
|
|
25
26
|
"Leaving the trigger without label or aria-label",
|
|
26
|
-
"Never set the size prop (if present) of Buttons, IconButtons or other interactive elements passed as addon other than small"
|
|
27
|
+
"Never set the size prop (if present) of Buttons, IconButtons or other interactive elements passed as addon other than small",
|
|
28
|
+
"Using the Select component as a combobox, use Autocomplete instead.",
|
|
29
|
+
"Set alignItemWithTrigger false when options don't have a leading addon"
|
|
27
30
|
],
|
|
28
31
|
"related": ["Autocomplete", "Fieldset", "Textfield", "Stack", "Surface", "Icon"],
|
|
29
32
|
"properties": {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-stack-row-gap{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-column-gap{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-h-align{syntax:"*";inherits:false;initial-value:initial}@property --vui-stack-v-align{syntax:"*";inherits:false;initial-value:initial}@property --vui-stack-padding-inline-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-padding-inline-end{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-padding-block-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-padding-block-end{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-max-width{syntax:"*";inherits:false;initial-value:none}@property --vui-stack-min-width{syntax:"*";inherits:false;initial-value:none}.viraui__stack-module__Stack_NR-Ey{display:flex;gap:var(--vui-stack-row-gap) var(--vui-stack-column-gap);flex-direction:column;align-items:var(--vui-stack-h-align);justify-content:var(--vui-stack-v-align);max-inline-size:var(--vui-stack-max-width);min-inline-size:var(--vui-stack-min-width);&[data-stack-direction=column-reverse]{flex-direction:column-reverse}&[data-stack-direction=row-reverse],&[data-stack-direction=row]{align-items:var(--vui-stack-v-align);justify-content:var(--vui-stack-h-align)}&[data-stack-direction=row]{flex-direction:row}&[data-stack-direction=row-reverse]{flex-direction:row-reverse}&[data-stack-inline=true]{display:inline-flex;flex-grow:0}:where(&[data-stack-wrap=true]){flex-wrap:wrap}:where(&[data-stack-has-padding=true]){padding:var(--vui-stack-padding-block-start) var(--vui-stack-padding-inline-end) var(--vui-stack-padding-block-end) var(--vui-stack-padding-inline-start)}:where(&[data-stack-fill-children=true]>*){flex-grow:var(--vira-flex-grow,1)}}}
|
|
1
|
+
@layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-stack-row-gap{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-column-gap{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-h-align{syntax:"*";inherits:false;initial-value:initial}@property --vui-stack-v-align{syntax:"*";inherits:false;initial-value:initial}@property --vui-stack-padding-inline-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-padding-inline-end{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-padding-block-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-padding-block-end{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-max-width{syntax:"*";inherits:false;initial-value:none}@property --vui-stack-min-width{syntax:"*";inherits:false;initial-value:none}.viraui__stack-module__Stack_NR-Ey{display:flex;gap:var(--vui-stack-row-gap) var(--vui-stack-column-gap);flex-direction:column;align-items:var(--vui-stack-h-align);justify-content:var(--vui-stack-v-align);max-inline-size:var(--vui-stack-max-width);min-inline-size:var(--vui-stack-min-width);&[data-stack-direction=column-reverse]{flex-direction:column-reverse}&[data-stack-direction=row-reverse],&[data-stack-direction=row]{align-items:var(--vui-stack-v-align);justify-content:var(--vui-stack-h-align)}&[data-stack-direction=row]{flex-direction:row}&[data-stack-direction=row-reverse]{flex-direction:row-reverse}&[data-stack-inline=true]{display:inline-flex;flex-grow:0}:where(&[data-stack-wrap=true]){flex-wrap:wrap}:where(&[data-stack-has-padding=true]){padding:var(--vui-stack-padding-block-start) var(--vui-stack-padding-inline-end) var(--vui-stack-padding-block-end) var(--vui-stack-padding-inline-start)}:where(&[data-stack-fill-children=true]>*){flex-grow:var(--vira-flex-grow,1)}&[data-stack-container=true]{container:stack/size}}}
|
|
@@ -97,6 +97,18 @@ export type StackProps = React.ComponentPropsWithoutRef<'div'> & {
|
|
|
97
97
|
* @default No min width constraint.
|
|
98
98
|
*/
|
|
99
99
|
minWidth?: string;
|
|
100
|
+
/**
|
|
101
|
+
* Opt-in named CSS container query context for this Stack.
|
|
102
|
+
*
|
|
103
|
+
* Enables `container: stack / size` on the rendered root (via `data-stack-container="true"`),
|
|
104
|
+
* so descendants can use `@container stack (min-width/min-height: ...)` against this Stack size.
|
|
105
|
+
*
|
|
106
|
+
* Warning: container size containment can affect nested layout (e.g. cards inside Masonry).
|
|
107
|
+
* Use only when you need container queries against this specific Stack.
|
|
108
|
+
*
|
|
109
|
+
* @default false
|
|
110
|
+
*/
|
|
111
|
+
enableContainer?: boolean;
|
|
100
112
|
};
|
|
101
113
|
export declare const Stack: React.FC<StackProps>;
|
|
102
114
|
export {};
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "Stack",
|
|
3
3
|
"structure": "<Stack>…</Stack>",
|
|
4
|
-
"summary": "Flex layout primitive for arranging children with token spacing, alignment, and padding;
|
|
4
|
+
"summary": "Flex layout primitive for arranging children with token spacing, alignment, and padding; optionally enables a named CSS container query context (`stack`) via `enableContainer`.",
|
|
5
5
|
"whenToUse": [
|
|
6
6
|
"Column or row layouts with token gap and alignment",
|
|
7
7
|
"Composing screens and component internals without custom flex CSS",
|
|
8
8
|
"Custom native root through render while keeping data-stack hooks",
|
|
9
|
-
"Style descendants with
|
|
9
|
+
"Style descendants with `@container stack` queries when layout, gap, or typography should respond to the Stack's own inline-size and block-size instead of the viewport (set `enableContainer` on the Stack you're querying)"
|
|
10
10
|
],
|
|
11
11
|
"whenNotToUse": [
|
|
12
12
|
"Cases where a single component already owns required flex chrome",
|
|
13
|
-
"Expecting the Stack root itself to grow via fillChildren"
|
|
13
|
+
"Expecting the Stack root itself to grow via fillChildren",
|
|
14
|
+
"Using `enableContainer` inside complex masonry-like layouts when you don't need container queries (size containment can change nested layout)"
|
|
14
15
|
],
|
|
15
16
|
"accessibility": [
|
|
16
17
|
"Stack is presentational — choose render roots that preserve correct semantics (button, list, heading)",
|
|
@@ -27,6 +28,9 @@
|
|
|
27
28
|
"columnGap": {
|
|
28
29
|
"description": "Sets the gap between flex columns using the Vira space token scale."
|
|
29
30
|
},
|
|
31
|
+
"enableContainer": {
|
|
32
|
+
"description": "Opt-in named CSS container query context for this Stack (enables `container: stack / size` on the root via `data-stack-container`). Required for `@container stack (min-width/min-height: ...)` rules to react to this Stack size. Warning: container size containment can affect nested layout (e.g. cards inside Masonry). Use only when you need container queries against this specific Stack."
|
|
33
|
+
},
|
|
30
34
|
"direction": {
|
|
31
35
|
"description": "Renders children across rows or columns using the chosen flex direction."
|
|
32
36
|
},
|
|
@@ -5,7 +5,7 @@ import { resolveAxisPadding } from "../../core/styles/resolve-axis-padding.js";
|
|
|
5
5
|
import stack_module_default from "./stack.module.js";
|
|
6
6
|
import { useRender } from "@base-ui/react/use-render";
|
|
7
7
|
//#region src/components/stack/stack.tsx
|
|
8
|
-
var Stack = ({ className, direction = "column", fillChildren = true, hAlign = "initial", hPadding, inline = false, maxWidth, minWidth, ref, render, rowGap, columnGap, style, vAlign = "initial", vPadding, wrap = false, ...otherProps }) => {
|
|
8
|
+
var Stack = ({ className, direction = "column", fillChildren = true, hAlign = "initial", hPadding, inline = false, maxWidth, minWidth, enableContainer, ref, render, rowGap, columnGap, style, vAlign = "initial", vPadding, wrap = false, ...otherProps }) => {
|
|
9
9
|
const hasPadding = Boolean(hPadding || vPadding);
|
|
10
10
|
const dynamicStyle = {
|
|
11
11
|
"--vui-stack-row-gap": resolveThemeValue(rowGap, "space", 0),
|
|
@@ -25,6 +25,7 @@ var Stack = ({ className, direction = "column", fillChildren = true, hAlign = "i
|
|
|
25
25
|
props: {
|
|
26
26
|
...otherProps,
|
|
27
27
|
"data-stack-direction": direction,
|
|
28
|
+
...enableContainer && { "data-stack-container": "true" },
|
|
28
29
|
"data-stack-inline": inline ? "true" : "false",
|
|
29
30
|
"data-stack-wrap": wrap ? "true" : "false",
|
|
30
31
|
"data-stack-fill-children": fillChildren ? "true" : "false",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-surface-background{syntax:"*";inherits:false;initial-value:none}@property --vui-surface-background-hover{syntax:"*";inherits:false;initial-value:none}@property --vui-surface-border-style{syntax:"<custom-ident>";inherits:false;initial-value:solid}@property --vui-surface-overflow{syntax:"<custom-ident>";inherits:false;initial-value:visible}@property --vui-surface-border-radius{syntax:"<length-percentage>";inherits:false;initial-value:0}@property --vui-surface-border-radius-top-left{syntax:"<length-percentage>";inherits:false;initial-value:0}@property --vui-surface-border-radius-top-right{syntax:"<length-percentage>";inherits:false;initial-value:0}@property --vui-surface-border-radius-bottom-right{syntax:"<length-percentage>";inherits:false;initial-value:0}@property --vui-surface-border-radius-bottom-left{syntax:"<length-percentage>";inherits:false;initial-value:0}@property --vui-surface-padding-inline-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-surface-padding-inline-end{syntax:"<length>";inherits:false;initial-value:0}@property --vui-surface-padding-block-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-surface-padding-block-end{syntax:"<length>";inherits:false;initial-value:0}.viraui__surface-module__Surface_slEYq{--vui-surface-border-radius-top-left:var(--vui-surface-border-radius);--vui-surface-border-radius-top-right:var(--vui-surface-border-radius);--vui-surface-border-radius-bottom-right:var(--vui-surface-border-radius);--vui-surface-border-radius-bottom-left:var(--vui-surface-border-radius);--vui-surface-background-hover:var(--vui-surface-background);position:relative;overflow:var(--vui-surface-overflow);box-sizing:border-box;background:var(--vui-surface-background);border-radius:var(--vui-surface-border-radius-top-left) var(--vui-surface-border-radius-top-right) var(--vui-surface-border-radius-bottom-right) var(--vui-surface-border-radius-bottom-left);border:0;&[data-surface-color=primary]{--vui-surface-background:light-dark(oklab(from var(--global-primary) l a b/20%),oklab(from var(--global-primary) l a b/10%))}&[data-surface-hover-color=primary]{--vui-surface-background-hover:light-dark(oklab(from var(--global-primary) l a b/20%),oklab(from var(--global-primary) l a b/10%))}@container root not style(--vibrancy-enable: initial){&[data-vibrant]{background:light-dark(oklab(from var(--vui-surface-background) l a b/60%),oklab(from var(--vui-surface-background) l a b/80%))}}&[data-surface-has-padding=true]{padding:var(--vui-surface-padding-block-start) var(--vui-surface-padding-inline-end) var(--vui-surface-padding-block-end) var(--vui-surface-padding-inline-start)}&[data-surface-border]{border-style:var(--vui-surface-border-style);border-color:var(--global-contrast)}&[data-surface-border=all]{border-width:1px}&[data-surface-border=top]{border-width:1px 0 0}&[data-surface-border=right]{border-width:0 1px 0 0}&[data-surface-border=bottom]{border-width:0 0 1px}&[data-surface-border=left]{border-width:0 0 0 1px}&[data-surface-border=x]{border-width:0 1px}&[data-surface-border=y]{border-width:1px 0}@media (hover:hover) and (pointer:fine){&[data-surface-has-hover-color=true]:hover{background:var(--vui-surface-background-hover)}}}}
|
|
1
|
+
@layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-surface-background{syntax:"*";inherits:false;initial-value:none}@property --vui-surface-background-hover{syntax:"*";inherits:false;initial-value:none}@property --vui-surface-border-style{syntax:"<custom-ident>";inherits:false;initial-value:solid}@property --vui-surface-overflow{syntax:"<custom-ident>";inherits:false;initial-value:visible}@property --vui-surface-border-radius{syntax:"<length-percentage>";inherits:false;initial-value:0}@property --vui-surface-border-radius-top-left{syntax:"<length-percentage>";inherits:false;initial-value:0}@property --vui-surface-border-radius-top-right{syntax:"<length-percentage>";inherits:false;initial-value:0}@property --vui-surface-border-radius-bottom-right{syntax:"<length-percentage>";inherits:false;initial-value:0}@property --vui-surface-border-radius-bottom-left{syntax:"<length-percentage>";inherits:false;initial-value:0}@property --vui-surface-padding-inline-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-surface-padding-inline-end{syntax:"<length>";inherits:false;initial-value:0}@property --vui-surface-padding-block-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-surface-padding-block-end{syntax:"<length>";inherits:false;initial-value:0}.viraui__surface-module__Surface_slEYq{--vui-surface-border-radius-top-left:var(--vui-surface-border-radius);--vui-surface-border-radius-top-right:var(--vui-surface-border-radius);--vui-surface-border-radius-bottom-right:var(--vui-surface-border-radius);--vui-surface-border-radius-bottom-left:var(--vui-surface-border-radius);--vui-surface-background-hover:var(--vui-surface-background);position:relative;overflow:var(--vui-surface-overflow);box-sizing:border-box;background:var(--vui-surface-background);border-radius:var(--vui-surface-border-radius-top-left) var(--vui-surface-border-radius-top-right) var(--vui-surface-border-radius-bottom-right) var(--vui-surface-border-radius-bottom-left);border:0;&[data-surface-color=primary]{--vui-surface-background:light-dark(oklab(from var(--global-primary) l a b/20%),oklab(from var(--global-primary) l a b/10%))}&[data-surface-hover-color=primary]{--vui-surface-background-hover:light-dark(oklab(from var(--global-primary) l a b/20%),oklab(from var(--global-primary) l a b/10%))}@container root not style(--vibrancy-enable: initial){&[data-vibrant]{background:light-dark(oklab(from var(--vui-surface-background) l a b/60%),oklab(from var(--vui-surface-background) l a b/80%))}}&[data-surface-has-padding=true]{padding:var(--vui-surface-padding-block-start) var(--vui-surface-padding-inline-end) var(--vui-surface-padding-block-end) var(--vui-surface-padding-inline-start)}&[data-surface-border]{border-style:var(--vui-surface-border-style);border-color:var(--global-contrast)}&[data-surface-border=all]{border-width:1px}&[data-surface-border=top]{border-width:1px 0 0}&[data-surface-border=right]{border-width:0 1px 0 0}&[data-surface-border=bottom]{border-width:0 0 1px}&[data-surface-border=left]{border-width:0 0 0 1px}&[data-surface-border=x]{border-width:0 1px}&[data-surface-border=y]{border-width:1px 0}@media (hover:hover) and (pointer:fine){&[data-surface-has-hover-color=true]:hover{background:var(--vui-surface-background-hover)}}&[data-surface-container=true]{container:surface/size}}}
|
|
@@ -77,6 +77,18 @@ export type SurfaceProps = Omit<React.ComponentPropsWithoutRef<'div'>, 'color'>
|
|
|
77
77
|
* @default visible
|
|
78
78
|
*/
|
|
79
79
|
overflow?: React.CSSProperties['overflow'];
|
|
80
|
+
/**
|
|
81
|
+
* Opt-in named CSS container query context for this Surface.
|
|
82
|
+
*
|
|
83
|
+
* Enables `container: surface / size` on the rendered root (via `data-surface-container="true"`),
|
|
84
|
+
* so descendants can use `@container surface (min-width/min-height: ...)` against this Surface size.
|
|
85
|
+
*
|
|
86
|
+
* Warning: container size containment can affect nested layout (e.g. cards inside Masonry).
|
|
87
|
+
* Use only when you need container queries against this specific Surface.
|
|
88
|
+
*
|
|
89
|
+
* @default false
|
|
90
|
+
*/
|
|
91
|
+
enableContainer?: boolean;
|
|
80
92
|
};
|
|
81
93
|
export declare const Surface: React.FC<SurfaceProps>;
|
|
82
94
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "Surface",
|
|
3
3
|
"structure": "<Surface>…</Surface>",
|
|
4
|
-
"summary": "Presentational container with token background, optional border, radius, and padding; nested surfaces use radius=\"auto\" for concentric corners;
|
|
4
|
+
"summary": "Presentational container with token background, optional border, radius, and padding; nested surfaces use radius=\"auto\" for concentric corners; optionally enables a named CSS container query context (`surface`) via `enableContainer`.",
|
|
5
5
|
"whenToUse": [
|
|
6
6
|
"Group content with base-level background and contrast border",
|
|
7
7
|
"Popup or card chrome with optional hover background",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"Set radius=\"auto\" on a nested Surface when its parent Surface has a radius so each corner subtracts the nearest ancestor padding and stays concentric",
|
|
12
12
|
"Stack nested auto-radius Surfaces recursively; context still resolves through wrapper layout such as Stack",
|
|
13
13
|
"Set overflow=\"hidden\" (or scroll/auto) when Surface must clip or scroll inner content with radius or padding",
|
|
14
|
-
"Style descendants with
|
|
14
|
+
"Style descendants with `@container surface` queries when layout or typography should respond to the Surface's own inline-size and block-size instead of the viewport (set `enableContainer` on the Surface you're querying)"
|
|
15
15
|
],
|
|
16
16
|
"whenNotToUse": [
|
|
17
17
|
"Interactive control semantics without an appropriate render root",
|
|
@@ -36,6 +36,9 @@
|
|
|
36
36
|
"border": {
|
|
37
37
|
"description": "Applies the shared contrast border on the chosen side or axis. Omit for no border."
|
|
38
38
|
},
|
|
39
|
+
"enableContainer": {
|
|
40
|
+
"description": "Opt-in named CSS container query context for this Surface (enables `container: surface / size` on the root). Required for `@container surface (min-width/min-height: ...)` rules to react to this Surface size. Warning: container size containment can affect nested layout (e.g. cards inside Masonry). Use only when you need container queries against this specific Surface."
|
|
41
|
+
},
|
|
39
42
|
"borderStyle": {
|
|
40
43
|
"description": "Sets the CSS border style when `border` is set."
|
|
41
44
|
},
|
|
@@ -20,7 +20,7 @@ var surfaceDefaultRadiusProps = {
|
|
|
20
20
|
style: void 0,
|
|
21
21
|
vPadding: void 0
|
|
22
22
|
};
|
|
23
|
-
var Surface = ({ border, borderStyle = "solid", className, color, hPadding, hoverColor, overflow, radius, ref, render, style, vPadding, ...otherProps }) => {
|
|
23
|
+
var Surface = ({ border, borderStyle = "solid", className, color, hPadding, hoverColor, overflow, radius, ref, render, style, vPadding, enableContainer, ...otherProps }) => {
|
|
24
24
|
const hasPadding = Boolean(hPadding || vPadding);
|
|
25
25
|
const hasHoverColor = hoverColor !== void 0;
|
|
26
26
|
const { contextValue, hasAutoRadius, radiusStyle } = useSurfaceRadius({
|
|
@@ -50,6 +50,7 @@ var Surface = ({ border, borderStyle = "solid", className, color, hPadding, hove
|
|
|
50
50
|
...hasAutoRadius && { "data-surface-radius": "auto" },
|
|
51
51
|
...isSurfaceColorToken(color) && { "data-surface-color": color },
|
|
52
52
|
...isSurfaceColorToken(hoverColor) && { "data-surface-hover-color": hoverColor },
|
|
53
|
+
...enableContainer && { "data-surface-container": "true" },
|
|
53
54
|
"data-surface-has-hover-color": hasHoverColor ? "true" : "false",
|
|
54
55
|
"data-surface-has-padding": hasPadding ? "true" : "false",
|
|
55
56
|
className: clsx(surface_module_default.Surface, className),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "Tabs",
|
|
3
|
+
"baseUIApi": "https://base-ui.com/react/components/tabs#api-reference",
|
|
3
4
|
"structure": "<Tabs>\n <Tabs.List>\n <Tabs.Tab value=\"a\">…</Tabs.Tab>\n </Tabs.List>\n <Tabs.Viewport>\n <Tabs.Panel value=\"a\">…</Tabs.Panel>\n </Tabs.Viewport>\n</Tabs>",
|
|
4
5
|
"summary": "Compound segmented tab control with Surface list chrome, moving indicator, and animated panels.",
|
|
5
6
|
"whenToUse": [
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "Toast",
|
|
3
|
+
"baseUIApi": "https://base-ui.com/react/components/toast#api-reference",
|
|
3
4
|
"structure": "<Toast.Provider>\n <Toast.Portal>\n <Toast.Viewport>\n <Toast.Banner toast={…}>\n <Toast.Action>…</Toast.Action>\n </Toast.Banner>\n </Toast.Viewport>\n </Toast.Portal>\n</Toast.Provider>",
|
|
4
5
|
"summary": "Transient notification surface with stacked or anchored placement, Banner high-level API, and optional action buttons.",
|
|
5
6
|
"whenToUse": [
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ToggleButton",
|
|
3
|
+
"baseUIApi": "https://base-ui.com/react/components/toggle#api-reference",
|
|
3
4
|
"structure": "<ToggleButton restingIcon={<Plus />} aria-label=\"Pin\" />",
|
|
4
5
|
"summary": "Icon-only two-state toggle that swaps resting and optional pressed icons on Base UI Toggle state; `interpolateIcons` (default false) opt-in crossfade + light rotate between dual icons.",
|
|
5
6
|
"whenToUse": [
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ToggleGroup",
|
|
3
|
+
"baseUIApi": "https://base-ui.com/react/components/toggle-group#api-reference",
|
|
3
4
|
"structure": "<ToggleGroup>\n <ToggleButton restingIcon={<Plus />} aria-label=\"List\" value=\"list\" />\n</ToggleGroup>",
|
|
4
5
|
"summary": "Toolbar toggle set with shared selection state; Stack direction follows orientation with zero default gap.",
|
|
5
6
|
"whenToUse": [
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "Tooltip",
|
|
3
|
+
"baseUIApi": "https://base-ui.com/react/components/tooltip#api-reference",
|
|
3
4
|
"structure": "<Tooltip>\n <Tooltip.Trigger />\n <Tooltip.Content />\n</Tooltip>",
|
|
4
5
|
"summary": "Compound tooltip built on Base UI Tooltip with `Tooltip.Provider`, `Tooltip.Trigger`, `Tooltip.Content`, and `Tooltip.createHandle` for detached and multiple triggers; `Content` encapsulates Portal + Positioner + Popup + Viewport and animates position, size, and content between triggers.",
|
|
5
6
|
"whenToUse": [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viraui/react",
|
|
3
|
-
"version": "2026.0.
|
|
3
|
+
"version": "2026.0.10",
|
|
4
4
|
"private": false,
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"unplugin-dts": "1.0.3",
|
|
36
36
|
"vite": "8.1.4",
|
|
37
37
|
"vite-plugin-static-copy": "4.1.1",
|
|
38
|
-
"@viraui/foundation": "2026.0.
|
|
38
|
+
"@viraui/foundation": "2026.0.10",
|
|
39
39
|
"@viraui/icons": "2026.0.0",
|
|
40
40
|
"@viraui/postcss-config": "2026.0.0",
|
|
41
41
|
"@viraui/tsconfig": "2026.0.0"
|