@viraui/react 2026.7.1 → 2026.9.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/catalog.json +9 -3
- package/dist/components/button/button.css +1 -1
- package/dist/components/direction-provider/index.d.ts +2 -0
- package/dist/components/direction-provider/index.js +2 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/menu/menu-popup.d.ts +2 -2
- package/dist/components/menu/menu.css +1 -1
- package/dist/components/progressive-blur/progressive-blur.css +1 -1
- package/dist/components/prose/prose.d.ts +4 -1
- package/dist/components/select/select-group.js +1 -1
- package/dist/components/select/select.css +1 -1
- package/dist/components/select/select.js +4 -1
- package/dist/components/spinner/spinner.d.ts +6 -1
- package/dist/components/spinner/variants/arc.css +1 -0
- package/dist/components/spinner/variants/arc.d.ts +2 -0
- package/dist/components/spinner/variants/arc.js +19 -0
- package/dist/components/spinner/variants/arc.module.js +8 -0
- package/dist/components/spinner/variants/atom.css +1 -0
- package/dist/components/spinner/variants/atom.d.ts +6 -0
- package/dist/components/spinner/variants/atom.js +40 -0
- package/dist/components/spinner/variants/atom.module.js +8 -0
- package/dist/components/spinner/variants/blocks.css +1 -0
- package/dist/components/spinner/variants/blocks.d.ts +2 -0
- package/dist/components/spinner/variants/blocks.js +25 -0
- package/dist/components/spinner/variants/blocks.module.js +8 -0
- package/dist/components/spinner/variants/bouncing-dots.css +1 -0
- package/dist/components/spinner/variants/bouncing-dots.d.ts +2 -0
- package/dist/components/spinner/variants/bouncing-dots.js +21 -0
- package/dist/components/spinner/variants/bouncing-dots.module.js +8 -0
- package/dist/components/spinner/variants/cascade.css +1 -0
- package/dist/components/spinner/variants/cascade.d.ts +2 -0
- package/dist/components/spinner/variants/cascade.js +34 -0
- package/dist/components/spinner/variants/cascade.module.js +8 -0
- package/dist/components/spinner/variants/circular-dots.css +1 -0
- package/dist/components/spinner/variants/circular-dots.d.ts +2 -0
- package/dist/components/spinner/variants/circular-dots.js +26 -0
- package/dist/components/spinner/variants/circular-dots.module.js +8 -0
- package/dist/components/spinner/variants/classic-v2.css +1 -0
- package/dist/components/spinner/variants/classic-v2.d.ts +2 -0
- package/dist/components/spinner/variants/classic-v2.js +24 -0
- package/dist/components/spinner/variants/classic-v2.module.js +8 -0
- package/dist/components/spinner/variants/classic.css +1 -0
- package/dist/components/spinner/variants/classic.d.ts +2 -0
- package/dist/components/spinner/variants/classic.js +22 -0
- package/dist/components/spinner/variants/classic.module.js +8 -0
- package/dist/components/spinner/variants/clock.css +1 -0
- package/dist/components/spinner/variants/clock.d.ts +2 -0
- package/dist/components/spinner/variants/clock.js +18 -0
- package/dist/components/spinner/variants/clock.module.js +8 -0
- package/dist/components/spinner/variants/comet.css +1 -0
- package/dist/components/spinner/variants/comet.d.ts +2 -0
- package/dist/components/spinner/variants/comet.js +33 -0
- package/dist/components/spinner/variants/comet.module.js +10 -0
- package/dist/components/spinner/variants/compass.css +1 -0
- package/dist/components/spinner/variants/compass.d.ts +2 -0
- package/dist/components/spinner/variants/compass.js +16 -0
- package/dist/components/spinner/variants/compass.module.js +8 -0
- package/dist/components/spinner/variants/dual.css +1 -0
- package/dist/components/spinner/variants/dual.d.ts +2 -0
- package/dist/components/spinner/variants/dual.js +25 -0
- package/dist/components/spinner/variants/dual.module.js +10 -0
- package/dist/components/spinner/variants/eclipse.css +1 -0
- package/dist/components/spinner/variants/eclipse.d.ts +6 -0
- package/dist/components/spinner/variants/eclipse.js +21 -0
- package/dist/components/spinner/variants/eclipse.module.js +9 -0
- package/dist/components/spinner/variants/flip.css +1 -0
- package/dist/components/spinner/variants/flip.d.ts +2 -0
- package/dist/components/spinner/variants/flip.js +17 -0
- package/dist/components/spinner/variants/flip.module.js +8 -0
- package/dist/components/spinner/variants/gather.css +1 -0
- package/dist/components/spinner/variants/gather.d.ts +2 -0
- package/dist/components/spinner/variants/gather.js +50 -0
- package/dist/components/spinner/variants/gather.module.js +11 -0
- package/dist/components/spinner/variants/index.d.ts +9 -1
- package/dist/components/spinner/variants/index.js +96 -10
- package/dist/components/spinner/variants/leap.css +1 -0
- package/dist/components/spinner/variants/leap.d.ts +6 -0
- package/dist/components/spinner/variants/leap.js +27 -0
- package/dist/components/spinner/variants/leap.module.js +8 -0
- package/dist/components/spinner/variants/linear-dots.css +1 -0
- package/dist/components/spinner/variants/linear-dots.d.ts +2 -0
- package/dist/components/spinner/variants/linear-dots.js +21 -0
- package/dist/components/spinner/variants/linear-dots.module.js +8 -0
- package/dist/components/spinner/variants/loading.css +1 -0
- package/dist/components/spinner/variants/loading.d.ts +2 -0
- package/dist/components/spinner/variants/loading.js +50 -0
- package/dist/components/spinner/variants/loading.module.js +8 -0
- package/dist/components/spinner/variants/morph.css +1 -0
- package/dist/components/spinner/variants/morph.d.ts +2 -0
- package/dist/components/spinner/variants/morph.js +17 -0
- package/dist/components/spinner/variants/morph.module.js +8 -0
- package/dist/components/spinner/variants/orbit.css +1 -0
- package/dist/components/spinner/variants/orbit.d.ts +2 -0
- package/dist/components/spinner/variants/orbit.js +24 -0
- package/dist/components/spinner/variants/orbit.module.js +8 -0
- package/dist/components/spinner/variants/pulse.css +1 -0
- package/dist/components/spinner/variants/pulse.d.ts +2 -0
- package/dist/components/spinner/variants/pulse.js +19 -0
- package/dist/components/spinner/variants/pulse.module.js +8 -0
- package/dist/components/spinner/variants/radar.css +1 -0
- package/dist/components/spinner/variants/radar.d.ts +2 -0
- package/dist/components/spinner/variants/radar.js +53 -0
- package/dist/components/spinner/variants/radar.module.js +8 -0
- package/dist/components/spinner/variants/ring.css +1 -0
- package/dist/components/spinner/variants/ring.d.ts +2 -0
- package/dist/components/spinner/variants/ring.js +24 -0
- package/dist/components/spinner/variants/ring.module.js +8 -0
- package/dist/components/spinner/variants/ripple.css +1 -0
- package/dist/components/spinner/variants/ripple.d.ts +2 -0
- package/dist/components/spinner/variants/ripple.js +23 -0
- package/dist/components/spinner/variants/ripple.module.js +8 -0
- package/dist/components/spinner/variants/slide.css +1 -0
- package/dist/components/spinner/variants/slide.d.ts +2 -0
- package/dist/components/spinner/variants/slide.js +24 -0
- package/dist/components/spinner/variants/slide.module.js +8 -0
- package/dist/components/spinner/variants/snake.css +1 -0
- package/dist/components/spinner/variants/snake.d.ts +2 -0
- package/dist/components/spinner/variants/snake.js +19 -0
- package/dist/components/spinner/variants/snake.module.js +11 -0
- package/dist/components/spinner/variants/swirl.css +1 -0
- package/dist/components/spinner/variants/swirl.d.ts +2 -0
- package/dist/components/spinner/variants/swirl.js +35 -0
- package/dist/components/spinner/variants/swirl.module.js +8 -0
- package/dist/components/spinner/variants/trace.css +1 -0
- package/dist/components/spinner/variants/trace.d.ts +2 -0
- package/dist/components/spinner/variants/trace.js +28 -0
- package/dist/components/spinner/variants/trace.module.js +8 -0
- package/dist/components/spinner/variants/wave.css +1 -0
- package/dist/components/spinner/variants/wave.d.ts +2 -0
- package/dist/components/spinner/variants/wave.js +25 -0
- package/dist/components/spinner/variants/wave.module.js +8 -0
- package/dist/components/stack/stack.css +1 -1
- package/dist/components/stack/stack.d.ts +15 -3
- package/dist/components/stack/stack.js +2 -1
- package/dist/components/surface/surface.css +1 -1
- package/dist/components/text/text.css +1 -1
- package/dist/components/text/text.d.ts +10 -2
- package/dist/components/title/title.d.ts +7 -0
- package/dist/index.js +2 -1
- package/dist/preflight.css +1 -1
- package/dist/specs/PROTOCOL.md +1 -1
- package/dist/specs/activity-hints.xml +4 -4
- package/dist/specs/components/accordion/props.xml +2 -2
- package/dist/specs/components/accordion/usage.xml +2 -0
- package/dist/specs/components/autocomplete/patterns.xml +4 -4
- package/dist/specs/components/autocomplete/props.xml +2 -2
- package/dist/specs/components/autocomplete/usage.xml +1 -1
- package/dist/specs/components/button/patterns.xml +2 -2
- package/dist/specs/components/button/props.xml +4 -4
- package/dist/specs/components/button/usage.xml +2 -1
- package/dist/specs/components/chip/patterns.xml +2 -2
- package/dist/specs/components/chip/props.xml +2 -2
- package/dist/specs/components/chip/usage.xml +2 -0
- package/dist/specs/components/direction-provider/a11y.xml +6 -0
- package/dist/specs/components/direction-provider/meta.xml +20 -0
- package/dist/specs/components/direction-provider/patterns.xml +27 -0
- package/dist/specs/components/direction-provider/props.xml +18 -0
- package/dist/specs/components/direction-provider/usage.xml +10 -0
- package/dist/specs/components/disclosure/patterns.xml +2 -2
- package/dist/specs/components/disclosure/props.xml +2 -2
- package/dist/specs/components/disclosure/usage.xml +2 -0
- package/dist/specs/components/glow/patterns.xml +1 -1
- package/dist/specs/components/grid/patterns.xml +3 -3
- package/dist/specs/components/icon-button/props.xml +4 -4
- package/dist/specs/components/icon-button/usage.xml +3 -1
- package/dist/specs/components/menu/patterns.xml +18 -18
- package/dist/specs/components/menu/props.xml +5 -5
- package/dist/specs/components/menu/usage.xml +3 -1
- package/dist/specs/components/meter/patterns.xml +1 -1
- package/dist/specs/components/progressive-blur/usage.xml +2 -0
- package/dist/specs/components/prose/meta.xml +1 -1
- package/dist/specs/components/prose/patterns.xml +34 -10
- package/dist/specs/components/prose/props.xml +3 -1
- package/dist/specs/components/prose/usage.xml +4 -1
- package/dist/specs/components/select/patterns.xml +2 -2
- package/dist/specs/components/select/props.xml +2 -2
- package/dist/specs/components/select/usage.xml +1 -0
- package/dist/specs/components/slider/patterns.xml +1 -1
- package/dist/specs/components/spinner/props.xml +1 -1
- package/dist/specs/components/spinner/usage.xml +1 -1
- package/dist/specs/components/stack/patterns.xml +102 -4
- package/dist/specs/components/stack/props.xml +9 -3
- package/dist/specs/components/stack/usage.xml +7 -3
- package/dist/specs/components/surface/patterns.xml +3 -3
- package/dist/specs/components/surface/usage.xml +1 -1
- package/dist/specs/components/tabs/patterns.xml +3 -3
- package/dist/specs/components/tabs/props.xml +1 -1
- package/dist/specs/components/tabs/usage.xml +2 -1
- package/dist/specs/components/text/meta.xml +2 -1
- package/dist/specs/components/text/patterns.xml +19 -16
- package/dist/specs/components/text/props.xml +8 -6
- package/dist/specs/components/text/usage.xml +9 -3
- package/dist/specs/components/textfield/patterns.xml +3 -3
- package/dist/specs/components/textfield/props.xml +2 -2
- package/dist/specs/components/textfield/usage.xml +2 -1
- package/dist/specs/components/title/meta.xml +2 -1
- package/dist/specs/components/title/patterns.xml +11 -10
- package/dist/specs/components/title/props.xml +5 -4
- package/dist/specs/components/title/usage.xml +8 -3
- package/dist/specs/components/toggle-button/patterns.xml +8 -8
- package/dist/specs/components/toggle-button/props.xml +3 -3
- package/dist/specs/components/toggle-button/usage.xml +2 -0
- package/dist/specs/components/toggle-group/patterns.xml +3 -3
- package/dist/specs/components/tooltip/patterns.xml +7 -7
- package/dist/specs/foundation/attributes.xml +24 -4
- package/dist/specs/foundation/bootstrap.xml +1 -1
- package/dist/specs/foundation/modules.xml +14 -5
- package/dist/specs/foundation/theme-topics.xml +3 -3
- package/dist/specs/foundation/toggles.xml +3 -3
- package/dist/specs/index.xml +14 -22
- package/dist/specs/patterns/compose-layout-first.xml +1 -1
- package/package.json +2 -2
- package/dist/components/spinner/variants/bars.d.ts +0 -2
- package/dist/components/spinner/variants/bars.js +0 -134
- package/dist/components/spinner/variants/dot-grid.css +0 -1
- package/dist/components/spinner/variants/dot-grid.d.ts +0 -2
- package/dist/components/spinner/variants/dot-grid.js +0 -57
- package/dist/components/spinner/variants/dot-grid.module.js +0 -16
- package/dist/components/spinner/variants/dots.d.ts +0 -2
- package/dist/components/spinner/variants/dots.js +0 -189
- package/dist/specs/patterns/equal-width-actions.xml +0 -22
- package/dist/specs/patterns/page-chrome.xml +0 -34
- package/dist/specs/patterns/stack-as-surface.xml +0 -37
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
</Text>
|
|
19
19
|
</Stack>
|
|
20
20
|
</Stack>
|
|
21
|
-
<ChevronExpandY aria-hidden
|
|
21
|
+
<ChevronExpandY aria-hidden />
|
|
22
22
|
</Stack>
|
|
23
23
|
</Stack>
|
|
24
24
|
}
|
|
@@ -36,15 +36,15 @@
|
|
|
36
36
|
</Stack>
|
|
37
37
|
</Stack>
|
|
38
38
|
<Menu.Separator />
|
|
39
|
-
<Menu.Item addon={<StarUpgrade aria-hidden
|
|
39
|
+
<Menu.Item addon={<StarUpgrade aria-hidden />}>Upgrade to Pro</Menu.Item>
|
|
40
40
|
<Menu.Separator />
|
|
41
41
|
<Menu.Group label="Settings">
|
|
42
|
-
<Menu.Item addon={<BadgeCheck aria-hidden
|
|
43
|
-
<Menu.Item addon={<CreditCards aria-hidden
|
|
44
|
-
<Menu.Item addon={<Bell aria-hidden
|
|
42
|
+
<Menu.Item addon={<BadgeCheck aria-hidden />}>Account</Menu.Item>
|
|
43
|
+
<Menu.Item addon={<CreditCards aria-hidden />}>Billing</Menu.Item>
|
|
44
|
+
<Menu.Item addon={<Bell aria-hidden />}>Notifications</Menu.Item>
|
|
45
45
|
</Menu.Group>
|
|
46
46
|
<Menu.Separator />
|
|
47
|
-
<Menu.Item addon={<ArrowDoorOut aria-hidden
|
|
47
|
+
<Menu.Item addon={<ArrowDoorOut aria-hidden />} sentiment="destructive">
|
|
48
48
|
Log out
|
|
49
49
|
</Menu.Item>
|
|
50
50
|
</Menu.Popup>
|
|
@@ -58,24 +58,24 @@
|
|
|
58
58
|
<Menu>
|
|
59
59
|
<Menu.Trigger
|
|
60
60
|
render={
|
|
61
|
-
<Button size="s" addon={<ChevronDown aria-hidden
|
|
61
|
+
<Button size="s" addon={<ChevronDown aria-hidden />} variant="secondary">
|
|
62
62
|
Actions
|
|
63
63
|
</Button>
|
|
64
64
|
}
|
|
65
65
|
/>
|
|
66
66
|
<Menu.Popup align="end" side="bottom">
|
|
67
67
|
<Menu.Group label="Edit">
|
|
68
|
-
<Menu.Item addon={<Pencil aria-hidden
|
|
68
|
+
<Menu.Item addon={<Pencil aria-hidden />} note="⌘E">
|
|
69
69
|
Rename report
|
|
70
70
|
</Menu.Item>
|
|
71
|
-
<Menu.Item addon={<Duplicate aria-hidden
|
|
71
|
+
<Menu.Item addon={<Duplicate aria-hidden />} note="⌘D">
|
|
72
72
|
Duplicate
|
|
73
73
|
</Menu.Item>
|
|
74
|
-
<Menu.Item addon={<Archive aria-hidden
|
|
74
|
+
<Menu.Item addon={<Archive aria-hidden />}>Archive</Menu.Item>
|
|
75
75
|
</Menu.Group>
|
|
76
76
|
<Menu.Separator />
|
|
77
77
|
<Menu.Group label="View">
|
|
78
|
-
<Menu.CheckboxItem addon={<Eye aria-hidden
|
|
78
|
+
<Menu.CheckboxItem addon={<Eye aria-hidden />} checked>
|
|
79
79
|
Show totals row
|
|
80
80
|
</Menu.CheckboxItem>
|
|
81
81
|
<Menu.CheckboxItem>Compact table rows</Menu.CheckboxItem>
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
</Menu.RadioGroup>
|
|
89
89
|
<Menu.Separator />
|
|
90
90
|
<Menu.Submenu>
|
|
91
|
-
<Menu.SubmenuTrigger addon={<Link aria-hidden
|
|
91
|
+
<Menu.SubmenuTrigger addon={<Link aria-hidden />}>Share</Menu.SubmenuTrigger>
|
|
92
92
|
<Menu.Popup side="inline-end">
|
|
93
93
|
<Menu.LinkItem href="#">Copy link</Menu.LinkItem>
|
|
94
94
|
<Menu.Item note="⌘⇧E">Export PDF</Menu.Item>
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
</Menu.Popup>
|
|
97
97
|
</Menu.Submenu>
|
|
98
98
|
<Menu.Separator />
|
|
99
|
-
<Menu.Item addon={<Trash aria-hidden
|
|
99
|
+
<Menu.Item addon={<Trash aria-hidden />} sentiment="destructive">
|
|
100
100
|
Delete report
|
|
101
101
|
</Menu.Item>
|
|
102
102
|
</Menu.Popup>
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
render={
|
|
120
120
|
<IconButton
|
|
121
121
|
aria-label="More actions for Q2 payout report"
|
|
122
|
-
icon={<DotsVertical
|
|
122
|
+
icon={<DotsVertical />}
|
|
123
123
|
pill
|
|
124
124
|
size="s"
|
|
125
125
|
variant="flat"
|
|
@@ -127,11 +127,11 @@
|
|
|
127
127
|
}
|
|
128
128
|
/>
|
|
129
129
|
<Menu.Popup align="end" side="bottom">
|
|
130
|
-
<Menu.Item addon={<Pencil aria-hidden
|
|
131
|
-
<Menu.Item addon={<Duplicate aria-hidden
|
|
132
|
-
<Menu.Item addon={<Archive aria-hidden
|
|
130
|
+
<Menu.Item addon={<Pencil aria-hidden />}>Rename</Menu.Item>
|
|
131
|
+
<Menu.Item addon={<Duplicate aria-hidden />}>Duplicate</Menu.Item>
|
|
132
|
+
<Menu.Item addon={<Archive aria-hidden />}>Archive</Menu.Item>
|
|
133
133
|
<Menu.Separator />
|
|
134
|
-
<Menu.Item addon={<Trash aria-hidden
|
|
134
|
+
<Menu.Item addon={<Trash aria-hidden />} sentiment="destructive">
|
|
135
135
|
Delete
|
|
136
136
|
</Menu.Item>
|
|
137
137
|
</Menu.Popup>
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
<item>Rich non-menu panels with forms or free layout (use Popover / Dialog — do not wrap Menu in Popover)</item>
|
|
17
17
|
</when_not_to_use>
|
|
18
18
|
<prop name="CheckboxItem.addon" kind="react">
|
|
19
|
-
<description>Decorative leading node rendered before the item label.</description>
|
|
19
|
+
<description>Decorative leading node rendered before the item label. Omit glyph `size` / width / height unless expressly overriding the icon-library default.</description>
|
|
20
20
|
</prop>
|
|
21
21
|
<prop name="CheckboxItem.note" kind="react">
|
|
22
22
|
<description>End-aligned secondary text (e.g. keyboard shortcut) before the check indicator. Rendered muted `xs`.</description>
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
<description>Accessible group label rendered with `Menu.GroupLabel`.</description>
|
|
29
29
|
</prop>
|
|
30
30
|
<prop name="Item.addon" kind="react">
|
|
31
|
-
<description>Decorative leading node rendered before the item label.</description>
|
|
31
|
+
<description>Decorative leading node rendered before the item label. Omit glyph `size` / width / height unless expressly overriding the icon-library default.</description>
|
|
32
32
|
</prop>
|
|
33
33
|
<prop name="Item.note" kind="react">
|
|
34
34
|
<description>End-aligned secondary text (e.g. keyboard shortcut). Rendered muted `xs`.</description>
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<description>Visual sentiment. `destructive` uses highlight-red wash + text.</description>
|
|
38
38
|
</prop>
|
|
39
39
|
<prop name="LinkItem.addon" kind="react">
|
|
40
|
-
<description>Decorative leading node rendered before the item label.</description>
|
|
40
|
+
<description>Decorative leading node rendered before the item label. Omit glyph `size` / width / height unless expressly overriding the icon-library default.</description>
|
|
41
41
|
</prop>
|
|
42
42
|
<prop name="LinkItem.note" kind="react">
|
|
43
43
|
<description>End-aligned secondary text (e.g. keyboard shortcut). Rendered muted `xs`.</description>
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
<description>Optional accessible group label rendered with `Menu.GroupLabel`.</description>
|
|
56
56
|
</prop>
|
|
57
57
|
<prop name="RadioItem.addon" kind="react">
|
|
58
|
-
<description>Decorative leading node rendered before the item label.</description>
|
|
58
|
+
<description>Decorative leading node rendered before the item label. Omit glyph `size` / width / height unless expressly overriding the icon-library default.</description>
|
|
59
59
|
</prop>
|
|
60
60
|
<prop name="RadioItem.note" kind="react">
|
|
61
61
|
<description>End-aligned secondary text (e.g. keyboard shortcut) before the check indicator. Rendered muted `xs`.</description>
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
<description>Visual sentiment. `destructive` uses highlight-red wash + text.</description>
|
|
65
65
|
</prop>
|
|
66
66
|
<prop name="SubmenuTrigger.addon" kind="react">
|
|
67
|
-
<description>Decorative leading node rendered before the item label.</description>
|
|
67
|
+
<description>Decorative leading node rendered before the item label. Omit glyph `size` / width / height unless expressly overriding the icon-library default.</description>
|
|
68
68
|
</prop>
|
|
69
69
|
<prop name="SubmenuTrigger.sentiment" kind="react">
|
|
70
70
|
<description>Visual sentiment. `destructive` uses highlight-red wash + text.</description>
|
|
@@ -6,10 +6,12 @@
|
|
|
6
6
|
<do>Account / user chip: `Menu.Trigger` as Surface/Stack (Avatar + Text) opening `Menu.Popup` with static profile header plus Items</do>
|
|
7
7
|
<do>Detached or multi-trigger menus via `Menu.createHandle`</do>
|
|
8
8
|
<do>Custom portal host (iframe preview, shadow root, or app overlay root) via `container` on `Menu.Popup`</do>
|
|
9
|
+
<do>Omit `size` / width / height on Item / LinkItem / checkbox / radio / submenu `addon` icons — prefer icon-library default; set only to expressly override</do>
|
|
9
10
|
<dont>Expecting `Menu.Arrow`, `Menu.Backdrop`, or public Portal/Positioner/Viewport exports</dont>
|
|
11
|
+
<dont>Passing `size={16}` on every menu `addon` icon by habit — omit unless expressly overriding the library default</dont>
|
|
10
12
|
<dont>Closing checkbox/radio items on click by default when the menu should stay open for multi-toggle — pass `closeOnClick` only when a single pick should dismiss</dont>
|
|
11
13
|
<dont>Using physical left/right CSS that breaks RTL submenu chevrons</dont>
|
|
12
|
-
<dont>Expecting RTL item rows / left-opening submenus without
|
|
14
|
+
<dont>Expecting RTL item rows / left-opening submenus without `@viraui/react` `DirectionProvider direction="rtl"` plus app `dir="rtl"` on a portal ancestor (usually `<html>` / document root — a local wrapper alone does not reach body-mounted popups)</dont>
|
|
13
15
|
<dont>Nesting Menu inside Popover for an account menu — Menu already owns portal, positioning, and listbox keyboard behavior</dont>
|
|
14
16
|
<dont>Putting focusable controls (inputs, nested buttons) in `Menu.Popup` outside `Menu.Item` / `Menu.LinkItem` / checkbox / radio / submenu trigger parts — use Popover or Dialog for forms</dont>
|
|
15
17
|
<dont>Using Menu for form-field single-select from a long list — use Select</dont>
|
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
<do>Edge scrim on glass / `data-vibrant` Surface heroes, sheets, or scroll regions where content should fade into blur</do>
|
|
5
5
|
<do>Keep semantics and layout on Surface/Stack/Title/Text children underneath — ProgressiveBlur is decorative atmosphere only</do>
|
|
6
6
|
<do>Use sparingly — stacked `backdrop-filter` is GPU/memory-heavy; prefer one focal overlay per view</do>
|
|
7
|
+
<do>Match a rounded Surface by setting `border-radius` on the ProgressiveBlur root — layers inherit it</do>
|
|
7
8
|
<dont>Leaving the ProgressiveBlur root `position: static` so absolute layers escape the intended overlay box</dont>
|
|
8
9
|
<dont>Driving layout size or scroll behavior from inside the overlay</dont>
|
|
9
10
|
<dont>Scattering ProgressiveBlur across many cards or stacking full-viewport instances</dont>
|
|
10
11
|
<dont>Using ProgressiveBlur as standalone loading or status feedback without a labeled parent region</dont>
|
|
12
|
+
<dont>Nesting under an ancestor that pairs overflow clipping with border-radius (e.g. Surface `overflow="hidden"` + `radius`) — Chromium drops masked backdrop-filter; leave Surface overflow alone and scroll on an inner node</dont>
|
|
11
13
|
</usage>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
2
|
<meta id="prose" title="Prose" category="typography" shared_contract="prose">
|
|
3
|
-
<summary>
|
|
3
|
+
<summary>Text-wall grouping region (articles, docs, privacy) with heading-aware em rhythm; reading column via parent Stack `maxWidth` sized for body Text `size`.</summary>
|
|
4
4
|
<exports>
|
|
5
5
|
<export name="Prose" />
|
|
6
6
|
</exports>
|
|
@@ -2,17 +2,41 @@
|
|
|
2
2
|
<patterns surface="prose">
|
|
3
3
|
<example title="Article with Title and Text">
|
|
4
4
|
<tsx><![CDATA[
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
5
|
+
{/* Body defaults to size m → mid reading column (not the xl band); prefer ch */}
|
|
6
|
+
<Stack maxWidth="60ch" fullWidth>
|
|
7
|
+
<Prose render={<article />}>
|
|
8
|
+
<Title size="2" lineHeight="s" render={<h2 />}>
|
|
9
|
+
Heading-aware document rhythm
|
|
10
|
+
</Title>
|
|
11
|
+
<Text render={<p />} lineHeight="l">
|
|
12
|
+
Direct heading and paragraph children pick up Prose gaps. Type stays on Title and Text. Column width follows body
|
|
13
|
+
size — not the full viewport.
|
|
14
|
+
</Text>
|
|
15
|
+
<Text render={<p />}>A second paragraph uses the block gap, not the heading-end gap.</Text>
|
|
16
|
+
</Prose>
|
|
17
|
+
</Stack>
|
|
18
|
+
]]></tsx>
|
|
19
|
+
<notes>Default `gap="l"`. Landmark via `render={<article />}`. Title in Prose uses `lineHeight="s"`. Stack `maxWidth` in `ch` tracks body Text size (~10–12 words/line). Prefer `ch` over rem. Do not wrap these blocks in Stack for rhythm.</notes>
|
|
20
|
+
</example>
|
|
21
|
+
|
|
22
|
+
<example title="Privacy / docs text wall">
|
|
23
|
+
<tsx><![CDATA[
|
|
24
|
+
{/* Dense body size s → narrower column than default m; prefer ch */}
|
|
25
|
+
<Stack maxWidth="48ch" fullWidth>
|
|
26
|
+
<Prose render={<article />} gap="l">
|
|
27
|
+
<Title size="2" lineHeight="s" render={<h2 />}>
|
|
28
|
+
Privacy policy
|
|
29
|
+
</Title>
|
|
30
|
+
<Text size="s" render={<p />} lineHeight="l">
|
|
31
|
+
Long legal paragraphs use Prose for block gaps. Leading stays on Text. Smaller body size → narrower Stack maxWidth.
|
|
32
|
+
</Text>
|
|
33
|
+
<Text size="s" render={<p />}>
|
|
34
|
+
Following paragraphs omit lineHeight when m is fine. Prefer render p for outline rhythm.
|
|
35
|
+
</Text>
|
|
36
|
+
</Prose>
|
|
37
|
+
</Stack>
|
|
14
38
|
]]></tsx>
|
|
15
|
-
<notes>
|
|
39
|
+
<notes>Text-wall path: Prose for rhythm + Stack measure sized for body `size` (here `s` → narrower than `m`). Not for short card blurbs — those stay Text/Title props (`maxWidth` / `balanced`).</notes>
|
|
16
40
|
</example>
|
|
17
41
|
|
|
18
42
|
<example title="Density and region align">
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
2
|
<props surface="prose">
|
|
3
3
|
<when_to_use>
|
|
4
|
-
<item>
|
|
4
|
+
<item>Text walls — articles, docs, privacy/terms, long editorial — whose direct children are headings and blocks that need heading-aware vertical rhythm</item>
|
|
5
5
|
<item>Article, docs, or changelog regions where Stack `rowGap` would make heading→body and body→body the same</item>
|
|
6
6
|
<item>Optional `gap` density (`s` / `m` / `l`) and region `align` (Title/Text that omit `align` inherit it)</item>
|
|
7
|
+
<item>Reading column via parent Stack `maxWidth` sized for the body Text `size` (smaller → narrower; not one fixed `65ch`–`75ch`); edge-to-edge wall of text is not OK</item>
|
|
7
8
|
</when_to_use>
|
|
8
9
|
<when_not_to_use>
|
|
9
10
|
<item>UI chrome spacing (cards, toolbars, form rows) — use Stack `rowGap` / `columnGap`</item>
|
|
11
|
+
<item>Short card/hero blurbs “for leading” — use Text/Title `lineHeight` / `maxWidth` / `balanced`</item>
|
|
10
12
|
<item>Restyling type, lists, links, or tables — stay on Title / Text / consumer CSS</item>
|
|
11
13
|
<item>Markdown parse or sanitize — Prose only spaces matching direct children</item>
|
|
12
14
|
</when_not_to_use>
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
2
|
<usage surface="prose">
|
|
3
|
+
<do>Use for text walls — articles, docs, privacy/terms, long editorial — not every card blurb (those stay Text/Title + Stack)</do>
|
|
3
4
|
<do>Put headings and blocks as **direct** children — Title/Text with `render={<h* />}` / `render={<p />}`, plus native `ul`/`ol`/`blockquote` when needed</do>
|
|
4
5
|
<do>Pick `gap` `s` / `m` / `l` (default `l`) for density; `align` on Prose to set one `text-align` for the region (omit Title/Text `align` so they inherit)</do>
|
|
6
|
+
<do>Keep a reading column: wrap Prose in Stack `maxWidth` in **`ch`** sized for the **body Text `size`** (smaller type → narrower; `m` mid band; large body → wider — not one fixed band for every article); prefer `ch` over rem; edge-to-edge wall of text is not OK</do>
|
|
5
7
|
<do>Use `render={<article />}` (or another landmark) when the region is the document landmark; name it if the landmark needs a name</do>
|
|
6
|
-
<do>Leave type on Title/Text; Title inside Prose uses `lineHeight="s"`; override `--vui-prose-gap-*` on the Prose root only when the em triple must change</do>
|
|
8
|
+
<do>Leave type on Title/Text; Title inside Prose uses `lineHeight="s"`; body leading via Text `lineHeight` per block (`m` / `l` / `s`); override `--vui-prose-gap-*` on the Prose root only when the em triple must change</do>
|
|
7
9
|
<dont>Using Stack `rowGap` as article rhythm — one gap cannot split heading→body vs body→body</dont>
|
|
8
10
|
<dont>Expecting default Title/Text `span` hosts to join rhythm — they are not heading/block tags</dont>
|
|
9
11
|
<dont>Setting `as` — replace the root with `render` only</dont>
|
|
10
12
|
<dont>Setting `align` on every Title/Text inside Prose when one Prose `align` covers the region</dont>
|
|
11
13
|
<dont>Setting a widget `role` on Prose, or painting font/color/list/link chrome in Prose CSS</dont>
|
|
14
|
+
<dont>Wrapping a short UI blurb in Prose “for leading” — use Text/Title `lineHeight` / `maxWidth` / `balanced` instead</dont>
|
|
12
15
|
</usage>
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
defaultValue="round"
|
|
65
65
|
items={cornerShapeItems}
|
|
66
66
|
alignListWithTrigger={false}
|
|
67
|
-
addon={<ChevronExpandY aria-hidden
|
|
67
|
+
addon={<ChevronExpandY aria-hidden />}
|
|
68
68
|
>
|
|
69
69
|
<Select.Option value="round">Round</Select.Option>
|
|
70
70
|
<Select.Option value="squircle">Squircle</Select.Option>
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
<Select.Option value="blue" addon={<Stack direction="row" columnGap="2xs">{/* swatches */}</Stack>}>
|
|
110
110
|
Blue
|
|
111
111
|
</Select.Option>
|
|
112
|
-
<Select.Option value="custom" addon={<EyeDropper aria-hidden
|
|
112
|
+
<Select.Option value="custom" addon={<EyeDropper aria-hidden />}>
|
|
113
113
|
Custom
|
|
114
114
|
</Select.Option>
|
|
115
115
|
</Select>
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
<item>Wrapping a lone Select in Fieldset when its own label is sufficient</item>
|
|
16
16
|
</when_not_to_use>
|
|
17
17
|
<prop name="addon" kind="react">
|
|
18
|
-
<description>Trigger addon rendered inside `Select.Icon`. Pass any React node; use a named icon from `@viraui/icons/react` for content icons.</description>
|
|
18
|
+
<description>Trigger addon rendered inside `Select.Icon`. Pass any React node; use a named icon from `@viraui/icons/react` for content icons. Omit glyph `size` / width / height unless expressly overriding the icon-library default.</description>
|
|
19
19
|
</prop>
|
|
20
20
|
<prop name="alignListWithTrigger" kind="react">
|
|
21
21
|
<description>When `true`, aligns the list popup width with the trigger via Base UI `alignItemWithTrigger`. Prefer `false` when options use a leading `addon`. On desktop, Base UI also scroll-locks the page while open when this is `true` (keeps the selected item aligned with the trigger) — independent of `modal`.</description>
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
<description>When `true`, open select locks page scroll and blocks outside pointer interaction (Base UI modal). Default `false` skips the modal backdrop/outside pointer block, but page scroll can still lock when `alignListWithTrigger` is `true` (Base UI coupling).</description>
|
|
40
40
|
</prop>
|
|
41
41
|
<prop name="Option.addon" kind="react">
|
|
42
|
-
<description>Decorative leading node rendered before the option label.</description>
|
|
42
|
+
<description>Decorative leading node rendered before the option label. Omit glyph `size` / width / height unless expressly overriding the icon-library default.</description>
|
|
43
43
|
</prop>
|
|
44
44
|
<prop name="Option.addonAlign" kind="react">
|
|
45
45
|
<description>Vertical alignment of the addon relative to the option label row.</description>
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
<dont>Leaving the trigger without `label` or `aria-label`</dont>
|
|
12
12
|
<dont>Inventing `width: 100%` / `w-full` CSS on Select when a parent Stack `fullWidth` / `expandChildren` can own the fill</dont>
|
|
13
13
|
<dont>Leaving `alignListWithTrigger` enabled when options have a leading addon — prefer `alignListWithTrigger={false}`</dont>
|
|
14
|
+
<dont>Passing `size={16}` / `size="1rem"` on every trigger or Option `addon` icon by habit — omit unless expressly overriding the icon-library default</dont>
|
|
14
15
|
<dont>Assuming `modal={false}` alone keeps page scroll — Base UI also scroll-locks while `alignListWithTrigger` is true on desktop</dont>
|
|
15
16
|
<dont>Wrapping a lone Select in Fieldset when its own label is enough</dont>
|
|
16
17
|
</usage>
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
<Surface color={2} radius="l" hPadding="m" vPadding="m">
|
|
25
25
|
<Stack columnGap="m" direction="row" vAlign="center" expandChildren>
|
|
26
26
|
<Stack data-grow={false} minWidth="13ch" direction="row" columnGap="s" vAlign="center">
|
|
27
|
-
<Sun
|
|
27
|
+
<Sun />
|
|
28
28
|
<Text weight="semibold" whiteSpace="nowrap">
|
|
29
29
|
Brightness
|
|
30
30
|
</Text>
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
<description>Sets the rendered spinner size.</description>
|
|
17
17
|
</prop>
|
|
18
18
|
<prop name="variant" kind="react">
|
|
19
|
-
<description>Visual animation style.</description>
|
|
19
|
+
<description>Visual animation style. Catalog: arc, atom, blocks, bouncing-dots, cascade, circular-dots, classic, classic-v2, clock, comet, compass, dual, eclipse, flip, gather, leap, linear-dots, loading, morph, orbit, pulse, radar, ring, ripple, slide, snake, swirl, trace, wave. Legacy aliases: bars→wave, dot-grid→blocks, dots→eclipse.</description>
|
|
20
20
|
</prop>
|
|
21
21
|
<prop name="size" kind="css">
|
|
22
22
|
<description>Spinner glyph size on the root.</description>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<do>Button / IconButton async chrome: set `loading` on the control — it owns the Spinner overlay, width lock, and `aria-busy`</do>
|
|
4
4
|
<do>Standalone status: Stack row with Spinner `aria-hidden` + visible Text (or Autocomplete status) that names the work</do>
|
|
5
5
|
<do>Chip in-progress affordance: small Spinner as Chip `addon` (`addonPosition="end"`) — Chip label stays the accessible name</do>
|
|
6
|
-
<do>Pair `variant
|
|
6
|
+
<do>Pair any Spinner `variant` (catalog or legacy `bars` / `dot-grid` / `dots`) with muted Text / Shimmer in Surface footers when the parent region owns busy semantics</do>
|
|
7
7
|
<dont>Nesting a manual Spinner inside Button / IconButton when `loading` already injects one</dont>
|
|
8
8
|
<dont>Using Spinner alone as the only page-level loading announcement</dont>
|
|
9
9
|
<dont>Omitting `aria-hidden` on decorative standalone Spinners — the component does not hide itself</dont>
|
|
@@ -1,6 +1,71 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
2
|
<patterns surface="stack">
|
|
3
3
|
<!-- Sources: viraui-app/components — cleaned (no handlers, no app-only chrome, no CSS that reinvents Stack props). -->
|
|
4
|
+
<!-- Stack-owned recipes live HERE (local patterns unit). Core `specs/patterns/*` = true multi-surface screen recipes only. -->
|
|
5
|
+
|
|
6
|
+
<example title="Stack as Surface (one DOM node)">
|
|
7
|
+
<tsx><![CDATA[
|
|
8
|
+
{/* Preferred: layout + chrome share one root */}
|
|
9
|
+
<Stack
|
|
10
|
+
direction="row"
|
|
11
|
+
columnGap="s"
|
|
12
|
+
vAlign="center"
|
|
13
|
+
fullWidth
|
|
14
|
+
render={<Surface border="all" color={1} radius="m" hPadding="m" vPadding="s" />}
|
|
15
|
+
>
|
|
16
|
+
<Text size="sm" color="muted">
|
|
17
|
+
Status
|
|
18
|
+
</Text>
|
|
19
|
+
<Chip>Active</Chip>
|
|
20
|
+
</Stack>
|
|
21
|
+
]]></tsx>
|
|
22
|
+
<notes>Gap/align/`fullWidth`/`expandChildren` on Stack; `border`/`color`/`radius`/padding on Surface in `render`. Nest Surface→Stack only when separate roots are required (Elevator, concentric Surfaces). Never invent border/radius CSS on Stack.</notes>
|
|
23
|
+
</example>
|
|
24
|
+
|
|
25
|
+
<example title="Equal-width action row">
|
|
26
|
+
<tsx><![CDATA[
|
|
27
|
+
{/* Full-bleed column CTAs */}
|
|
28
|
+
<Stack fullWidth rowGap="s">
|
|
29
|
+
<Button>Continue</Button>
|
|
30
|
+
<Button variant="secondary">Cancel</Button>
|
|
31
|
+
</Stack>
|
|
32
|
+
|
|
33
|
+
{/* Equal-width row actions — children grow on the main axis. Add fullWidth when this Stack must fill parent width */}
|
|
34
|
+
<Stack expandChildren direction="row" columnGap="s">
|
|
35
|
+
<Button>Continue</Button>
|
|
36
|
+
<Button variant="secondary">Cancel</Button>
|
|
37
|
+
</Stack>
|
|
38
|
+
]]></tsx>
|
|
39
|
+
<notes>`fullWidth` sizes this Stack; `expandChildren` grows children on the main axis. Never invent `width: 100%` / `flex: 1` CSS on Button. Both-axes fill → examples below (not height CSS).</notes>
|
|
40
|
+
</example>
|
|
41
|
+
|
|
42
|
+
<example title="Page chrome (semantic hosts)">
|
|
43
|
+
<tsx><![CDATA[
|
|
44
|
+
<Stack rowGap="m" expandChildren>
|
|
45
|
+
<Stack
|
|
46
|
+
direction="row"
|
|
47
|
+
hAlign="space-between"
|
|
48
|
+
vAlign="center"
|
|
49
|
+
columnGap="m"
|
|
50
|
+
hPadding="m"
|
|
51
|
+
vPadding="m"
|
|
52
|
+
render={<header />}
|
|
53
|
+
>
|
|
54
|
+
<Title render={<h1 />}>Settings</Title>
|
|
55
|
+
<Button>Save</Button>
|
|
56
|
+
</Stack>
|
|
57
|
+
<Stack direction="row" columnGap="m" expandChildren render={<main />}>
|
|
58
|
+
<Stack rowGap="xs" hPadding="s" vPadding="s" render={<nav aria-label="Settings" />}>
|
|
59
|
+
{/* nav links */}
|
|
60
|
+
</Stack>
|
|
61
|
+
<Stack rowGap="l" expandChildren>
|
|
62
|
+
{/* content */}
|
|
63
|
+
</Stack>
|
|
64
|
+
</Stack>
|
|
65
|
+
</Stack>
|
|
66
|
+
]]></tsx>
|
|
67
|
+
<notes>Semantic tags via `render` — Stack stays the layout engine. CSS may set `min-block-size` / scroll; never `display:flex`. Omit `render={<div />}` (default host).</notes>
|
|
68
|
+
</example>
|
|
4
69
|
|
|
5
70
|
<example title="App header (hub)">
|
|
6
71
|
<tsx><![CDATA[
|
|
@@ -73,10 +138,10 @@
|
|
|
73
138
|
{/* brand */}
|
|
74
139
|
<Stack rowGap="xl" vAlign="center">
|
|
75
140
|
<Stack vPadding={[0, 'l']} rowGap="xl">
|
|
76
|
-
<Title size="1" render={<h1 />} maxWidth="
|
|
141
|
+
<Title size="1" render={<h1 />} maxWidth="36ch" lineHeight="s">
|
|
77
142
|
Design systems that ship
|
|
78
143
|
</Title>
|
|
79
|
-
<Text size="2xl" tone="muted" maxWidth="
|
|
144
|
+
<Text size="2xl" tone="muted" maxWidth="68ch">
|
|
80
145
|
Sign in to continue to the studio.
|
|
81
146
|
</Text>
|
|
82
147
|
</Stack>
|
|
@@ -216,7 +281,7 @@
|
|
|
216
281
|
<Title align="center" size="5" render={<h3 />}>
|
|
217
282
|
No Team Members
|
|
218
283
|
</Title>
|
|
219
|
-
<Text size="s" align="center" maxWidth="
|
|
284
|
+
<Text size="s" align="center" maxWidth="40ch" tone="muted">
|
|
220
285
|
Invite your team to collaborate on this project.
|
|
221
286
|
</Text>
|
|
222
287
|
<Button>Invite Members</Button>
|
|
@@ -236,7 +301,7 @@
|
|
|
236
301
|
<Title size="6" render={<h2 />}>
|
|
237
302
|
Preferences
|
|
238
303
|
</Title>
|
|
239
|
-
<Text size="s" maxWidth="
|
|
304
|
+
<Text size="s" maxWidth="45ch" tone="muted">
|
|
240
305
|
Manage your account settings and notifications.
|
|
241
306
|
</Text>
|
|
242
307
|
</Stack>
|
|
@@ -360,4 +425,37 @@
|
|
|
360
425
|
]]></tsx>
|
|
361
426
|
<notes>From `editor/preview-grid/blocks/shipping-address`. `expandChildren` on row Stacks shares width across field pairs — do not invent per-field `flex`/`width` CSS.</notes>
|
|
362
427
|
</example>
|
|
428
|
+
|
|
429
|
+
<example title="Row panels fill both axes">
|
|
430
|
+
<tsx><![CDATA[
|
|
431
|
+
{/* Parent must be sized (viewport shell, fullHeight ancestor, …). No height CSS on Stack/children. */}
|
|
432
|
+
<Stack direction="row" columnGap="s" expandChildren fullHeight vAlign="stretch">
|
|
433
|
+
<Stack rowGap="s" hPadding="m" vPadding="m">
|
|
434
|
+
{/* sidebar / panel A */}
|
|
435
|
+
</Stack>
|
|
436
|
+
<Stack rowGap="m" hPadding="m" vPadding="m" expandChildren>
|
|
437
|
+
{/* main / panel B */}
|
|
438
|
+
</Stack>
|
|
439
|
+
</Stack>
|
|
440
|
+
]]></tsx>
|
|
441
|
+
<notes>Canonical horizontal both-axes fill (Stack-owned). Main = `expandChildren`; cross = `vAlign="stretch"`; root block size = `fullHeight`. Never `style`/`className` height on Stack or children.</notes>
|
|
442
|
+
</example>
|
|
443
|
+
|
|
444
|
+
<example title="Column sections fill both axes">
|
|
445
|
+
<tsx><![CDATA[
|
|
446
|
+
{/* Parent must be sized. Children share height + fill width — props only. */}
|
|
447
|
+
<Stack rowGap="s" expandChildren fullWidth fullHeight hAlign="stretch">
|
|
448
|
+
<Stack direction="row" columnGap="m" vAlign="center" hPadding="m" vPadding="s">
|
|
449
|
+
{/* header strip */}
|
|
450
|
+
</Stack>
|
|
451
|
+
<Stack rowGap="m" hPadding="m" vPadding="m" expandChildren>
|
|
452
|
+
{/* grow body */}
|
|
453
|
+
</Stack>
|
|
454
|
+
<Stack direction="row" columnGap="s" hPadding="m" vPadding="s" data-grow="false">
|
|
455
|
+
{/* footer actions — opt out of main-axis grow */}
|
|
456
|
+
</Stack>
|
|
457
|
+
</Stack>
|
|
458
|
+
]]></tsx>
|
|
459
|
+
<notes>Canonical vertical both-axes fill (Stack-owned). Main = `expandChildren`; cross = `hAlign="stretch"`; root = `fullWidth` + `fullHeight`. Footer uses `data-grow="false"` so only the body expands.</notes>
|
|
460
|
+
</example>
|
|
363
461
|
</patterns>
|
|
@@ -6,13 +6,16 @@
|
|
|
6
6
|
<item>Custom native root through render while keeping data-stack hooks</item>
|
|
7
7
|
<item>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)</item>
|
|
8
8
|
<item>Centered max-width shells: parent `hAlign="center"` + child `fullWidth` + `maxWidth`</item>
|
|
9
|
+
<item>Readable type columns: `maxWidth` in **`ch`** around Text/Title/Prose for ~10–12 words/line — width **tracks body `size`** (smaller → narrower; prefer `ch` over rem; never one fixed band for every size)</item>
|
|
9
10
|
<item>Full-bleed or equal-width action clusters (Buttons, etc.): `fullWidth` and/or `expandChildren` instead of per-child width CSS</item>
|
|
11
|
+
<item>Children fill both axes in a sized parent — see this surface `patterns.xml`: row = `direction="row"` + `expandChildren` + `fullHeight` + `vAlign="stretch"`; column = `expandChildren` + `fullWidth` + `fullHeight` + `hAlign="stretch"` — never invent `height`/`width` / `block-size`/`inline-size: 100%` CSS</item>
|
|
10
12
|
</when_to_use>
|
|
11
13
|
<when_not_to_use>
|
|
12
14
|
<item>Cases where a single component already owns required flex chrome</item>
|
|
13
15
|
<item>Expecting direct children to grow on the main axis without setting `expandChildren`</item>
|
|
14
16
|
<item>Expecting this stack to fill parent inline size under non-stretch alignment without `fullWidth` (or an explicit `inlineSize`)</item>
|
|
15
|
-
<item>
|
|
17
|
+
<item>Expecting this stack to fill parent block size without `fullHeight` (or an explicit `blockSize`)</item>
|
|
18
|
+
<item>Inventing `width`/`height` / `inline-size`/`block-size: 100%` / `w-full` / size-fill className on this Stack or content-sized children when `fullWidth` / `fullHeight` / `expandChildren` + stretch align cover it (see `patterns.xml`) — or on fixed-size children (IconButton) where size CSS is useless</item>
|
|
16
19
|
<item>Using `enableContainer` inside complex masonry-like layouts when you don't need container queries (inline-size containment can change nested layout)</item>
|
|
17
20
|
</when_not_to_use>
|
|
18
21
|
<prop name="columnGap" kind="react">
|
|
@@ -25,10 +28,13 @@
|
|
|
25
28
|
<description>Renders children across rows or columns using the chosen flex direction.</description>
|
|
26
29
|
</prop>
|
|
27
30
|
<prop name="expandChildren" kind="react">
|
|
28
|
-
<description>Makes direct children grow along the flex main axis (`flex-grow`). Default `false`. Use for equal-width row actions (Buttons, etc.) instead of inventing `width`/`flex` CSS on each child. Orthogonal to `fullWidth` (children grow vs this root's
|
|
31
|
+
<description>Makes direct children grow along the flex main axis (`flex-grow`). Default `false`. Use for equal-width row actions (Buttons, etc.) instead of inventing `width`/`flex` CSS on each child. Cross-axis fill stays on `hAlign` / `vAlign="stretch"` (which prop is cross depends on `direction`). Orthogonal to `fullWidth` / `fullHeight` (children grow vs this root's size). A child opts out with its own `data-grow="false"`; ancestor `data-grow` does not inherit into nested stacks.</description>
|
|
32
|
+
</prop>
|
|
33
|
+
<prop name="fullHeight" kind="react">
|
|
34
|
+
<description>Sets `block-size: 100%` on the stack root so it fills the parent's block size. Default `false`. Prefer this over `style`/`className` `height` / `block-size: 100%` on this Stack. Pair with `expandChildren` and cross-axis `hAlign`/`vAlign="stretch"` so children fill both axes without per-child size CSS. Orthogonal to `expandChildren` and `fullWidth`.</description>
|
|
29
35
|
</prop>
|
|
30
36
|
<prop name="fullWidth" kind="react">
|
|
31
|
-
<description>Sets `inline-size: 100%` on the stack root so it fills the parent's inline size. Default `false`. Prefer this (plus cross-axis stretch) so content-sized children like Button span a panel — do not add `width: 100%` CSS on those children. Use with `maxWidth` under a parent `hAlign="center"` for a fluid capped centered shell. Does not grow children — use `expandChildren` for that.</description>
|
|
37
|
+
<description>Sets `inline-size: 100%` on the stack root so it fills the parent's inline size. Default `false`. Prefer this (plus cross-axis stretch) so content-sized children like Button span a panel — do not add `width: 100%` CSS on those children. Use with `maxWidth` under a parent `hAlign="center"` for a fluid capped centered shell. Pair with `fullHeight` when the root must fill both parent axes. Does not grow children — use `expandChildren` for that.</description>
|
|
32
38
|
</prop>
|
|
33
39
|
<prop name="hAlign" kind="react">
|
|
34
40
|
<description>Aligns content on the horizontal axis from the consumer point of view.</description>
|
|
@@ -2,17 +2,21 @@
|
|
|
2
2
|
<usage surface="stack">
|
|
3
3
|
<do>Default structural box instead of a bare wrapper `div` — Stack owns flex + token gap/padding/align/`fullWidth`/`render`</do>
|
|
4
4
|
<do>Login/signup (or similar auth swap): host Tabs + Textfield(s) + Button (+ optional Fieldset) inside a Stack or `Stack render={<Surface … />}` shell — props only, 0 custom CSS</do>
|
|
5
|
-
<do>Flex + Surface chrome on one node via `render={<Surface … />}` — prefer over a CSS border class or an extra wrapper (see
|
|
6
|
-
<do>Equal-width action or field clusters (Button, Chip, Textfield): `fullWidth` and/or `expandChildren` on this Stack — never per-child width CSS</do>
|
|
5
|
+
<do>Flex + Surface chrome on one node via `render={<Surface … />}` — prefer over a CSS border class or an extra wrapper (see this surface `patterns.xml` — Stack as Surface)</do>
|
|
6
|
+
<do>Equal-width action or field clusters (Button, Chip, Textfield): `fullWidth` and/or `expandChildren` on this Stack — never per-child width CSS (see `patterns.xml`)</do>
|
|
7
|
+
<do>Children fill **both** axes inside a sized parent — this surface `patterns.xml` (never invent size-fill CSS):
|
|
8
|
+
row → `direction="row"` + `expandChildren` + `fullHeight` + `vAlign="stretch"` (share width + fill height);
|
|
9
|
+
column → `expandChildren` + `fullWidth` + `fullHeight` + `hAlign="stretch"` (share height + fill width)</do>
|
|
7
10
|
<do>Settings rows: Stack `direction="row"` + Text (label/description column) + Switch or Checkbox — nest in Surface for panel chrome</do>
|
|
8
11
|
<do>Centered capped shells: parent `hAlign="center"` + child Stack `fullWidth` + `maxWidth`</do>
|
|
12
|
+
<do>Readable type column: Stack `maxWidth` in **`ch`** around Text/Title/Prose sized for the dominant body `size` (~10–12 words/line; smaller → narrower) — prefer `ch` over rem; never one fixed ch for every size</do>
|
|
9
13
|
<do>Semantic/native roots via `render` (`header`, `main`, `nav`, `section`, …) while keeping Stack as the layout engine</do>
|
|
10
14
|
<do>Opt into `@container stack` with `enableContainer` when layout should follow this Stack's inline-size, not the viewport</do>
|
|
11
15
|
<dont>Reaching for a plain wrapper `div` when Stack (optionally with `render` for a semantic tag) can own the box</dont>
|
|
12
16
|
<dont>Passing `render={<div />}` (or any host that matches Stack's default root) — omit `render`; use it only for a different host (`header`, `Surface`, …)</dont>
|
|
13
17
|
<dont>Assuming Stack expands direct children by default — pass `expandChildren` when children should grow on the flex main axis</dont>
|
|
14
18
|
<dont>Using `expandChildren` to fill parent width under `hAlign="center"` — that is `fullWidth` on the child Stack (self `inline-size`), not child flex-grow</dont>
|
|
15
|
-
<dont>Inventing `width
|
|
19
|
+
<dont>Inventing `width`/`height` / `inline-size`/`block-size: 100%` / `w-full` / size-fill `className` on this Stack or content-sized children when `fullWidth` / `fullHeight` / `expandChildren` + stretch align can own the fill — or when children are intentionally fixed-size (e.g. IconButton)</dont>
|
|
16
20
|
<dont>Inventing CSS `gap` / `padding` / `paddingBlock*` / `paddingInline*` / side paddings (`style` or className) when public spacing props cover it — one-sided inset uses `hPadding`/`vPadding` `[start, end]` tuples (e.g. `vPadding={[0, 'l']}`), not `paddingBlockEnd: '1rem'`</dont>
|
|
17
21
|
<dont>Putting `data-grow="false"` on an ancestor to control nested `expandChildren` — set it on the child that should not grow</dont>
|
|
18
22
|
<dont>Combining `fullWidth` with `inline` — prefer block flex when the root must fill parent inline size</dont>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<ToggleButton
|
|
31
31
|
value="light"
|
|
32
32
|
aria-label="Light"
|
|
33
|
-
restingIcon={<Sun aria-hidden
|
|
33
|
+
restingIcon={<Sun aria-hidden />}
|
|
34
34
|
variant="flat"
|
|
35
35
|
size="s"
|
|
36
36
|
pressedVariant="secondary"
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
<ToggleButton
|
|
39
39
|
value="dark"
|
|
40
40
|
aria-label="Dark"
|
|
41
|
-
restingIcon={<MoonStars aria-hidden
|
|
41
|
+
restingIcon={<MoonStars aria-hidden />}
|
|
42
42
|
variant="flat"
|
|
43
43
|
size="s"
|
|
44
44
|
pressedVariant="secondary"
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
<ToggleButton
|
|
47
47
|
value="system"
|
|
48
48
|
aria-label="System"
|
|
49
|
-
restingIcon={<DarkLight aria-hidden
|
|
49
|
+
restingIcon={<DarkLight aria-hidden />}
|
|
50
50
|
variant="flat"
|
|
51
51
|
size="s"
|
|
52
52
|
pressedVariant="secondary"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<usage surface="surface">
|
|
3
3
|
<do>Group content with base-level background and contrast border — nest Stack for child gaps (Surface has no gap prop)</do>
|
|
4
4
|
<do>Login/signup shell: Surface (or `Stack render={<Surface … />}`) hosts Tabs + Textfield(s) + Button (+ optional Fieldset) — chrome + layout via props, 0 custom CSS</do>
|
|
5
|
-
<do>Accept Stack as host via their `render={<Surface … />}` so border/fill/radius share one DOM node — prefer over inventing chrome CSS (see
|
|
5
|
+
<do>Accept Stack as host via their `render={<Surface … />}` so border/fill/radius share one DOM node — prefer over inventing chrome CSS (see Stack `patterns.xml` — Stack as Surface)</do>
|
|
6
6
|
<do>Settings / preferences panels: Surface card + Stack body + Switch/Checkbox rows (optionally padded inner Surfaces) + Button footer strip</do>
|
|
7
7
|
<do>Frosted glass panels with `data-vibrant` — omit `color` for page-level shell or pass `color` for a tinted fill</do>
|
|
8
8
|
<do>Compose with Elevator for animated elevation — Surface has no `elevation` prop</do>
|