@cdx-ui/components 0.3.7 → 0.3.8

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 (44) hide show
  1. package/docs/components/content.md +2 -1
  2. package/docs/components/country-flag/content.md +3 -3
  3. package/docs/components/currency-flag/content.md +202 -0
  4. package/docs/components/currency-input/content.md +175 -56
  5. package/docs/foundations/expressions/icons/content.md +1 -1
  6. package/docs/getting-started/developers/styling/content.md +2 -2
  7. package/docs/llms.txt +3 -1
  8. package/docs/resources/release-notes/0.3.7/content.md +27 -0
  9. package/docs/resources/release-notes/content.md +1 -0
  10. package/lib/commonjs/components/CountryFlag/index.js +2 -2
  11. package/lib/commonjs/components/CountryFlag/index.js.map +1 -1
  12. package/lib/commonjs/components/CurrencyFlag/index.js +77 -0
  13. package/lib/commonjs/components/CurrencyFlag/index.js.map +1 -0
  14. package/lib/commonjs/components/CurrencyInput/index.js +3 -1
  15. package/lib/commonjs/components/CurrencyInput/index.js.map +1 -1
  16. package/lib/commonjs/components/CurrencyInput/styles.js +23 -7
  17. package/lib/commonjs/components/CurrencyInput/styles.js.map +1 -1
  18. package/lib/commonjs/components/index.js +12 -0
  19. package/lib/commonjs/components/index.js.map +1 -1
  20. package/lib/module/components/CountryFlag/index.js +2 -2
  21. package/lib/module/components/CountryFlag/index.js.map +1 -1
  22. package/lib/module/components/CurrencyFlag/index.js +72 -0
  23. package/lib/module/components/CurrencyFlag/index.js.map +1 -0
  24. package/lib/module/components/CurrencyInput/index.js +3 -1
  25. package/lib/module/components/CurrencyInput/index.js.map +1 -1
  26. package/lib/module/components/CurrencyInput/styles.js +23 -7
  27. package/lib/module/components/CurrencyInput/styles.js.map +1 -1
  28. package/lib/module/components/index.js +1 -0
  29. package/lib/module/components/index.js.map +1 -1
  30. package/lib/typescript/components/CountryFlag/index.d.ts +8 -3
  31. package/lib/typescript/components/CountryFlag/index.d.ts.map +1 -1
  32. package/lib/typescript/components/CurrencyFlag/index.d.ts +47 -0
  33. package/lib/typescript/components/CurrencyFlag/index.d.ts.map +1 -0
  34. package/lib/typescript/components/CurrencyInput/index.d.ts.map +1 -1
  35. package/lib/typescript/components/CurrencyInput/styles.d.ts +6 -1
  36. package/lib/typescript/components/CurrencyInput/styles.d.ts.map +1 -1
  37. package/lib/typescript/components/index.d.ts +1 -0
  38. package/lib/typescript/components/index.d.ts.map +1 -1
  39. package/package.json +5 -5
  40. package/src/components/CountryFlag/index.tsx +8 -3
  41. package/src/components/CurrencyFlag/index.tsx +71 -0
  42. package/src/components/CurrencyInput/index.tsx +2 -1
  43. package/src/components/CurrencyInput/styles.ts +29 -3
  44. package/src/components/index.ts +1 -0
@@ -61,7 +61,8 @@
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
+ - [Country Flag](https://design.candescent.com/docs/components/country-flag/content.md) — A flag for a country-flag-icons code, including unofficial codes used by libphonenumber-js.
65
+ - [Currency Flag](https://design.candescent.com/docs/components/currency-flag/content.md) — The flag of the country or union that issues an ISO 4217 currency.
65
66
  - [Image](https://design.candescent.com/docs/components/image/content.md) — Displays local or remote images across native and web platforms.
66
67
  - [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.
67
68
  - [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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/content-countryflag--default)
4
4
 
5
- `CountryFlag` renders a country's flag from an officially assigned ISO 3166-1 alpha-2 `code`.
5
+ `CountryFlag` renders a flag from a `FlagCode`. The codes match the `country-flag-icons` 3x2 set this package was built with: officially assigned ISO 3166-1 alpha-2 codes, the unofficial codes that package ships for `libphonenumber-js`, and its subdivision codes.
6
6
 
7
7
  ```tsx
8
8
  import { CountryFlag, Select } from '@cdx-ui/components';
@@ -208,9 +208,9 @@ Renders the flag for `code`. An unknown `code` renders nothing and logs a warnin
208
208
  | `children?` | `React.ReactNode` | — | — |
209
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
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. |
211
+ | `code` | `'AC' \| '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' \| 'BQ-BO' \| 'BQ-SA' \| 'BQ-SE' \| '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' \| 'ES-CT' \| 'ET' \| 'EU' \| 'FI' \| 'FJ' \| 'FK' \| 'FM' \| 'FO' \| 'FR' \| 'GA' \| 'GB' \| 'GB-ENG' \| 'GB-NIR' \| 'GB-SCT' \| 'GB-WLS' \| 'GD' \| 'GE' \| 'GF' \| 'GG' \| 'GH' \| 'GI' \| 'GL' \| 'GM' \| 'GN' \| 'GP' \| 'GQ' \| 'GR' \| 'GS' \| 'GT' \| 'GU' \| 'GW' \| 'GY' \| 'HK' \| 'HM' \| 'HN' \| 'HR' \| 'HT' \| 'HU' \| 'IC' \| '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' \| 'TA' \| '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' \| 'XA' \| 'XC' \| 'XK' \| 'XO' \| 'YE' \| 'YT' \| 'ZA' \| 'ZM' \| 'ZW'` | — | Code from the country-flag-icons 3x2 set. Includes officially assigned ISO 3166-1 alpha-2 codes, the unofficial codes that package ships for libphonenumber-js, and its subdivision codes. Subdivision codes keep their hyphen (`GB-ENG`). |
212
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`.
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 `FlagCode`, exported from `@cdx-ui/components` and `@cdx-ui/icons/flags`. Subdivision codes keep the hyphen (`GB-ENG`). The icon component replaces it with an underscore (`FlagGB_ENG`).
214
214
 
215
215
  ## Defaults and styling
216
216
 
@@ -0,0 +1,202 @@
1
+ # Currency Flag (https://design.candescent.com/docs/components/currency-flag)
2
+
3
+ Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/content-currencyflag--default)
4
+
5
+ `CurrencyFlag` renders the flag of the country or union that issues an ISO 4217 currency `code`. `EUR` renders the European Union flag.
6
+
7
+ ```tsx
8
+ import { CurrencyFlag, CountryFlag, Select } from '@cdx-ui/components';
9
+ ```
10
+
11
+ Flags keep their source colors. Each path has an explicit fill, so text color classes and theme tokens do not recolor the artwork.
12
+
13
+ ## Basic
14
+
15
+ Pass a currency `code`. The default box is `size-5`, and a `size-*` class overrides it.
16
+
17
+ ```tsx
18
+ import { Box, CurrencyFlag, Text } from '@cdx-ui/components';
19
+
20
+ const examples = [
21
+ { code: 'USD', name: 'US Dollar' },
22
+ { code: 'EUR', name: 'Euro' },
23
+ { code: 'GBP', name: 'British Pound' },
24
+ { code: 'JPY', name: 'Japanese Yen' },
25
+ ];
26
+
27
+ export default function CurrencyFlagBasicDemo() {
28
+ return (
29
+ <Box className="flex-row items-end gap-5">
30
+ {examples.map((currency) => (
31
+ <Box key={currency.code} className="items-center gap-2">
32
+ <CurrencyFlag code={currency.code} accessibilityLabel={currency.name} />
33
+ <Text size="sm" color="secondary">
34
+ {currency.code}
35
+ </Text>
36
+ </Box>
37
+ ))}
38
+ </Box>
39
+ );
40
+ }
41
+ ```
42
+
43
+ ## Shared currencies
44
+
45
+ The flag shows the currency's issuer, not where the user is. `DKK` renders Denmark's flag for accounts in Greenland and the Faroe Islands, and `USD` renders the United States flag in Ecuador. When the flag should show the user's country, pass the account's country code to [`CountryFlag`](https://design.candescent.com/docs/components/country-flag/content.md) instead.
46
+
47
+ ```tsx
48
+ import { Box, CountryFlag, CurrencyFlag, Text } from '@cdx-ui/components';
49
+
50
+ export default function CurrencyFlagSharedCurrenciesDemo() {
51
+ return (
52
+ <Box className="gap-5">
53
+ <Box className="flex-row items-center gap-3">
54
+ <CurrencyFlag code="DKK" />
55
+ <Text>DKK in Greenland shows the issuer, Denmark</Text>
56
+ </Box>
57
+ <Box className="flex-row items-center gap-3">
58
+ <CountryFlag code="GL" />
59
+ <Text>Greenland, from the account country code</Text>
60
+ </Box>
61
+ </Box>
62
+ );
63
+ }
64
+ ```
65
+
66
+ ## With icons
67
+
68
+ 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`.
69
+
70
+ ```tsx
71
+ import { useState } from 'react';
72
+ import { Box, CurrencyFlag, Select, Text, type SelectProps } from '@cdx-ui/components';
73
+
74
+ const currencies = [
75
+ { value: 'USD', label: 'US Dollar (USD)' },
76
+ { value: 'EUR', label: 'Euro (EUR)' },
77
+ { value: 'GBP', label: 'British Pound (GBP)' },
78
+ { value: 'CAD', label: 'Canadian Dollar (CAD)' },
79
+ ];
80
+
81
+ function CurrencySelect({
82
+ size,
83
+ defaultCode,
84
+ }: {
85
+ size: NonNullable<SelectProps['size']>;
86
+ defaultCode: string;
87
+ }) {
88
+ const [code, setCode] = useState(defaultCode);
89
+
90
+ return (
91
+ <Select
92
+ items={currencies}
93
+ size={size}
94
+ value={code}
95
+ onValueChange={setCode}
96
+ className="w-full"
97
+ accessibilityLabel="Currency"
98
+ >
99
+ <Select.Trigger>
100
+ <Select.Icon asChild position="leading">
101
+ <CurrencyFlag code={code} />
102
+ </Select.Icon>
103
+ <Select.Value />
104
+ </Select.Trigger>
105
+ <Select.Content>
106
+ {currencies.map((currency) => (
107
+ <Select.Item key={currency.value} value={currency.value}>
108
+ <CurrencyFlag code={currency.value} />
109
+ <Select.ItemLabel>{currency.label}</Select.ItemLabel>
110
+ </Select.Item>
111
+ ))}
112
+ </Select.Content>
113
+ </Select>
114
+ );
115
+ }
116
+
117
+ export default function CurrencyFlagWithIconsDemo() {
118
+ return (
119
+ <Box className="w-full gap-4">
120
+ <Box className="gap-2">
121
+ <Text size="sm" color="secondary">
122
+ default
123
+ </Text>
124
+ <CurrencySelect size="default" defaultCode="USD" />
125
+ </Box>
126
+ <Box className="gap-2">
127
+ <Text size="sm" color="secondary">
128
+ small
129
+ </Text>
130
+ <CurrencySelect size="small" defaultCode="EUR" />
131
+ </Box>
132
+ </Box>
133
+ );
134
+ }
135
+ ```
136
+
137
+ ## Accessibility
138
+
139
+ The flag is decorative unless `accessibilityLabel` is set. Omit the label when the currency name or code is already next to the flag.
140
+
141
+ ```tsx
142
+ import { Box, CurrencyFlag, Text } from '@cdx-ui/components';
143
+
144
+ export default function CurrencyFlagAccessibilityDemo() {
145
+ return (
146
+ <Box className="gap-5">
147
+ <Box className="flex-row items-center gap-3">
148
+ <CurrencyFlag code="EUR" accessibilityLabel="Euro" />
149
+ <Text>Informative flag with a screen reader label</Text>
150
+ </Box>
151
+ <Box className="flex-row items-center gap-3">
152
+ <CurrencyFlag code="USD" />
153
+ <Text>US Dollar</Text>
154
+ </Box>
155
+ </Box>
156
+ );
157
+ }
158
+ ```
159
+
160
+ ## API
161
+
162
+ ### CurrencyFlag
163
+
164
+ Renders the issuer flag for `code`. A code with no single issuer or no flag renders nothing and logs a warning in development only. It does not throw.
165
+
166
+ | Prop | Type | Default | Description |
167
+ | --- | --- | --- | --- |
168
+ | `className?` | `string` | — | Utility classes for size (`size-*`) and placement, merged after the defaults. |
169
+ | `children?` | `React.ReactNode` | — | — |
170
+ | `size?` | `string \| number` | — | Width and height of the icon, in pixels or any SVG length. The bare icon renders at 24 when omitted. |
171
+ | `data-testid?` | `string` | — | Test identifier forwarded to the rendered SVG. |
172
+ | `code` | `string` | — | ISO 4217 alphabetic currency code, such as `USD` or `EUR`. |
173
+
174
+ 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.
175
+
176
+ ### currencyFlagCode
177
+
178
+ `currencyFlagCode(code)` returns the `FlagCode` that `CurrencyFlag` renders for `code`, or `undefined` when it renders nothing. Use it to decide whether to reserve space for a flag.
179
+
180
+ - A national code resolves to its first two letters, which ISO 4217 takes from the issuer's ISO 3166-1 alpha-2 code: `USD` resolves to `US`.
181
+ - `EUR` resolves to `EU`.
182
+ - Codes that start with `X` resolve to `undefined`. They name currencies shared by a region (`XOF`, `XAF`, `XCD`, `XPF`), precious metals (`XAU`), and fund or testing codes, none of which has a single issuing country.
183
+ - A code that is not three uppercase letters resolves to `undefined`.
184
+
185
+ ## Defaults and styling
186
+
187
+ - `className` defaults to a `size-5` box. Consumer classes are merged after that default, so a `size-*` utility overrides it.
188
+ - Flag artwork keeps its source colors. Text color classes and theme tokens do not recolor it, because each path has an explicit fill.
189
+ - Prefer a `size-*` class over the inherited numeric `size` prop. The numeric prop bypasses the spacing scale.
190
+
191
+ ## Anatomy
192
+
193
+ | `data-slot` | Element |
194
+ | --------------- | ------------- |
195
+ | `currency-flag` | Rendered flag |
196
+
197
+ When `CurrencyFlag` is the child of `Select.Icon` with `asChild`, the rendered node keeps `data-slot="currency-flag"`. `position="leading"` still sets `data-icon="inline-start"`, and `position="trailing"` sets `data-icon="inline-end"`.
198
+
199
+ ## Accessibility
200
+
201
+ - Without `accessibilityLabel`, the flag is decorative and hidden from assistive technology.
202
+ - With `accessibilityLabel`, the flag is exposed as an image and announced with that label. Use the currency name, such as `Euro`, not the issuer's country name.
@@ -129,32 +129,72 @@ export default function CurrencyInputCustomSymbolDemo() {
129
129
 
130
130
  ## States
131
131
 
132
- The root controls disabled, read-only, required, and invalid state for the field.
132
+ The root controls disabled, read-only, required, and invalid state for the field. Disabled, read-only, and invalid apply to both `ghost` and `outline`.
133
133
 
134
134
  ```tsx
135
- import { Box, CurrencyInput, Text } from '@cdx-ui/components';
135
+ import { Box, CurrencyInput, Text, type CurrencyInputProps } from '@cdx-ui/components';
136
+
137
+ const variants = ['ghost', 'outline'] as const satisfies readonly NonNullable<
138
+ CurrencyInputProps['variant']
139
+ >[];
140
+
141
+ const states = [
142
+ { label: 'Disabled', value: 1200, isDisabled: true },
143
+ { label: 'Read-only', value: 4890, isReadOnly: true },
144
+ { label: 'Invalid', value: 0, isInvalid: true },
145
+ ] as const satisfies readonly {
146
+ label: string;
147
+ value: number;
148
+ isDisabled?: boolean;
149
+ isReadOnly?: boolean;
150
+ isInvalid?: boolean;
151
+ }[];
152
+
153
+ function StateRow({
154
+ variant,
155
+ label,
156
+ value,
157
+ isDisabled,
158
+ isReadOnly,
159
+ isInvalid,
160
+ }: {
161
+ variant: NonNullable<CurrencyInputProps['variant']>;
162
+ label: string;
163
+ value: number;
164
+ isDisabled?: boolean;
165
+ isReadOnly?: boolean;
166
+ isInvalid?: boolean;
167
+ }) {
168
+ return (
169
+ <Box className="gap-2">
170
+ <Text size="sm" color="secondary">
171
+ {label}
172
+ </Text>
173
+ <CurrencyInput
174
+ accessibilityLabel={`${label} ${variant} transfer amount`}
175
+ isDisabled={isDisabled}
176
+ isInvalid={isInvalid}
177
+ isReadOnly={isReadOnly}
178
+ variant={variant}
179
+ value={value}
180
+ />
181
+ </Box>
182
+ );
183
+ }
136
184
 
137
185
  export default function CurrencyInputStatesDemo() {
138
186
  return (
139
- <Box className="w-full gap-4">
140
- <Box className="gap-2">
141
- <Text size="sm" color="secondary">
142
- Disabled
143
- </Text>
144
- <CurrencyInput accessibilityLabel="Disabled transfer amount" isDisabled value={1200} />
145
- </Box>
146
- <Box className="gap-2">
147
- <Text size="sm" color="secondary">
148
- Read-only
149
- </Text>
150
- <CurrencyInput accessibilityLabel="Read-only transfer amount" isReadOnly value={4890} />
151
- </Box>
152
- <Box className="gap-2">
153
- <Text size="sm" color="secondary">
154
- Invalid
155
- </Text>
156
- <CurrencyInput accessibilityLabel="Invalid transfer amount" isInvalid value={0} />
157
- </Box>
187
+ <Box className="w-full gap-6">
188
+ {variants.map((variant) => (
189
+ <Box key={variant} className="gap-4">
190
+ <Text size="sm" color="secondary">
191
+ {variant}
192
+ </Text>
193
+ {states.map((state) => (
194
+ <StateRow key={state.label} variant={variant} {...state} />
195
+ ))}
196
+ </Box>
197
+ ))}
158
198
  </Box>
159
199
  );
160
200
  }
@@ -200,60 +240,138 @@ export default function CurrencyInputWithFieldDemo() {
200
240
  }
201
241
  ```
202
242
 
203
- ## With field and validation
243
+ ## In card
204
244
 
205
- Set invalid state on both `Field` and `CurrencyInput` so the error message and amount styling stay in sync.
245
+ Stack the label above the amount. Align `Field.Label` to the start, and set `align="end"` on `CurrencyInput`.
206
246
 
207
247
  ```tsx
208
- import { useState } from 'react';
209
- import { CurrencyInput, Field } from '@cdx-ui/components';
210
-
211
- const DAILY_LIMIT = 1200;
212
-
213
- export default function CurrencyInputOutlineWithFieldInvalidDemo() {
214
- const [amount, setAmount] = useState(1500);
215
- const isInvalid = amount > DAILY_LIMIT;
248
+ import { Card, CurrencyInput, Field } from '@cdx-ui/components';
216
249
 
250
+ export default function CurrencyInputInCardDemo() {
217
251
  return (
218
- <Field className="w-full" isRequired isInvalid={isInvalid}>
219
- <Field.Label>Amount</Field.Label>
220
- <CurrencyInput
221
- isInvalid={isInvalid}
222
- isRequired
223
- variant="outline"
224
- value={amount}
225
- onChangeValue={setAmount}
226
- />
227
- <Field.Error>Amount exceeds your daily limit.</Field.Error>
228
- </Field>
252
+ <Card className="w-full max-w-md">
253
+ <Card.Content>
254
+ <Field className="w-full">
255
+ <Field.Label className="self-start">Available balance</Field.Label>
256
+ <CurrencyInput align="end" isReadOnly size="small" value={4250.18} />
257
+ </Field>
258
+ </Card.Content>
259
+ </Card>
229
260
  );
230
261
  }
231
262
  ```
232
263
 
233
- The same validation in the `ghost` pattern, with a centered label and error.
264
+ ## With field and validation
265
+
266
+ Set disabled, read-only, and invalid on both `Field` and `CurrencyInput` so the label, message, and amount styling stay in sync. Keep the `outline` label and error aligned to the start. For `ghost`, center the label and error and use `size="small"`.
234
267
 
235
268
  ```tsx
236
269
  import { useState } from 'react';
237
- import { CurrencyInput, Field } from '@cdx-ui/components';
270
+ import { Box, CurrencyInput, Field, Text } from '@cdx-ui/components';
238
271
 
239
272
  const DAILY_LIMIT = 1200;
240
273
 
241
- export default function CurrencyInputWithFieldInvalidDemo() {
274
+ function OutlineFields() {
242
275
  const [amount, setAmount] = useState(1500);
243
276
  const isInvalid = amount > DAILY_LIMIT;
244
277
 
245
278
  return (
246
- <Field className="w-full" isRequired isInvalid={isInvalid}>
247
- <Field.Label className="text-center">Amount</Field.Label>
248
- <CurrencyInput
249
- isInvalid={isInvalid}
250
- isRequired
251
- size="small"
252
- value={amount}
253
- onChangeValue={setAmount}
254
- />
255
- <Field.Error className="justify-center">Amount exceeds your daily limit.</Field.Error>
256
- </Field>
279
+ <Box className="w-full gap-4">
280
+ <Text size="sm" color="secondary">
281
+ outline
282
+ </Text>
283
+ <Box className="gap-2">
284
+ <Text size="sm" color="secondary">
285
+ Disabled
286
+ </Text>
287
+ <Field className="w-full" isDisabled>
288
+ <Field.Label>Amount</Field.Label>
289
+ <CurrencyInput isDisabled variant="outline" value={1200} />
290
+ </Field>
291
+ </Box>
292
+ <Box className="gap-2">
293
+ <Text size="sm" color="secondary">
294
+ Read-only
295
+ </Text>
296
+ <Field className="w-full" isReadOnly>
297
+ <Field.Label>Amount</Field.Label>
298
+ <CurrencyInput isReadOnly variant="outline" value={4890} />
299
+ </Field>
300
+ </Box>
301
+ <Box className="gap-2">
302
+ <Text size="sm" color="secondary">
303
+ Invalid
304
+ </Text>
305
+ <Field className="w-full" isRequired isInvalid={isInvalid}>
306
+ <Field.Label>Amount</Field.Label>
307
+ <CurrencyInput
308
+ isInvalid={isInvalid}
309
+ isRequired
310
+ variant="outline"
311
+ value={amount}
312
+ onChangeValue={setAmount}
313
+ />
314
+ <Field.Error>Amount exceeds your daily limit.</Field.Error>
315
+ </Field>
316
+ </Box>
317
+ </Box>
318
+ );
319
+ }
320
+
321
+ function GhostFields() {
322
+ const [amount, setAmount] = useState(1500);
323
+ const isInvalid = amount > DAILY_LIMIT;
324
+
325
+ return (
326
+ <Box className="w-full gap-4">
327
+ <Text size="sm" color="secondary">
328
+ ghost
329
+ </Text>
330
+ <Box className="gap-2">
331
+ <Text size="sm" color="secondary">
332
+ Disabled
333
+ </Text>
334
+ <Field className="w-full" isDisabled>
335
+ <Field.Label className="text-center">Amount</Field.Label>
336
+ <CurrencyInput isDisabled size="small" variant="ghost" value={1200} />
337
+ </Field>
338
+ </Box>
339
+ <Box className="gap-2">
340
+ <Text size="sm" color="secondary">
341
+ Read-only
342
+ </Text>
343
+ <Field className="w-full" isReadOnly>
344
+ <Field.Label className="text-center">Amount</Field.Label>
345
+ <CurrencyInput isReadOnly size="small" variant="ghost" value={4890} />
346
+ </Field>
347
+ </Box>
348
+ <Box className="gap-2">
349
+ <Text size="sm" color="secondary">
350
+ Invalid
351
+ </Text>
352
+ <Field className="w-full" isRequired isInvalid={isInvalid}>
353
+ <Field.Label className="text-center">Amount</Field.Label>
354
+ <CurrencyInput
355
+ isInvalid={isInvalid}
356
+ isRequired
357
+ size="small"
358
+ variant="ghost"
359
+ value={amount}
360
+ onChangeValue={setAmount}
361
+ />
362
+ <Field.Error className="justify-center">Amount exceeds your daily limit.</Field.Error>
363
+ </Field>
364
+ </Box>
365
+ </Box>
366
+ );
367
+ }
368
+
369
+ export default function CurrencyInputOutlineWithFieldInvalidDemo() {
370
+ return (
371
+ <Box className="w-full gap-6">
372
+ <OutlineFields />
373
+ <GhostFields />
374
+ </Box>
257
375
  );
258
376
  }
259
377
  ```
@@ -278,6 +396,7 @@ Controlled calculator-style monetary entry. The numeric `value` is expressed in
278
396
  | `isFullWidth?` | `boolean` | — | If true, the input element will span the full width of its parent. |
279
397
  | `variant?` | `'ghost' \| 'outline'` | `'ghost'` | Visual style. `ghost` is the large, centered, borderless amount entry; `outline` renders the bordered `Input` shell with a leading currency-symbol prefix, for amounts that sit alongside other form fields. |
280
398
  | `size?` | `'default' \| 'small'` | `'default'` | Height, padding, and text size. |
399
+ | `align?` | `'center' \| 'end'` | — | Horizontal alignment of the amount. Defaults to `center` on `ghost`. On `outline`, the amount stays at the start of the field until `align` is set. |
281
400
 
282
401
  Supports `accessibilityLabel`, `accessibilityHint`, `testID`, `onFocus`, `onBlur`, and `returnKeyType` from [`TextInputProps`](https://reactnative.dev/docs/textinput#props). `style` applies to the root container, and the forwarded ref targets the underlying `TextInput`.
283
402
 
@@ -2,7 +2,7 @@
2
2
 
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
- 3,986 icons are available, each with outlined and filled variants, plus support for custom
5
+ 3,991 icons are available, each with outlined and filled variants, plus support for custom
6
6
  SVGs. Country flags are a separate set and do not appear in the browser below. Render one with
7
7
  [`CountryFlag`](https://design.candescent.com/docs/components/country-flag/content.md).
8
8
 
@@ -52,7 +52,7 @@ Every component's API table lists the props that choose its look. Reach for them
52
52
  - **Typography:** `Text` takes `size`, `weight` and `italic`. `Heading` takes `size` only.
53
53
  - **Nesting:** a `Text` inside another text element (a `Text`, a `Heading`, or a slot such as `Button.Label`) inherits its color, size and weight. Set only what differs.
54
54
  - **Alignment:** `text-center`, `text-start` and `text-end` are allowed as classes. Never use `text-left` or `text-right`, which break right-to-left layouts.
55
- - **Casing:** `uppercase` is allowed as a class.
55
+ - **Other text styling:** `color`, `size`, `weight` and `italic` are the only typography props, and Forge UI will not add more. Everything else is a plain class, on `Text`, `Heading` and a component's text slot (`Button.Label`, `Chip.Label`): decoration (`underline`, `line-through`), casing (`uppercase`, `capitalize`), truncation and wrapping (`truncate`, `line-clamp-*`, `text-ellipsis`, `whitespace-nowrap`) and numerals (`tabular-nums`). Line height and letter spacing come with `size`, so `leading-*` and `tracking-*` stay off.
56
56
  - **Icon size:** use a `size-*` class on the spacing scale. The default is `size-5`, so don't restate it, and don't pass a numeric `size`.
57
57
 
58
58
  ```tsx
@@ -86,7 +86,7 @@ On a Forge UI component, `className` positions the component in its parent and n
86
86
  | Width constraints | `w-full`, `max-w-md`, `min-w-0` |
87
87
  | Margin on the spacing scale | `mt-4`, `mx-2` |
88
88
 
89
- Padding, backgrounds, borders, radii, colors, typography and heights are not allowed, on the component or on any of its parts. Between siblings, prefer a stack's `space` prop to margins.
89
+ Padding, backgrounds, borders, radii, colors, font size, weight and family, and heights are not allowed, on the component or on any of its parts. The text classes under [Text, Heading and Icon](#text-heading-and-icon) are. Between siblings, prefer a stack's `space` prop to margins.
90
90
 
91
91
  ```tsx
92
92
  // Wrong: restyling Card parts to match a mockup
package/docs/llms.txt CHANGED
@@ -85,7 +85,8 @@ 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
+ - [Country Flag](components/country-flag/content.md): A flag for a country-flag-icons code, including unofficial codes used by libphonenumber-js. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/content-countryflag--default)
89
+ - [Currency Flag](components/currency-flag/content.md): The flag of the country or union that issues an ISO 4217 currency. Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/content-currencyflag--default)
89
90
  - [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)
90
91
  - [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)
91
92
  - [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)
@@ -150,6 +151,7 @@ Links point at each page's `content.md`, which carries the page's prose, demo so
150
151
 
151
152
  ## Release notes
152
153
 
154
+ - [0.3.7](resources/release-notes/0.3.7/content.md): Adds CountryFlag for ISO country flags, ProgressBar size and color props, DataGrid autoHeight, and fixes for web charts and published DataGrid styles.
153
155
  - [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.
154
156
  - [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.
155
157
  - [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.
@@ -0,0 +1,27 @@
1
+ # 0.3.7 (https://design.candescent.com/docs/resources/release-notes/0.3.7)
2
+
3
+ Adds CountryFlag for ISO country flags, ProgressBar size and color props, DataGrid autoHeight, and fixes for web charts and published DataGrid styles.
4
+
5
+ This release adds **[CountryFlag](https://design.candescent.com/docs/components/country-flag/content.md)** and new **[Progress Bar](https://design.candescent.com/docs/components/progress-bar/content.md)** styling options, lets **DataGrid** size to its rows, and fixes web chart accessibility warnings plus DataGrid styling when installed from npm.
6
+
7
+ ## What's new
8
+
9
+ **[CountryFlag](https://design.candescent.com/docs/components/country-flag/content.md)** — Renders officially assigned ISO country flags from `@cdx-ui/icons/flags` so country pickers and forms can show a flag without a third-party flag library. Pass a country code and optional `size` to match surrounding icons; use it inside **[Input](https://design.candescent.com/docs/components/input/content.md)** or **[Select](https://design.candescent.com/docs/components/select/content.md)** adornments the same way you use other Forge icons ([#912](https://github.com/dfh-candescent/forge-design-system/pull/912)).
10
+
11
+ **[Progress Bar](https://design.candescent.com/docs/components/progress-bar/content.md)** — `size` and `color` props tune track height and semantic fill without custom classes. Use them for dense lists, dashboards, and budget-style insights where several bars share one screen ([#873](https://github.com/dfh-candescent/forge-design-system/pull/873)).
12
+
13
+ **DataGrid** — `autoHeight` (MUI X naming) removes the default fixed viewport height so the grid grows with its rows; horizontal overflow still scrolls. Empty and custom loading overlays keep a minimum height because they are absolutely positioned ([#899](https://github.com/dfh-candescent/forge-design-system/pull/899)).
14
+
15
+ ## Bug fixes
16
+
17
+ **[Progress Bar](https://design.candescent.com/docs/components/progress-bar/content.md)** — Indeterminate mode (`value={null}`) animates a segment across the track instead of collapsing the indicator to zero width ([#873](https://github.com/dfh-candescent/forge-design-system/pull/873)).
18
+
19
+ **[Input](https://design.candescent.com/docs/components/input/content.md)** — `Input.Icon` with `asChild` accepts a child element, so icons such as CountryFlag typecheck and render in adornment slots ([#912](https://github.com/dfh-candescent/forge-design-system/pull/912)).
20
+
21
+ **DataGrid** — Published `@cdx-ui/data-grid` installs include a stylesheet so Uniwind generates grid utility classes in consumer apps; import it alongside your other Forge UI styles as documented on the DataGrid page ([#906](https://github.com/dfh-candescent/forge-design-system/pull/906)).
22
+
23
+ **[LineChart](https://design.candescent.com/docs/components/line-chart/content.md)** and **[BarChart](https://design.candescent.com/docs/components/bar-chart/content.md)** — Decorative chart SVGs on web no longer pass React Native accessibility props through to the DOM, which removes React warnings in the browser ([#899](https://github.com/dfh-candescent/forge-design-system/pull/899)).
24
+
25
+ ## Dependencies
26
+
27
+ Upgrade every installed `@cdx-ui/*` package to `0.3.7` together when you adopt this release ([#910](https://github.com/dfh-candescent/forge-design-system/pull/910)).
@@ -8,6 +8,7 @@ Notes are generated from the release commit itself, so the versions and commit r
8
8
  each entry are exact. Releases that contained nothing but backlog or dependency bookkeeping
9
9
  are omitted.
10
10
 
11
+ - [0.3.7](https://design.candescent.com/docs/resources/release-notes/0.3.7/content.md) — 2026-10-27 — Adds CountryFlag for ISO country flags, ProgressBar size and color props, DataGrid autoHeight, and fixes for web charts and published DataGrid styles.
11
12
  - [0.3.6](https://design.candescent.com/docs/resources/release-notes/0.3.6/content.md) — 2026-10-23 — Adds SystemAlert, bar, line, and pie charts on a shared MUI X-shaped API, Stepper, and a fix for tabs scroll controls.
12
13
  - [0.3.5](https://design.candescent.com/docs/resources/release-notes/0.3.5/content.md) — 2026-10-21 — Selected subtle Chip labels stay visible on Android when the variant changes from outline to subtle.
13
14
  - [0.3.4](https://design.candescent.com/docs/resources/release-notes/0.3.4/content.md) — 2026-10-20 — Select adds multiple selection, in-list search, and a native bottom sheet; Input gains a subtle variant for fields inside popups and sheets.
@@ -10,7 +10,7 @@ var _utils = require("@cdx-ui/utils");
10
10
  var _Icon = require("../Icon");
11
11
  var _jsxRuntime = require("react/jsx-runtime");
12
12
  /**
13
- * Renders the country flag for an ISO 3166-1 alpha-2 code.
13
+ * Renders the flag for a country-flag-icons code, including unofficial libphonenumber-js codes.
14
14
  *
15
15
  * The flag is drawn through `Icon`, so `className` sizing and `asChild` icon slots
16
16
  * apply. Flag artwork keeps its own colors. The flag is decorative unless
@@ -26,7 +26,7 @@ var _jsxRuntime = require("react/jsx-runtime");
26
26
  * <CountryFlag code="US" className="size-6" accessibilityLabel="United States" />
27
27
  * ```
28
28
  *
29
- * @param {FlagCode} code - ISO 3166-1 alpha-2 country code.
29
+ * @param {FlagCode} code - Code from the country-flag-icons 3x2 set. Subdivision codes keep their hyphen (`GB-ENG`).
30
30
  * @param {string} className - Utility classes for size and placement, merged after the default `size-5` box.
31
31
  * @param {string} accessibilityLabel - When set, the flag is announced as an image with this name.
32
32
  * @param {object} style - Style overrides passed through to the icon.