@cdx-ui/components 0.3.6 → 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 (191) hide show
  1. package/docs/components/content.md +2 -0
  2. package/docs/components/country-flag/content.md +232 -0
  3. package/docs/components/currency-flag/content.md +202 -0
  4. package/docs/components/currency-input/content.md +175 -56
  5. package/docs/components/data-grid/content.md +3 -1
  6. package/docs/components/icon/content.md +1 -1
  7. package/docs/components/input/content.md +1 -0
  8. package/docs/components/progress-bar/content.md +164 -3
  9. package/docs/components/select/content.md +1 -0
  10. package/docs/foundations/expressions/icons/content.md +3 -2
  11. package/docs/getting-started/developers/content.md +1 -1
  12. package/docs/getting-started/developers/styling/content.md +2 -2
  13. package/docs/llms.txt +5 -0
  14. package/docs/patterns/insights/content.md +70 -1
  15. package/docs/resources/content.md +1 -0
  16. package/docs/resources/release-notes/0.3.6/content.md +29 -0
  17. package/docs/resources/release-notes/0.3.7/content.md +27 -0
  18. package/docs/resources/release-notes/content.md +2 -0
  19. package/docs/resources/skills/content.md +66 -0
  20. package/lib/commonjs/components/BarChart/index.js +5 -12
  21. package/lib/commonjs/components/BarChart/index.js.map +1 -1
  22. package/lib/commonjs/components/CountryFlag/index.js +56 -0
  23. package/lib/commonjs/components/CountryFlag/index.js.map +1 -0
  24. package/lib/commonjs/components/CurrencyFlag/index.js +77 -0
  25. package/lib/commonjs/components/CurrencyFlag/index.js.map +1 -0
  26. package/lib/commonjs/components/CurrencyInput/index.js +3 -1
  27. package/lib/commonjs/components/CurrencyInput/index.js.map +1 -1
  28. package/lib/commonjs/components/CurrencyInput/styles.js +23 -7
  29. package/lib/commonjs/components/CurrencyInput/styles.js.map +1 -1
  30. package/lib/commonjs/components/Input/index.js.map +1 -1
  31. package/lib/commonjs/components/LineChart/index.js +3 -6
  32. package/lib/commonjs/components/LineChart/index.js.map +1 -1
  33. package/lib/commonjs/components/ProgressBar/index.js +44 -12
  34. package/lib/commonjs/components/ProgressBar/index.js.map +1 -1
  35. package/lib/commonjs/components/ProgressBar/styles.js +31 -2
  36. package/lib/commonjs/components/ProgressBar/styles.js.map +1 -1
  37. package/lib/commonjs/components/Select/index.js.map +1 -1
  38. package/lib/commonjs/components/chart/hiddenSvgProps.js +23 -0
  39. package/lib/commonjs/components/chart/hiddenSvgProps.js.map +1 -0
  40. package/lib/commonjs/components/index.js +24 -0
  41. package/lib/commonjs/components/index.js.map +1 -1
  42. package/lib/commonjs/figma/Accordion.figma.js +2 -2
  43. package/lib/commonjs/figma/Accordion.figma.js.map +1 -1
  44. package/lib/commonjs/figma/Alert.figma.js +7 -7
  45. package/lib/commonjs/figma/Alert.figma.js.map +1 -1
  46. package/lib/commonjs/figma/Badge.Indicator.figma.js +6 -5
  47. package/lib/commonjs/figma/Badge.Indicator.figma.js.map +1 -1
  48. package/lib/commonjs/figma/Badge.figma.js +22 -22
  49. package/lib/commonjs/figma/Badge.figma.js.map +1 -1
  50. package/lib/commonjs/figma/Button.figma.js +5 -2
  51. package/lib/commonjs/figma/Button.figma.js.map +1 -1
  52. package/lib/commonjs/figma/CLAUDE.md +1 -0
  53. package/lib/commonjs/figma/Card.Header.figma.js +8 -4
  54. package/lib/commonjs/figma/Card.Header.figma.js.map +1 -1
  55. package/lib/commonjs/figma/Card.figma.js +2 -1
  56. package/lib/commonjs/figma/Card.figma.js.map +1 -1
  57. package/lib/commonjs/figma/Chip.figma.js +2 -2
  58. package/lib/commonjs/figma/Chip.figma.js.map +1 -1
  59. package/lib/commonjs/figma/CurrencyInput.figma.js +1 -1
  60. package/lib/commonjs/figma/CurrencyInput.figma.js.map +1 -1
  61. package/lib/commonjs/figma/Dialog.figma.js +5 -2
  62. package/lib/commonjs/figma/Dialog.figma.js.map +1 -1
  63. package/lib/commonjs/figma/Divider.figma.js +1 -1
  64. package/lib/commonjs/figma/Divider.figma.js.map +1 -1
  65. package/lib/commonjs/figma/Drawer.figma.js +3 -3
  66. package/lib/commonjs/figma/Drawer.figma.js.map +1 -1
  67. package/lib/commonjs/figma/IconButton.figma.js +10 -4
  68. package/lib/commonjs/figma/IconButton.figma.js.map +1 -1
  69. package/lib/commonjs/figma/Input.figma.js +2 -1
  70. package/lib/commonjs/figma/Input.figma.js.map +1 -1
  71. package/lib/commonjs/figma/Insight.figma.js +3 -3
  72. package/lib/commonjs/figma/Insight.figma.js.map +1 -1
  73. package/lib/commonjs/figma/ProgressBar.figma.js +11 -2
  74. package/lib/commonjs/figma/ProgressBar.figma.js.map +1 -1
  75. package/lib/commonjs/figma/ProgressSegmented.figma.js +9 -1
  76. package/lib/commonjs/figma/ProgressSegmented.figma.js.map +1 -1
  77. package/lib/commonjs/figma/Select.figma.js +2 -1
  78. package/lib/commonjs/figma/Select.figma.js.map +1 -1
  79. package/lib/commonjs/figma/SystemAlert.figma.js +2 -3
  80. package/lib/commonjs/figma/SystemAlert.figma.js.map +1 -1
  81. package/lib/commonjs/styles.css +0 -1
  82. package/lib/module/components/BarChart/index.js +5 -12
  83. package/lib/module/components/BarChart/index.js.map +1 -1
  84. package/lib/module/components/CountryFlag/index.js +52 -0
  85. package/lib/module/components/CountryFlag/index.js.map +1 -0
  86. package/lib/module/components/CurrencyFlag/index.js +72 -0
  87. package/lib/module/components/CurrencyFlag/index.js.map +1 -0
  88. package/lib/module/components/CurrencyInput/index.js +3 -1
  89. package/lib/module/components/CurrencyInput/index.js.map +1 -1
  90. package/lib/module/components/CurrencyInput/styles.js +23 -7
  91. package/lib/module/components/CurrencyInput/styles.js.map +1 -1
  92. package/lib/module/components/Input/index.js.map +1 -1
  93. package/lib/module/components/LineChart/index.js +3 -6
  94. package/lib/module/components/LineChart/index.js.map +1 -1
  95. package/lib/module/components/ProgressBar/index.js +47 -15
  96. package/lib/module/components/ProgressBar/index.js.map +1 -1
  97. package/lib/module/components/ProgressBar/styles.js +31 -2
  98. package/lib/module/components/ProgressBar/styles.js.map +1 -1
  99. package/lib/module/components/Select/index.js.map +1 -1
  100. package/lib/module/components/chart/hiddenSvgProps.js +20 -0
  101. package/lib/module/components/chart/hiddenSvgProps.js.map +1 -0
  102. package/lib/module/components/index.js +2 -0
  103. package/lib/module/components/index.js.map +1 -1
  104. package/lib/module/figma/Accordion.figma.js +2 -2
  105. package/lib/module/figma/Accordion.figma.js.map +1 -1
  106. package/lib/module/figma/Alert.figma.js +7 -7
  107. package/lib/module/figma/Alert.figma.js.map +1 -1
  108. package/lib/module/figma/Badge.Indicator.figma.js +6 -5
  109. package/lib/module/figma/Badge.Indicator.figma.js.map +1 -1
  110. package/lib/module/figma/Badge.figma.js +22 -22
  111. package/lib/module/figma/Badge.figma.js.map +1 -1
  112. package/lib/module/figma/Button.figma.js +5 -2
  113. package/lib/module/figma/Button.figma.js.map +1 -1
  114. package/lib/module/figma/CLAUDE.md +1 -0
  115. package/lib/module/figma/Card.Header.figma.js +8 -4
  116. package/lib/module/figma/Card.Header.figma.js.map +1 -1
  117. package/lib/module/figma/Card.figma.js +2 -1
  118. package/lib/module/figma/Card.figma.js.map +1 -1
  119. package/lib/module/figma/Chip.figma.js +2 -2
  120. package/lib/module/figma/Chip.figma.js.map +1 -1
  121. package/lib/module/figma/CurrencyInput.figma.js +1 -1
  122. package/lib/module/figma/CurrencyInput.figma.js.map +1 -1
  123. package/lib/module/figma/Dialog.figma.js +5 -2
  124. package/lib/module/figma/Dialog.figma.js.map +1 -1
  125. package/lib/module/figma/Divider.figma.js +1 -1
  126. package/lib/module/figma/Divider.figma.js.map +1 -1
  127. package/lib/module/figma/Drawer.figma.js +3 -3
  128. package/lib/module/figma/Drawer.figma.js.map +1 -1
  129. package/lib/module/figma/IconButton.figma.js +10 -4
  130. package/lib/module/figma/IconButton.figma.js.map +1 -1
  131. package/lib/module/figma/Input.figma.js +2 -1
  132. package/lib/module/figma/Input.figma.js.map +1 -1
  133. package/lib/module/figma/Insight.figma.js +3 -3
  134. package/lib/module/figma/Insight.figma.js.map +1 -1
  135. package/lib/module/figma/ProgressBar.figma.js +12 -2
  136. package/lib/module/figma/ProgressBar.figma.js.map +1 -1
  137. package/lib/module/figma/ProgressSegmented.figma.js +9 -1
  138. package/lib/module/figma/ProgressSegmented.figma.js.map +1 -1
  139. package/lib/module/figma/Select.figma.js +2 -1
  140. package/lib/module/figma/Select.figma.js.map +1 -1
  141. package/lib/module/figma/SystemAlert.figma.js +2 -3
  142. package/lib/module/figma/SystemAlert.figma.js.map +1 -1
  143. package/lib/module/styles.css +0 -1
  144. package/lib/typescript/components/BarChart/index.d.ts.map +1 -1
  145. package/lib/typescript/components/CountryFlag/index.d.ts +40 -0
  146. package/lib/typescript/components/CountryFlag/index.d.ts.map +1 -0
  147. package/lib/typescript/components/CurrencyFlag/index.d.ts +47 -0
  148. package/lib/typescript/components/CurrencyFlag/index.d.ts.map +1 -0
  149. package/lib/typescript/components/CurrencyInput/index.d.ts.map +1 -1
  150. package/lib/typescript/components/CurrencyInput/styles.d.ts +6 -1
  151. package/lib/typescript/components/CurrencyInput/styles.d.ts.map +1 -1
  152. package/lib/typescript/components/Input/index.d.ts +2 -0
  153. package/lib/typescript/components/Input/index.d.ts.map +1 -1
  154. package/lib/typescript/components/LineChart/index.d.ts.map +1 -1
  155. package/lib/typescript/components/ProgressBar/index.d.ts +16 -1
  156. package/lib/typescript/components/ProgressBar/index.d.ts.map +1 -1
  157. package/lib/typescript/components/ProgressBar/styles.d.ts +7 -2
  158. package/lib/typescript/components/ProgressBar/styles.d.ts.map +1 -1
  159. package/lib/typescript/components/Select/index.d.ts +2 -0
  160. package/lib/typescript/components/Select/index.d.ts.map +1 -1
  161. package/lib/typescript/components/chart/hiddenSvgProps.d.ts +17 -0
  162. package/lib/typescript/components/chart/hiddenSvgProps.d.ts.map +1 -0
  163. package/lib/typescript/components/index.d.ts +2 -0
  164. package/lib/typescript/components/index.d.ts.map +1 -1
  165. package/lib/typescript/figma/Alert.figma.d.ts.map +1 -1
  166. package/lib/typescript/figma/Badge.Indicator.figma.d.ts.map +1 -1
  167. package/lib/typescript/figma/Badge.figma.d.ts.map +1 -1
  168. package/lib/typescript/figma/Button.figma.d.ts.map +1 -1
  169. package/lib/typescript/figma/Card.Header.figma.d.ts.map +1 -1
  170. package/lib/typescript/figma/Card.figma.d.ts.map +1 -1
  171. package/lib/typescript/figma/Dialog.figma.d.ts.map +1 -1
  172. package/lib/typescript/figma/IconButton.figma.d.ts.map +1 -1
  173. package/lib/typescript/figma/Input.figma.d.ts.map +1 -1
  174. package/lib/typescript/figma/ProgressBar.figma.d.ts.map +1 -1
  175. package/lib/typescript/figma/ProgressSegmented.figma.d.ts.map +1 -1
  176. package/lib/typescript/figma/Select.figma.d.ts.map +1 -1
  177. package/lib/typescript/figma/SystemAlert.figma.d.ts.map +1 -1
  178. package/package.json +5 -5
  179. package/src/components/BarChart/index.tsx +5 -12
  180. package/src/components/CountryFlag/index.tsx +58 -0
  181. package/src/components/CurrencyFlag/index.tsx +71 -0
  182. package/src/components/CurrencyInput/index.tsx +2 -1
  183. package/src/components/CurrencyInput/styles.ts +29 -3
  184. package/src/components/Input/index.tsx +2 -0
  185. package/src/components/LineChart/index.tsx +3 -6
  186. package/src/components/ProgressBar/index.tsx +66 -14
  187. package/src/components/ProgressBar/styles.ts +35 -4
  188. package/src/components/Select/index.tsx +2 -0
  189. package/src/components/chart/hiddenSvgProps.ts +15 -0
  190. package/src/components/index.ts +2 -0
  191. package/src/styles.css +0 -1
@@ -61,6 +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 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.
64
66
  - [Image](https://design.candescent.com/docs/components/image/content.md) — Displays local or remote images across native and web platforms.
65
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.
66
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.
@@ -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 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
+
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` | `'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
+
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
+
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.
@@ -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.