@cdx-ui/components 0.3.6 → 0.3.7

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 (167) hide show
  1. package/docs/components/content.md +1 -0
  2. package/docs/components/country-flag/content.md +232 -0
  3. package/docs/components/data-grid/content.md +3 -1
  4. package/docs/components/icon/content.md +1 -1
  5. package/docs/components/input/content.md +1 -0
  6. package/docs/components/progress-bar/content.md +164 -3
  7. package/docs/components/select/content.md +1 -0
  8. package/docs/foundations/expressions/icons/content.md +2 -1
  9. package/docs/getting-started/developers/content.md +1 -1
  10. package/docs/llms.txt +3 -0
  11. package/docs/patterns/insights/content.md +70 -1
  12. package/docs/resources/content.md +1 -0
  13. package/docs/resources/release-notes/0.3.6/content.md +29 -0
  14. package/docs/resources/release-notes/content.md +1 -0
  15. package/docs/resources/skills/content.md +66 -0
  16. package/lib/commonjs/components/BarChart/index.js +5 -12
  17. package/lib/commonjs/components/BarChart/index.js.map +1 -1
  18. package/lib/commonjs/components/CountryFlag/index.js +56 -0
  19. package/lib/commonjs/components/CountryFlag/index.js.map +1 -0
  20. package/lib/commonjs/components/Input/index.js.map +1 -1
  21. package/lib/commonjs/components/LineChart/index.js +3 -6
  22. package/lib/commonjs/components/LineChart/index.js.map +1 -1
  23. package/lib/commonjs/components/ProgressBar/index.js +44 -12
  24. package/lib/commonjs/components/ProgressBar/index.js.map +1 -1
  25. package/lib/commonjs/components/ProgressBar/styles.js +31 -2
  26. package/lib/commonjs/components/ProgressBar/styles.js.map +1 -1
  27. package/lib/commonjs/components/Select/index.js.map +1 -1
  28. package/lib/commonjs/components/chart/hiddenSvgProps.js +23 -0
  29. package/lib/commonjs/components/chart/hiddenSvgProps.js.map +1 -0
  30. package/lib/commonjs/components/index.js +12 -0
  31. package/lib/commonjs/components/index.js.map +1 -1
  32. package/lib/commonjs/figma/Accordion.figma.js +2 -2
  33. package/lib/commonjs/figma/Accordion.figma.js.map +1 -1
  34. package/lib/commonjs/figma/Alert.figma.js +7 -7
  35. package/lib/commonjs/figma/Alert.figma.js.map +1 -1
  36. package/lib/commonjs/figma/Badge.Indicator.figma.js +6 -5
  37. package/lib/commonjs/figma/Badge.Indicator.figma.js.map +1 -1
  38. package/lib/commonjs/figma/Badge.figma.js +22 -22
  39. package/lib/commonjs/figma/Badge.figma.js.map +1 -1
  40. package/lib/commonjs/figma/Button.figma.js +5 -2
  41. package/lib/commonjs/figma/Button.figma.js.map +1 -1
  42. package/lib/commonjs/figma/CLAUDE.md +1 -0
  43. package/lib/commonjs/figma/Card.Header.figma.js +8 -4
  44. package/lib/commonjs/figma/Card.Header.figma.js.map +1 -1
  45. package/lib/commonjs/figma/Card.figma.js +2 -1
  46. package/lib/commonjs/figma/Card.figma.js.map +1 -1
  47. package/lib/commonjs/figma/Chip.figma.js +2 -2
  48. package/lib/commonjs/figma/Chip.figma.js.map +1 -1
  49. package/lib/commonjs/figma/CurrencyInput.figma.js +1 -1
  50. package/lib/commonjs/figma/CurrencyInput.figma.js.map +1 -1
  51. package/lib/commonjs/figma/Dialog.figma.js +5 -2
  52. package/lib/commonjs/figma/Dialog.figma.js.map +1 -1
  53. package/lib/commonjs/figma/Divider.figma.js +1 -1
  54. package/lib/commonjs/figma/Divider.figma.js.map +1 -1
  55. package/lib/commonjs/figma/Drawer.figma.js +3 -3
  56. package/lib/commonjs/figma/Drawer.figma.js.map +1 -1
  57. package/lib/commonjs/figma/IconButton.figma.js +10 -4
  58. package/lib/commonjs/figma/IconButton.figma.js.map +1 -1
  59. package/lib/commonjs/figma/Input.figma.js +2 -1
  60. package/lib/commonjs/figma/Input.figma.js.map +1 -1
  61. package/lib/commonjs/figma/Insight.figma.js +3 -3
  62. package/lib/commonjs/figma/Insight.figma.js.map +1 -1
  63. package/lib/commonjs/figma/ProgressBar.figma.js +11 -2
  64. package/lib/commonjs/figma/ProgressBar.figma.js.map +1 -1
  65. package/lib/commonjs/figma/ProgressSegmented.figma.js +9 -1
  66. package/lib/commonjs/figma/ProgressSegmented.figma.js.map +1 -1
  67. package/lib/commonjs/figma/Select.figma.js +2 -1
  68. package/lib/commonjs/figma/Select.figma.js.map +1 -1
  69. package/lib/commonjs/figma/SystemAlert.figma.js +2 -3
  70. package/lib/commonjs/figma/SystemAlert.figma.js.map +1 -1
  71. package/lib/commonjs/styles.css +0 -1
  72. package/lib/module/components/BarChart/index.js +5 -12
  73. package/lib/module/components/BarChart/index.js.map +1 -1
  74. package/lib/module/components/CountryFlag/index.js +52 -0
  75. package/lib/module/components/CountryFlag/index.js.map +1 -0
  76. package/lib/module/components/Input/index.js.map +1 -1
  77. package/lib/module/components/LineChart/index.js +3 -6
  78. package/lib/module/components/LineChart/index.js.map +1 -1
  79. package/lib/module/components/ProgressBar/index.js +47 -15
  80. package/lib/module/components/ProgressBar/index.js.map +1 -1
  81. package/lib/module/components/ProgressBar/styles.js +31 -2
  82. package/lib/module/components/ProgressBar/styles.js.map +1 -1
  83. package/lib/module/components/Select/index.js.map +1 -1
  84. package/lib/module/components/chart/hiddenSvgProps.js +20 -0
  85. package/lib/module/components/chart/hiddenSvgProps.js.map +1 -0
  86. package/lib/module/components/index.js +1 -0
  87. package/lib/module/components/index.js.map +1 -1
  88. package/lib/module/figma/Accordion.figma.js +2 -2
  89. package/lib/module/figma/Accordion.figma.js.map +1 -1
  90. package/lib/module/figma/Alert.figma.js +7 -7
  91. package/lib/module/figma/Alert.figma.js.map +1 -1
  92. package/lib/module/figma/Badge.Indicator.figma.js +6 -5
  93. package/lib/module/figma/Badge.Indicator.figma.js.map +1 -1
  94. package/lib/module/figma/Badge.figma.js +22 -22
  95. package/lib/module/figma/Badge.figma.js.map +1 -1
  96. package/lib/module/figma/Button.figma.js +5 -2
  97. package/lib/module/figma/Button.figma.js.map +1 -1
  98. package/lib/module/figma/CLAUDE.md +1 -0
  99. package/lib/module/figma/Card.Header.figma.js +8 -4
  100. package/lib/module/figma/Card.Header.figma.js.map +1 -1
  101. package/lib/module/figma/Card.figma.js +2 -1
  102. package/lib/module/figma/Card.figma.js.map +1 -1
  103. package/lib/module/figma/Chip.figma.js +2 -2
  104. package/lib/module/figma/Chip.figma.js.map +1 -1
  105. package/lib/module/figma/CurrencyInput.figma.js +1 -1
  106. package/lib/module/figma/CurrencyInput.figma.js.map +1 -1
  107. package/lib/module/figma/Dialog.figma.js +5 -2
  108. package/lib/module/figma/Dialog.figma.js.map +1 -1
  109. package/lib/module/figma/Divider.figma.js +1 -1
  110. package/lib/module/figma/Divider.figma.js.map +1 -1
  111. package/lib/module/figma/Drawer.figma.js +3 -3
  112. package/lib/module/figma/Drawer.figma.js.map +1 -1
  113. package/lib/module/figma/IconButton.figma.js +10 -4
  114. package/lib/module/figma/IconButton.figma.js.map +1 -1
  115. package/lib/module/figma/Input.figma.js +2 -1
  116. package/lib/module/figma/Input.figma.js.map +1 -1
  117. package/lib/module/figma/Insight.figma.js +3 -3
  118. package/lib/module/figma/Insight.figma.js.map +1 -1
  119. package/lib/module/figma/ProgressBar.figma.js +12 -2
  120. package/lib/module/figma/ProgressBar.figma.js.map +1 -1
  121. package/lib/module/figma/ProgressSegmented.figma.js +9 -1
  122. package/lib/module/figma/ProgressSegmented.figma.js.map +1 -1
  123. package/lib/module/figma/Select.figma.js +2 -1
  124. package/lib/module/figma/Select.figma.js.map +1 -1
  125. package/lib/module/figma/SystemAlert.figma.js +2 -3
  126. package/lib/module/figma/SystemAlert.figma.js.map +1 -1
  127. package/lib/module/styles.css +0 -1
  128. package/lib/typescript/components/BarChart/index.d.ts.map +1 -1
  129. package/lib/typescript/components/CountryFlag/index.d.ts +35 -0
  130. package/lib/typescript/components/CountryFlag/index.d.ts.map +1 -0
  131. package/lib/typescript/components/Input/index.d.ts +2 -0
  132. package/lib/typescript/components/Input/index.d.ts.map +1 -1
  133. package/lib/typescript/components/LineChart/index.d.ts.map +1 -1
  134. package/lib/typescript/components/ProgressBar/index.d.ts +16 -1
  135. package/lib/typescript/components/ProgressBar/index.d.ts.map +1 -1
  136. package/lib/typescript/components/ProgressBar/styles.d.ts +7 -2
  137. package/lib/typescript/components/ProgressBar/styles.d.ts.map +1 -1
  138. package/lib/typescript/components/Select/index.d.ts +2 -0
  139. package/lib/typescript/components/Select/index.d.ts.map +1 -1
  140. package/lib/typescript/components/chart/hiddenSvgProps.d.ts +17 -0
  141. package/lib/typescript/components/chart/hiddenSvgProps.d.ts.map +1 -0
  142. package/lib/typescript/components/index.d.ts +1 -0
  143. package/lib/typescript/components/index.d.ts.map +1 -1
  144. package/lib/typescript/figma/Alert.figma.d.ts.map +1 -1
  145. package/lib/typescript/figma/Badge.Indicator.figma.d.ts.map +1 -1
  146. package/lib/typescript/figma/Badge.figma.d.ts.map +1 -1
  147. package/lib/typescript/figma/Button.figma.d.ts.map +1 -1
  148. package/lib/typescript/figma/Card.Header.figma.d.ts.map +1 -1
  149. package/lib/typescript/figma/Card.figma.d.ts.map +1 -1
  150. package/lib/typescript/figma/Dialog.figma.d.ts.map +1 -1
  151. package/lib/typescript/figma/IconButton.figma.d.ts.map +1 -1
  152. package/lib/typescript/figma/Input.figma.d.ts.map +1 -1
  153. package/lib/typescript/figma/ProgressBar.figma.d.ts.map +1 -1
  154. package/lib/typescript/figma/ProgressSegmented.figma.d.ts.map +1 -1
  155. package/lib/typescript/figma/Select.figma.d.ts.map +1 -1
  156. package/lib/typescript/figma/SystemAlert.figma.d.ts.map +1 -1
  157. package/package.json +5 -5
  158. package/src/components/BarChart/index.tsx +5 -12
  159. package/src/components/CountryFlag/index.tsx +53 -0
  160. package/src/components/Input/index.tsx +2 -0
  161. package/src/components/LineChart/index.tsx +3 -6
  162. package/src/components/ProgressBar/index.tsx +66 -14
  163. package/src/components/ProgressBar/styles.ts +35 -4
  164. package/src/components/Select/index.tsx +2 -0
  165. package/src/components/chart/hiddenSvgProps.ts +15 -0
  166. package/src/components/index.ts +1 -0
  167. package/src/styles.css +0 -1
@@ -61,6 +61,7 @@
61
61
  - [Divider](https://design.candescent.com/docs/components/divider/content.md) — A horizontal or vertical separator for grouping related content, with an optional inline label.
62
62
  - [Insurance Disclosure](https://design.candescent.com/docs/components/insurance-disclosure/content.md) — Domain-specific regulatory disclosure — official FDIC lockup with optional copy for account footers, deposit screens, and onboarding.
63
63
  - [Icon](https://design.candescent.com/docs/components/icon/content.md) — A cross-platform SVG icon wrapper with semantic color, sizing, filled variants, and accessibility support.
64
+ - [Country Flag](https://design.candescent.com/docs/components/country-flag/content.md) — A country flag rendered from an officially assigned ISO 3166-1 alpha-2 code.
64
65
  - [Image](https://design.candescent.com/docs/components/image/content.md) — Displays local or remote images across native and web platforms.
65
66
  - [List Item](https://design.candescent.com/docs/components/list-item/content.md) — A composable row for display and navigation — accounts, transactions, alerts, settings, and nav rows.
66
67
  - [Reorderable List](https://design.candescent.com/docs/components/reorderable-list/content.md) — A short, mount-all list that lets members drag rows into a new order via an explicit handle.
@@ -0,0 +1,232 @@
1
+ # Country Flag (https://design.candescent.com/docs/components/country-flag)
2
+
3
+ Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/content-countryflag--default)
4
+
5
+ `CountryFlag` renders a country's flag from an officially assigned ISO 3166-1 alpha-2 `code`.
6
+
7
+ ```tsx
8
+ import { CountryFlag, Select } from '@cdx-ui/components';
9
+ import { FlagUS } from '@cdx-ui/icons/flags';
10
+ ```
11
+
12
+ Flags keep their source colors. Each path has an explicit fill, so text color classes and theme tokens do not recolor the artwork.
13
+
14
+ An app that shows one fixed flag can import that component from `@cdx-ui/icons/flags` (`FlagUS`) instead of `CountryFlag`. `CountryFlag` pulls in the `flags` record and therefore every flag.
15
+
16
+ ## Basic
17
+
18
+ Pass `code`. The default box is `size-5`.
19
+
20
+ ```tsx
21
+ import { Box, CountryFlag, Text, type FlagCode } from '@cdx-ui/components';
22
+
23
+ const examples: { code: FlagCode; name: string }[] = [
24
+ { code: 'US', name: 'United States' },
25
+ { code: 'CA', name: 'Canada' },
26
+ { code: 'GB', name: 'United Kingdom' },
27
+ { code: 'JP', name: 'Japan' },
28
+ ];
29
+
30
+ export default function CountryFlagBasicDemo() {
31
+ return (
32
+ <Box className="flex-row items-end gap-5">
33
+ {examples.map((country) => (
34
+ <Box key={country.code} className="items-center gap-2">
35
+ <CountryFlag code={country.code} accessibilityLabel={country.name} />
36
+ <Text size="sm" color="secondary">
37
+ {country.code}
38
+ </Text>
39
+ </Box>
40
+ ))}
41
+ </Box>
42
+ );
43
+ }
44
+ ```
45
+
46
+ ## Sizes
47
+
48
+ A `size-*` class overrides the default box. The flag scales with the box. The default `size-5` box is 20 pixels.
49
+
50
+ ```tsx
51
+ import { Box, CountryFlag, Text } from '@cdx-ui/components';
52
+
53
+ const sizes = [
54
+ { className: 'size-4', label: '16' },
55
+ { className: 'size-5', label: '20' },
56
+ { className: 'size-6', label: '24' },
57
+ { className: 'size-8', label: '32' },
58
+ { className: 'size-10', label: '40' },
59
+ ] as const;
60
+
61
+ export default function CountryFlagSizesDemo() {
62
+ return (
63
+ <Box className="flex-row items-end gap-5">
64
+ {sizes.map((size) => (
65
+ <Box key={size.className} className="items-center gap-2">
66
+ <CountryFlag code="US" className={size.className} />
67
+ <Text size="sm" color="secondary">
68
+ {size.label}
69
+ </Text>
70
+ </Box>
71
+ ))}
72
+ </Box>
73
+ );
74
+ }
75
+ ```
76
+
77
+ ## With icons
78
+
79
+ Place the flag in the leading slot of a [`Select`](https://design.candescent.com/docs/components/select/content.md). `position="leading"` emits `data-icon="inline-start"`, and the slot's size class wins over `size-5`. A small select uses `size-4`. The same flag works in an [`Input`](https://design.candescent.com/docs/components/input/content.md) through `Input.Icon` with `asChild`, which sizes the flag for both the default and small input. On that composed node, `data-slot` is `country-flag` and `data-icon` is kept.
80
+
81
+ ```tsx
82
+ import { useState } from 'react';
83
+ import {
84
+ Box,
85
+ CountryFlag,
86
+ Input,
87
+ Select,
88
+ Text,
89
+ type FlagCode,
90
+ type InputProps,
91
+ type SelectProps,
92
+ } from '@cdx-ui/components';
93
+
94
+ const countries: { value: FlagCode; label: string }[] = [
95
+ { value: 'US', label: 'United States (+1)' },
96
+ { value: 'CA', label: 'Canada (+1)' },
97
+ { value: 'GB', label: 'United Kingdom (+44)' },
98
+ { value: 'JP', label: 'Japan (+81)' },
99
+ ];
100
+
101
+ function isListedCode(value: string): value is FlagCode {
102
+ return countries.some((country) => country.value === value);
103
+ }
104
+
105
+ function CountryCodeSelect({
106
+ size,
107
+ defaultCode,
108
+ }: {
109
+ size: NonNullable<SelectProps['size']>;
110
+ defaultCode: FlagCode;
111
+ }) {
112
+ const [code, setCode] = useState(defaultCode);
113
+
114
+ return (
115
+ <Select
116
+ items={countries}
117
+ size={size}
118
+ value={code}
119
+ onValueChange={(value) => {
120
+ if (isListedCode(value)) setCode(value);
121
+ }}
122
+ className="w-full"
123
+ accessibilityLabel="Country code"
124
+ >
125
+ <Select.Trigger>
126
+ <Select.Icon asChild position="leading">
127
+ <CountryFlag code={code} />
128
+ </Select.Icon>
129
+ <Select.Value />
130
+ </Select.Trigger>
131
+ <Select.Content>
132
+ {countries.map((country) => (
133
+ <Select.Item key={country.value} value={country.value}>
134
+ <CountryFlag code={country.value} />
135
+ <Select.ItemLabel>{country.label}</Select.ItemLabel>
136
+ </Select.Item>
137
+ ))}
138
+ </Select.Content>
139
+ </Select>
140
+ );
141
+ }
142
+
143
+ function CountryInput({ size, code }: { size: NonNullable<InputProps['size']>; code: FlagCode }) {
144
+ return (
145
+ <Input size={size}>
146
+ <Input.Icon asChild>
147
+ <CountryFlag code={code} />
148
+ </Input.Icon>
149
+ <Input.Field accessibilityLabel={`${size} phone number`} placeholder="Phone number" />
150
+ </Input>
151
+ );
152
+ }
153
+
154
+ export default function CountryFlagWithIconsDemo() {
155
+ return (
156
+ <Box className="w-full gap-4">
157
+ <Box className="gap-2">
158
+ <Text size="sm" color="secondary">
159
+ default
160
+ </Text>
161
+ <CountryCodeSelect size="default" defaultCode="US" />
162
+ <CountryInput size="default" code="US" />
163
+ </Box>
164
+ <Box className="gap-2">
165
+ <Text size="sm" color="secondary">
166
+ small
167
+ </Text>
168
+ <CountryCodeSelect size="small" defaultCode="CA" />
169
+ <CountryInput size="small" code="CA" />
170
+ </Box>
171
+ </Box>
172
+ );
173
+ }
174
+ ```
175
+
176
+ ## Accessibility
177
+
178
+ The flag is decorative unless `accessibilityLabel` is set. Omit the label when the country name or dialing code is already next to the flag.
179
+
180
+ ```tsx
181
+ import { Box, CountryFlag, Text } from '@cdx-ui/components';
182
+
183
+ export default function CountryFlagAccessibilityDemo() {
184
+ return (
185
+ <Box className="gap-5">
186
+ <Box className="flex-row items-center gap-3">
187
+ <CountryFlag code="US" accessibilityLabel="United States" />
188
+ <Text>Informative flag with a screen reader label</Text>
189
+ </Box>
190
+ <Box className="flex-row items-center gap-3">
191
+ <CountryFlag code="CA" />
192
+ <Text>Canada</Text>
193
+ </Box>
194
+ </Box>
195
+ );
196
+ }
197
+ ```
198
+
199
+ ## API
200
+
201
+ ### CountryFlag
202
+
203
+ Renders the flag for `code`. An unknown `code` renders nothing and logs a warning in development only. It does not throw.
204
+
205
+ | Prop | Type | Default | Description |
206
+ | --- | --- | --- | --- |
207
+ | `className?` | `string` | — | Utility classes for size (`size-*`) and placement, merged after the defaults. |
208
+ | `children?` | `React.ReactNode` | — | — |
209
+ | `size?` | `string \| number` | — | Width and height of the icon, in pixels or any SVG length. The bare icon renders at 24 when omitted. |
210
+ | `data-testid?` | `string` | — | Test identifier forwarded to the rendered SVG. |
211
+ | `code` | `'AD' \| 'AE' \| 'AF' \| 'AG' \| 'AI' \| 'AL' \| 'AM' \| 'AO' \| 'AQ' \| 'AR' \| 'AS' \| 'AT' \| 'AU' \| 'AW' \| 'AX' \| 'AZ' \| 'BA' \| 'BB' \| 'BD' \| 'BE' \| 'BF' \| 'BG' \| 'BH' \| 'BI' \| 'BJ' \| 'BL' \| 'BM' \| 'BN' \| 'BO' \| 'BQ' \| 'BR' \| 'BS' \| 'BT' \| 'BV' \| 'BW' \| 'BY' \| 'BZ' \| 'CA' \| 'CC' \| 'CD' \| 'CF' \| 'CG' \| 'CH' \| 'CI' \| 'CK' \| 'CL' \| 'CM' \| 'CN' \| 'CO' \| 'CR' \| 'CU' \| 'CV' \| 'CW' \| 'CX' \| 'CY' \| 'CZ' \| 'DE' \| 'DJ' \| 'DK' \| 'DM' \| 'DO' \| 'DZ' \| 'EC' \| 'EE' \| 'EG' \| 'EH' \| 'ER' \| 'ES' \| 'ET' \| 'FI' \| 'FJ' \| 'FK' \| 'FM' \| 'FO' \| 'FR' \| 'GA' \| 'GB' \| 'GD' \| 'GE' \| 'GF' \| 'GG' \| 'GH' \| 'GI' \| 'GL' \| 'GM' \| 'GN' \| 'GP' \| 'GQ' \| 'GR' \| 'GS' \| 'GT' \| 'GU' \| 'GW' \| 'GY' \| 'HK' \| 'HM' \| 'HN' \| 'HR' \| 'HT' \| 'HU' \| 'ID' \| 'IE' \| 'IL' \| 'IM' \| 'IN' \| 'IO' \| 'IQ' \| 'IR' \| 'IS' \| 'IT' \| 'JE' \| 'JM' \| 'JO' \| 'JP' \| 'KE' \| 'KG' \| 'KH' \| 'KI' \| 'KM' \| 'KN' \| 'KP' \| 'KR' \| 'KW' \| 'KY' \| 'KZ' \| 'LA' \| 'LB' \| 'LC' \| 'LI' \| 'LK' \| 'LR' \| 'LS' \| 'LT' \| 'LU' \| 'LV' \| 'LY' \| 'MA' \| 'MC' \| 'MD' \| 'ME' \| 'MF' \| 'MG' \| 'MH' \| 'MK' \| 'ML' \| 'MM' \| 'MN' \| 'MO' \| 'MP' \| 'MQ' \| 'MR' \| 'MS' \| 'MT' \| 'MU' \| 'MV' \| 'MW' \| 'MX' \| 'MY' \| 'MZ' \| 'NA' \| 'NC' \| 'NE' \| 'NF' \| 'NG' \| 'NI' \| 'NL' \| 'NO' \| 'NP' \| 'NR' \| 'NU' \| 'NZ' \| 'OM' \| 'PA' \| 'PE' \| 'PF' \| 'PG' \| 'PH' \| 'PK' \| 'PL' \| 'PM' \| 'PN' \| 'PR' \| 'PS' \| 'PT' \| 'PW' \| 'PY' \| 'QA' \| 'RE' \| 'RO' \| 'RS' \| 'RU' \| 'RW' \| 'SA' \| 'SB' \| 'SC' \| 'SD' \| 'SE' \| 'SG' \| 'SH' \| 'SI' \| 'SJ' \| 'SK' \| 'SL' \| 'SM' \| 'SN' \| 'SO' \| 'SR' \| 'SS' \| 'ST' \| 'SV' \| 'SX' \| 'SY' \| 'SZ' \| 'TC' \| 'TD' \| 'TF' \| 'TG' \| 'TH' \| 'TJ' \| 'TK' \| 'TL' \| 'TM' \| 'TN' \| 'TO' \| 'TR' \| 'TT' \| 'TV' \| 'TW' \| 'TZ' \| 'UA' \| 'UG' \| 'UM' \| 'US' \| 'UY' \| 'UZ' \| 'VA' \| 'VC' \| 'VE' \| 'VG' \| 'VI' \| 'VN' \| 'VU' \| 'WF' \| 'WS' \| 'YE' \| 'YT' \| 'ZA' \| 'ZM' \| 'ZW'` | — | ISO 3166-1 alpha-2 country code. |
212
+
213
+ Inherits [`SvgProps`](https://github.com/software-mansion/react-native-svg#common-props) except `color`, including `style` and `accessibilityLabel`. `as`, `filled`, and `color` are not accepted. `code` is the officially assigned ISO 3166-1 alpha-2 set, exported as `FlagCode` from `@cdx-ui/components` and `@cdx-ui/icons/flags`.
214
+
215
+ ## Defaults and styling
216
+
217
+ - `className` defaults to a `size-5` box. Consumer classes are merged after that default, so a `size-*` utility overrides it.
218
+ - Flag artwork keeps its source colors. Text color classes and theme tokens do not recolor it, because each path has an explicit fill.
219
+ - Prefer a `size-*` class over the inherited numeric `size` prop. The numeric prop bypasses the spacing scale.
220
+
221
+ ## Anatomy
222
+
223
+ | `data-slot` | Element |
224
+ | -------------- | ------------- |
225
+ | `country-flag` | Rendered flag |
226
+
227
+ When `CountryFlag` is the child of `Select.Icon` with `asChild`, the rendered node keeps `data-slot="country-flag"`. `position="leading"` still sets `data-icon="inline-start"`, and `position="trailing"` sets `data-icon="inline-end"`. The select's icon size class replaces the default `size-5`. A small select uses `size-4`.
228
+
229
+ ## Accessibility
230
+
231
+ - Without `accessibilityLabel`, the flag is decorative and hidden from assistive technology.
232
+ - With `accessibilityLabel`, the flag is exposed as an image and announced with that label.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/data-visualization-datagrid--default)
4
4
 
5
- `DataGrid` is a **web-only** data-driven grid. Install `@cdx-ui/data-grid` in addition to `@cdx-ui/components`. For fully custom markup use `Table`. For a standalone pager use `TablePagination`.
5
+ `DataGrid` is a **web-only** data-driven grid. Install `@cdx-ui/data-grid` in addition to `@cdx-ui/components`, and add `@import '@cdx-ui/data-grid/styles.css';` after `@cdx-ui/components/styles.css` in your Tailwind CSS entry; without it the grid renders without its border, header background, or row dividers. For fully custom markup use `Table`. For a standalone pager use `TablePagination`.
6
6
 
7
7
  ```tsx
8
8
  import {
@@ -26,6 +26,8 @@ Search is **not** always on. Set `showToolbar` to show the search field (same op
26
26
 
27
27
  The grid is a fixed viewport like MUI Data Grid Community: **300px** tall by default. Column headers stay visible while rows scroll; pagination stays at the bottom. Override height with a `className` such as `h-full` or a spacing-scale height (`h-130`).
28
28
 
29
+ Set `autoHeight` to size the grid to its rows instead, so a short table leaves no empty space below the last row. The grid then grows with every row on the page, so pair it with pagination for long data. The empty state keeps a minimum height.
30
+
29
31
  When `rows` is empty, a centered "No rows" message is shown and pagination is omitted. Pass `noRowsOverlay` to replace the default message.
30
32
 
31
33
  ```tsx
@@ -180,7 +180,7 @@ Inherits all `ForgeIconProps` except the SVG `color`: [`SvgProps`](https://githu
180
180
  - A raw `color` value, such as a hex string, is deprecated. It is passed to the SVG unchanged and logs a one-time warning in development. Use a semantic color instead.
181
181
  - `className` defaults to `size-5 shrink-0`, so an icon keeps its size in a row of text on web.
182
182
  - Consumer classes are merged after the defaults, so `size-*` and `shrink` utilities override them.
183
- - Don't pass the inherited numeric `size` prop; it bypasses the spacing scale. Use `size-4` or `size-6` when the default doesn't fit.
183
+ - Don't pass the inherited numeric `size` prop; it bypasses the spacing scale. Use another `size-*` class on the spacing scale when the default doesn't fit.
184
184
  - `filled` defaults to `false`.
185
185
 
186
186
  ## Accessibility
@@ -346,6 +346,7 @@ Renders a Forge icon sized to the input. Inherits size from the parent Input con
346
346
  | Prop | Type | Default | Description |
347
347
  | --- | --- | --- | --- |
348
348
  | `className?` | `string` | — | Utility classes for size (`size-*`) and placement, merged after the defaults. |
349
+ | `children?` | `ReactNode` | — | The element rendered when `asChild` is set. |
349
350
  | `filled?` | `boolean` | — | When `true`, renders the filled variant of the icon (if available). Defaults to `false` (outlined). |
350
351
  | `size?` | `string \| number` | — | Width and height of the icon, in pixels or any SVG length. The bare icon renders at 24 when omitted. |
351
352
  | `data-testid?` | `string` | — | Test identifier forwarded to the rendered SVG. |
@@ -47,6 +47,165 @@ export default function ProgressBarValuesDemo() {
47
47
  }
48
48
  ```
49
49
 
50
+ ## Sizes
51
+
52
+ `default` is 6px tall; `large` is 8px. Size is set on the root and applied to the track.
53
+
54
+ ```tsx
55
+ import { Box, ProgressBar, Text } from '@cdx-ui/components';
56
+
57
+ export default function ProgressBarSizesDemo() {
58
+ return (
59
+ <Box className="w-full max-w-md gap-4">
60
+ <Box className="gap-1.5">
61
+ <Text size="sm" color="secondary">
62
+ default
63
+ </Text>
64
+ <ProgressBar value={60} max={100} size="default" accessibilityLabel="Default size progress">
65
+ <ProgressBar.Indicator />
66
+ </ProgressBar>
67
+ </Box>
68
+ <Box className="gap-1.5">
69
+ <Text size="sm" color="secondary">
70
+ large
71
+ </Text>
72
+ <ProgressBar value={60} max={100} size="large" accessibilityLabel="Large size progress">
73
+ <ProgressBar.Indicator />
74
+ </ProgressBar>
75
+ </Box>
76
+ </Box>
77
+ );
78
+ }
79
+ ```
80
+
81
+ ## Colors
82
+
83
+ Severity colors use `surface-*-strong` fills. Categorical colors use `chart-categorical-*` so FI theme overrides flow through without a component change. The track is always `surface-neutral-subtle`.
84
+
85
+ ```tsx
86
+ import { Box, ProgressBar, Text, type ProgressBarColor } from '@cdx-ui/components';
87
+
88
+ const COLORS: readonly ProgressBarColor[] = [
89
+ 'action',
90
+ 'danger',
91
+ 'warning',
92
+ 'success',
93
+ 'info',
94
+ 'categorical-1',
95
+ 'categorical-2',
96
+ 'categorical-3',
97
+ 'categorical-4',
98
+ 'categorical-5',
99
+ 'categorical-6',
100
+ ];
101
+
102
+ export default function ProgressBarColorsDemo() {
103
+ return (
104
+ <Box className="w-full max-w-md gap-3">
105
+ {COLORS.map((color) => (
106
+ <Box key={color} className="gap-1.5">
107
+ <Text size="sm" color="secondary">
108
+ {color}
109
+ </Text>
110
+ <ProgressBar value={65} max={100} color={color} accessibilityLabel={`${color} progress`}>
111
+ <ProgressBar.Indicator />
112
+ </ProgressBar>
113
+ </Box>
114
+ ))}
115
+ </Box>
116
+ );
117
+ }
118
+ ```
119
+
120
+ ## Indeterminate
121
+
122
+ Pass `value={null}` for a segment that passes across the track until a value is known.
123
+
124
+ ```tsx
125
+ import { ProgressBar } from '@cdx-ui/components';
126
+
127
+ export default function ProgressBarIndeterminateDemo() {
128
+ return (
129
+ <ProgressBar value={null} accessibilityLabel="Loading">
130
+ <ProgressBar.Indicator />
131
+ </ProgressBar>
132
+ );
133
+ }
134
+ ```
135
+
136
+ ## Budget rows
137
+
138
+ Compose a label, percent, bar, and caption so status is clear in text, not by color alone.
139
+
140
+ ```tsx
141
+ import { Box, HStack, ProgressBar, Text, type ProgressBarColor } from '@cdx-ui/components';
142
+
143
+ interface BudgetRow {
144
+ readonly label: string;
145
+ readonly percent: number;
146
+ readonly caption: string;
147
+ readonly color: ProgressBarColor;
148
+ }
149
+
150
+ const ROWS: readonly BudgetRow[] = [
151
+ {
152
+ label: 'Dining',
153
+ percent: 80,
154
+ caption: '$320 of $400 — 10 days left',
155
+ color: 'categorical-1',
156
+ },
157
+ {
158
+ label: 'Groceries',
159
+ percent: 55,
160
+ caption: '$275 of $500 — on track',
161
+ color: 'categorical-2',
162
+ },
163
+ {
164
+ label: 'Transport',
165
+ percent: 95,
166
+ caption: '$190 of $200 — near limit',
167
+ color: 'warning',
168
+ },
169
+ {
170
+ label: 'Entertainment',
171
+ percent: 40,
172
+ caption: '$60 of $150 — under budget',
173
+ color: 'success',
174
+ },
175
+ ];
176
+
177
+ export default function ProgressBarBudgetRowsDemo() {
178
+ return (
179
+ <Box className="w-full max-w-md gap-4">
180
+ {ROWS.map((row) => (
181
+ <Box key={row.label} className="gap-1.5">
182
+ <HStack space="sm" className="items-baseline justify-between">
183
+ <Text size="sm" weight="medium">
184
+ {row.label}
185
+ </Text>
186
+ <Text size="sm" color="secondary">
187
+ {row.percent}%
188
+ </Text>
189
+ </HStack>
190
+ <ProgressBar
191
+ value={row.percent}
192
+ max={100}
193
+ size="large"
194
+ color={row.color}
195
+ accessibilityLabel={`${row.label} budget ${String(row.percent)} percent used`}
196
+ >
197
+ <ProgressBar.Indicator />
198
+ </ProgressBar>
199
+ <Text size="sm" color="secondary">
200
+ {row.caption}
201
+ </Text>
202
+ </Box>
203
+ ))}
204
+ </Box>
205
+ );
206
+ }
207
+ ```
208
+
50
209
  ## API
51
210
 
52
211
  ### ProgressBar
@@ -55,8 +214,10 @@ Sets `role="progressbar"` and `accessibilityRole="progressbar"`. Pass `value={nu
55
214
 
56
215
  | Prop | Type | Default | Description |
57
216
  | --- | --- | --- | --- |
58
- | `className?` | `string` | — | — |
217
+ | `className?` | `string` | — | Additional Uniwind/Tailwind classes, merged after the track's own styles. |
59
218
  | `children?` | `React.ReactNode` | — | — |
219
+ | `size?` | `'default' \| 'large'` | `'default'` | Track height. Inherited by `ProgressBar.Indicator` via style context. |
220
+ | `color?` | `'action' \| 'danger' \| 'warning' \| 'success' \| 'info' \| 'categorical-1' \| 'categorical-2' \| 'categorical-3' \| 'categorical-4' \| 'categorical-5' \| 'categorical-6'` | `'action'` | Indicator fill color. Inherited by `ProgressBar.Indicator` via style context. The track is always `surface-neutral-subtle`. |
60
221
  | `value?` | `number \| null` | `0` | Current value in the range `[0, max]`, or `null` for indeterminate progress. Values below `0` clamp to `0`; values above `max` clamp to `max`. Non-finite values (such as `NaN`) are treated as `0`. |
61
222
  | `max?` | `number` | `100` | Maximum value. The minimum is always `0`. A `max` of `0` or less is treated as complete. |
62
223
  | `getValueLabel?` | `((value: number, max: number) => string)` | — | Screen-reader text for determinate progress (`accessibilityValue.text`). Defaults to a rounded percentage of `max`, such as `"45%"`. No effect when `value` is `null`, or when `accessibilityValue` is set. |
@@ -73,11 +234,11 @@ Inherits all [`ViewProps`](https://reactnative.dev/docs/view#props).
73
234
 
74
235
  ### ProgressBar.Indicator
75
236
 
76
- The filled portion of the track. Width is set automatically from `value / max`.
237
+ The filled portion of the track. Width is set automatically from `value / max`. In indeterminate mode a partial segment passes across the track.
77
238
 
78
239
  | Prop | Type | Default | Description |
79
240
  | --- | --- | --- | --- |
80
- | `className?` | `string` | — | — |
241
+ | `className?` | `string` | — | Additional Uniwind/Tailwind classes, merged after the indicator's own styles. |
81
242
  | `children?` | `React.ReactNode` | — | — |
82
243
 
83
244
  Inherits all [`ViewProps`](https://reactnative.dev/docs/view#props).
@@ -644,6 +644,7 @@ Renders a Forge icon sized to the select. Use it as the `indicator` value when a
644
644
  | Prop | Type | Default | Description |
645
645
  | --- | --- | --- | --- |
646
646
  | `className?` | `string` | — | Utility classes for size (`size-*`) and placement, merged after the defaults. |
647
+ | `children?` | `ReactNode` | — | The element rendered when `asChild` is set. |
647
648
  | `filled?` | `boolean` | — | When `true`, renders the filled variant of the icon (if available). Defaults to `false` (outlined). |
648
649
  | `size?` | `string \| number` | — | Width and height of the icon, in pixels or any SVG length. The bare icon renders at 24 when omitted. |
649
650
  | `data-testid?` | `string` | — | Test identifier forwarded to the rendered SVG. |
@@ -3,7 +3,8 @@
3
3
  Cross-platform icon library for Forge UI, built on [Material Symbols](https://fonts.google.com/icons) (outlined style, weight 400, optical size 24). Renders via `react-native-svg` and targets iOS, Android, and Web.
4
4
 
5
5
  3,986 icons are available, each with outlined and filled variants, plus support for custom
6
- SVGs.
6
+ SVGs. Country flags are a separate set and do not appear in the browser below. Render one with
7
+ [`CountryFlag`](https://design.candescent.com/docs/components/country-flag/content.md).
7
8
 
8
9
  ```bash
9
10
  pnpm add @cdx-ui/icons
@@ -93,7 +93,7 @@ Create `global.css` in your project root:
93
93
  - **`@custom-variant dark`** — Switches Tailwind v4's dark mode from `@media (prefers-color-scheme)` to class-based activation. Required for `ScopedTheme` to work on web. Harmless if you don't use `ScopedTheme` — global dark mode continues to work via `Uniwind.setTheme()`.
94
94
  - **`@cdx-ui/styles/theme.css`** — Design tokens (colors, spacing, radii, shadows, fonts) as a Tailwind v4 `@theme static` block, plus light/dark mode and platform font overrides via `@variant`.
95
95
  - **`@cdx-ui/styles/utilities.css`** — Composite typography utilities (`heading-xl`…`heading-xs`, `body-xl`…`body-xs`, `label-sm`, `label-xs`) used by `Heading`, `Text`, and `Link`. Each has a `-size` companion (`body-sm-size`) that sets only the font size, line height, and letter spacing, so nested text can change size and keep its inherited font family and weight.
96
- - **`@cdx-ui/components/styles.css`** — `@source` directive telling Tailwind where to scan for component utility classes.
96
+ - **`@cdx-ui/components/styles.css`** — `@source` directive telling Tailwind where to scan for component utility classes. If you use `DataGrid`, also import `@cdx-ui/data-grid/styles.css`, which does the same for `@cdx-ui/data-grid`.
97
97
 
98
98
  > [!NOTE]
99
99
  >
package/docs/llms.txt CHANGED
@@ -85,6 +85,7 @@ Links point at each page's `content.md`, which carries the page's prose, demo so
85
85
  - [Divider](components/divider/content.md): A horizontal or vertical separator for grouping related content, with an optional inline label. Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--Components?node-id=6771-8895), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/layout-divider--default)
86
86
  - [Insurance Disclosure](components/insurance-disclosure/content.md): Domain-specific regulatory disclosure — official FDIC lockup with optional copy for account footers, deposit screens, and onboarding. Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--Components?node-id=8550-3291), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/domain-insurancedisclosure--default)
87
87
  - [Icon](components/icon/content.md): A cross-platform SVG icon wrapper with semantic color, sizing, filled variants, and accessibility support. Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--React-Native-Components?node-id=397-33), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/content-icon--default)
88
+ - [Country Flag](components/country-flag/content.md): A country flag rendered from an officially assigned ISO 3166-1 alpha-2 code. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/content-countryflag--default)
88
89
  - [Image](components/image/content.md): Displays local or remote images across native and web platforms. Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--Components?node-id=9091-16186), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/content-image--default)
89
90
  - [List Item](components/list-item/content.md): A composable row for display and navigation — accounts, transactions, alerts, settings, and nav rows. Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--React-Native-Components?node-id=3710-4649), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/surfaces-listitem--default)
90
91
  - [Reorderable List](components/reorderable-list/content.md): A short, mount-all list that lets members drag rows into a new order via an explicit handle. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/layout-reorderablelist--default)
@@ -141,6 +142,7 @@ Links point at each page's `content.md`, which carries the page's prose, demo so
141
142
 
142
143
  - **Tools**
143
144
  - [Figma libraries](resources/figma-libraries/content.md): Access our official design system Figma libraries
145
+ - [Agent skills](resources/skills/content.md): Teach AI coding agents to build with Forge UI components as they ship, without restyling them.
144
146
 
145
147
  - **Changelogs**
146
148
  - Release notes
@@ -148,6 +150,7 @@ Links point at each page's `content.md`, which carries the page's prose, demo so
148
150
 
149
151
  ## Release notes
150
152
 
153
+ - [0.3.6](resources/release-notes/0.3.6/content.md): Adds SystemAlert, bar, line, and pie charts on a shared MUI X-shaped API, Stepper, and a fix for tabs scroll controls.
151
154
  - [0.3.5](resources/release-notes/0.3.5/content.md): Selected subtle Chip labels stay visible on Android when the variant changes from outline to subtle.
152
155
  - [0.3.4](resources/release-notes/0.3.4/content.md): Select adds multiple selection, in-list search, and a native bottom sheet; Input gains a subtle variant for fields inside popups and sheets.
153
156
  - [0.3.3](resources/release-notes/0.3.3/content.md): Insight and InsightStack add dismissible summary cards with status colors, optional AI styling, and stacked depth for insight feeds.
@@ -391,7 +391,7 @@ export default function InsightsOverviewBlock() {
391
391
 
392
392
  ## Insight with Chart
393
393
 
394
- Dismissible insight cards that back their headline with a chart: a horizontal bar comparison with month-over-month change, and a cash-flow waterfall.
394
+ Dismissible insight cards that back their headline with a chart: a horizontal bar comparison with month-over-month change, a cash-flow waterfall, and budget progress bars.
395
395
 
396
396
  **Platforms:** iOS, Android
397
397
 
@@ -399,11 +399,15 @@ Dismissible insight cards that back their headline with a chart: a horizontal ba
399
399
  import {
400
400
  BarChart,
401
401
  Button,
402
+ HStack,
403
+ Icon,
402
404
  Insight,
405
+ ProgressBar,
403
406
  Text,
404
407
  VStack,
405
408
  type ChartValueFormatter,
406
409
  } from '@cdx-ui/components';
410
+ import { CheckCircle, Error } from '@cdx-ui/icons';
407
411
  import { FILL_WIDTH, formatUsd } from '../_utils';
408
412
 
409
413
  const SPENDING = [
@@ -516,11 +520,76 @@ function CashFlowInsight() {
516
520
  );
517
521
  }
518
522
 
523
+ function BudgetInsight() {
524
+ return (
525
+ <Insight layout="detail" onClose={() => {}}>
526
+ <Insight.Tag>Budget</Insight.Tag>
527
+ <Insight.Header>
528
+ <Insight.Title>You’ve gone over your Entertainment budget this month</Insight.Title>
529
+ <Insight.Description>
530
+ Dining Out is close to its limit · <Text weight="bold">8 days left</Text>
531
+ </Insight.Description>
532
+ </Insight.Header>
533
+ <Insight.Content className="gap-4">
534
+ <VStack space="xs">
535
+ <HStack className="items-center justify-between">
536
+ <Text weight="semibold">Entertainment</Text>
537
+ <HStack space="xs" className="items-center">
538
+ <Icon as={Error} className="size-4 text-chart-categorical-2" />
539
+ <Text size="sm" weight="semibold">
540
+ $65 over
541
+ </Text>
542
+ </HStack>
543
+ </HStack>
544
+ <ProgressBar
545
+ value={100}
546
+ max={100}
547
+ size="large"
548
+ color="categorical-2"
549
+ accessibilityLabel="Entertainment budget, $65 over"
550
+ >
551
+ <ProgressBar.Indicator />
552
+ </ProgressBar>
553
+ </VStack>
554
+ <VStack space="xs">
555
+ <HStack className="items-center justify-between">
556
+ <Text weight="semibold">Dining Out</Text>
557
+ <Text size="sm" weight="medium" color="secondary">
558
+ $120 left
559
+ </Text>
560
+ </HStack>
561
+ <ProgressBar
562
+ value={73}
563
+ max={100}
564
+ size="large"
565
+ color="categorical-1"
566
+ accessibilityLabel="Dining Out budget, $120 left"
567
+ >
568
+ <ProgressBar.Indicator />
569
+ </ProgressBar>
570
+ </VStack>
571
+ </Insight.Content>
572
+ <Insight.Footer className="justify-between">
573
+ <HStack space="xs" className="shrink items-center">
574
+ <Icon as={CheckCircle} color="success" className="size-4" />
575
+ <Text size="sm" color="secondary">
576
+ 3 other budgets on track
577
+ </Text>
578
+ </HStack>
579
+ <Button variant="outline" color="action" size="small">
580
+ <Button.Label>View budgets</Button.Label>
581
+ </Button>
582
+ </Insight.Footer>
583
+ </Insight>
584
+ );
585
+ }
586
+
519
587
  export default function InsightChartBlock() {
520
588
  return (
521
589
  <VStack space="lg" className="w-full">
522
590
  <SpendingInsight />
523
591
  <CashFlowInsight />
592
+ <BudgetInsight />
524
593
  </VStack>
525
594
  );
526
595
  }
@@ -3,6 +3,7 @@
3
3
  ## Tools
4
4
 
5
5
  - [Figma libraries](https://design.candescent.com/docs/resources/figma-libraries/content.md) — Access our official design system Figma libraries
6
+ - [Agent skills](https://design.candescent.com/docs/resources/skills/content.md) — Teach AI coding agents to build with Forge UI components as they ship, without restyling them.
6
7
 
7
8
  ## Changelogs
8
9