@viraui/react 2026.6.0 → 2026.6.2
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 +5 -5
- package/dist/components/radio/radio-group.d.ts +1 -1
- package/dist/components/stack/stack.d.ts +4 -1
- package/dist/components/tabs/tabs.css +1 -1
- package/dist/components/text/text.css +1 -1
- package/dist/components/text/text.d.ts +12 -2
- package/dist/components/text/text.js +2 -1
- package/dist/components/textfield/textfield.d.ts +1 -0
- package/dist/components/title/title.css +1 -1
- package/dist/components/title/title.d.ts +12 -2
- package/dist/components/title/title.js +2 -1
- package/dist/specs/PROTOCOL.md +1 -1
- package/dist/specs/activity-hints.xml +18 -3
- package/dist/specs/components/accordion/patterns.xml +69 -5
- package/dist/specs/components/accordion/props.xml +4 -4
- package/dist/specs/components/accordion/usage.xml +8 -4
- package/dist/specs/components/annotate/patterns.xml +50 -3
- package/dist/specs/components/annotate/props.xml +22 -22
- package/dist/specs/components/annotate/usage.xml +7 -6
- package/dist/specs/components/autocomplete/patterns.xml +123 -7
- package/dist/specs/components/autocomplete/props.xml +14 -14
- package/dist/specs/components/autocomplete/usage.xml +11 -6
- package/dist/specs/components/avatar/patterns.xml +78 -3
- package/dist/specs/components/avatar/props.xml +8 -8
- package/dist/specs/components/avatar/usage.xml +9 -3
- package/dist/specs/components/avatar-group/patterns.xml +65 -3
- package/dist/specs/components/avatar-group/props.xml +8 -8
- package/dist/specs/components/avatar-group/usage.xml +10 -7
- package/dist/specs/components/badge/patterns.xml +57 -3
- package/dist/specs/components/badge/props.xml +8 -8
- package/dist/specs/components/badge/usage.xml +5 -3
- package/dist/specs/components/beam/meta.xml +1 -1
- package/dist/specs/components/beam/patterns.xml +68 -3
- package/dist/specs/components/beam/props.xml +22 -22
- package/dist/specs/components/beam/usage.xml +7 -7
- package/dist/specs/components/bleed/patterns.xml +54 -3
- package/dist/specs/components/bleed/props.xml +2 -2
- package/dist/specs/components/bleed/usage.xml +6 -3
- package/dist/specs/components/breakpoints/meta.xml +1 -1
- package/dist/specs/components/breakpoints/patterns.xml +1 -6
- package/dist/specs/components/breakpoints/props.xml +4 -2
- package/dist/specs/components/breakpoints/usage.xml +10 -2
- package/dist/specs/components/button/patterns.xml +124 -6
- package/dist/specs/components/button/props.xml +33 -32
- package/dist/specs/components/button/usage.xml +13 -13
- package/dist/specs/components/checkbox/patterns.xml +83 -3
- package/dist/specs/components/checkbox/props.xml +10 -10
- package/dist/specs/components/checkbox/usage.xml +11 -6
- package/dist/specs/components/chip/patterns.xml +74 -3
- package/dist/specs/components/chip/props.xml +14 -14
- package/dist/specs/components/chip/usage.xml +10 -6
- package/dist/specs/components/clamp-text/patterns.xml +1 -4
- package/dist/specs/components/clamp-text/props.xml +2 -2
- package/dist/specs/components/clamp-text/usage.xml +8 -5
- package/dist/specs/components/dialog/patterns.xml +136 -15
- package/dist/specs/components/dialog/props.xml +2 -2
- package/dist/specs/components/dialog/usage.xml +9 -7
- package/dist/specs/components/elevator/patterns.xml +54 -3
- package/dist/specs/components/elevator/usage.xml +8 -5
- package/dist/specs/components/fieldset/patterns.xml +97 -3
- package/dist/specs/components/fieldset/usage.xml +7 -5
- package/dist/specs/components/fit-text/patterns.xml +1 -4
- package/dist/specs/components/fit-text/props.xml +2 -2
- package/dist/specs/components/fit-text/usage.xml +8 -6
- package/dist/specs/components/glow/meta.xml +1 -1
- package/dist/specs/components/glow/patterns.xml +74 -3
- package/dist/specs/components/glow/props.xml +16 -16
- package/dist/specs/components/glow/usage.xml +8 -7
- package/dist/specs/components/grid/patterns.xml +88 -5
- package/dist/specs/components/grid/props.xml +23 -23
- package/dist/specs/components/grid/usage.xml +9 -5
- package/dist/specs/components/icon-button/patterns.xml +97 -6
- package/dist/specs/components/icon-button/props.xml +32 -32
- package/dist/specs/components/icon-button/usage.xml +11 -9
- package/dist/specs/components/linear-progress/patterns.xml +58 -3
- package/dist/specs/components/linear-progress/props.xml +6 -6
- package/dist/specs/components/linear-progress/usage.xml +9 -8
- package/dist/specs/components/masonry/patterns.xml +68 -5
- package/dist/specs/components/masonry/props.xml +2 -2
- package/dist/specs/components/masonry/usage.xml +9 -4
- package/dist/specs/components/menu/patterns.xml +179 -15
- package/dist/specs/components/menu/usage.xml +8 -7
- package/dist/specs/components/meter/patterns.xml +49 -3
- package/dist/specs/components/meter/props.xml +6 -6
- package/dist/specs/components/meter/usage.xml +10 -7
- package/dist/specs/components/popover/patterns.xml +118 -9
- package/dist/specs/components/popover/props.xml +2 -2
- package/dist/specs/components/popover/usage.xml +9 -8
- package/dist/specs/components/progressive-blur/meta.xml +1 -1
- package/dist/specs/components/progressive-blur/patterns.xml +1 -4
- package/dist/specs/components/progressive-blur/props.xml +2 -2
- package/dist/specs/components/progressive-blur/usage.xml +7 -6
- package/dist/specs/components/radio/patterns.xml +55 -5
- package/dist/specs/components/radio/props.xml +8 -8
- package/dist/specs/components/radio/usage.xml +9 -6
- package/dist/specs/components/select/patterns.xml +124 -8
- package/dist/specs/components/select/props.xml +18 -18
- package/dist/specs/components/select/usage.xml +11 -10
- package/dist/specs/components/separator/patterns.xml +121 -3
- package/dist/specs/components/separator/props.xml +4 -4
- package/dist/specs/components/separator/usage.xml +8 -5
- package/dist/specs/components/shimmer/patterns.xml +23 -3
- package/dist/specs/components/shimmer/props.xml +8 -8
- package/dist/specs/components/shimmer/usage.xml +7 -5
- package/dist/specs/components/skeleton/patterns.xml +172 -4
- package/dist/specs/components/skeleton/props.xml +14 -14
- package/dist/specs/components/skeleton/usage.xml +11 -7
- package/dist/specs/components/slider/patterns.xml +111 -3
- package/dist/specs/components/slider/props.xml +10 -10
- package/dist/specs/components/slider/usage.xml +11 -5
- package/dist/specs/components/spinner/patterns.xml +35 -3
- package/dist/specs/components/spinner/props.xml +2 -2
- package/dist/specs/components/spinner/usage.xml +8 -5
- package/dist/specs/components/stack/patterns.xml +359 -3
- package/dist/specs/components/stack/props.xml +24 -22
- package/dist/specs/components/stack/usage.xml +16 -10
- package/dist/specs/components/static-noise/meta.xml +1 -1
- package/dist/specs/components/static-noise/patterns.xml +20 -3
- package/dist/specs/components/static-noise/usage.xml +5 -5
- package/dist/specs/components/surface/patterns.xml +188 -3
- package/dist/specs/components/surface/props.xml +26 -26
- package/dist/specs/components/surface/usage.xml +15 -12
- package/dist/specs/components/switch/patterns.xml +73 -3
- package/dist/specs/components/switch/props.xml +12 -12
- package/dist/specs/components/switch/usage.xml +10 -5
- package/dist/specs/components/tabs/patterns.xml +111 -6
- package/dist/specs/components/tabs/props.xml +2 -2
- package/dist/specs/components/tabs/usage.xml +7 -3
- package/dist/specs/components/text/patterns.xml +97 -3
- package/dist/specs/components/text/props.xml +48 -43
- package/dist/specs/components/text/usage.xml +11 -4
- package/dist/specs/components/textarea/patterns.xml +49 -3
- package/dist/specs/components/textarea/props.xml +7 -6
- package/dist/specs/components/textarea/usage.xml +8 -5
- package/dist/specs/components/textfield/patterns.xml +163 -3
- package/dist/specs/components/textfield/props.xml +12 -11
- package/dist/specs/components/textfield/usage.xml +9 -3
- package/dist/specs/components/title/patterns.xml +74 -3
- package/dist/specs/components/title/props.xml +48 -43
- package/dist/specs/components/title/usage.xml +10 -7
- package/dist/specs/components/toast/patterns.xml +85 -8
- package/dist/specs/components/toast/usage.xml +8 -5
- package/dist/specs/components/toggle-button/patterns.xml +101 -3
- package/dist/specs/components/toggle-button/props.xml +16 -16
- package/dist/specs/components/toggle-button/usage.xml +9 -5
- package/dist/specs/components/toggle-group/patterns.xml +34 -5
- package/dist/specs/components/toggle-group/usage.xml +9 -5
- package/dist/specs/components/tooltip/patterns.xml +110 -6
- package/dist/specs/components/tooltip/props.xml +2 -2
- package/dist/specs/components/tooltip/usage.xml +8 -5
- package/dist/specs/components/typewriter/patterns.xml +18 -3
- package/dist/specs/components/typewriter/props.xml +2 -2
- package/dist/specs/components/typewriter/usage.xml +9 -8
- package/dist/specs/foundation/attributes.xml +67 -37
- package/dist/specs/foundation/bootstrap.xml +6 -6
- package/dist/specs/foundation/elevation.xml +51 -3
- package/dist/specs/foundation/modules.xml +117 -40
- package/dist/specs/foundation/theme-topics.xml +62 -27
- package/dist/specs/foundation/toggles.xml +2 -2
- package/dist/specs/index.xml +42 -6
- package/dist/specs/patterns/card-grid.xml +35 -0
- package/dist/specs/patterns/compose-layout-first.xml +32 -0
- package/dist/specs/patterns/equal-width-actions.xml +22 -0
- package/dist/specs/patterns/page-chrome.xml +34 -0
- package/dist/specs/patterns/settings-panel.xml +30 -0
- package/dist/specs/patterns/settings-row.xml +9 -7
- package/dist/specs/patterns/stack-as-surface.xml +37 -0
- package/package.json +9 -9
|
@@ -1,12 +1,116 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
2
|
<patterns surface="tooltip">
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
<!-- Sources: viraui-app/components + design-kitchen preview-grid — cleaned (no handlers, no portal/preview chrome). -->
|
|
4
|
+
|
|
5
|
+
<example title="Provider wrap">
|
|
6
|
+
<tsx><![CDATA[
|
|
7
|
+
<Tooltip.Provider>
|
|
8
|
+
{/* app / toolbar tree */}
|
|
9
|
+
</Tooltip.Provider>
|
|
10
|
+
]]></tsx>
|
|
11
|
+
<notes>From `providers/providers` (+ preview providers). One Provider groups adjacent tooltips for shared open/close delay.</notes>
|
|
12
|
+
</example>
|
|
13
|
+
|
|
14
|
+
<example title="Canvas zoom chip">
|
|
15
|
+
<tsx><![CDATA[
|
|
16
|
+
<Tooltip>
|
|
17
|
+
<Tooltip.Trigger
|
|
18
|
+
render={
|
|
19
|
+
<Surface color={1} border="all" radius="m" vPadding="2xs" hPadding="2xs" aria-label="100%">
|
|
20
|
+
<Stack direction="row" vAlign="center">
|
|
21
|
+
<IconButton aria-label="Zoom out" icon={<Minus aria-hidden size="1rem" />} variant="flat" />
|
|
22
|
+
<IconButton aria-label="Reset zoom" icon={<FocusCenter aria-hidden size="1rem" />} variant="flat" />
|
|
23
|
+
<IconButton aria-label="Zoom in" icon={<Plus aria-hidden size="1rem" />} variant="flat" />
|
|
24
|
+
</Stack>
|
|
25
|
+
</Surface>
|
|
26
|
+
}
|
|
27
|
+
/>
|
|
28
|
+
<Tooltip.Content side="bottom">100%</Tooltip.Content>
|
|
29
|
+
</Tooltip>
|
|
30
|
+
]]></tsx>
|
|
31
|
+
<notes>From `editor/canvas/canvas-zoom`. Whole chip is the Trigger; Content shows current zoom. Absolute shell position stays outside this hint.</notes>
|
|
32
|
+
</example>
|
|
33
|
+
|
|
34
|
+
<example title="Shuffle lock toggle">
|
|
35
|
+
<tsx><![CDATA[
|
|
36
|
+
<Tooltip>
|
|
37
|
+
<Tooltip.Trigger
|
|
38
|
+
render={
|
|
39
|
+
<ToggleButton
|
|
40
|
+
aria-label="Shuffle lock"
|
|
41
|
+
pressed={false}
|
|
42
|
+
variant="flat"
|
|
43
|
+
restingIcon={<LockOpen2 aria-hidden size="1rem" />}
|
|
44
|
+
pressedIcon={<Lock aria-hidden size="1rem" />}
|
|
45
|
+
/>
|
|
46
|
+
}
|
|
47
|
+
/>
|
|
48
|
+
<Tooltip.Content>Unlocked in shuffle</Tooltip.Content>
|
|
49
|
+
</Tooltip>
|
|
50
|
+
]]></tsx>
|
|
51
|
+
<notes>From `editor/controls/shuffle-lock-toggle`. Icon ToggleButton + short lock state copy. Same shape as primary-color sync Tooltip addon.</notes>
|
|
52
|
+
</example>
|
|
53
|
+
|
|
54
|
+
<example title="Compat hint glyph">
|
|
55
|
+
<tsx><![CDATA[
|
|
56
|
+
<Tooltip>
|
|
57
|
+
<Tooltip.Trigger
|
|
58
|
+
delay={50}
|
|
59
|
+
render={
|
|
60
|
+
<span aria-label="Supported by: Chrome, Edge, Firefox">
|
|
61
|
+
<TriangleWarning aria-hidden size="1rem" color="var(--highlight-yellow)" />
|
|
62
|
+
</span>
|
|
63
|
+
}
|
|
64
|
+
/>
|
|
65
|
+
<Tooltip.Content>
|
|
66
|
+
<Stack direction="row" columnGap="s" vAlign="center">
|
|
67
|
+
{/* browser logos */}
|
|
68
|
+
</Stack>
|
|
69
|
+
</Tooltip.Content>
|
|
70
|
+
</Tooltip>
|
|
71
|
+
]]></tsx>
|
|
72
|
+
<notes>From `editor/controls/compat-label`. Non-button Trigger + rich Content row. Drop module CSS classes.</notes>
|
|
73
|
+
</example>
|
|
74
|
+
|
|
75
|
+
<example title="Metric label hint">
|
|
76
|
+
<tsx><![CDATA[
|
|
77
|
+
<Stack columnGap="m" direction="row" hAlign="space-between" vAlign="center">
|
|
5
78
|
<Tooltip>
|
|
6
|
-
<Tooltip.Trigger
|
|
7
|
-
|
|
79
|
+
<Tooltip.Trigger
|
|
80
|
+
render={
|
|
81
|
+
<Button size="s" variant="flat">
|
|
82
|
+
APY
|
|
83
|
+
</Button>
|
|
84
|
+
}
|
|
85
|
+
/>
|
|
86
|
+
<Tooltip.Content>
|
|
87
|
+
<Text size="s">Annual percentage yield after daily compounding on cash sweep.</Text>
|
|
88
|
+
</Tooltip.Content>
|
|
8
89
|
</Tooltip>
|
|
9
|
-
|
|
10
|
-
|
|
90
|
+
<Text family="mono" size="s" weight="semibold">
|
|
91
|
+
4.82%
|
|
92
|
+
</Text>
|
|
93
|
+
</Stack>
|
|
94
|
+
]]></tsx>
|
|
95
|
+
<notes>From preview-grid `contextual-hints`. Flat Button label as Trigger; Content carries the definition.</notes>
|
|
96
|
+
</example>
|
|
97
|
+
|
|
98
|
+
<example title="Toolbar shared handle">
|
|
99
|
+
<tsx><![CDATA[
|
|
100
|
+
const toolbarHandle = Tooltip.createHandle<string>();
|
|
101
|
+
|
|
102
|
+
<Tooltip.Trigger
|
|
103
|
+
closeDelay={200}
|
|
104
|
+
handle={toolbarHandle}
|
|
105
|
+
payload="Duplicate"
|
|
106
|
+
render={<Duplicate size={22} aria-label="Duplicate" />}
|
|
107
|
+
/>
|
|
108
|
+
{/* more Icon triggers with the same handle… */}
|
|
109
|
+
|
|
110
|
+
<Tooltip handle={toolbarHandle}>
|
|
111
|
+
{({ payload }) => <Tooltip.Content>{payload as string}</Tooltip.Content>}
|
|
112
|
+
</Tooltip>
|
|
113
|
+
]]></tsx>
|
|
114
|
+
<notes>From preview-grid `action-toolbar` (+ team-directory mute Badge). One `createHandle` morphs Content across many triggers.</notes>
|
|
11
115
|
</example>
|
|
12
116
|
</patterns>
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
<prop name="Content.container" kind="react">
|
|
15
15
|
<description>Portal mount node (iframe body, shadow root, or app overlay root). Omit for Base UI default (`document.body` from the module window — iframe hosts must pass the iframe document body explicitly).</description>
|
|
16
16
|
</prop>
|
|
17
|
-
<
|
|
17
|
+
<prop name="content-fade-duration" kind="css">
|
|
18
18
|
<description>content fade duration custom property on the component root.</description>
|
|
19
|
-
</
|
|
19
|
+
</prop>
|
|
20
20
|
</props>
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
2
|
<usage surface="tooltip">
|
|
3
|
-
<do>Short hints on
|
|
4
|
-
<do>
|
|
5
|
-
<do>
|
|
6
|
-
<do>
|
|
3
|
+
<do>Short hover/focus hints on IconButton, ToggleButton, flat Button, or glyph triggers</do>
|
|
4
|
+
<do>Wrap adjacent tooltips in `Tooltip.Provider` for shared open/close delay</do>
|
|
5
|
+
<do>Compose Trigger via `render` (Surface chip, IconButton, ToggleButton) — Content holds the short copy</do>
|
|
6
|
+
<do>Shared toolbar labels: `Tooltip.createHandle` + Trigger `payload` + Root render-function children</do>
|
|
7
|
+
<do>Custom portal host via `container` on `Tooltip.Content`</do>
|
|
8
|
+
<do>Use Tooltip for concise hints; use Popover for rich panels, links, forms, or content that must stay open under pointer</do>
|
|
9
|
+
<do>Use Toast for system-wide transient alerts — not Tooltip</do>
|
|
7
10
|
<dont>Putting essential-only information in a tooltip with no accessible name on the trigger</dont>
|
|
8
11
|
<dont>Expecting `Tooltip.Arrow` (it is intentionally not exported or rendered)</dont>
|
|
9
|
-
<dont>Using tooltip for modal or focus-trapped tasks</dont>
|
|
12
|
+
<dont>Using tooltip for modal or focus-trapped tasks — use Dialog or Popover</dont>
|
|
10
13
|
</usage>
|
|
@@ -1,7 +1,22 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
2
|
<patterns surface="typewriter">
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
<!-- Sources: viraui-app/components/auth/login-view — cleaned (no i18n / mobile branching). -->
|
|
4
|
+
|
|
5
|
+
<example title="Auth hero cycle">
|
|
6
|
+
<tsx><![CDATA[
|
|
7
|
+
<Title size="1" render={<h1 />} maxWidth="32rem" lineHeight="s">
|
|
8
|
+
<Typewriter
|
|
9
|
+
texts={[
|
|
10
|
+
'Ship real UI at the speed of thought.',
|
|
11
|
+
'Ship real UI at the speed of your LLM.',
|
|
12
|
+
'Ship real UI at the speed of your team.',
|
|
13
|
+
]}
|
|
14
|
+
preserveSpace
|
|
15
|
+
caret="underscore"
|
|
16
|
+
caretColor="var(--base-5)"
|
|
17
|
+
/>
|
|
18
|
+
</Title>
|
|
19
|
+
]]></tsx>
|
|
20
|
+
<notes>From `auth/login-view`. Typewriter nests inside Title for display preset + `h1`. `preserveSpace` holds layout through phrase cycle; caret themed via `caretColor`. Only app usage found.</notes>
|
|
6
21
|
</example>
|
|
7
22
|
</patterns>
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<prop name="texts" kind="react">
|
|
38
38
|
<description>Cycles through multiple phrases instead of a single `children` string.</description>
|
|
39
39
|
</prop>
|
|
40
|
-
<
|
|
40
|
+
<prop name="caret-color" kind="css">
|
|
41
41
|
<description>Typewriter caret color.</description>
|
|
42
|
-
</
|
|
42
|
+
</prop>
|
|
43
43
|
</props>
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
2
|
<usage surface="typewriter">
|
|
3
|
-
<do>
|
|
4
|
-
<do>
|
|
5
|
-
<do>
|
|
6
|
-
<
|
|
7
|
-
<dont>
|
|
8
|
-
<dont>
|
|
9
|
-
<dont>Setting parent Text
|
|
10
|
-
<dont>Driving per-character typing through React state
|
|
3
|
+
<do>Nest inside Title or Text so size/tone/heading `render` live on the parent — Typewriter stays decorative typed copy</do>
|
|
4
|
+
<do>Hero / marketing phrase cycles via `texts` + `preserveSpace` so layout holds through type/delete (see auth Title compose)</do>
|
|
5
|
+
<do>Caret via `caret` / `caretColor`; timing via `speed` / `deleteSpeed` / `pause` / `delay` / `loop`</do>
|
|
6
|
+
<do>Loading shimmer on static copy is Shimmer inside Text/Title — Typewriter when progressive letter reveal is the intent</do>
|
|
7
|
+
<dont>Using Typewriter as the only source of critical status without a labeled surrounding region</dont>
|
|
8
|
+
<dont>Passing unstable inline `texts` arrays that restart the cycle on every parent render</dont>
|
|
9
|
+
<dont>Setting parent Text/Title `trim={false}` solely so `preserveSpace` can reserve wrapped height</dont>
|
|
10
|
+
<dont>Driving per-character typing through React state — typed layer uses DOM text writes</dont>
|
|
11
|
+
<dont>Expecting reduced-motion users to see every phrase in a multi-text cycle — final phrase shows immediately</dont>
|
|
11
12
|
</usage>
|
|
@@ -4,18 +4,18 @@
|
|
|
4
4
|
<prerequisite>Import compatible theme CSS, then @viraui/react/preflight.css. See foundation/bootstrap.xml.</prerequisite>
|
|
5
5
|
<attr name="data-mode">
|
|
6
6
|
<presence>value required</presence>
|
|
7
|
-
<effect>Narrows color-scheme on the element subtree: light forces light, dark forces dark, inverted flips color-scheme relative to the active theme using --is-light-mode on the root container.</effect>
|
|
7
|
+
<effect>Narrows color-scheme on the element subtree: light forces light, dark forces dark, inverted flips color-scheme relative to the active theme using --is-light-mode on the root container. (autoamtic in preflight).</effect>
|
|
8
8
|
<values>
|
|
9
9
|
<value>light</value>
|
|
10
10
|
<value>dark</value>
|
|
11
11
|
<value>inverted</value>
|
|
12
12
|
</values>
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
<when>Toggle runtime light or dark mode on html, body, or a layout wrapper</when>
|
|
14
|
+
<when>Scope a subtree to one mode while the rest of the page stays unchanged</when>
|
|
15
|
+
<when>Invert color-scheme on a nested surface that must contrast the active theme, for example a dark content section inside a light theme</when>
|
|
16
|
+
<when_not>As a substitute for loading compatible theme CSS</when_not>
|
|
17
|
+
<when_not>To swap brand stylesheets; use theme CSS imports instead and use the attribute data-mode as flag only</when_not>
|
|
18
|
+
<gotcha>data-mode is independent from brand stylesheet selection that may expose or not light and dark modes;</gotcha>
|
|
19
19
|
</attr>
|
|
20
20
|
<attr name="data-no-link-style">
|
|
21
21
|
<presence>boolean attribute on anchor elements</presence>
|
|
@@ -23,14 +23,17 @@
|
|
|
23
23
|
<values>
|
|
24
24
|
<value>(boolean presence)</value>
|
|
25
25
|
</values>
|
|
26
|
-
<when>Links that must keep component-owned or custom link chrome</when>
|
|
27
|
-
<when>Anchors
|
|
26
|
+
<when>Links that must keep component-owned or custom link chrome like linked Surfaces or other components</when>
|
|
27
|
+
<when>Anchors with their own link styling</when>
|
|
28
28
|
<when_not>Standard inline prose links that should inherit preflight link styling</when_not>
|
|
29
29
|
|
|
30
30
|
</attr>
|
|
31
31
|
<attr name="data-elevation">
|
|
32
32
|
<presence>value required</presence>
|
|
33
|
-
<
|
|
33
|
+
<reference>elevation.xml</reference>
|
|
34
|
+
<effect>
|
|
35
|
+
Shadow depth only — not z-index / paint order. When the active theme leaves --effect-shadows empty or unset, applies the preflight box-shadow stack for the chosen level (0–4). Same numbers usually align with stacking vocabulary, but this attr never changes stacking; set z-index separately when paint order must change.
|
|
36
|
+
</effect>
|
|
34
37
|
<values>
|
|
35
38
|
<value>0</value>
|
|
36
39
|
<value>1</value>
|
|
@@ -38,18 +41,22 @@
|
|
|
38
41
|
<value>3</value>
|
|
39
42
|
<value>4</value>
|
|
40
43
|
</values>
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
<when>Raw DOM hosts that need resting shadow when Elevator / getElevationProps do not fit</when>
|
|
45
|
+
<when>Static surfaces such as cards, panels, and popovers that should read raised</when>
|
|
46
|
+
<when_not>When Elevator or getElevationProps already sets elevation hooks on the target element — prefer those for React nodes</when_not>
|
|
47
|
+
<when_not>As a substitute for z-index; raising shadow does not move a surface above sticky headers or modals</when_not>
|
|
48
|
+
<when_not>When the theme sets --effect-shadows: initial (attr is a no-op for box-shadow; surface stays flat)</when_not>
|
|
49
|
+
<when_not>On Surface via an elevation prop — Surface has none; wrap with Elevator or use getElevationProps / these attrs</when_not>
|
|
50
|
+
<gotcha>Prefer Elevator or getElevationProps on React elements; raw data-elevation* only when those utilities do not fit. Full compose guidance: elevation.xml.</gotcha>
|
|
51
|
+
<gotcha>Empty/unset --effect-shadows = shadows on; initial = off. Attrs may remain while stacks stay flat.</gotcha>
|
|
52
|
+
<gotcha>Do not hand-roll box-shadow; elevation stacks need the theme gate and preflight.</gotcha>
|
|
49
53
|
</attr>
|
|
50
54
|
<attr name="data-elevation-hover">
|
|
51
55
|
<presence>optional value</presence>
|
|
52
|
-
<
|
|
56
|
+
<reference>elevation.xml</reference>
|
|
57
|
+
<effect>
|
|
58
|
+
When --effect-shadows is on, applies a different elevation level on :hover than the resting data-elevation value. Shadows only — does not change z-index. Pair with data-elevation for resting and hover depth (e.g. card that lifts on hover).
|
|
59
|
+
</effect>
|
|
53
60
|
<values>
|
|
54
61
|
<value>0</value>
|
|
55
62
|
<value>1</value>
|
|
@@ -57,33 +64,48 @@
|
|
|
57
64
|
<value>3</value>
|
|
58
65
|
<value>4</value>
|
|
59
66
|
</values>
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
<when>Interactive surfaces that should lift on hover</when>
|
|
68
|
+
<when>Pair with data-elevation for resting and hover shadow levels</when>
|
|
69
|
+
<when_not>When hover elevation is not desired; omit the attribute entirely</when_not>
|
|
70
|
+
<when_not>When Elevator hover={…} or getElevationProps already maps hover on the target</when_not>
|
|
71
|
+
<when_not>When the theme sets --effect-shadows: initial (attr is a no-op for box-shadow)</when_not>
|
|
72
|
+
<gotcha>Prefer Elevator resting/hover props or getElevationProps; raw attrs only when utilities do not fit.</gotcha>
|
|
73
|
+
<gotcha>Hover shadow does not change stacking order.</gotcha>
|
|
74
|
+
<tsx><![CDATA[
|
|
75
|
+
<div data-elevation="1" data-elevation-hover="4">
|
|
76
|
+
{/* subtle rest; lifts more on hover */}
|
|
77
|
+
</div>
|
|
78
|
+
]]></tsx>
|
|
67
79
|
</attr>
|
|
68
80
|
<attr name="data-elevation-direction">
|
|
69
81
|
<presence>optional; defaults to bottom when data-elevation is present</presence>
|
|
70
|
-
<
|
|
82
|
+
<reference>elevation.xml</reference>
|
|
83
|
+
<effect>
|
|
84
|
+
When --effect-shadows is on, casts the shadow downward (bottom), upward (top), to the left, or to the right. Direction is appearance only — not stacking.
|
|
85
|
+
</effect>
|
|
71
86
|
<values>
|
|
72
87
|
<value>bottom</value>
|
|
73
88
|
<value>top</value>
|
|
74
89
|
<value>left</value>
|
|
75
90
|
<value>right</value>
|
|
76
91
|
</values>
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
92
|
+
<when>Side drawers, top bars, or lateral panels where shadow cast direction matters</when>
|
|
93
|
+
<when_not>When default bottom cast is sufficient</when_not>
|
|
94
|
+
<when_not>When Elevator direction={…} or getElevationProps already sets direction on the target</when_not>
|
|
95
|
+
<when_not>When the theme sets --effect-shadows: initial (attr is a no-op for box-shadow)</when_not>
|
|
96
|
+
<gotcha>Prefer Elevator direction or getElevationProps; raw attrs only when utilities do not fit.</gotcha>
|
|
97
|
+
<tsx><![CDATA[
|
|
98
|
+
<aside data-elevation="2" data-elevation-direction="left">
|
|
99
|
+
{/* drawer — shadow casts left */}
|
|
100
|
+
</aside>
|
|
101
|
+
]]></tsx>
|
|
83
102
|
</attr>
|
|
84
103
|
<attr name="data-grow">
|
|
85
104
|
<presence>optional; omit for default flex growth</presence>
|
|
86
|
-
<effect>
|
|
105
|
+
<effect>
|
|
106
|
+
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.
|
|
107
|
+
Generally this attribute is used on children of a Stack to force/prevent grow on specific children while keeping the default flex growth for the rest of the children.
|
|
108
|
+
</effect>
|
|
87
109
|
<values>
|
|
88
110
|
<value>true</value>
|
|
89
111
|
<value>false</value>
|
|
@@ -92,12 +114,16 @@
|
|
|
92
114
|
<when>Fixed-width icons, indicators, or trailing slots (false)</when>
|
|
93
115
|
<when_not>When default flex growth is already correct</when_not>
|
|
94
116
|
<when_not>Expecting ancestor data-grow to change nested expandChildren children</when_not>
|
|
117
|
+
<when_not>Inventing width: 100% CSS on Button/Chip instead of Stack fullWidth / expandChildren</when_not>
|
|
95
118
|
<gotcha>Stack</gotcha>
|
|
96
119
|
<gotcha>--vira-flex-grow</gotcha>
|
|
97
120
|
</attr>
|
|
98
121
|
<attr name="data-shrink">
|
|
99
122
|
<presence>optional; omit for default flex shrink</presence>
|
|
100
|
-
<effect>
|
|
123
|
+
<effect>
|
|
124
|
+
Affects only the element: true sets --vira-flex-shrink: 1 and flex-shrink: 1; false sets --vira-flex-shrink: 0 and flex-shrink: 0. Custom props are registered inherits: false.
|
|
125
|
+
Generally this attribute is used on children of a Stack to force/prevent shrink on specific children while keeping the default flex shrink for the rest of the children.
|
|
126
|
+
</effect>
|
|
101
127
|
<values>
|
|
102
128
|
<value>true</value>
|
|
103
129
|
<value>false</value>
|
|
@@ -111,12 +137,16 @@
|
|
|
111
137
|
</attr>
|
|
112
138
|
<attr name="data-vibrant">
|
|
113
139
|
<presence>boolean attribute; value ignored</presence>
|
|
114
|
-
<effect>
|
|
140
|
+
<effect>
|
|
141
|
+
When the active theme sets --effect-vibrancy, applies vibrancy backdrop-filter (brightness/blur/saturate). Surface with data-vibrant translucifies its fill via component CSS: it doesn't apply a background color to the element, that still need to be set by the consumer.
|
|
142
|
+
Only the urface component applies the correct `color` prop based on the presence of the attribute. For custom styles you need to set the background color explicitly if you need one.
|
|
143
|
+
In built-in themes, the applied backdrop-filter is different based on the active theme mode: light or dark.
|
|
144
|
+
</effect>
|
|
115
145
|
<values>
|
|
116
146
|
<value>(boolean presence)</value>
|
|
117
147
|
</values>
|
|
118
148
|
<when>Glass / frosted panels on Surface or other hosts over busy backgrounds</when>
|
|
119
|
-
<when>Match overlay chrome (Dialog/Popover/Menu/Toast) that ships with data-vibrant</when>
|
|
149
|
+
<when>Match overlay chrome (Dialog/Popover/Menu/Toast) that ships with data-vibrant internally</when>
|
|
120
150
|
<when_not>When the theme does not expose --effect-vibrancy (attr is a no-op for filters)</when_not>
|
|
121
151
|
<when_not>Hand-rolling backdrop-filter CSS instead of the documented attr</when_not>
|
|
122
152
|
<gotcha>Surface</gotcha>
|
|
@@ -5,16 +5,16 @@
|
|
|
5
5
|
<package name="@viraui/react">Public components, preflight CSS, and package specs.</package>
|
|
6
6
|
<package name="react">Peer dependency.</package>
|
|
7
7
|
<package name="react-dom">Peer dependency.</package>
|
|
8
|
-
<package name="@base-ui/react">Peer dependency for wrapped primitives.</package>
|
|
8
|
+
<package name="@base-ui/react">Peer dependency for wrapped primitives. Always install the version that matches the @viraui/react major/minor peer dependency version, patches are free to change.</package>
|
|
9
9
|
</required_packages>
|
|
10
10
|
<optional_packages>
|
|
11
|
-
<package name="@viraui/foundation">Preset Vira brand theme CSS, ThemeTypes, and
|
|
12
|
-
<package name="@viraui/icons">Optional
|
|
11
|
+
<package name="@viraui/foundation">Preset Vira brand theme CSS, ThemeTypes, and design tokens only.</package>
|
|
12
|
+
<package name="@viraui/icons">Optional ViraUI iconography (@viraui/icons/react). Icon slots accept any ReactNode.</package>
|
|
13
13
|
</optional_packages>
|
|
14
14
|
<import_order>
|
|
15
|
-
<step>Compatible theme CSS (preset @viraui/foundation/vira.css, custom theme CSS, or future theme-builder export)</step>
|
|
16
15
|
<step>Consumer font CSS or @font-face rules matching theme font-family strings</step>
|
|
17
16
|
<step>@viraui/react/preflight.css</step>
|
|
17
|
+
<step>Compatible theme CSS (preset @viraui/foundation/vira.css, custom theme CSS, or future theme-builder export)</step>
|
|
18
18
|
</import_order>
|
|
19
19
|
<component_css>
|
|
20
20
|
<rule>Import public components from the @viraui/react root barrel. Component CSS follows the JS module graph through side-effect CSS imports.</rule>
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
</cascade_layers>
|
|
27
27
|
<import_mechanism>
|
|
28
28
|
<rule>Load theme CSS, font CSS, and preflight through JavaScript side-effect imports in the app root entry module.</rule>
|
|
29
|
-
<forbidden>
|
|
29
|
+
<forbidden>Bootstrap Vira theme, font, or preflight CSS with CSS @import in a global stylesheet only if the consumer project requires it. Do not require per-component CSS imports in app bootstrap.</forbidden>
|
|
30
30
|
</import_mechanism>
|
|
31
31
|
<root_providers>
|
|
32
32
|
<rule>After CSS bootstrap, wrap the app tree once in Dialog.Provider, Dialog.IndentBackground, Dialog.Indent, Tooltip.Provider, and Toast.Provider. Toast.createToastManager() stays at module scope. Map Toast.useToastManager().toasts to Toast.Banner inside Toast.Portal and Toast.Viewport.</rule>
|
|
@@ -45,10 +45,10 @@
|
|
|
45
45
|
<rule>In Next.js App Router apps, import theme CSS, font CSS, and @viraui/react/preflight.css as JavaScript side-effect imports in root app/layout.tsx; never bootstrap them with CSS @import in globals.css.</rule>
|
|
46
46
|
<entry_module>app/layout.tsx</entry_module>
|
|
47
47
|
<tsx><![CDATA[
|
|
48
|
-
import '@viraui/foundation/vira.css';
|
|
49
48
|
import '@fontsource-variable/geist/wght.css';
|
|
50
49
|
import '@fontsource-variable/geist-mono/wght.css';
|
|
51
50
|
import '@viraui/react/preflight.css';
|
|
51
|
+
import '@viraui/foundation/vira.css';
|
|
52
52
|
import './globals.css';
|
|
53
53
|
]]></tsx>
|
|
54
54
|
</next_js_app_router>
|
|
@@ -1,12 +1,41 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
2
|
<elevation>
|
|
3
|
-
<summary>Elevation
|
|
4
|
-
<
|
|
3
|
+
<summary>Elevation is shadow depth, not paint order. Apply shadows with Elevator or getElevationProps; raw data-elevation* only when those do not fit. Surface has no elevation prop. Elevator never sets z-index — stacking is a separate control that usually shares the same 0–4 vocabulary.</summary>
|
|
4
|
+
<concept>
|
|
5
|
+
A raised surface casts a larger, softer shadow. ViraUI maps that to a stepped scale (0–4). z-index is who paints on top of whom. Same layer numbers usually line up so something that looks elevated also stacks where expected, but raising a card's shadow does not move it above a sticky header. A popover that looks elevated but paints under its trigger is a stack problem, not an Elevator problem.
|
|
6
|
+
</concept>
|
|
7
|
+
<gate>
|
|
8
|
+
Shadows respect the --effect-shadows theme gate: empty or unset means on, initial means off. When the gate is off, elevated surfaces stay flat even if data-elevation* attrs remain. Full gate polarity lives in foundation/toggles.xml and Effects theme topics.
|
|
9
|
+
</gate>
|
|
10
|
+
<layers>
|
|
11
|
+
<layer value="0">Plane content — page backgrounds, body, non-lifted surfaces.</layer>
|
|
12
|
+
<layer value="1">Cards, fields, buttons, and other lightly raised page chrome.</layer>
|
|
13
|
+
<layer value="2">Anchored overlays above nearby page content — Popover, Tooltip, non-modal sheets.</layer>
|
|
14
|
+
<layer value="3">Fixed chrome above the page but below blocking modals — sticky header/nav, floating actions.</layer>
|
|
15
|
+
<layer value="4">Modals, drawers, and global toasts at the top of app UI. Vira overlays already own this layer.</layer>
|
|
16
|
+
</layers>
|
|
17
|
+
<do>Use the same stepped numbers for shadow and stacking so depth stays consistent; elevate for appearance, stack for paint order.</do>
|
|
18
|
+
<do>Prefer Elevator or getElevationProps for React elements that need resting/hover shadow stacks.</do>
|
|
5
19
|
<do>Pass data-elevation / data-elevation-hover values 0–4 and data-elevation-direction bottom|top|left|right on raw DOM when utilities do not fit.</do>
|
|
20
|
+
<do>Set z-index separately when paint order must change; stay within the built-in 0–4 scale for app UI.</do>
|
|
6
21
|
<dont>Do not pass elevation={…} on Surface — use Elevator / getElevationProps / data-elevation*.</dont>
|
|
22
|
+
<dont>Do not expect Elevator to change stacking; it never sets z-index.</dont>
|
|
7
23
|
<dont>Do not hand-roll box-shadow; elevation needs --effect-shadows on the active theme.</dont>
|
|
24
|
+
<dont>Do not copy theme chrome z-index patterns (e.g. body::after holofoil at very high values) to beat modals in app UI.</dont>
|
|
25
|
+
<api name="Elevator">
|
|
26
|
+
<description>No-DOM helper: merges data-elevation* and elevation CSS vars onto each valid element child. Shadows only — wrap Surface or other hosts; invalid/non-element children pass through.</description>
|
|
27
|
+
<tsx><![CDATA[
|
|
28
|
+
import { Elevator, Surface } from '@viraui/react';
|
|
29
|
+
|
|
30
|
+
<Elevator resting={1} hover={4}>
|
|
31
|
+
<Surface color={1} radius="m" hPadding="m" vPadding="m">
|
|
32
|
+
{/* card — shadows change; z-index does not */}
|
|
33
|
+
</Surface>
|
|
34
|
+
</Elevator>
|
|
35
|
+
]]></tsx>
|
|
36
|
+
</api>
|
|
8
37
|
<api name="getElevationProps">
|
|
9
|
-
<description>Returns data-elevation* attributes plus --shadow-color / --extra-shadow style hooks from resting, hover, direction, shadowColor, and extraShadow.</description>
|
|
38
|
+
<description>Returns data-elevation* attributes plus --shadow-color / --extra-shadow style hooks from resting, hover, direction, shadowColor, and extraShadow. Use on a host you already own.</description>
|
|
10
39
|
<tsx><![CDATA[
|
|
11
40
|
import { getElevationProps } from '@viraui/react';
|
|
12
41
|
|
|
@@ -14,8 +43,27 @@ const { attributes, style } = getElevationProps({ resting: 2, hover: 3 });
|
|
|
14
43
|
<div {...attributes} style={style} />
|
|
15
44
|
]]></tsx>
|
|
16
45
|
</api>
|
|
46
|
+
<api name="data-elevation*">
|
|
47
|
+
<description>Raw preflight attrs for resting shadow (data-elevation), hover shadow (data-elevation-hover), and cast direction (data-elevation-direction). Prefer Elevator / getElevationProps; reach for raw attrs only when those utilities do not fit. See foundation/attributes.xml.</description>
|
|
48
|
+
<tsx><![CDATA[
|
|
49
|
+
<div
|
|
50
|
+
data-elevation="1"
|
|
51
|
+
data-elevation-hover="2"
|
|
52
|
+
data-elevation-direction="bottom"
|
|
53
|
+
>
|
|
54
|
+
{/* raw DOM host — shadows only */}
|
|
55
|
+
</div>
|
|
56
|
+
]]></tsx>
|
|
57
|
+
</api>
|
|
58
|
+
<prompt title="Hover-lift card">Give this card a subtle shadow that lifts a bit more on hover. Shadows only — don't change stacking order.</prompt>
|
|
59
|
+
<prompt title="Popover depth">This popover should look elevated above the page but sit below modals and drawers. The sticky header should stay under modal overlays.</prompt>
|
|
60
|
+
<prompt title="Flat brand">Turn off drop shadows everywhere so elevated surfaces stay flat. Keep stacking order as it is — this is appearance only.</prompt>
|
|
61
|
+
<tune>
|
|
62
|
+
Compose elevation on Elevator and stack with z-index. Retune on the theme whether shadows can run at all via --effect-shadows (and related shadow tokens when the brand softens or hardens depth). Flat brand = set --effect-shadows: initial; attrs may remain but stacks stay flat.
|
|
63
|
+
</tune>
|
|
17
64
|
<related>
|
|
18
65
|
<ref id="elevator" />
|
|
19
66
|
<ref id="foundation-attributes" />
|
|
67
|
+
<ref id="foundation-toggles" />
|
|
20
68
|
</related>
|
|
21
69
|
</elevation>
|