@viraui/react 2026.2.18 → 2026.3.0
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/components/autocomplete/autocomplete-item.js +1 -1
- package/dist/components/autocomplete/autocomplete.js +1 -1
- package/dist/components/dialog/dialog-sheet.js +3 -3
- package/dist/components/fieldset/fieldset.js +1 -1
- package/dist/components/menu/menu-item-row.js +1 -1
- package/dist/components/menu/menu-link-item.js +1 -1
- package/dist/components/popover/popover-sheet.js +1 -1
- package/dist/components/select/select-option.js +2 -2
- package/dist/components/select/select.js +2 -2
- package/dist/components/stack/stack.css +1 -1
- package/dist/components/stack/stack.d.ts +15 -3
- package/dist/components/stack/stack.guide.json +14 -7
- package/dist/components/stack/stack.js +3 -2
- package/dist/components/switch/switch.js +1 -1
- package/dist/components/tabs/tabs-list.js +1 -1
- package/dist/components/textarea/textarea.js +1 -1
- package/dist/components/textfield/textfield.js +1 -1
- package/dist/preflight-surface.json +6 -6
- package/package.json +3 -3
|
@@ -19,7 +19,7 @@ var AutocompleteItemPart = ({ addon, addonAlign = "center", children, className,
|
|
|
19
19
|
vAlign: addonAlign,
|
|
20
20
|
vPadding: "small",
|
|
21
21
|
children: [addon && /* @__PURE__ */ jsx(Stack, {
|
|
22
|
-
|
|
22
|
+
expandChildren: true,
|
|
23
23
|
"aria-hidden": "true",
|
|
24
24
|
"data-grow": "false",
|
|
25
25
|
"data-shrink": "false",
|
|
@@ -30,7 +30,7 @@ var DialogSheet = ({ children, description, title, showCloseButton = false, fitC
|
|
|
30
30
|
render: /* @__PURE__ */ jsx(Surface, {
|
|
31
31
|
border: "top",
|
|
32
32
|
render: /* @__PURE__ */ jsx(Stack, {
|
|
33
|
-
|
|
33
|
+
expandChildren: true,
|
|
34
34
|
hAlign: "center"
|
|
35
35
|
}),
|
|
36
36
|
color: 1,
|
|
@@ -39,7 +39,7 @@ var DialogSheet = ({ children, description, title, showCloseButton = false, fitC
|
|
|
39
39
|
vPadding: ["medium", 0]
|
|
40
40
|
}),
|
|
41
41
|
children: [showHandle && /* @__PURE__ */ jsxs(Stack, {
|
|
42
|
-
|
|
42
|
+
expandChildren: true,
|
|
43
43
|
inline: true,
|
|
44
44
|
direction: "row",
|
|
45
45
|
vPadding: [0, "medium"],
|
|
@@ -50,7 +50,7 @@ var DialogSheet = ({ children, description, title, showCloseButton = false, fitC
|
|
|
50
50
|
/* @__PURE__ */ jsx("div", { className: dialog_module_default.HandleShape })
|
|
51
51
|
]
|
|
52
52
|
}), /* @__PURE__ */ jsxs(Stack, {
|
|
53
|
-
|
|
53
|
+
expandChildren: true,
|
|
54
54
|
maxWidth: maxContentWidth,
|
|
55
55
|
rowGap: "large",
|
|
56
56
|
className: dialog_module_default.Body,
|
|
@@ -9,7 +9,7 @@ var Fieldset$1 = ({ children, className, description, disabled, error, label, ..
|
|
|
9
9
|
className,
|
|
10
10
|
disabled,
|
|
11
11
|
children: [(label || description || error) && /* @__PURE__ */ jsxs(Stack, {
|
|
12
|
-
|
|
12
|
+
expandChildren: true,
|
|
13
13
|
vPadding: [0, "small"],
|
|
14
14
|
rowGap: "small",
|
|
15
15
|
children: [label && /* @__PURE__ */ jsx(Fieldset.Legend, {
|
|
@@ -17,7 +17,7 @@ var MenuItemRow = ({ addon, children, note, trailing }) => /* @__PURE__ */ jsxs(
|
|
|
17
17
|
className: menu_module_default.ItemRow,
|
|
18
18
|
children: [
|
|
19
19
|
addon && /* @__PURE__ */ jsx(Stack, {
|
|
20
|
-
|
|
20
|
+
expandChildren: true,
|
|
21
21
|
"aria-hidden": "true",
|
|
22
22
|
"data-grow": "false",
|
|
23
23
|
"data-shrink": "false",
|
|
@@ -13,7 +13,7 @@ var MenuLinkItem = ({ addon, children, className, note, sentiment, ...otherProps
|
|
|
13
13
|
render: /* @__PURE__ */ jsx(Surface, {
|
|
14
14
|
radius: "auto",
|
|
15
15
|
render: /* @__PURE__ */ jsx(Stack, {
|
|
16
|
-
|
|
16
|
+
expandChildren: true,
|
|
17
17
|
render: /* @__PURE__ */ jsx("a", {})
|
|
18
18
|
})
|
|
19
19
|
}),
|
|
@@ -16,7 +16,7 @@ function SelectOption({ addon, addonAlign = "center", children, className, indic
|
|
|
16
16
|
className: clsx(select_module_default.Option, className),
|
|
17
17
|
render: /* @__PURE__ */ jsx(Surface, { radius: "auto" }),
|
|
18
18
|
children: /* @__PURE__ */ jsxs(Stack, {
|
|
19
|
-
|
|
19
|
+
expandChildren: true,
|
|
20
20
|
columnGap: "medium",
|
|
21
21
|
direction: "row",
|
|
22
22
|
hPadding: "small",
|
|
@@ -27,7 +27,7 @@ function SelectOption({ addon, addonAlign = "center", children, className, indic
|
|
|
27
27
|
columnGap: "small",
|
|
28
28
|
vAlign: addonAlign,
|
|
29
29
|
children: [addon && /* @__PURE__ */ jsx(Stack, {
|
|
30
|
-
|
|
30
|
+
expandChildren: true,
|
|
31
31
|
"aria-hidden": "true",
|
|
32
32
|
"data-grow": "false",
|
|
33
33
|
"data-shrink": "false",
|
|
@@ -36,7 +36,7 @@ function SelectRootComponent({ alignListWithTrigger = true, children, className,
|
|
|
36
36
|
validationDebounceTime,
|
|
37
37
|
validationMode,
|
|
38
38
|
render: /* @__PURE__ */ jsx(Stack, {
|
|
39
|
-
|
|
39
|
+
expandChildren: true,
|
|
40
40
|
rowGap: "small"
|
|
41
41
|
}),
|
|
42
42
|
children: [
|
|
@@ -56,7 +56,7 @@ function SelectRootComponent({ alignListWithTrigger = true, children, className,
|
|
|
56
56
|
disabled,
|
|
57
57
|
ref,
|
|
58
58
|
children: /* @__PURE__ */ jsxs(Stack, {
|
|
59
|
-
|
|
59
|
+
expandChildren: true,
|
|
60
60
|
className: select_module_default.Trigger,
|
|
61
61
|
direction: "row",
|
|
62
62
|
columnGap: "x-small",
|
|
@@ -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-
|
|
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-expand-children=true]>*){flex-grow:var(--vira-flex-grow,1)}&[data-stack-full-width=true]{inline-size:100%}&[data-stack-container=true]{container:stack/inline-size}}}
|
|
@@ -44,11 +44,23 @@ export type StackProps = React.ComponentPropsWithoutRef<'div'> & {
|
|
|
44
44
|
*/
|
|
45
45
|
wrap?: boolean;
|
|
46
46
|
/**
|
|
47
|
-
* Makes direct children grow
|
|
47
|
+
* Makes direct children grow along the flex main axis (`flex-grow`).
|
|
48
|
+
*
|
|
49
|
+
* Does not set the stack root's own inline size — use `fullWidth` when this stack must
|
|
50
|
+
* fill its parent width (e.g. centered shell with `maxWidth`).
|
|
51
|
+
*
|
|
52
|
+
* @default false
|
|
53
|
+
*/
|
|
54
|
+
expandChildren?: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Sets `inline-size: 100%` on the stack root so it fills the parent's inline size.
|
|
57
|
+
*
|
|
58
|
+
* Use with `maxWidth` under a parent `hAlign="center"` for a fluid, capped, centered shell.
|
|
59
|
+
* Orthogonal to `expandChildren` (self size vs children grow).
|
|
48
60
|
*
|
|
49
61
|
* @default false
|
|
50
62
|
*/
|
|
51
|
-
|
|
63
|
+
fullWidth?: boolean;
|
|
52
64
|
/**
|
|
53
65
|
* Sets the gap between flex rows using the Vira space token scale.
|
|
54
66
|
*
|
|
@@ -94,7 +106,7 @@ export type StackProps = React.ComponentPropsWithoutRef<'div'> & {
|
|
|
94
106
|
/**
|
|
95
107
|
* Applies a minimum width value to the stack root.
|
|
96
108
|
*
|
|
97
|
-
* @default No
|
|
109
|
+
* @default No minimum width constraint.
|
|
98
110
|
*/
|
|
99
111
|
minWidth?: string;
|
|
100
112
|
/**
|
|
@@ -6,11 +6,13 @@
|
|
|
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 `@container stack` queries when layout, gap, or typography should respond to the Stack's own inline-size instead of the viewport (set `enableContainer` on the Stack you're querying)"
|
|
9
|
+
"Style descendants with `@container stack` queries when layout, gap, or typography should respond to the Stack's own inline-size instead of the viewport (set `enableContainer` on the Stack you're querying)",
|
|
10
|
+
"Centered max-width shells: parent `hAlign=\"center\"` + child `fullWidth` + `maxWidth`"
|
|
10
11
|
],
|
|
11
12
|
"whenNotToUse": [
|
|
12
13
|
"Cases where a single component already owns required flex chrome",
|
|
13
|
-
"Expecting direct children to
|
|
14
|
+
"Expecting direct children to grow on the main axis without setting `expandChildren`",
|
|
15
|
+
"Expecting this stack to fill parent inline size under non-stretch alignment without `fullWidth` (or an explicit `inlineSize`)",
|
|
14
16
|
"Using `enableContainer` inside complex masonry-like layouts when you don't need container queries (inline-size containment can change nested layout)"
|
|
15
17
|
],
|
|
16
18
|
"accessibility": [
|
|
@@ -19,10 +21,12 @@
|
|
|
19
21
|
"Do not use Stack alone to imply grouping; use landmarks or headings where needed"
|
|
20
22
|
],
|
|
21
23
|
"antiPatterns": [
|
|
22
|
-
"Assuming Stack
|
|
23
|
-
"
|
|
24
|
+
"Assuming Stack expands direct children by default — pass `expandChildren` when children should grow along the flex main axis",
|
|
25
|
+
"Using `expandChildren` to fill parent width under `hAlign=\"center\"` — that is `fullWidth` on the child stack (self `inline-size`), not child flex-grow",
|
|
26
|
+
"Putting `data-grow=\"false\"` on an ancestor to control nested expandChildren — set it on the child that should not grow",
|
|
24
27
|
"Re-declaring primitive flex container rules in app CSS when Stack can own the layout",
|
|
25
|
-
"Using viewport media queries when @container stack queries against the rendered Stack inline-size would match the design intent"
|
|
28
|
+
"Using viewport media queries when @container stack queries against the rendered Stack inline-size would match the design intent",
|
|
29
|
+
"Combining `fullWidth` with `inline` — prefer block flex when the root must fill parent inline size"
|
|
26
30
|
],
|
|
27
31
|
"related": ["Surface", "Text", "Button"],
|
|
28
32
|
"properties": {
|
|
@@ -36,8 +40,11 @@
|
|
|
36
40
|
"direction": {
|
|
37
41
|
"description": "Renders children across rows or columns using the chosen flex direction."
|
|
38
42
|
},
|
|
39
|
-
"
|
|
40
|
-
"description": "Makes direct children grow
|
|
43
|
+
"expandChildren": {
|
|
44
|
+
"description": "Makes direct children grow along the flex main axis (`flex-grow`). Default `false`. Orthogonal to `fullWidth` (children grow vs this root's inline size). A child opts out with its own `data-grow=\"false\"`; ancestor `data-grow` does not inherit into nested stacks."
|
|
45
|
+
},
|
|
46
|
+
"fullWidth": {
|
|
47
|
+
"description": "Sets `inline-size: 100%` on the stack root so it fills the parent's inline size. Default `false`. Use with `maxWidth` under a parent `hAlign=\"center\"` for a fluid capped centered shell. Does not grow children — use `expandChildren` for that."
|
|
41
48
|
},
|
|
42
49
|
"hAlign": {
|
|
43
50
|
"description": "Aligns content on the horizontal axis from the consumer point of view."
|
|
@@ -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",
|
|
8
|
+
var Stack = ({ className, direction = "column", expandChildren = false, fullWidth = false, 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),
|
|
@@ -28,7 +28,8 @@ var Stack = ({ className, direction = "column", fillChildren = false, hAlign = "
|
|
|
28
28
|
...enableContainer && { "data-stack-container": "true" },
|
|
29
29
|
"data-stack-inline": inline ? "true" : "false",
|
|
30
30
|
"data-stack-wrap": wrap ? "true" : "false",
|
|
31
|
-
"data-stack-
|
|
31
|
+
"data-stack-expand-children": expandChildren ? "true" : "false",
|
|
32
|
+
"data-stack-full-width": fullWidth ? "true" : "false",
|
|
32
33
|
"data-stack-has-padding": hasPadding ? "true" : "false",
|
|
33
34
|
className: clsx(stack_module_default.Stack, className),
|
|
34
35
|
style: dynamicStyle
|
|
@@ -22,7 +22,7 @@ var Switch$1 = ({ className, description, dirty, disabled, error, invalid, label
|
|
|
22
22
|
validationMode,
|
|
23
23
|
render: /* @__PURE__ */ jsx(Stack, {
|
|
24
24
|
direction: "row",
|
|
25
|
-
|
|
25
|
+
expandChildren: true,
|
|
26
26
|
columnGap: size === "small" ? "small" : "medium",
|
|
27
27
|
vAlign: hasTextDescription ? "start" : "center"
|
|
28
28
|
}),
|
|
@@ -20,7 +20,7 @@ var TabsList = ({ children, className, activateOnFocus = true, ref, ...otherProp
|
|
|
20
20
|
children: [/* @__PURE__ */ jsx(TabsIndicator, {}), /* @__PURE__ */ jsx("div", {
|
|
21
21
|
className: tabs_module_default.Track,
|
|
22
22
|
children: /* @__PURE__ */ jsx(Stack, {
|
|
23
|
-
|
|
23
|
+
expandChildren: true,
|
|
24
24
|
direction: "row",
|
|
25
25
|
hAlign: "start",
|
|
26
26
|
vAlign: "center",
|
|
@@ -22,7 +22,7 @@ var Textfield = ({ className, description, dirty, disabled, endAddon, error, fit
|
|
|
22
22
|
validationMode,
|
|
23
23
|
"data-fullwidth": fullWidth,
|
|
24
24
|
render: /* @__PURE__ */ jsx(Stack, {
|
|
25
|
-
|
|
25
|
+
expandChildren: true,
|
|
26
26
|
rowGap: "small"
|
|
27
27
|
}),
|
|
28
28
|
children: [
|
|
@@ -114,14 +114,14 @@
|
|
|
114
114
|
"module": "layout",
|
|
115
115
|
"values": ["true", "false"],
|
|
116
116
|
"presence": "optional; omit for default flex growth",
|
|
117
|
-
"effect": "Affects only the element: true sets --vira-flex-grow: 1 and flex-grow: 1; false sets --vira-flex-grow: 0 and flex-grow: 0. Custom props are registered inherits: false so ancestors do not poison nested Stack
|
|
117
|
+
"effect": "Affects only the element: true sets --vira-flex-grow: 1 and flex-grow: 1; false sets --vira-flex-grow: 0 and flex-grow: 0. Custom props are registered inherits: false so ancestors do not poison nested Stack expandChildren.",
|
|
118
118
|
"whenToUse": [
|
|
119
|
-
"Force grow or opt out on
|
|
119
|
+
"Force grow or opt out on an expandChildren direct child",
|
|
120
120
|
"Fixed-width icons, indicators, or trailing slots (false)"
|
|
121
121
|
],
|
|
122
122
|
"whenNotToUse": [
|
|
123
123
|
"When default flex growth is already correct",
|
|
124
|
-
"Expecting ancestor data-grow to change nested
|
|
124
|
+
"Expecting ancestor data-grow to change nested expandChildren children"
|
|
125
125
|
],
|
|
126
126
|
"related": ["Stack", "--vira-flex-grow"]
|
|
127
127
|
},
|
|
@@ -198,8 +198,8 @@
|
|
|
198
198
|
"name": "--vira-flex-grow",
|
|
199
199
|
"module": "layout",
|
|
200
200
|
"setBy": "data-grow=\"true\" or data-grow=\"false\"; registered in global-properties.css",
|
|
201
|
-
"default": "1 (initial-value); inherits: false; Stack
|
|
202
|
-
"purpose": "Local grow signal for Stack
|
|
201
|
+
"default": "1 (initial-value); inherits: false; Stack expandChildren uses var(--vira-flex-grow, 1)",
|
|
202
|
+
"purpose": "Local grow signal for Stack expandChildren / child flex defaults; does not inherit so ancestor data-grow cannot poison nested stacks."
|
|
203
203
|
},
|
|
204
204
|
{
|
|
205
205
|
"name": "--vira-flex-shrink",
|
|
@@ -216,7 +216,7 @@
|
|
|
216
216
|
"Inventing backdrop-filter CSS instead of data-vibrant when vibrancy is desired",
|
|
217
217
|
"Inventing box-shadow CSS instead of data-elevation when theme-gated shadows are desired",
|
|
218
218
|
"Shipping a new consumer-facing data-* without updating preflight-surface.json and viraui-design/custom-attributes.md",
|
|
219
|
-
"Relying on ancestor data-grow / data-shrink to control nested Stack
|
|
219
|
+
"Relying on ancestor data-grow / data-shrink to control nested Stack expandChildren (props do not inherit)"
|
|
220
220
|
],
|
|
221
221
|
"discovery": {
|
|
222
222
|
"consumption": "@viraui/react/consumption.json",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viraui/react",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.3.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@base-ui/react": ">=1.7.0",
|
|
31
|
-
"@viraui/foundation": "2026.
|
|
32
|
-
"@viraui/icons": "2026.0.
|
|
31
|
+
"@viraui/foundation": "2026.3.0",
|
|
32
|
+
"@viraui/icons": "2026.0.3",
|
|
33
33
|
"@viraui/postcss-config": "2026.0.0",
|
|
34
34
|
"@viraui/tsconfig": "2026.0.0",
|
|
35
35
|
"postcss": "8.5.26",
|