@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.
Files changed (168) hide show
  1. package/dist/catalog.json +5 -5
  2. package/dist/components/radio/radio-group.d.ts +1 -1
  3. package/dist/components/stack/stack.d.ts +4 -1
  4. package/dist/components/tabs/tabs.css +1 -1
  5. package/dist/components/text/text.css +1 -1
  6. package/dist/components/text/text.d.ts +12 -2
  7. package/dist/components/text/text.js +2 -1
  8. package/dist/components/textfield/textfield.d.ts +1 -0
  9. package/dist/components/title/title.css +1 -1
  10. package/dist/components/title/title.d.ts +12 -2
  11. package/dist/components/title/title.js +2 -1
  12. package/dist/specs/PROTOCOL.md +1 -1
  13. package/dist/specs/activity-hints.xml +18 -3
  14. package/dist/specs/components/accordion/patterns.xml +69 -5
  15. package/dist/specs/components/accordion/props.xml +4 -4
  16. package/dist/specs/components/accordion/usage.xml +8 -4
  17. package/dist/specs/components/annotate/patterns.xml +50 -3
  18. package/dist/specs/components/annotate/props.xml +22 -22
  19. package/dist/specs/components/annotate/usage.xml +7 -6
  20. package/dist/specs/components/autocomplete/patterns.xml +123 -7
  21. package/dist/specs/components/autocomplete/props.xml +14 -14
  22. package/dist/specs/components/autocomplete/usage.xml +11 -6
  23. package/dist/specs/components/avatar/patterns.xml +78 -3
  24. package/dist/specs/components/avatar/props.xml +8 -8
  25. package/dist/specs/components/avatar/usage.xml +9 -3
  26. package/dist/specs/components/avatar-group/patterns.xml +65 -3
  27. package/dist/specs/components/avatar-group/props.xml +8 -8
  28. package/dist/specs/components/avatar-group/usage.xml +10 -7
  29. package/dist/specs/components/badge/patterns.xml +57 -3
  30. package/dist/specs/components/badge/props.xml +8 -8
  31. package/dist/specs/components/badge/usage.xml +5 -3
  32. package/dist/specs/components/beam/meta.xml +1 -1
  33. package/dist/specs/components/beam/patterns.xml +68 -3
  34. package/dist/specs/components/beam/props.xml +22 -22
  35. package/dist/specs/components/beam/usage.xml +7 -7
  36. package/dist/specs/components/bleed/patterns.xml +54 -3
  37. package/dist/specs/components/bleed/props.xml +2 -2
  38. package/dist/specs/components/bleed/usage.xml +6 -3
  39. package/dist/specs/components/breakpoints/meta.xml +1 -1
  40. package/dist/specs/components/breakpoints/patterns.xml +1 -6
  41. package/dist/specs/components/breakpoints/props.xml +4 -2
  42. package/dist/specs/components/breakpoints/usage.xml +10 -2
  43. package/dist/specs/components/button/patterns.xml +124 -6
  44. package/dist/specs/components/button/props.xml +33 -32
  45. package/dist/specs/components/button/usage.xml +13 -13
  46. package/dist/specs/components/checkbox/patterns.xml +83 -3
  47. package/dist/specs/components/checkbox/props.xml +10 -10
  48. package/dist/specs/components/checkbox/usage.xml +11 -6
  49. package/dist/specs/components/chip/patterns.xml +74 -3
  50. package/dist/specs/components/chip/props.xml +14 -14
  51. package/dist/specs/components/chip/usage.xml +10 -6
  52. package/dist/specs/components/clamp-text/patterns.xml +1 -4
  53. package/dist/specs/components/clamp-text/props.xml +2 -2
  54. package/dist/specs/components/clamp-text/usage.xml +8 -5
  55. package/dist/specs/components/dialog/patterns.xml +136 -15
  56. package/dist/specs/components/dialog/props.xml +2 -2
  57. package/dist/specs/components/dialog/usage.xml +9 -7
  58. package/dist/specs/components/elevator/patterns.xml +54 -3
  59. package/dist/specs/components/elevator/usage.xml +8 -5
  60. package/dist/specs/components/fieldset/patterns.xml +97 -3
  61. package/dist/specs/components/fieldset/usage.xml +7 -5
  62. package/dist/specs/components/fit-text/patterns.xml +1 -4
  63. package/dist/specs/components/fit-text/props.xml +2 -2
  64. package/dist/specs/components/fit-text/usage.xml +8 -6
  65. package/dist/specs/components/glow/meta.xml +1 -1
  66. package/dist/specs/components/glow/patterns.xml +74 -3
  67. package/dist/specs/components/glow/props.xml +16 -16
  68. package/dist/specs/components/glow/usage.xml +8 -7
  69. package/dist/specs/components/grid/patterns.xml +88 -5
  70. package/dist/specs/components/grid/props.xml +23 -23
  71. package/dist/specs/components/grid/usage.xml +9 -5
  72. package/dist/specs/components/icon-button/patterns.xml +97 -6
  73. package/dist/specs/components/icon-button/props.xml +32 -32
  74. package/dist/specs/components/icon-button/usage.xml +11 -9
  75. package/dist/specs/components/linear-progress/patterns.xml +58 -3
  76. package/dist/specs/components/linear-progress/props.xml +6 -6
  77. package/dist/specs/components/linear-progress/usage.xml +9 -8
  78. package/dist/specs/components/masonry/patterns.xml +68 -5
  79. package/dist/specs/components/masonry/props.xml +2 -2
  80. package/dist/specs/components/masonry/usage.xml +9 -4
  81. package/dist/specs/components/menu/patterns.xml +179 -15
  82. package/dist/specs/components/menu/usage.xml +8 -7
  83. package/dist/specs/components/meter/patterns.xml +49 -3
  84. package/dist/specs/components/meter/props.xml +6 -6
  85. package/dist/specs/components/meter/usage.xml +10 -7
  86. package/dist/specs/components/popover/patterns.xml +118 -9
  87. package/dist/specs/components/popover/props.xml +2 -2
  88. package/dist/specs/components/popover/usage.xml +9 -8
  89. package/dist/specs/components/progressive-blur/meta.xml +1 -1
  90. package/dist/specs/components/progressive-blur/patterns.xml +1 -4
  91. package/dist/specs/components/progressive-blur/props.xml +2 -2
  92. package/dist/specs/components/progressive-blur/usage.xml +7 -6
  93. package/dist/specs/components/radio/patterns.xml +55 -5
  94. package/dist/specs/components/radio/props.xml +8 -8
  95. package/dist/specs/components/radio/usage.xml +9 -6
  96. package/dist/specs/components/select/patterns.xml +124 -8
  97. package/dist/specs/components/select/props.xml +18 -18
  98. package/dist/specs/components/select/usage.xml +11 -10
  99. package/dist/specs/components/separator/patterns.xml +121 -3
  100. package/dist/specs/components/separator/props.xml +4 -4
  101. package/dist/specs/components/separator/usage.xml +8 -5
  102. package/dist/specs/components/shimmer/patterns.xml +23 -3
  103. package/dist/specs/components/shimmer/props.xml +8 -8
  104. package/dist/specs/components/shimmer/usage.xml +7 -5
  105. package/dist/specs/components/skeleton/patterns.xml +172 -4
  106. package/dist/specs/components/skeleton/props.xml +14 -14
  107. package/dist/specs/components/skeleton/usage.xml +11 -7
  108. package/dist/specs/components/slider/patterns.xml +111 -3
  109. package/dist/specs/components/slider/props.xml +10 -10
  110. package/dist/specs/components/slider/usage.xml +11 -5
  111. package/dist/specs/components/spinner/patterns.xml +35 -3
  112. package/dist/specs/components/spinner/props.xml +2 -2
  113. package/dist/specs/components/spinner/usage.xml +8 -5
  114. package/dist/specs/components/stack/patterns.xml +359 -3
  115. package/dist/specs/components/stack/props.xml +24 -22
  116. package/dist/specs/components/stack/usage.xml +16 -10
  117. package/dist/specs/components/static-noise/meta.xml +1 -1
  118. package/dist/specs/components/static-noise/patterns.xml +20 -3
  119. package/dist/specs/components/static-noise/usage.xml +5 -5
  120. package/dist/specs/components/surface/patterns.xml +188 -3
  121. package/dist/specs/components/surface/props.xml +26 -26
  122. package/dist/specs/components/surface/usage.xml +15 -12
  123. package/dist/specs/components/switch/patterns.xml +73 -3
  124. package/dist/specs/components/switch/props.xml +12 -12
  125. package/dist/specs/components/switch/usage.xml +10 -5
  126. package/dist/specs/components/tabs/patterns.xml +111 -6
  127. package/dist/specs/components/tabs/props.xml +2 -2
  128. package/dist/specs/components/tabs/usage.xml +7 -3
  129. package/dist/specs/components/text/patterns.xml +97 -3
  130. package/dist/specs/components/text/props.xml +48 -43
  131. package/dist/specs/components/text/usage.xml +11 -4
  132. package/dist/specs/components/textarea/patterns.xml +49 -3
  133. package/dist/specs/components/textarea/props.xml +7 -6
  134. package/dist/specs/components/textarea/usage.xml +8 -5
  135. package/dist/specs/components/textfield/patterns.xml +163 -3
  136. package/dist/specs/components/textfield/props.xml +12 -11
  137. package/dist/specs/components/textfield/usage.xml +9 -3
  138. package/dist/specs/components/title/patterns.xml +74 -3
  139. package/dist/specs/components/title/props.xml +48 -43
  140. package/dist/specs/components/title/usage.xml +10 -7
  141. package/dist/specs/components/toast/patterns.xml +85 -8
  142. package/dist/specs/components/toast/usage.xml +8 -5
  143. package/dist/specs/components/toggle-button/patterns.xml +101 -3
  144. package/dist/specs/components/toggle-button/props.xml +16 -16
  145. package/dist/specs/components/toggle-button/usage.xml +9 -5
  146. package/dist/specs/components/toggle-group/patterns.xml +34 -5
  147. package/dist/specs/components/toggle-group/usage.xml +9 -5
  148. package/dist/specs/components/tooltip/patterns.xml +110 -6
  149. package/dist/specs/components/tooltip/props.xml +2 -2
  150. package/dist/specs/components/tooltip/usage.xml +8 -5
  151. package/dist/specs/components/typewriter/patterns.xml +18 -3
  152. package/dist/specs/components/typewriter/props.xml +2 -2
  153. package/dist/specs/components/typewriter/usage.xml +9 -8
  154. package/dist/specs/foundation/attributes.xml +67 -37
  155. package/dist/specs/foundation/bootstrap.xml +6 -6
  156. package/dist/specs/foundation/elevation.xml +51 -3
  157. package/dist/specs/foundation/modules.xml +117 -40
  158. package/dist/specs/foundation/theme-topics.xml +62 -27
  159. package/dist/specs/foundation/toggles.xml +2 -2
  160. package/dist/specs/index.xml +42 -6
  161. package/dist/specs/patterns/card-grid.xml +35 -0
  162. package/dist/specs/patterns/compose-layout-first.xml +32 -0
  163. package/dist/specs/patterns/equal-width-actions.xml +22 -0
  164. package/dist/specs/patterns/page-chrome.xml +34 -0
  165. package/dist/specs/patterns/settings-panel.xml +30 -0
  166. package/dist/specs/patterns/settings-row.xml +9 -7
  167. package/dist/specs/patterns/stack-as-surface.xml +37 -0
  168. package/package.json +9 -9
@@ -1,7 +1,101 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <patterns surface="text">
3
- <example title="Text structure">
4
- <tsx><![CDATA[<Text>…</Text>]]></tsx>
5
- <notes>Public assembly hint from legacy guide; not API authority.</notes>
3
+ <!-- Sources: viraui-app + design-kitchen preview-grid — cleaned (no handlers, no i18n, no app-only chrome). -->
4
+
5
+ <example title="Auth muted lead">
6
+ <tsx><![CDATA[
7
+ <Stack vPadding={[0, 'l']} rowGap="xl">
8
+ <Title size="1" render={<h1 />} maxWidth="32rem" lineHeight="s">
9
+ Design systems that ship
10
+ </Title>
11
+ <Text size="2xl" tone="muted" maxWidth="32rem">
12
+ Login to create custom ViraUI themes, access prompts and more.
13
+ </Text>
14
+ </Stack>
15
+ ]]></tsx>
16
+ <notes>From `auth/login-view`. Large muted body under Title; `maxWidth` on Text — no CSS width.</notes>
17
+ </example>
18
+
19
+ <example title="Card section blurb">
20
+ <tsx><![CDATA[
21
+ <Stack rowGap="xs">
22
+ <Title size="6" render={<h2 />}>
23
+ Payout Threshold
24
+ </Title>
25
+ <Text tone="muted" size="s">
26
+ Set the minimum balance required before a payout is triggered.
27
+ </Text>
28
+ </Stack>
29
+ ]]></tsx>
30
+ <notes>From preview-grid `payout-threshold` (+ preferences / workspace-usage). Default pairing: Title + muted `size="s"` Text.</notes>
31
+ </example>
32
+
33
+ <example title="Nested weight + tone">
34
+ <tsx><![CDATA[
35
+ <Text lineHeight="s" render={<p />}>
36
+ <Text weight="semibold">Code reviews</Text>{' '}
37
+ <Text tone="muted">with full codebase context to catch hard-to-find bugs.</Text>
38
+ </Text>
39
+ ]]></tsx>
40
+ <notes>From preview-grid `vercel-agent`. Outer Text owns paragraph/`lineHeight`; nested Text carry weight/tone — no span CSS.</notes>
41
+ </example>
42
+
43
+ <example title="Mono range labels">
44
+ <tsx><![CDATA[
45
+ <Stack columnGap="s" direction="row" hAlign="space-between" vAlign="center">
46
+ <Text family="mono" size="xs" tone="muted">
47
+ $50 (MIN)
48
+ </Text>
49
+ <Text family="mono" size="xs" tone="muted">
50
+ $10,000 (MAX)
51
+ </Text>
52
+ </Stack>
53
+ ]]></tsx>
54
+ <notes>From preview-grid `payout-threshold`. `family="mono"` + muted xs for metric chrome.</notes>
55
+ </example>
56
+
57
+ <example title="Form success paragraph">
58
+ <tsx><![CDATA[
59
+ <Text render={<p />}>Check your email — we sent a link to your@email.com</Text>
60
+ ]]></tsx>
61
+ <notes>From `auth/login-form` acknowledged state. `render={<p />}` for block semantics; default body size/tone.</notes>
62
+ </example>
63
+
64
+ <example title="Empty-state centered">
65
+ <tsx><![CDATA[
66
+ <Stack hAlign="center" rowGap="m">
67
+ <Title align="center" size="5" render={<h3 />}>
68
+ No Team Members
69
+ </Title>
70
+ <Text size="s" align="center" maxWidth="14rem" tone="muted">
71
+ Invite your team to collaborate on this project.
72
+ </Text>
73
+ </Stack>
74
+ ]]></tsx>
75
+ <notes>From preview-grid `empty-team`. Centered muted copy with `maxWidth` — Stack owns alignment.</notes>
76
+ </example>
77
+
78
+ <example title="Claimable balance rows">
79
+ <tsx><![CDATA[
80
+ <Stack rowGap="m">
81
+ <Stack direction="row" hAlign="space-between">
82
+ <Text size="s" tone="muted">
83
+ Net Royalties
84
+ </Text>
85
+ <Text family="mono" size="s">
86
+ $0.00
87
+ </Text>
88
+ </Stack>
89
+ <Stack direction="row" hAlign="space-between">
90
+ <Text size="s" tone="muted">
91
+ Total Ready to Claim
92
+ </Text>
93
+ <Text family="mono" size="s" weight="semibold">
94
+ $0.00 USD
95
+ </Text>
96
+ </Stack>
97
+ </Stack>
98
+ ]]></tsx>
99
+ <notes>From preview-grid `claimable-balance`. Label/value rows: muted label + mono value; semibold for totals.</notes>
6
100
  </example>
7
101
  </patterns>
@@ -2,12 +2,14 @@
2
2
  <props surface="text">
3
3
  <when_to_use>
4
4
  <item>Body copy with semantic tone (including brand `primary`) and token-backed typography</item>
5
+ <item>Letter-spacing via `tracking` or text-transform via `transform` — prefer props over CSS on the Text root</item>
5
6
  <item>Helper, label, or inline copy inside other components</item>
6
- <item>Mono or body family text with fluid clamp sizing (gated by --effect-fluid-typography; off → fixed at --font-scale-body-* for that size)</item>
7
+ <item>Mono or body family text; size locked by default (`fluid` false → --font-scale-body-*); pass `fluid` for viewport clamp (also gated by theme `--effect-fluid-typography`)</item>
7
8
  </when_to_use>
8
9
  <when_not_to_use>
9
10
  <item>Headings or display typography — use Title</item>
10
11
  <item>Heading semantics without an appropriate render root</item>
12
+ <item>Inventing CSS `letter-spacing` / `text-transform` / `width: 100%` when `tracking` / `transform` / parent Stack `fullWidth` cover the need</item>
11
13
  </when_not_to_use>
12
14
  <prop name="align" kind="react">
13
15
  <description>Aligns text using logical alignment values.</description>
@@ -21,6 +23,9 @@
21
23
  <prop name="family" kind="react">
22
24
  <description>Selects the semantic font family for body copy and inline code-like text.</description>
23
25
  </prop>
26
+ <prop name="fluid" kind="react">
27
+ <description>Enables viewport fluid clamp sizing for this instance. Default false locks at this size’s --font-scale-body-* token. Pass true for fluid page/body copy. Theme --effect-fluid-typography: initial still locks all Text globally. size xs stays fixed either way (min=max).</description>
28
+ </prop>
24
29
  <prop name="fontWidth" kind="react">
25
30
  <description>Overrides font width as a percentage (100 = normal); maps to `font-stretch` and `wdth`.</description>
26
31
  </prop>
@@ -46,16 +51,16 @@
46
51
  <description>Enables text selection on the rendered copy.</description>
47
52
  </prop>
48
53
  <prop name="size" kind="react">
49
- <description>Selects a semantic body typography size from the active theme scale (`4xl` \| `3xl` \| `2xl` \| `xl` \| `l` \| `m` \| `s` \| `xs`). Fluid clamp between prev step and this size’s --font-scale-body-* token is on when --effect-fluid-typography is empty; set the theme effect to initial to lock at that body scale token. size xs is always fixed.</description>
54
+ <description>Selects a semantic body typography size from the active theme scale (`4xl` \| `3xl` \| `2xl` \| `xl` \| `l` \| `m` \| `s` \| `xs`). Default locks at that size’s --font-scale-body-* token; fluid clamp (prev step→token) applies when `fluid` is true and --effect-fluid-typography is empty. Theme effect initial still locks all Text. size xs is always fixed (min=max).</description>
50
55
  </prop>
51
56
  <prop name="tone" kind="react">
52
57
  <description>Sets the semantic text color role when no literal `color` override is used. `default` inherits; `primary` → `--global-primary`; `muted` → `--global-muted`; `interactive` → `--global-interactive-text`; `positive` / `informative` / `danger` / `warning` → `--highlight-green` / `--highlight-blue` / `--highlight-red` / `--highlight-yellow`.</description>
53
58
  </prop>
54
59
  <prop name="tracking" kind="react">
55
- <description>Sets letter spacing on the rendered copy.</description>
60
+ <description>Sets letter-spacing on the rendered copy via `--vui-text-letter-spacing`. Prefer this prop over CSS `letter-spacing` / Tailwind tracking utilities on the same Text root.</description>
56
61
  </prop>
57
62
  <prop name="transform" kind="react">
58
- <description>Applies a text-transform on the rendered copy.</description>
63
+ <description>Applies CSS `text-transform` on the rendered copy via `--vui-text-text-transform` (`uppercase` \| `lowercase` \| `capitalize` \| …). Prefer this prop over CSS `text-transform` on the same Text root.</description>
59
64
  </prop>
60
65
  <prop name="trim" kind="react">
61
66
  <description>Trims text box whitespace at the chosen edge when the browser supports `text-box`. Pass `false` to disable text-box trim.</description>
@@ -72,58 +77,58 @@
72
77
  <prop name="whiteSpace" kind="react">
73
78
  <description>Controls white-space preservation and wrapping behavior.</description>
74
79
  </prop>
75
- <css_var suffix="align">
80
+ <prop name="align" kind="css">
76
81
  <description>Text alignment on the root.</description>
77
- </css_var>
78
- <css_var suffix="font-family">
82
+ </prop>
83
+ <prop name="font-family" kind="css">
79
84
  <description>Font family; family prop presets via data attributes.</description>
80
- </css_var>
81
- <css_var suffix="font-opsz">
85
+ </prop>
86
+ <prop name="font-opsz" kind="css">
82
87
  <description>Optical size axis on the root (variable fonts).</description>
83
- </css_var>
84
- <css_var suffix="font-size">
85
- <description>Body font size; size prop presets via data attributes. Defaults to the theme body scale token for that size; clamp (prev step→token) applies only when --effect-fluid-typography is on.</description>
86
- </css_var>
87
- <css_var suffix="font-weight">
88
+ </prop>
89
+ <prop name="font-size" kind="css">
90
+ <description>Body font size; size prop presets via data attributes. Defaults to the theme body scale token for that size; clamp (prev step→token) applies only when --effect-fluid-typography is on and `fluid` is true (Text defaults fluid false).</description>
91
+ </prop>
92
+ <prop name="font-weight" kind="css">
88
93
  <description>Font weight on the root; keyword presets or numeric via weight prop.</description>
89
- </css_var>
90
- <css_var suffix="font-width">
94
+ </prop>
95
+ <prop name="font-width" kind="css">
91
96
  <description>Font width percentage on the root (font-stretch + wdth).</description>
92
- </css_var>
93
- <css_var suffix="line-height">
97
+ </prop>
98
+ <prop name="line-height" kind="css">
94
99
  <description>Line height; lineHeight prop presets via data attributes.</description>
95
- </css_var>
96
- <css_var suffix="letter-spacing">
97
- <description>Letter spacing on the root.</description>
98
- </css_var>
99
- <css_var suffix="literal-color">
100
+ </prop>
101
+ <prop name="letter-spacing" kind="css">
102
+ <description>Letter spacing on the root. Prefer the `tracking` React prop; set this hook only when theming beyond the prop.</description>
103
+ </prop>
104
+ <prop name="literal-color" kind="css">
100
105
  <description>Literal color override on the root.</description>
101
- </css_var>
102
- <css_var suffix="max-width">
106
+ </prop>
107
+ <prop name="max-width" kind="css">
103
108
  <description>Max inline size of the text root.</description>
104
- </css_var>
105
- <css_var suffix="padding-block-end">
109
+ </prop>
110
+ <prop name="padding-block-end" kind="css">
106
111
  <description>Block-end padding when padding is enabled.</description>
107
- </css_var>
108
- <css_var suffix="padding-block-start">
112
+ </prop>
113
+ <prop name="padding-block-start" kind="css">
109
114
  <description>Block-start padding when padding is enabled.</description>
110
- </css_var>
111
- <css_var suffix="padding-inline-end">
115
+ </prop>
116
+ <prop name="padding-inline-end" kind="css">
112
117
  <description>Inline-end padding when padding is enabled.</description>
113
- </css_var>
114
- <css_var suffix="padding-inline-start">
118
+ </prop>
119
+ <prop name="padding-inline-start" kind="css">
115
120
  <description>Inline-start padding when padding is enabled.</description>
116
- </css_var>
117
- <css_var suffix="trim">
121
+ </prop>
122
+ <prop name="trim" kind="css">
118
123
  <description>Text-box trim mode on the root.</description>
119
- </css_var>
120
- <css_var suffix="trim-type">
124
+ </prop>
125
+ <prop name="trim-type" kind="css">
121
126
  <description>Text-box trim basis on the root.</description>
122
- </css_var>
123
- <css_var suffix="text-transform">
124
- <description>Text transform on the root.</description>
125
- </css_var>
126
- <css_var suffix="white-space">
127
+ </prop>
128
+ <prop name="text-transform" kind="css">
129
+ <description>Text transform on the root. Prefer the `transform` React prop; set this hook only when theming beyond the prop.</description>
130
+ </prop>
131
+ <prop name="white-space" kind="css">
127
132
  <description>White-space behavior on the root.</description>
128
- </css_var>
133
+ </prop>
129
134
  </props>
@@ -1,7 +1,14 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <usage surface="text">
3
- <do>Body copy with semantic tone (including brand `primary`) and token-backed typography</do>
4
- <do>Helper, label, or inline copy inside other components</do>
5
- <do>Mono or body family text with fluid clamp sizing (gated by --effect-fluid-typography; off → fixed at --font-scale-body-* for that size)</do>
6
- <dont>Using Text for headings instead of Title</dont>
3
+ <do>Body copy, helpers, and labels — semantic `tone` before literal `color` or raw theme vars</do>
4
+ <do>Card / settings section blurb: Stack `rowGap` + Title heading + muted `size=&quot;s&quot;` Text — no invent CSS gap</do>
5
+ <do>Settings row: Stack `direction=&quot;row&quot;` + Text label + Switch/Checkbox (or nest Text inside Switch `label`) — Surface for chrome</do>
6
+ <do>Label/value metric rows: Stack row `hAlign=&quot;space-between&quot;` + muted Text label + `family=&quot;mono&quot;` Text value</do>
7
+ <do>Loading placeholder copy: nest Shimmer inside Text (parent region owns `aria-busy`) — not Skeleton for final-dimension text</do>
8
+ <do>Hero / status motion: nest Typewriter inside Text when body tone/size should drive the typed line</do>
9
+ <do>Ellipsis: ClampText `render={&lt;Text … /&gt;}` — FitText when copy must scale to fill width instead of truncate</do>
10
+ <do>Letter-spacing via `tracking`; text-transform via `transform`; width via `maxWidth` or parent Stack `fullWidth`</do>
11
+ <dont>Using Text for headings — use Title (`render` for h1–h6)</dont>
12
+ <dont>Inventing CSS `letter-spacing` / `text-transform` / `width: 100%` when `tracking` / `transform` / Stack `fullWidth` cover it</dont>
13
+ <dont>Setting body color with raw `--global-*` when `tone` covers the role</dont>
7
14
  </usage>
@@ -1,7 +1,53 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <patterns surface="textarea">
3
- <example title="Textarea structure">
4
- <tsx><![CDATA[<Textarea />]]></tsx>
5
- <notes>Public assembly hint from legacy guide; not API authority.</notes>
3
+ <!-- Sources: preview-grid — cleaned (no handlers). -->
4
+
5
+ <example title="Notes with resize + fitContent">
6
+ <tsx><![CDATA[
7
+ <Stack rowGap="l" hPadding="s" vPadding="s">
8
+ <Textarea
9
+ label="Notes"
10
+ placeholder="Add any notes for this payout configuration..."
11
+ rows={4}
12
+ resize="vertical"
13
+ fitContent
14
+ />
15
+ <Button>Save Threshold</Button>
16
+ </Stack>
17
+ ]]></tsx>
18
+ <notes>From preview-grid `payout-threshold`. `resize="vertical"` + `fitContent`; Stack owns panel gap.</notes>
19
+ </example>
20
+
21
+ <example title="Disabled on nested surface">
22
+ <tsx><![CDATA[
23
+ <Stack rowGap="s" hPadding="s" expandChildren>
24
+ <Textarea
25
+ disabled
26
+ label="Notes"
27
+ rows={3}
28
+ defaultValue="Disabled helper content on nested surface."
29
+ />
30
+ <Button disabled>Primary</Button>
31
+ </Stack>
32
+ ]]></tsx>
33
+ <notes>From preview-grid `disabled-surface-contrast`. Disabled Textarea inherits surface contrast; no custom CSS.</notes>
34
+ </example>
35
+
36
+ <example title="Labeled section under Fieldset">
37
+ <tsx><![CDATA[
38
+ <Fieldset label="Launch notes">
39
+ <Stack rowGap="m">
40
+ <Textarea
41
+ name="summary"
42
+ label="Summary"
43
+ description="One line shown in the dashboard."
44
+ placeholder="e.g. Production API"
45
+ rows={3}
46
+ />
47
+ <Textarea name="details" label="Details" rows={5} resize="vertical" />
48
+ </Stack>
49
+ </Fieldset>
50
+ ]]></tsx>
51
+ <notes>From Fieldset stories (`WithTextarea`). Section legend on Fieldset; each Textarea keeps its own label.</notes>
6
52
  </example>
7
53
  </patterns>
@@ -11,6 +11,7 @@
11
11
  <item>Single-line input — use Textfield</item>
12
12
  <item>Addon slots like Textfield startAddon or endAddon</item>
13
13
  <item>Wrapping a lone Textarea in Fieldset when its own label is sufficient</item>
14
+ <item>Forcing panel width with CSS `width: 100%` — wrap in Stack with `fullWidth` (see stack units)</item>
14
15
  </when_not_to_use>
15
16
  <prop name="description" kind="react">
16
17
  <description>Helper copy rendered with `Field.Description` and `Text` while the field is valid.</description>
@@ -27,13 +28,13 @@
27
28
  <prop name="resize" kind="react">
28
29
  <description>Native CSS `resize` for the control, serialized to `data-resize`. Omitted keeps resize disabled (`none`); accepts any valid `CSSProperties[&apos;resize&apos;]` value such as `&quot;vertical&quot;`, `&quot;horizontal&quot;`, or `&quot;both&quot;`.</description>
29
30
  </prop>
30
- <css_var suffix="input-border-radius">
31
+ <prop name="input-border-radius" kind="css">
31
32
  <description>Corner radius for the BasicInput textarea control (also drives field label/description inline padding).</description>
32
- </css_var>
33
- <css_var suffix="min-block-size">
33
+ </prop>
34
+ <prop name="min-block-size" kind="css">
34
35
  <description>Minimum block size of the BasicInput textarea control.</description>
35
- </css_var>
36
- <css_var suffix="padding-block">
36
+ </prop>
37
+ <prop name="padding-block" kind="css">
37
38
  <description>Block padding on the BasicInput textarea control.</description>
38
- </css_var>
39
+ </prop>
39
40
  </props>
@@ -1,10 +1,13 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <usage surface="textarea">
3
3
  <do>Multi-line text entry with label, description, and error</do>
4
- <do>Optional native CSS resize (vertical, horizontal, both, and other valid resize values)</do>
5
- <do>Content-sized growth via fitContent</do>
6
- <do>Native textarea attributes through the field control</do>
7
- <do>One or more Textareas inside Fieldset when they belong to a labeled form section with other fields</do>
8
- <dont>Using Textarea for single-line values</dont>
4
+ <do>Form section: Fieldset legend + one or more Textareas (and sibling Textfield/Select) — Stack owns `rowGap`; each Textarea keeps its own `label`</do>
5
+ <do>Fill a form column via a parent Stack `fullWidth` / `expandChildren` (Textarea has no `fullWidth` prop) — not CSS `width: 100%`</do>
6
+ <do>Notes + submit: Stack `rowGap` wrapping Textarea then Button — no panel width CSS</do>
7
+ <do>Optional native CSS `resize` via the `resize` prop; content-sized growth via `fitContent`</do>
8
+ <dont>Using Textarea for single-line values — use Textfield</dont>
9
+ <dont>Expecting Textfield `startAddon` / `endAddon` slots — Textarea has none</dont>
10
+ <dont>Inventing `width: 100%` / `w-full` CSS on Textarea when a parent Stack `fullWidth` can own the fill</dont>
9
11
  <dont>Expecting unsupported size or variant props</dont>
12
+ <dont>Wrapping a lone Textarea in Fieldset when its own label is enough</dont>
10
13
  </usage>
@@ -1,7 +1,167 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <patterns surface="textfield">
3
- <example title="Textfield structure">
4
- <tsx><![CDATA[<Textfield />]]></tsx>
5
- <notes>Public assembly hint from legacy guide; not API authority.</notes>
3
+ <!-- Sources: viraui-app + preview-grid — cleaned (no handlers, Controllers, i18n). -->
4
+
5
+ <example title="Inline email (login)">
6
+ <tsx><![CDATA[
7
+ <form>
8
+ <Stack direction="row" columnGap="m" rowGap="m" hAlign="start" vAlign="start" wrap>
9
+ <Textfield
10
+ type="email"
11
+ autoComplete="email"
12
+ placeholder="your@email.com"
13
+ size={30}
14
+ aria-label="Email"
15
+ startAddon={<EnvelopeSparkle />}
16
+ />
17
+ <Stack direction="row" vAlign="center" columnGap="m">
18
+ <Button type="submit">Send magic link</Button>
19
+ or
20
+ <ButtonLink variant="secondary" href="#">
21
+ Get ViraUI Pro
22
+ </ButtonLink>
23
+ </Stack>
24
+ </Stack>
25
+ </form>
26
+ ]]></tsx>
27
+ <notes>From `auth/login-form`. Wrap row for field + CTA cluster. Addon is decorative; strip react-hook-form Controller / i18n.</notes>
28
+ </example>
29
+
30
+ <example title="Read-only with swatch + end addon">
31
+ <tsx><![CDATA[
32
+ <Textfield
33
+ readOnly
34
+ label="Primary"
35
+ value="oklch(0.62 0.18 250)"
36
+ fullWidth
37
+ startAddon={<LineSwatch aria-hidden color="oklch(0.62 0.18 250)" />}
38
+ endAddon={<IconButton aria-label="Lock color" icon={<Lock />} size="s" variant="flat" type="button" />}
39
+ />
40
+ ]]></tsx>
41
+ <notes>From `common/color-picker`. `fullWidth` on Textfield — not CSS width. Buttons in addons need `type="button"`.</notes>
42
+ </example>
43
+
44
+ <example title="Dialog paste + invalid">
45
+ <tsx><![CDATA[
46
+ <Dialog.Sheet title="Import preset" description="Paste preset code." showCloseButton headerAlign="center">
47
+ <Stack rowGap="m" hAlign="center" hPadding="m" vPadding={['s', 0]}>
48
+ <Textfield
49
+ size={40}
50
+ placeholder="Paste preset…"
51
+ aria-label="Preset code"
52
+ invalid
53
+ error="Invalid preset code"
54
+ />
55
+ <Stack direction="row" hAlign="end" columnGap="s">
56
+ <Button>Apply</Button>
57
+ <Dialog.Close render={<Button variant="secondary">Cancel</Button>} />
58
+ </Stack>
59
+ </Stack>
60
+ </Dialog.Sheet>
61
+ ]]></tsx>
62
+ <notes>From `editor/import-preset-dialog`. Field copy via `error` / `invalid`; no module CSS.</notes>
63
+ </example>
64
+
65
+ <example title="Fit-content copy row (export)">
66
+ <tsx><![CDATA[
67
+ <Stack vPadding={['s', '3xl']}>
68
+ <Textfield
69
+ fitContent
70
+ readOnly
71
+ aria-label="Preset share code"
72
+ value="vira-preset-abc123"
73
+ endAddon={
74
+ <IconButton aria-label="Copy preset code" icon={<Duplicate />} size="s" variant="flat" type="button" />
75
+ }
76
+ />
77
+ </Stack>
78
+ ]]></tsx>
79
+ <notes>From `editor/export-dialog`. `fitContent` grows inline with value; end addon is chrome only.</notes>
80
+ </example>
81
+
82
+ <example title="Shipping address grid">
83
+ <tsx><![CDATA[
84
+ <Stack rowGap="l" hPadding="m" vPadding="m">
85
+ <Textfield label="Street address" required defaultValue="123 Main Street" />
86
+ <Textfield label="Apt / Suite" defaultValue="Apt 4B" />
87
+ <Stack columnGap="m" direction="row" expandChildren>
88
+ <Textfield label="City" defaultValue="San Francisco" />
89
+ <Textfield label="ZIP Code" defaultValue="94102" />
90
+ </Stack>
91
+ </Stack>
92
+ ]]></tsx>
93
+ <notes>From preview-grid `shipping-address`. Row pairs use Stack `expandChildren` — not width CSS on fields.</notes>
94
+ </example>
95
+
96
+ <example title="Invite row + link with end addon">
97
+ <tsx><![CDATA[
98
+ <Stack rowGap="s">
99
+ <Stack columnGap="s" direction="row" vAlign="end" expandChildren>
100
+ <Textfield aria-label="Invite email" defaultValue="alex@example.com" />
101
+ {/* role Select sibling */}
102
+ </Stack>
103
+ <Textfield
104
+ aria-label="Invite link"
105
+ defaultValue="https://app.co/invite/x8f2k"
106
+ endAddon={
107
+ <IconButton aria-label="Copy invite link" icon={<ArrowUpRight size={16} />} size="s" variant="secondary" type="button" />
108
+ }
109
+ />
110
+ </Stack>
111
+ ]]></tsx>
112
+ <notes>From preview-grid `invite-team`. End-aligned row for email + role; link field keeps copy action in `endAddon`.</notes>
113
+ </example>
114
+
115
+ <example title="Search with start addon">
116
+ <tsx><![CDATA[
117
+ <Stack columnGap="m" direction="row" vAlign="center" hAlign="space-between">
118
+ <Textfield
119
+ type="search"
120
+ aria-label="Search holdings or tickers"
121
+ placeholder="Search holdings or tickers..."
122
+ startAddon={<Magnifier size={16} />}
123
+ />
124
+ <Stack columnGap="xs" direction="row">
125
+ <Button variant="secondary">Stocks</Button>
126
+ <Button variant="secondary">ETFs</Button>
127
+ </Stack>
128
+ </Stack>
129
+ ]]></tsx>
130
+ <notes>From preview-grid `holdings`. Leading magnifier is `startAddon`, not a second control.</notes>
131
+ </example>
132
+
133
+ <example title="Currency prefix + verify end addon">
134
+ <tsx><![CDATA[
135
+ <Stack rowGap="m">
136
+ <Textfield label="Amount to Invest" defaultValue="1,000.00" startAddon={<>$</>} />
137
+ <Textfield
138
+ label="Account Holder Name"
139
+ defaultValue="Synthetic Horizons Music LLC"
140
+ endAddon={
141
+ <Button size="s" variant="secondary" addon={<ShieldCheck />} aria-label="Verify" type="button">
142
+ Verify
143
+ </Button>
144
+ }
145
+ />
146
+ </Stack>
147
+ ]]></tsx>
148
+ <notes>From preview-grid `buy-investment` + `payout-preferences`. Prefix text / action button live in addon slots.</notes>
149
+ </example>
150
+
151
+ <example title="Read-only clone URL">
152
+ <tsx><![CDATA[
153
+ <Surface border="all" radius="m" hPadding="m" vPadding="m">
154
+ <Stack rowGap="m">
155
+ <Textfield
156
+ aria-label="Repository clone URL"
157
+ readOnly
158
+ value="https://github.com/vira-soft/vira-ui.git"
159
+ endAddon={<Duplicate size={16} />}
160
+ />
161
+ <Text tone="muted">Clone using the web URL.</Text>
162
+ </Stack>
163
+ </Surface>
164
+ ]]></tsx>
165
+ <notes>From preview-grid `clone-repository`. Read-only value + trailing glyph; no handlers.</notes>
6
166
  </example>
7
167
  </patterns>
@@ -11,6 +11,7 @@
11
11
  <item>Custom size or variant props — fixed medium treatment</item>
12
12
  <item>Wrapping a lone Textfield in Fieldset when its own label is sufficient — Fieldset is for multi-field sections or shared legends</item>
13
13
  <item>Using Fieldset instead of the Textfield label for a single control</item>
14
+ <item>Inventing CSS `width: 100%` / `w-full` when the `fullWidth` prop covers it</item>
14
15
  </when_not_to_use>
15
16
  <prop name="description" kind="react">
16
17
  <description>Helper copy rendered with `Field.Description` and `Text` while the field is valid.</description>
@@ -25,7 +26,7 @@
25
26
  <description>When `true`, sets `field-sizing: content` so the control grows inline with its value. Block chrome stays `var(--vui-textfield-input-height)`. Omitted / `false` keeps the browser fixed default.</description>
26
27
  </prop>
27
28
  <prop name="fullWidth" kind="react">
28
- <description>When `true`, root and control group take `inline-size: 100%`.</description>
29
+ <description>When `true`, root and control group take `inline-size: 100%`. Prefer this prop over CSS `width: 100%` / `w-full` on the Textfield root. For controls without a `fullWidth` prop (e.g. Button), use a parent Stack `fullWidth` / `expandChildren` instead.</description>
29
30
  </prop>
30
31
  <prop name="label" kind="react">
31
32
  <description>Visible label rendered with shared internal `FieldLabel`.</description>
@@ -33,19 +34,19 @@
33
34
  <prop name="startAddon" kind="react">
34
35
  <description>Leading decoration (prefix text, icon). Not a second field control.</description>
35
36
  </prop>
36
- <css_var suffix="control-group-background">
37
+ <prop name="control-group-background" kind="css">
37
38
  <description>Textfield control group background.</description>
38
- </css_var>
39
- <css_var suffix="control-group-border-color">
39
+ </prop>
40
+ <prop name="control-group-border-color" kind="css">
40
41
  <description>Textfield control group border color.</description>
41
- </css_var>
42
- <css_var suffix="control-group-border-radius">
42
+ </prop>
43
+ <prop name="control-group-border-radius" kind="css">
43
44
  <description>Textfield control group corner radius.</description>
44
- </css_var>
45
- <css_var suffix="control-group-color">
45
+ </prop>
46
+ <prop name="control-group-color" kind="css">
46
47
  <description>Textfield control group foreground color.</description>
47
- </css_var>
48
- <css_var suffix="input-height">
48
+ </prop>
49
+ <prop name="input-height" kind="css">
49
50
  <description>Textfield control group block size.</description>
50
- </css_var>
51
+ </prop>
51
52
  </props>
@@ -1,9 +1,15 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <usage surface="textfield">
3
3
  <do>Single-line text, email, password, or similar native input types</do>
4
- <do>Start or end addon slots inside the shared control group</do>
4
+ <do>Login/signup swap: Tabs panels with Textfield(s) + Button (+ optional Fieldset) inside Stack/Surface — Stack gap/`fullWidth`/`expandChildren` only; 0 custom CSS</do>
5
+ <do>Several related Textfields under one Fieldset legend (e.g. billing) — each field keeps its own `label`</do>
6
+ <do>Equal-width form rows (city/ZIP, email + Select): parent Stack `direction=&quot;row&quot;` + `expandChildren` — not width CSS on children</do>
7
+ <do>Span the form column with Textfield `fullWidth` — open props before inventing width CSS</do>
8
+ <do>`startAddon` / `endAddon` for prefix text, icons, or actions inside the control group — IconButton/Button addons use `size=&quot;s&quot;` and `type=&quot;button&quot;`</do>
5
9
  <do>Label, description, and error copy with validation states</do>
6
- <do>Several related Textfields grouped under one section legend as Fieldset children (e.g. billing details)</do>
7
- <dont>Passing unsupported size or variant props</dont>
10
+ <dont>Multi-line entry — use Textarea</dont>
11
+ <dont>Inventing `width: 100%` / `w-full` CSS on the Textfield root when `fullWidth` covers it</dont>
12
+ <dont>Passing unsupported size or variant props — fixed medium treatment</dont>
8
13
  <dont>Expecting a focus ring when focus is only on addon controls</dont>
14
+ <dont>Wrapping a lone Textfield in Fieldset when its own label is enough</dont>
9
15
  </usage>