@cdx-ui/components 0.0.1-beta.4 → 0.0.1-beta.40

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 (283) hide show
  1. package/README.md +18 -11
  2. package/lib/commonjs/components/Avatar/index.js +1 -1
  3. package/lib/commonjs/components/Avatar/styles.js +36 -29
  4. package/lib/commonjs/components/Avatar/styles.js.map +1 -1
  5. package/lib/commonjs/components/Button/styles.js +2 -2
  6. package/lib/commonjs/components/Button/styles.js.map +1 -1
  7. package/lib/commonjs/components/CLAUDE.md +90 -0
  8. package/lib/commonjs/components/Card/index.js +22 -4
  9. package/lib/commonjs/components/Card/index.js.map +1 -1
  10. package/lib/commonjs/components/Card/styles.js +27 -5
  11. package/lib/commonjs/components/Card/styles.js.map +1 -1
  12. package/lib/commonjs/components/Checkbox/index.js +5 -29
  13. package/lib/commonjs/components/Checkbox/index.js.map +1 -1
  14. package/lib/commonjs/components/Checkbox/styles.js +39 -47
  15. package/lib/commonjs/components/Checkbox/styles.js.map +1 -1
  16. package/lib/commonjs/components/Chip/index.js +78 -9
  17. package/lib/commonjs/components/Chip/index.js.map +1 -1
  18. package/lib/commonjs/components/Chip/styles.js +207 -21
  19. package/lib/commonjs/components/Chip/styles.js.map +1 -1
  20. package/lib/commonjs/components/Field/index.js +8 -2
  21. package/lib/commonjs/components/Field/index.js.map +1 -1
  22. package/lib/commonjs/components/Field/styles.js +4 -4
  23. package/lib/commonjs/components/Field/styles.js.map +1 -1
  24. package/lib/commonjs/components/Heading/styles.js +1 -1
  25. package/lib/commonjs/components/Heading/styles.js.map +1 -1
  26. package/lib/commonjs/components/Icon/index.js +1 -2
  27. package/lib/commonjs/components/Icon/index.js.map +1 -1
  28. package/lib/commonjs/components/IconButton/index.js +6 -1
  29. package/lib/commonjs/components/IconButton/index.js.map +1 -1
  30. package/lib/commonjs/components/IconButton/styles.js +135 -10
  31. package/lib/commonjs/components/IconButton/styles.js.map +1 -1
  32. package/lib/commonjs/components/Input/styles.js +7 -6
  33. package/lib/commonjs/components/Input/styles.js.map +1 -1
  34. package/lib/commonjs/components/ListItem/index.js +283 -0
  35. package/lib/commonjs/components/ListItem/index.js.map +1 -0
  36. package/lib/commonjs/components/ListItem/styles.js +130 -0
  37. package/lib/commonjs/components/ListItem/styles.js.map +1 -0
  38. package/lib/commonjs/components/ProgressSegmented/index.js +22 -10
  39. package/lib/commonjs/components/ProgressSegmented/index.js.map +1 -1
  40. package/lib/commonjs/components/Radio/index.js +167 -0
  41. package/lib/commonjs/components/Radio/index.js.map +1 -0
  42. package/lib/commonjs/components/Radio/styles.js +31 -0
  43. package/lib/commonjs/components/Radio/styles.js.map +1 -0
  44. package/lib/commonjs/components/Text/styles.js +2 -2
  45. package/lib/commonjs/components/Text/styles.js.map +1 -1
  46. package/lib/commonjs/components/Tile/index.js +251 -0
  47. package/lib/commonjs/components/Tile/index.js.map +1 -0
  48. package/lib/commonjs/components/Tile/styles.js +52 -0
  49. package/lib/commonjs/components/Tile/styles.js.map +1 -0
  50. package/lib/commonjs/components/index.js +36 -0
  51. package/lib/commonjs/components/index.js.map +1 -1
  52. package/lib/commonjs/figma/Avatar.figma.js +54 -0
  53. package/lib/commonjs/figma/Avatar.figma.js.map +1 -0
  54. package/lib/commonjs/figma/Button.figma.js +28 -11
  55. package/lib/commonjs/figma/Button.figma.js.map +1 -1
  56. package/lib/commonjs/figma/CLAUDE.md +30 -0
  57. package/lib/commonjs/figma/Card.Header.figma.js +28 -0
  58. package/lib/commonjs/figma/Card.Header.figma.js.map +1 -0
  59. package/lib/commonjs/figma/Card.figma.js +42 -0
  60. package/lib/commonjs/figma/Card.figma.js.map +1 -0
  61. package/lib/commonjs/figma/Checkbox.figma.js +55 -0
  62. package/lib/commonjs/figma/Checkbox.figma.js.map +1 -0
  63. package/lib/commonjs/figma/Chip.figma.js +68 -0
  64. package/lib/commonjs/figma/Chip.figma.js.map +1 -0
  65. package/lib/commonjs/figma/Field.Input.figma.js +57 -0
  66. package/lib/commonjs/figma/Field.Input.figma.js.map +1 -0
  67. package/lib/commonjs/figma/Field.Select.figma.js +57 -0
  68. package/lib/commonjs/figma/Field.Select.figma.js.map +1 -0
  69. package/lib/commonjs/figma/Heading.figma.js +30 -0
  70. package/lib/commonjs/figma/Heading.figma.js.map +1 -0
  71. package/lib/commonjs/figma/Icon.figma.js +20 -0
  72. package/lib/commonjs/figma/Icon.figma.js.map +1 -0
  73. package/lib/commonjs/figma/IconButton.figma.js +47 -0
  74. package/lib/commonjs/figma/IconButton.figma.js.map +1 -0
  75. package/lib/commonjs/figma/Input.figma.js +52 -0
  76. package/lib/commonjs/figma/Input.figma.js.map +1 -0
  77. package/lib/commonjs/figma/ProgressSegmented.figma.js +39 -0
  78. package/lib/commonjs/figma/ProgressSegmented.figma.js.map +1 -0
  79. package/lib/commonjs/figma/Radio.figma.js +38 -0
  80. package/lib/commonjs/figma/Radio.figma.js.map +1 -0
  81. package/lib/commonjs/figma/Select.figma.js +53 -0
  82. package/lib/commonjs/figma/Select.figma.js.map +1 -0
  83. package/lib/commonjs/figma/Text.figma.js +29 -0
  84. package/lib/commonjs/figma/Text.figma.js.map +1 -0
  85. package/lib/commonjs/figma/icons.figma.batch.js +27 -0
  86. package/lib/commonjs/figma/icons.figma.batch.js.map +1 -0
  87. package/lib/commonjs/figma/icons.figma.batch.json +17705 -0
  88. package/lib/commonjs/styles/primitives.js +42 -5
  89. package/lib/commonjs/styles/primitives.js.map +1 -1
  90. package/lib/module/components/Avatar/index.js +1 -1
  91. package/lib/module/components/Avatar/styles.js +36 -29
  92. package/lib/module/components/Avatar/styles.js.map +1 -1
  93. package/lib/module/components/Button/styles.js +2 -2
  94. package/lib/module/components/Button/styles.js.map +1 -1
  95. package/lib/module/components/CLAUDE.md +90 -0
  96. package/lib/module/components/Card/index.js +23 -4
  97. package/lib/module/components/Card/index.js.map +1 -1
  98. package/lib/module/components/Card/styles.js +27 -5
  99. package/lib/module/components/Card/styles.js.map +1 -1
  100. package/lib/module/components/Checkbox/index.js +6 -30
  101. package/lib/module/components/Checkbox/index.js.map +1 -1
  102. package/lib/module/components/Checkbox/styles.js +40 -48
  103. package/lib/module/components/Checkbox/styles.js.map +1 -1
  104. package/lib/module/components/Chip/index.js +82 -13
  105. package/lib/module/components/Chip/index.js.map +1 -1
  106. package/lib/module/components/Chip/styles.js +206 -20
  107. package/lib/module/components/Chip/styles.js.map +1 -1
  108. package/lib/module/components/Field/index.js +9 -3
  109. package/lib/module/components/Field/index.js.map +1 -1
  110. package/lib/module/components/Field/styles.js +4 -4
  111. package/lib/module/components/Field/styles.js.map +1 -1
  112. package/lib/module/components/Heading/styles.js +1 -1
  113. package/lib/module/components/Heading/styles.js.map +1 -1
  114. package/lib/module/components/Icon/index.js +1 -2
  115. package/lib/module/components/Icon/index.js.map +1 -1
  116. package/lib/module/components/IconButton/index.js +6 -1
  117. package/lib/module/components/IconButton/index.js.map +1 -1
  118. package/lib/module/components/IconButton/styles.js +135 -10
  119. package/lib/module/components/IconButton/styles.js.map +1 -1
  120. package/lib/module/components/Input/styles.js +7 -6
  121. package/lib/module/components/Input/styles.js.map +1 -1
  122. package/lib/module/components/ListItem/index.js +226 -0
  123. package/lib/module/components/ListItem/index.js.map +1 -0
  124. package/lib/module/components/ListItem/styles.js +127 -0
  125. package/lib/module/components/ListItem/styles.js.map +1 -0
  126. package/lib/module/components/ProgressSegmented/index.js +23 -11
  127. package/lib/module/components/ProgressSegmented/index.js.map +1 -1
  128. package/lib/module/components/Radio/index.js +164 -0
  129. package/lib/module/components/Radio/index.js.map +1 -0
  130. package/lib/module/components/Radio/styles.js +27 -0
  131. package/lib/module/components/Radio/styles.js.map +1 -0
  132. package/lib/module/components/Text/styles.js +2 -2
  133. package/lib/module/components/Text/styles.js.map +1 -1
  134. package/lib/module/components/Tile/index.js +243 -0
  135. package/lib/module/components/Tile/index.js.map +1 -0
  136. package/lib/module/components/Tile/styles.js +48 -0
  137. package/lib/module/components/Tile/styles.js.map +1 -0
  138. package/lib/module/components/index.js +3 -0
  139. package/lib/module/components/index.js.map +1 -1
  140. package/lib/module/figma/Avatar.figma.js +48 -0
  141. package/lib/module/figma/Avatar.figma.js.map +1 -0
  142. package/lib/module/figma/Button.figma.js +28 -11
  143. package/lib/module/figma/Button.figma.js.map +1 -1
  144. package/lib/module/figma/CLAUDE.md +30 -0
  145. package/lib/module/figma/Card.Header.figma.js +22 -0
  146. package/lib/module/figma/Card.Header.figma.js.map +1 -0
  147. package/lib/module/figma/Card.figma.js +36 -0
  148. package/lib/module/figma/Card.figma.js.map +1 -0
  149. package/lib/module/figma/Checkbox.figma.js +49 -0
  150. package/lib/module/figma/Checkbox.figma.js.map +1 -0
  151. package/lib/module/figma/Chip.figma.js +62 -0
  152. package/lib/module/figma/Chip.figma.js.map +1 -0
  153. package/lib/module/figma/Field.Input.figma.js +51 -0
  154. package/lib/module/figma/Field.Input.figma.js.map +1 -0
  155. package/lib/module/figma/Field.Select.figma.js +51 -0
  156. package/lib/module/figma/Field.Select.figma.js.map +1 -0
  157. package/lib/module/figma/Heading.figma.js +24 -0
  158. package/lib/module/figma/Heading.figma.js.map +1 -0
  159. package/lib/module/figma/Icon.figma.js +14 -0
  160. package/lib/module/figma/Icon.figma.js.map +1 -0
  161. package/lib/module/figma/IconButton.figma.js +41 -0
  162. package/lib/module/figma/IconButton.figma.js.map +1 -0
  163. package/lib/module/figma/Input.figma.js +46 -0
  164. package/lib/module/figma/Input.figma.js.map +1 -0
  165. package/lib/module/figma/ProgressSegmented.figma.js +33 -0
  166. package/lib/module/figma/ProgressSegmented.figma.js.map +1 -0
  167. package/lib/module/figma/Radio.figma.js +32 -0
  168. package/lib/module/figma/Radio.figma.js.map +1 -0
  169. package/lib/module/figma/Select.figma.js +47 -0
  170. package/lib/module/figma/Select.figma.js.map +1 -0
  171. package/lib/module/figma/Text.figma.js +23 -0
  172. package/lib/module/figma/Text.figma.js.map +1 -0
  173. package/lib/module/figma/icons.figma.batch.js +22 -0
  174. package/lib/module/figma/icons.figma.batch.js.map +1 -0
  175. package/lib/module/figma/icons.figma.batch.json +17705 -0
  176. package/lib/module/styles/primitives.js +42 -5
  177. package/lib/module/styles/primitives.js.map +1 -1
  178. package/lib/typescript/components/Avatar/styles.d.ts +4 -4
  179. package/lib/typescript/components/Avatar/styles.d.ts.map +1 -1
  180. package/lib/typescript/components/Card/index.d.ts +4 -3
  181. package/lib/typescript/components/Card/index.d.ts.map +1 -1
  182. package/lib/typescript/components/Card/styles.d.ts +13 -3
  183. package/lib/typescript/components/Card/styles.d.ts.map +1 -1
  184. package/lib/typescript/components/Checkbox/index.d.ts +1 -2
  185. package/lib/typescript/components/Checkbox/index.d.ts.map +1 -1
  186. package/lib/typescript/components/Checkbox/styles.d.ts +4 -14
  187. package/lib/typescript/components/Checkbox/styles.d.ts.map +1 -1
  188. package/lib/typescript/components/Chip/index.d.ts +19 -6
  189. package/lib/typescript/components/Chip/index.d.ts.map +1 -1
  190. package/lib/typescript/components/Chip/styles.d.ts +13 -4
  191. package/lib/typescript/components/Chip/styles.d.ts.map +1 -1
  192. package/lib/typescript/components/Field/FieldLabel.web.d.ts +2 -2
  193. package/lib/typescript/components/Field/FieldLabel.web.d.ts.map +1 -1
  194. package/lib/typescript/components/Field/index.d.ts.map +1 -1
  195. package/lib/typescript/components/Field/styles.d.ts.map +1 -1
  196. package/lib/typescript/components/Heading/styles.d.ts +1 -1
  197. package/lib/typescript/components/Icon/index.d.ts.map +1 -1
  198. package/lib/typescript/components/IconButton/index.d.ts.map +1 -1
  199. package/lib/typescript/components/IconButton/styles.d.ts +6 -2
  200. package/lib/typescript/components/IconButton/styles.d.ts.map +1 -1
  201. package/lib/typescript/components/Input/styles.d.ts.map +1 -1
  202. package/lib/typescript/components/ListItem/index.d.ts +49 -0
  203. package/lib/typescript/components/ListItem/index.d.ts.map +1 -0
  204. package/lib/typescript/components/ListItem/styles.d.ts +30 -0
  205. package/lib/typescript/components/ListItem/styles.d.ts.map +1 -0
  206. package/lib/typescript/components/ProgressSegmented/index.d.ts +14 -3
  207. package/lib/typescript/components/ProgressSegmented/index.d.ts.map +1 -1
  208. package/lib/typescript/components/Radio/index.d.ts +40 -0
  209. package/lib/typescript/components/Radio/index.d.ts.map +1 -0
  210. package/lib/typescript/components/Radio/styles.d.ts +8 -0
  211. package/lib/typescript/components/Radio/styles.d.ts.map +1 -0
  212. package/lib/typescript/components/Stack/styles.d.ts +2 -2
  213. package/lib/typescript/components/Text/styles.d.ts +1 -1
  214. package/lib/typescript/components/Tile/index.d.ts +70 -0
  215. package/lib/typescript/components/Tile/index.d.ts.map +1 -0
  216. package/lib/typescript/components/Tile/styles.d.ts +18 -0
  217. package/lib/typescript/components/Tile/styles.d.ts.map +1 -0
  218. package/lib/typescript/components/index.d.ts +3 -0
  219. package/lib/typescript/components/index.d.ts.map +1 -1
  220. package/lib/typescript/figma/Avatar.figma.d.ts +8 -0
  221. package/lib/typescript/figma/Avatar.figma.d.ts.map +1 -0
  222. package/lib/typescript/figma/Button.figma.d.ts.map +1 -1
  223. package/lib/typescript/figma/Card.Header.figma.d.ts +8 -0
  224. package/lib/typescript/figma/Card.Header.figma.d.ts.map +1 -0
  225. package/lib/typescript/figma/Card.figma.d.ts +8 -0
  226. package/lib/typescript/figma/Card.figma.d.ts.map +1 -0
  227. package/lib/typescript/figma/Checkbox.figma.d.ts +8 -0
  228. package/lib/typescript/figma/Checkbox.figma.d.ts.map +1 -0
  229. package/lib/typescript/figma/Chip.figma.d.ts +8 -0
  230. package/lib/typescript/figma/Chip.figma.d.ts.map +1 -0
  231. package/lib/typescript/figma/Field.Input.figma.d.ts +8 -0
  232. package/lib/typescript/figma/Field.Input.figma.d.ts.map +1 -0
  233. package/lib/typescript/figma/Field.Select.figma.d.ts +8 -0
  234. package/lib/typescript/figma/Field.Select.figma.d.ts.map +1 -0
  235. package/lib/typescript/figma/Heading.figma.d.ts +8 -0
  236. package/lib/typescript/figma/Heading.figma.d.ts.map +1 -0
  237. package/lib/typescript/figma/Icon.figma.d.ts +8 -0
  238. package/lib/typescript/figma/Icon.figma.d.ts.map +1 -0
  239. package/lib/typescript/figma/IconButton.figma.d.ts +8 -0
  240. package/lib/typescript/figma/IconButton.figma.d.ts.map +1 -0
  241. package/lib/typescript/figma/Input.figma.d.ts +8 -0
  242. package/lib/typescript/figma/Input.figma.d.ts.map +1 -0
  243. package/lib/typescript/figma/ProgressSegmented.figma.d.ts +8 -0
  244. package/lib/typescript/figma/ProgressSegmented.figma.d.ts.map +1 -0
  245. package/lib/typescript/figma/Radio.figma.d.ts +8 -0
  246. package/lib/typescript/figma/Radio.figma.d.ts.map +1 -0
  247. package/lib/typescript/figma/Select.figma.d.ts +8 -0
  248. package/lib/typescript/figma/Select.figma.d.ts.map +1 -0
  249. package/lib/typescript/figma/Text.figma.d.ts +8 -0
  250. package/lib/typescript/figma/Text.figma.d.ts.map +1 -0
  251. package/lib/typescript/figma/icons.figma.batch.d.ts +14 -0
  252. package/lib/typescript/figma/icons.figma.batch.d.ts.map +1 -0
  253. package/lib/typescript/styles/primitives.d.ts +38 -0
  254. package/lib/typescript/styles/primitives.d.ts.map +1 -1
  255. package/package.json +4 -4
  256. package/src/components/Avatar/index.tsx +1 -1
  257. package/src/components/Avatar/styles.ts +49 -34
  258. package/src/components/Button/styles.ts +2 -2
  259. package/src/components/CLAUDE.md +90 -0
  260. package/src/components/Card/index.tsx +41 -16
  261. package/src/components/Card/styles.ts +43 -23
  262. package/src/components/Checkbox/index.tsx +8 -19
  263. package/src/components/Checkbox/styles.ts +82 -86
  264. package/src/components/Chip/index.tsx +104 -27
  265. package/src/components/Chip/styles.ts +232 -18
  266. package/src/components/Field/FieldLabel.web.tsx +1 -1
  267. package/src/components/Field/index.tsx +10 -3
  268. package/src/components/Field/styles.ts +5 -4
  269. package/src/components/Heading/styles.ts +1 -1
  270. package/src/components/Icon/index.tsx +1 -2
  271. package/src/components/IconButton/index.tsx +3 -2
  272. package/src/components/IconButton/styles.ts +136 -10
  273. package/src/components/Input/styles.ts +14 -9
  274. package/src/components/ListItem/index.tsx +285 -0
  275. package/src/components/ListItem/styles.ts +153 -0
  276. package/src/components/ProgressSegmented/index.tsx +49 -14
  277. package/src/components/Radio/index.tsx +192 -0
  278. package/src/components/Radio/styles.ts +59 -0
  279. package/src/components/Text/styles.ts +2 -2
  280. package/src/components/Tile/index.tsx +296 -0
  281. package/src/components/Tile/styles.ts +82 -0
  282. package/src/components/index.ts +3 -0
  283. package/src/styles/primitives.ts +42 -5
@@ -0,0 +1,153 @@
1
+ import { Platform } from 'react-native';
2
+ import { cva, type VariantProps } from 'class-variance-authority';
3
+ import { TRANSITION_COLORS } from '../../styles/primitives';
4
+
5
+ // ── Root (row): density, surface, separator, interactive feedback ──────────
6
+
7
+ export const listItemRootVariants = cva(
8
+ [
9
+ 'flex-row self-stretch w-full px-4',
10
+ 'data-[disabled=true]:opacity-50 data-[disabled=true]:pointer-events-none',
11
+ 'data-[active=true]:opacity-70',
12
+ TRANSITION_COLORS,
13
+ Platform.select({
14
+ web: [
15
+ 'outline-none',
16
+ 'web:data-[hover=true]:bg-slate-50',
17
+ 'web:focus-visible:data-[disabled=false]:bg-slate-50',
18
+ 'web:focus-visible:data-[disabled=false]:ring-2 web:focus-visible:data-[disabled=false]:ring-slate-400/40 web:focus-visible:data-[disabled=false]:ring-offset-2',
19
+ ].join(' '),
20
+ default: '',
21
+ }),
22
+ ],
23
+ {
24
+ variants: {
25
+ size: {
26
+ default: 'gap-3 py-4',
27
+ compact: 'gap-2 py-3',
28
+ },
29
+ surface: {
30
+ default: 'bg-white',
31
+ negative: 'bg-red-50',
32
+ },
33
+ showSeparator: {
34
+ true: 'border-b border-solid border-stroke-secondary',
35
+ false: 'border-b-0',
36
+ },
37
+ crossAlign: {
38
+ center: 'items-center',
39
+ start: 'items-start',
40
+ },
41
+ },
42
+ compoundVariants: [
43
+ {
44
+ surface: 'negative',
45
+ className: Platform.select({
46
+ web: 'web:data-[hover=true]:bg-red-100/90',
47
+ default: '',
48
+ }),
49
+ },
50
+ ],
51
+ defaultVariants: {
52
+ size: 'default',
53
+ surface: 'default',
54
+ showSeparator: true,
55
+ crossAlign: 'center',
56
+ },
57
+ },
58
+ );
59
+
60
+ // ── Leading / trailing slots ─────────────────────────────────────────────────
61
+
62
+ export const listItemLeadingSlotVariants = cva(['flex shrink-0 items-center justify-center']);
63
+
64
+ export const listItemTrailingSlotVariants = cva(['flex shrink-0 flex-row justify-end gap-2'], {
65
+ variants: {
66
+ crossAlign: {
67
+ center: 'items-center',
68
+ start: 'items-start self-start',
69
+ },
70
+ },
71
+ defaultVariants: {
72
+ crossAlign: 'center',
73
+ },
74
+ });
75
+
76
+ // ── Content stack (title / description / meta) ───────────────────────────────
77
+
78
+ export const listItemContentVariants = cva('flex min-w-0 flex-1 flex-col gap-1', {
79
+ variants: {
80
+ crossAlign: {
81
+ center: 'justify-center',
82
+ start: 'justify-start',
83
+ },
84
+ },
85
+ defaultVariants: {
86
+ crossAlign: 'center',
87
+ },
88
+ });
89
+
90
+ // ── Typography ───────────────────────────────────────────────────────────────
91
+
92
+ export const listItemTitleVariants = cva('text-content-primary font-medium', {
93
+ variants: {
94
+ size: {
95
+ default: 'text-base leading-snug',
96
+ compact: 'text-sm leading-snug',
97
+ },
98
+ },
99
+ defaultVariants: {
100
+ size: 'default',
101
+ },
102
+ });
103
+
104
+ export const listItemDescriptionVariants = cva('text-content-secondary', {
105
+ variants: {
106
+ size: {
107
+ default: 'text-sm leading-normal',
108
+ compact: 'text-xs leading-normal',
109
+ },
110
+ },
111
+ defaultVariants: {
112
+ size: 'default',
113
+ },
114
+ });
115
+
116
+ export const listItemMetaVariants = cva('text-content-tertiary', {
117
+ variants: {
118
+ size: {
119
+ default: 'text-xs leading-normal',
120
+ compact: 'text-[11px] leading-normal',
121
+ },
122
+ },
123
+ defaultVariants: {
124
+ size: 'default',
125
+ },
126
+ });
127
+
128
+ // ── Section header (group label row inside lists / cards) ───────────────────
129
+
130
+ export const listItemSectionHeaderVariants = cva(
131
+ [
132
+ 'flex-row items-center justify-between gap-2 border-b border-solid px-4 py-3',
133
+ 'border-stroke-secondary',
134
+ ],
135
+ {
136
+ variants: {
137
+ showDivider: {
138
+ true: ['border-t-4 border-solid border-t-surface-brand-strong/40', 'border-x-0'],
139
+ false: 'border-t-0',
140
+ },
141
+ },
142
+ defaultVariants: {
143
+ showDivider: true,
144
+ },
145
+ },
146
+ );
147
+
148
+ /** Default section-title typography; applied by `ListItem.SectionHeader` for string/number children. Exported for rare custom composition. */
149
+ export const listItemSectionHeaderLabelVariants = cva(
150
+ 'text-xs font-semibold uppercase tracking-wide text-content-secondary',
151
+ );
152
+
153
+ export type ListItemVariantProps = VariantProps<typeof listItemRootVariants>;
@@ -1,4 +1,4 @@
1
- import { forwardRef, useMemo } from 'react';
1
+ import { forwardRef, useEffect, useMemo } from 'react';
2
2
  import { View, type ViewProps } from 'react-native';
3
3
  import { cn } from '@cdx-ui/utils';
4
4
  import {
@@ -7,15 +7,32 @@ import {
7
7
  type ProgressSegmentedVariants,
8
8
  } from './styles';
9
9
 
10
+ /* `ProgressSegmentedProps.total` remains in the public API until the next major release. */
11
+ /* eslint-disable @typescript-eslint/no-deprecated */
10
12
  export interface ProgressSegmentedProps extends ViewProps, ProgressSegmentedVariants {
11
13
  /** Current step (1-based index into the segment count) */
12
14
  readonly step: number;
13
- /** Total number of segments */
15
+ /**
16
+ * Number of segments in the bar. Matches the Figma `segments` variant (2–6 in the design
17
+ * system file); the prop accepts any positive integer for backward compatibility.
18
+ */
19
+ readonly segments?: number;
20
+ /**
21
+ * @deprecated Use {@link ProgressSegmentedProps.segments} instead. This alias will be removed
22
+ * in a future major release.
23
+ */
14
24
  readonly total?: number;
15
25
  /** When true, the current step segment is marked as complete rather than in-progress */
16
26
  readonly isStepComplete?: boolean;
17
- /** Returns the accessibility value text announced by screen readers. Receives the clamped step, total, and whether the step is complete. */
18
- readonly getAccessibilityText?: (step: number, total: number, isStepComplete: boolean) => string;
27
+ /**
28
+ * Returns the accessibility value text announced by screen readers. Receives the clamped
29
+ * step, segment count, and whether the step is complete.
30
+ */
31
+ readonly getAccessibilityText?: (
32
+ step: number,
33
+ segmentCount: number,
34
+ isStepComplete: boolean,
35
+ ) => string;
19
36
  readonly className?: string;
20
37
  }
21
38
 
@@ -23,7 +40,8 @@ export const ProgressSegmented = forwardRef<View, ProgressSegmentedProps>(
23
40
  (
24
41
  {
25
42
  step,
26
- total = 5,
43
+ segments,
44
+ total,
27
45
  isStepComplete = false,
28
46
  getAccessibilityText,
29
47
  className,
@@ -32,10 +50,25 @@ export const ProgressSegmented = forwardRef<View, ProgressSegmentedProps>(
32
50
  },
33
51
  ref,
34
52
  ) => {
35
- const clampedStep = Math.max(0, Math.min(step, total));
53
+ const segmentCount = segments ?? total ?? 5;
36
54
 
37
- const segments = useMemo(() => {
38
- return Array.from({ length: total }, (_, index) => {
55
+ useEffect(() => {
56
+ if (
57
+ typeof process !== 'undefined' &&
58
+ process.env.NODE_ENV !== 'production' &&
59
+ total !== undefined &&
60
+ segments === undefined
61
+ ) {
62
+ console.warn(
63
+ '[ProgressSegmented] The `total` prop is deprecated and will be removed in a future major release. Use `segments` instead.',
64
+ );
65
+ }
66
+ }, [total, segments]);
67
+
68
+ const clampedStep = Math.max(0, Math.min(step, segmentCount));
69
+
70
+ const segmentStates = useMemo(() => {
71
+ return Array.from({ length: segmentCount }, (_, index) => {
39
72
  const segmentIndex = index + 1;
40
73
  let state: 'complete' | 'incomplete' | 'inprogress' = 'incomplete';
41
74
 
@@ -47,13 +80,13 @@ export const ProgressSegmented = forwardRef<View, ProgressSegmentedProps>(
47
80
 
48
81
  return state;
49
82
  });
50
- }, [total, clampedStep, isStepComplete]);
83
+ }, [segmentCount, clampedStep, isStepComplete]);
51
84
 
52
- let accessibilityText = `Step ${String(clampedStep)} of ${String(total)}`;
85
+ let accessibilityText = `Step ${String(clampedStep)} of ${String(segmentCount)}`;
53
86
  if (getAccessibilityText) {
54
- accessibilityText = getAccessibilityText(clampedStep, total, isStepComplete);
87
+ accessibilityText = getAccessibilityText(clampedStep, segmentCount, isStepComplete);
55
88
  } else if (isStepComplete) {
56
- accessibilityText = `Step ${String(clampedStep)} of ${String(total)}, completed`;
89
+ accessibilityText = `Step ${String(clampedStep)} of ${String(segmentCount)}, completed`;
57
90
  }
58
91
 
59
92
  return (
@@ -63,14 +96,14 @@ export const ProgressSegmented = forwardRef<View, ProgressSegmentedProps>(
63
96
  accessibilityLabel={accessibilityLabel}
64
97
  accessibilityValue={{
65
98
  min: 0,
66
- max: total,
99
+ max: segmentCount,
67
100
  now: clampedStep,
68
101
  text: accessibilityText,
69
102
  }}
70
103
  className={cn(progressSegmentedVariants(), className)}
71
104
  {...props}
72
105
  >
73
- {segments.map((state, index) => (
106
+ {segmentStates.map((state, index) => (
74
107
  <View key={index} className={cn(segmentVariants({ state }))} />
75
108
  ))}
76
109
  </View>
@@ -79,3 +112,5 @@ export const ProgressSegmented = forwardRef<View, ProgressSegmentedProps>(
79
112
  );
80
113
 
81
114
  ProgressSegmented.displayName = 'ProgressSegmented';
115
+
116
+ /* eslint-enable @typescript-eslint/no-deprecated */
@@ -0,0 +1,192 @@
1
+ import { forwardRef, type ReactNode } from 'react';
2
+ import { Pressable, Text, type TextProps, View, type ViewProps } from 'react-native';
3
+ import { createRadio, dataAttributes, type IRadioProps } from '@cdx-ui/primitives';
4
+ import { cn } from '@cdx-ui/utils';
5
+ import {
6
+ radioGroupVariants,
7
+ radioIndicatorVariants,
8
+ radioInnerDotVariants,
9
+ radioLabelVariants,
10
+ radioRootVariants,
11
+ } from './styles';
12
+
13
+ // =============================================================================
14
+ // STYLED INDICATOR BASE
15
+ // =============================================================================
16
+
17
+ const RadioIndicatorBase = forwardRef<View, ViewProps & { className?: string }>(
18
+ ({ className, children, style, ...props }, ref) => {
19
+ // On web, data attributes arrive as `dataSet: { checked: true }`.
20
+ // On native, they arrive as individual `data-checked: "true"` props.
21
+ const ds = (props as any).dataSet;
22
+ const isChecked = ds ? ds.checked === true : (props as any)['data-checked'] === 'true';
23
+ const isInvalid = ds ? ds.invalid === true : (props as any)['data-invalid'] === 'true';
24
+ const isHovered = ds ? ds.hover === true : (props as any)['data-hover'] === 'true';
25
+
26
+ return (
27
+ <View ref={ref} className={cn(radioIndicatorVariants(), className)} style={style} {...props}>
28
+ <View
29
+ className={cn(radioInnerDotVariants())}
30
+ {...dataAttributes({ checked: isChecked, invalid: isInvalid, hover: isHovered })}
31
+ />
32
+ {children}
33
+ </View>
34
+ );
35
+ },
36
+ );
37
+
38
+ RadioIndicatorBase.displayName = 'Radio.IndicatorBase';
39
+
40
+ // =============================================================================
41
+ // PRIMITIVE ASSEMBLY
42
+ // =============================================================================
43
+
44
+ const RadioPrimitive = createRadio({
45
+ Root: Pressable,
46
+ Indicator: RadioIndicatorBase,
47
+ Label: Text,
48
+ Group: View,
49
+ });
50
+
51
+ // =============================================================================
52
+ // RADIO ROOT
53
+ // =============================================================================
54
+
55
+ export interface RadioProps extends IRadioProps {
56
+ className?: string;
57
+ children?: ReactNode;
58
+ }
59
+
60
+ const RadioRoot = forwardRef<View, RadioProps>(({ className, children, style, ...props }, ref) => {
61
+ const computedClassName = cn(radioRootVariants(), className);
62
+
63
+ return (
64
+ <RadioPrimitive ref={ref as any} className={computedClassName} style={style} {...props}>
65
+ {children}
66
+ </RadioPrimitive>
67
+ );
68
+ });
69
+
70
+ RadioRoot.displayName = 'Radio';
71
+
72
+ // =============================================================================
73
+ // RADIO INDICATOR
74
+ // =============================================================================
75
+
76
+ export interface RadioIndicatorProps extends ViewProps {
77
+ className?: string;
78
+ children?: ReactNode;
79
+ }
80
+
81
+ const RadioIndicator = forwardRef<View, RadioIndicatorProps>(
82
+ ({ className, children, style, ...props }, ref) => {
83
+ return (
84
+ <RadioPrimitive.Indicator ref={ref as any} className={className} style={style} {...props}>
85
+ {children}
86
+ </RadioPrimitive.Indicator>
87
+ );
88
+ },
89
+ );
90
+
91
+ RadioIndicator.displayName = 'Radio.Indicator';
92
+
93
+ // =============================================================================
94
+ // RADIO LABEL
95
+ // =============================================================================
96
+
97
+ export interface RadioLabelProps extends TextProps {
98
+ className?: string;
99
+ children?: ReactNode;
100
+ }
101
+
102
+ const RadioLabel = forwardRef<Text, RadioLabelProps>(
103
+ ({ className, children, style, ...props }, ref) => {
104
+ const computedClassName = cn(radioLabelVariants(), className);
105
+
106
+ return (
107
+ <RadioPrimitive.Label ref={ref as any} className={computedClassName} style={style} {...props}>
108
+ {children}
109
+ </RadioPrimitive.Label>
110
+ );
111
+ },
112
+ );
113
+
114
+ RadioLabel.displayName = 'Radio.Label';
115
+
116
+ // =============================================================================
117
+ // RADIO GROUP
118
+ // =============================================================================
119
+
120
+ export interface RadioGroupProps extends ViewProps {
121
+ className?: string;
122
+ children?: ReactNode;
123
+ value?: string;
124
+ defaultValue?: string;
125
+ onChange?: (value: string) => void;
126
+ isDisabled?: boolean;
127
+ isInvalid?: boolean;
128
+ isRequired?: boolean;
129
+ isReadOnly?: boolean;
130
+ direction?: 'column' | 'row';
131
+ name?: string;
132
+ }
133
+
134
+ const RadioGroup = forwardRef<View, RadioGroupProps>(
135
+ (
136
+ {
137
+ className,
138
+ children,
139
+ style,
140
+ direction = 'column',
141
+ value,
142
+ defaultValue,
143
+ onChange,
144
+ isDisabled,
145
+ isInvalid,
146
+ isRequired,
147
+ isReadOnly,
148
+ name,
149
+ ...viewProps
150
+ },
151
+ ref,
152
+ ) => {
153
+ const computedClassName = cn(radioGroupVariants({ direction }), className);
154
+
155
+ return (
156
+ <RadioPrimitive.Group
157
+ ref={ref as any}
158
+ className={computedClassName}
159
+ style={style}
160
+ value={value}
161
+ defaultValue={defaultValue}
162
+ onChange={onChange}
163
+ isDisabled={isDisabled}
164
+ isInvalid={isInvalid}
165
+ isRequired={isRequired}
166
+ isReadOnly={isReadOnly}
167
+ name={name}
168
+ {...viewProps}
169
+ >
170
+ {children}
171
+ </RadioPrimitive.Group>
172
+ );
173
+ },
174
+ );
175
+
176
+ RadioGroup.displayName = 'Radio.Group';
177
+
178
+ // =============================================================================
179
+ // COMPOUND COMPONENT
180
+ // =============================================================================
181
+
182
+ type RadioCompoundComponent = typeof RadioRoot & {
183
+ Indicator: typeof RadioIndicator;
184
+ Label: typeof RadioLabel;
185
+ Group: typeof RadioGroup;
186
+ };
187
+
188
+ export const Radio = Object.assign(RadioRoot, {
189
+ Indicator: RadioIndicator,
190
+ Label: RadioLabel,
191
+ Group: RadioGroup,
192
+ }) as RadioCompoundComponent;
@@ -0,0 +1,59 @@
1
+ import { Platform } from 'react-native';
2
+ import { cva } from 'class-variance-authority';
3
+ import { DISABLED_CURSOR, TRANSITION_COLORS } from '../../styles/primitives';
4
+
5
+ export const radioRootVariants = cva([
6
+ 'flex-row items-center gap-2',
7
+ 'data-[disabled=true]:opacity-[var(--opacity-disabled)]',
8
+ DISABLED_CURSOR,
9
+ ]);
10
+
11
+ export const radioIndicatorVariants = cva([
12
+ 'items-center justify-center',
13
+ 'rounded-[var(--border-radius-round)]',
14
+ 'border-2',
15
+ 'h-5 w-5',
16
+ 'bg-surface-primary',
17
+ 'data-[checked=false]:border-content-secondary',
18
+ 'data-[checked=true]:border-stroke-action',
19
+ 'data-[invalid=true]:border-stroke-danger',
20
+ 'data-[checked=true]:data-[invalid=true]:border-stroke-danger',
21
+ Platform.select({
22
+ web: [
23
+ TRANSITION_COLORS,
24
+ 'data-[hover=true]:data-[checked=true]:border-surface-action-strong-hover',
25
+ 'data-[hover=true]:data-[invalid=true]:border-surface-danger-strong-hover',
26
+ 'web:data-[focus-visible=true]:outline-none',
27
+ 'web:data-[focus-visible=true]:ring-2 web:data-[focus-visible=true]:ring-[var(--color-stroke-ring)] web:data-[focus-visible=true]:ring-offset-2',
28
+ ].join(' '),
29
+ default: '',
30
+ }),
31
+ ]);
32
+
33
+ export const radioInnerDotVariants = cva([
34
+ 'rounded-[var(--border-radius-round)]',
35
+ 'h-2.5 w-2.5',
36
+ 'scale-0',
37
+ 'data-[checked=true]:scale-100',
38
+ 'bg-surface-action-strong',
39
+ 'data-[invalid=true]:bg-surface-danger-strong',
40
+ Platform.select({
41
+ web: [
42
+ 'data-[hover=true]:bg-surface-action-strong-hover',
43
+ 'data-[hover=true]:data-[invalid=true]:bg-surface-danger-strong-hover',
44
+ ].join(' '),
45
+ default: '',
46
+ }),
47
+ ]);
48
+
49
+ export const radioLabelVariants = cva(['body-md', 'text-content-primary']);
50
+
51
+ export const radioGroupVariants = cva([], {
52
+ variants: {
53
+ direction: {
54
+ column: 'gap-2',
55
+ row: 'flex-row gap-4',
56
+ },
57
+ },
58
+ defaultVariants: { direction: 'column' },
59
+ });
@@ -3,9 +3,9 @@ import { cva, type VariantProps } from 'class-variance-authority';
3
3
 
4
4
  export const textStyle = cva(
5
5
  [
6
- `text-content-primary font-normal`,
6
+ 'text-content-primary',
7
7
  Platform.select({
8
- web: 'font-sans my-0 bg-transparent display-inline no-underline',
8
+ web: 'font-body my-0 bg-transparent no-underline',
9
9
  default: '',
10
10
  }),
11
11
  ],