@cdx-ui/primitives 0.0.1-beta.4 → 0.0.1-beta.41

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 (287) hide show
  1. package/README.md +51 -25
  2. package/lib/commonjs/CLAUDE.md +32 -0
  3. package/lib/commonjs/avatar/createAvatarText.js +9 -1
  4. package/lib/commonjs/avatar/createAvatarText.js.map +1 -1
  5. package/lib/commonjs/button/createButtonText.js +1 -0
  6. package/lib/commonjs/button/createButtonText.js.map +1 -1
  7. package/lib/commonjs/checkbox/createCheckboxRoot.web.js +8 -3
  8. package/lib/commonjs/checkbox/createCheckboxRoot.web.js.map +1 -1
  9. package/lib/commonjs/chip/createChipRoot.js +132 -0
  10. package/lib/commonjs/chip/createChipRoot.js.map +1 -0
  11. package/lib/commonjs/chip/index.js +16 -0
  12. package/lib/commonjs/chip/index.js.map +1 -0
  13. package/lib/commonjs/chip/types.js +6 -0
  14. package/lib/commonjs/chip/types.js.map +1 -0
  15. package/lib/commonjs/field/createFieldLabel.js.map +1 -1
  16. package/lib/commonjs/index.js +48 -0
  17. package/lib/commonjs/index.js.map +1 -1
  18. package/lib/commonjs/input/createInputField.js +5 -0
  19. package/lib/commonjs/input/createInputField.js.map +1 -1
  20. package/lib/commonjs/list-item/context.js +11 -0
  21. package/lib/commonjs/list-item/context.js.map +1 -0
  22. package/lib/commonjs/list-item/createListItemContent.js +30 -0
  23. package/lib/commonjs/list-item/createListItemContent.js.map +1 -0
  24. package/lib/commonjs/list-item/createListItemDescription.js +25 -0
  25. package/lib/commonjs/list-item/createListItemDescription.js.map +1 -0
  26. package/lib/commonjs/list-item/createListItemLeadingSlot.js +34 -0
  27. package/lib/commonjs/list-item/createListItemLeadingSlot.js.map +1 -0
  28. package/lib/commonjs/list-item/createListItemMeta.js +25 -0
  29. package/lib/commonjs/list-item/createListItemMeta.js.map +1 -0
  30. package/lib/commonjs/list-item/createListItemRoot.js +157 -0
  31. package/lib/commonjs/list-item/createListItemRoot.js.map +1 -0
  32. package/lib/commonjs/list-item/createListItemSectionHeader.js +54 -0
  33. package/lib/commonjs/list-item/createListItemSectionHeader.js.map +1 -0
  34. package/lib/commonjs/list-item/createListItemTitle.js +25 -0
  35. package/lib/commonjs/list-item/createListItemTitle.js.map +1 -0
  36. package/lib/commonjs/list-item/createListItemTrailingSlot.js +28 -0
  37. package/lib/commonjs/list-item/createListItemTrailingSlot.js.map +1 -0
  38. package/lib/commonjs/list-item/index.js +55 -0
  39. package/lib/commonjs/list-item/index.js.map +1 -0
  40. package/lib/commonjs/list-item/types.js +6 -0
  41. package/lib/commonjs/list-item/types.js.map +1 -0
  42. package/lib/commonjs/radio/context.js +14 -0
  43. package/lib/commonjs/radio/context.js.map +1 -0
  44. package/lib/commonjs/radio/createRadioGroup.js +66 -0
  45. package/lib/commonjs/radio/createRadioGroup.js.map +1 -0
  46. package/lib/commonjs/radio/createRadioIndicator.js +43 -0
  47. package/lib/commonjs/radio/createRadioIndicator.js.map +1 -0
  48. package/lib/commonjs/radio/createRadioLabel.js +38 -0
  49. package/lib/commonjs/radio/createRadioLabel.js.map +1 -0
  50. package/lib/commonjs/radio/createRadioRoot.js +95 -0
  51. package/lib/commonjs/radio/createRadioRoot.js.map +1 -0
  52. package/lib/commonjs/radio/createRadioRoot.web.js +87 -0
  53. package/lib/commonjs/radio/createRadioRoot.web.js.map +1 -0
  54. package/lib/commonjs/radio/index.js +26 -0
  55. package/lib/commonjs/radio/index.js.map +1 -0
  56. package/lib/commonjs/radio/types.js +6 -0
  57. package/lib/commonjs/radio/types.js.map +1 -0
  58. package/lib/commonjs/radio/useRadioRoot.js +64 -0
  59. package/lib/commonjs/radio/useRadioRoot.js.map +1 -0
  60. package/lib/commonjs/select/createSelectTrigger.js +17 -4
  61. package/lib/commonjs/select/createSelectTrigger.js.map +1 -1
  62. package/lib/commonjs/tile/context.js +30 -0
  63. package/lib/commonjs/tile/context.js.map +1 -0
  64. package/lib/commonjs/tile/createTileContent.js +30 -0
  65. package/lib/commonjs/tile/createTileContent.js.map +1 -0
  66. package/lib/commonjs/tile/createTileDescription.js +28 -0
  67. package/lib/commonjs/tile/createTileDescription.js.map +1 -0
  68. package/lib/commonjs/tile/createTileGroup.js +112 -0
  69. package/lib/commonjs/tile/createTileGroup.js.map +1 -0
  70. package/lib/commonjs/tile/createTileIndicator.js +46 -0
  71. package/lib/commonjs/tile/createTileIndicator.js.map +1 -0
  72. package/lib/commonjs/tile/createTileLeadingSlot.js +34 -0
  73. package/lib/commonjs/tile/createTileLeadingSlot.js.map +1 -0
  74. package/lib/commonjs/tile/createTileRoot.js +133 -0
  75. package/lib/commonjs/tile/createTileRoot.js.map +1 -0
  76. package/lib/commonjs/tile/createTileTitle.js +28 -0
  77. package/lib/commonjs/tile/createTileTitle.js.map +1 -0
  78. package/lib/commonjs/tile/createTileTrailingSlot.js +35 -0
  79. package/lib/commonjs/tile/createTileTrailingSlot.js.map +1 -0
  80. package/lib/commonjs/tile/index.js +55 -0
  81. package/lib/commonjs/tile/index.js.map +1 -0
  82. package/lib/commonjs/tile/types.js +6 -0
  83. package/lib/commonjs/tile/types.js.map +1 -0
  84. package/lib/module/CLAUDE.md +32 -0
  85. package/lib/module/avatar/createAvatarText.js +9 -1
  86. package/lib/module/avatar/createAvatarText.js.map +1 -1
  87. package/lib/module/button/createButtonText.js +1 -0
  88. package/lib/module/button/createButtonText.js.map +1 -1
  89. package/lib/module/checkbox/createCheckboxRoot.web.js +8 -2
  90. package/lib/module/checkbox/createCheckboxRoot.web.js.map +1 -1
  91. package/lib/module/chip/createChipRoot.js +126 -0
  92. package/lib/module/chip/createChipRoot.js.map +1 -0
  93. package/lib/module/chip/index.js +12 -0
  94. package/lib/module/chip/index.js.map +1 -0
  95. package/lib/module/chip/types.js +4 -0
  96. package/lib/module/chip/types.js.map +1 -0
  97. package/lib/module/field/createFieldLabel.js.map +1 -1
  98. package/lib/module/index.js +4 -0
  99. package/lib/module/index.js.map +1 -1
  100. package/lib/module/input/createInputField.js +5 -0
  101. package/lib/module/input/createInputField.js.map +1 -1
  102. package/lib/module/list-item/context.js +5 -0
  103. package/lib/module/list-item/context.js.map +1 -0
  104. package/lib/module/list-item/createListItemContent.js +24 -0
  105. package/lib/module/list-item/createListItemContent.js.map +1 -0
  106. package/lib/module/list-item/createListItemDescription.js +19 -0
  107. package/lib/module/list-item/createListItemDescription.js.map +1 -0
  108. package/lib/module/list-item/createListItemLeadingSlot.js +28 -0
  109. package/lib/module/list-item/createListItemLeadingSlot.js.map +1 -0
  110. package/lib/module/list-item/createListItemMeta.js +19 -0
  111. package/lib/module/list-item/createListItemMeta.js.map +1 -0
  112. package/lib/module/list-item/createListItemRoot.js +151 -0
  113. package/lib/module/list-item/createListItemRoot.js.map +1 -0
  114. package/lib/module/list-item/createListItemSectionHeader.js +48 -0
  115. package/lib/module/list-item/createListItemSectionHeader.js.map +1 -0
  116. package/lib/module/list-item/createListItemTitle.js +19 -0
  117. package/lib/module/list-item/createListItemTitle.js.map +1 -0
  118. package/lib/module/list-item/createListItemTrailingSlot.js +22 -0
  119. package/lib/module/list-item/createListItemTrailingSlot.js.map +1 -0
  120. package/lib/module/list-item/index.js +39 -0
  121. package/lib/module/list-item/index.js.map +1 -0
  122. package/lib/module/list-item/types.js +4 -0
  123. package/lib/module/list-item/types.js.map +1 -0
  124. package/lib/module/radio/context.js +7 -0
  125. package/lib/module/radio/context.js.map +1 -0
  126. package/lib/module/radio/createRadioGroup.js +61 -0
  127. package/lib/module/radio/createRadioGroup.js.map +1 -0
  128. package/lib/module/radio/createRadioIndicator.js +38 -0
  129. package/lib/module/radio/createRadioIndicator.js.map +1 -0
  130. package/lib/module/radio/createRadioLabel.js +33 -0
  131. package/lib/module/radio/createRadioLabel.js.map +1 -0
  132. package/lib/module/radio/createRadioRoot.js +90 -0
  133. package/lib/module/radio/createRadioRoot.js.map +1 -0
  134. package/lib/module/radio/createRadioRoot.web.js +82 -0
  135. package/lib/module/radio/createRadioRoot.web.js.map +1 -0
  136. package/lib/module/radio/index.js +22 -0
  137. package/lib/module/radio/index.js.map +1 -0
  138. package/lib/module/radio/types.js +4 -0
  139. package/lib/module/radio/types.js.map +1 -0
  140. package/lib/module/radio/useRadioRoot.js +60 -0
  141. package/lib/module/radio/useRadioRoot.js.map +1 -0
  142. package/lib/module/select/createSelectTrigger.js +19 -6
  143. package/lib/module/select/createSelectTrigger.js.map +1 -1
  144. package/lib/module/tile/context.js +21 -0
  145. package/lib/module/tile/context.js.map +1 -0
  146. package/lib/module/tile/createTileContent.js +24 -0
  147. package/lib/module/tile/createTileContent.js.map +1 -0
  148. package/lib/module/tile/createTileDescription.js +22 -0
  149. package/lib/module/tile/createTileDescription.js.map +1 -0
  150. package/lib/module/tile/createTileGroup.js +106 -0
  151. package/lib/module/tile/createTileGroup.js.map +1 -0
  152. package/lib/module/tile/createTileIndicator.js +40 -0
  153. package/lib/module/tile/createTileIndicator.js.map +1 -0
  154. package/lib/module/tile/createTileLeadingSlot.js +28 -0
  155. package/lib/module/tile/createTileLeadingSlot.js.map +1 -0
  156. package/lib/module/tile/createTileRoot.js +127 -0
  157. package/lib/module/tile/createTileRoot.js.map +1 -0
  158. package/lib/module/tile/createTileTitle.js +22 -0
  159. package/lib/module/tile/createTileTitle.js.map +1 -0
  160. package/lib/module/tile/createTileTrailingSlot.js +29 -0
  161. package/lib/module/tile/createTileTrailingSlot.js.map +1 -0
  162. package/lib/module/tile/index.js +39 -0
  163. package/lib/module/tile/index.js.map +1 -0
  164. package/lib/module/tile/types.js +4 -0
  165. package/lib/module/tile/types.js.map +1 -0
  166. package/lib/typescript/avatar/createAvatarText.d.ts.map +1 -1
  167. package/lib/typescript/button/createButtonText.d.ts.map +1 -1
  168. package/lib/typescript/checkbox/createCheckboxRoot.web.d.ts +4 -0
  169. package/lib/typescript/checkbox/createCheckboxRoot.web.d.ts.map +1 -1
  170. package/lib/typescript/checkbox/useCheckboxRoot.d.ts +2 -0
  171. package/lib/typescript/checkbox/useCheckboxRoot.d.ts.map +1 -1
  172. package/lib/typescript/chip/createChipRoot.d.ts +4 -0
  173. package/lib/typescript/chip/createChipRoot.d.ts.map +1 -0
  174. package/lib/typescript/chip/index.d.ts +9 -0
  175. package/lib/typescript/chip/index.d.ts.map +1 -0
  176. package/lib/typescript/chip/types.d.ts +17 -0
  177. package/lib/typescript/chip/types.d.ts.map +1 -0
  178. package/lib/typescript/field/createFieldLabel.d.ts.map +1 -1
  179. package/lib/typescript/index.d.ts +4 -0
  180. package/lib/typescript/index.d.ts.map +1 -1
  181. package/lib/typescript/input/createInputField.d.ts.map +1 -1
  182. package/lib/typescript/list-item/context.d.ts +6 -0
  183. package/lib/typescript/list-item/context.d.ts.map +1 -0
  184. package/lib/typescript/list-item/createListItemContent.d.ts +3 -0
  185. package/lib/typescript/list-item/createListItemContent.d.ts.map +1 -0
  186. package/lib/typescript/list-item/createListItemDescription.d.ts +3 -0
  187. package/lib/typescript/list-item/createListItemDescription.d.ts.map +1 -0
  188. package/lib/typescript/list-item/createListItemLeadingSlot.d.ts +4 -0
  189. package/lib/typescript/list-item/createListItemLeadingSlot.d.ts.map +1 -0
  190. package/lib/typescript/list-item/createListItemMeta.d.ts +3 -0
  191. package/lib/typescript/list-item/createListItemMeta.d.ts.map +1 -0
  192. package/lib/typescript/list-item/createListItemRoot.d.ts +4 -0
  193. package/lib/typescript/list-item/createListItemRoot.d.ts.map +1 -0
  194. package/lib/typescript/list-item/createListItemSectionHeader.d.ts +4 -0
  195. package/lib/typescript/list-item/createListItemSectionHeader.d.ts.map +1 -0
  196. package/lib/typescript/list-item/createListItemTitle.d.ts +3 -0
  197. package/lib/typescript/list-item/createListItemTitle.d.ts.map +1 -0
  198. package/lib/typescript/list-item/createListItemTrailingSlot.d.ts +3 -0
  199. package/lib/typescript/list-item/createListItemTrailingSlot.d.ts.map +1 -0
  200. package/lib/typescript/list-item/index.d.ts +16 -0
  201. package/lib/typescript/list-item/index.d.ts.map +1 -0
  202. package/lib/typescript/list-item/types.d.ts +86 -0
  203. package/lib/typescript/list-item/types.d.ts.map +1 -0
  204. package/lib/typescript/radio/context.d.ts +21 -0
  205. package/lib/typescript/radio/context.d.ts.map +1 -0
  206. package/lib/typescript/radio/createRadioGroup.d.ts +3 -0
  207. package/lib/typescript/radio/createRadioGroup.d.ts.map +1 -0
  208. package/lib/typescript/radio/createRadioIndicator.d.ts +5 -0
  209. package/lib/typescript/radio/createRadioIndicator.d.ts.map +1 -0
  210. package/lib/typescript/radio/createRadioLabel.d.ts +5 -0
  211. package/lib/typescript/radio/createRadioLabel.d.ts.map +1 -0
  212. package/lib/typescript/radio/createRadioRoot.d.ts +3 -0
  213. package/lib/typescript/radio/createRadioRoot.d.ts.map +1 -0
  214. package/lib/typescript/radio/createRadioRoot.web.d.ts +3 -0
  215. package/lib/typescript/radio/createRadioRoot.web.d.ts.map +1 -0
  216. package/lib/typescript/radio/index.d.ts +10 -0
  217. package/lib/typescript/radio/index.d.ts.map +1 -0
  218. package/lib/typescript/radio/types.d.ts +54 -0
  219. package/lib/typescript/radio/types.d.ts.map +1 -0
  220. package/lib/typescript/radio/useRadioRoot.d.ts +151 -0
  221. package/lib/typescript/radio/useRadioRoot.d.ts.map +1 -0
  222. package/lib/typescript/select/createSelectTrigger.d.ts.map +1 -1
  223. package/lib/typescript/tile/context.d.ts +9 -0
  224. package/lib/typescript/tile/context.d.ts.map +1 -0
  225. package/lib/typescript/tile/createTileContent.d.ts +3 -0
  226. package/lib/typescript/tile/createTileContent.d.ts.map +1 -0
  227. package/lib/typescript/tile/createTileDescription.d.ts +3 -0
  228. package/lib/typescript/tile/createTileDescription.d.ts.map +1 -0
  229. package/lib/typescript/tile/createTileGroup.d.ts +4 -0
  230. package/lib/typescript/tile/createTileGroup.d.ts.map +1 -0
  231. package/lib/typescript/tile/createTileIndicator.d.ts +4 -0
  232. package/lib/typescript/tile/createTileIndicator.d.ts.map +1 -0
  233. package/lib/typescript/tile/createTileLeadingSlot.d.ts +4 -0
  234. package/lib/typescript/tile/createTileLeadingSlot.d.ts.map +1 -0
  235. package/lib/typescript/tile/createTileRoot.d.ts +4 -0
  236. package/lib/typescript/tile/createTileRoot.d.ts.map +1 -0
  237. package/lib/typescript/tile/createTileTitle.d.ts +3 -0
  238. package/lib/typescript/tile/createTileTitle.d.ts.map +1 -0
  239. package/lib/typescript/tile/createTileTrailingSlot.d.ts +9 -0
  240. package/lib/typescript/tile/createTileTrailingSlot.d.ts.map +1 -0
  241. package/lib/typescript/tile/index.d.ts +15 -0
  242. package/lib/typescript/tile/index.d.ts.map +1 -0
  243. package/lib/typescript/tile/types.d.ts +119 -0
  244. package/lib/typescript/tile/types.d.ts.map +1 -0
  245. package/package.json +5 -2
  246. package/src/CLAUDE.md +32 -0
  247. package/src/avatar/createAvatarText.tsx +10 -1
  248. package/src/button/createButtonText.tsx +1 -0
  249. package/src/checkbox/createCheckboxRoot.web.tsx +6 -2
  250. package/src/chip/createChipRoot.tsx +144 -0
  251. package/src/chip/index.ts +18 -0
  252. package/src/chip/types.ts +23 -0
  253. package/src/field/createFieldLabel.tsx +4 -1
  254. package/src/index.ts +4 -0
  255. package/src/input/createInputField.tsx +6 -0
  256. package/src/list-item/context.tsx +5 -0
  257. package/src/list-item/createListItemContent.tsx +23 -0
  258. package/src/list-item/createListItemDescription.tsx +19 -0
  259. package/src/list-item/createListItemLeadingSlot.tsx +30 -0
  260. package/src/list-item/createListItemMeta.tsx +17 -0
  261. package/src/list-item/createListItemRoot.tsx +178 -0
  262. package/src/list-item/createListItemSectionHeader.tsx +53 -0
  263. package/src/list-item/createListItemTitle.tsx +17 -0
  264. package/src/list-item/createListItemTrailingSlot.tsx +21 -0
  265. package/src/list-item/index.ts +88 -0
  266. package/src/list-item/types.ts +122 -0
  267. package/src/radio/context.tsx +21 -0
  268. package/src/radio/createRadioGroup.tsx +67 -0
  269. package/src/radio/createRadioIndicator.tsx +32 -0
  270. package/src/radio/createRadioLabel.tsx +28 -0
  271. package/src/radio/createRadioRoot.tsx +100 -0
  272. package/src/radio/createRadioRoot.web.tsx +81 -0
  273. package/src/radio/index.ts +37 -0
  274. package/src/radio/types.ts +67 -0
  275. package/src/radio/useRadioRoot.ts +69 -0
  276. package/src/select/createSelectTrigger.tsx +26 -3
  277. package/src/tile/context.tsx +23 -0
  278. package/src/tile/createTileContent.tsx +23 -0
  279. package/src/tile/createTileDescription.tsx +19 -0
  280. package/src/tile/createTileGroup.tsx +134 -0
  281. package/src/tile/createTileIndicator.tsx +38 -0
  282. package/src/tile/createTileLeadingSlot.tsx +30 -0
  283. package/src/tile/createTileRoot.tsx +124 -0
  284. package/src/tile/createTileTitle.tsx +19 -0
  285. package/src/tile/createTileTrailingSlot.tsx +25 -0
  286. package/src/tile/index.ts +88 -0
  287. package/src/tile/types.ts +153 -0
@@ -0,0 +1,9 @@
1
+ import type { ITileContextValue, ITileGroupContextValue } from './types';
2
+ export declare const TileProvider: import("react").FunctionComponent<{
3
+ children: import("react").ReactNode;
4
+ value: ITileContextValue;
5
+ }>, useTileContext: () => ITileContextValue;
6
+ export declare const TileGroupContextProvider: import("react").Provider<ITileGroupContextValue | null>;
7
+ export declare function useTileGroupContext(): ITileGroupContextValue;
8
+ export declare function useOptionalTileGroupContext(): ITileGroupContextValue | null;
9
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/tile/context.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAGzE,eAAO,MAAO,YAAY;;;IAAE,cAAc,yBAAmD,CAAC;AAK9F,eAAO,MAAM,wBAAwB,yDAA4B,CAAC;AAElE,wBAAgB,mBAAmB,IAAI,sBAAsB,CAM5D;AAED,wBAAgB,2BAA2B,IAAI,sBAAsB,GAAG,IAAI,CAE3E"}
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ export declare const createTileContent: <T>(Base: React.ComponentType<T>) => React.ForwardRefExoticComponent<import("react-native").ViewProps & React.RefAttributes<unknown>>;
3
+ //# sourceMappingURL=createTileContent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createTileContent.d.ts","sourceRoot":"","sources":["../../../src/tile/createTileContent.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAU1C,eAAO,MAAM,iBAAiB,GAAI,CAAC,EAAG,MAAM,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,qGAY9D,CAAC"}
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ export declare const createTileDescription: <T>(Base: React.ComponentType<T>) => React.ForwardRefExoticComponent<import("react-native").TextProps & React.RefAttributes<unknown>>;
3
+ //# sourceMappingURL=createTileDescription.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createTileDescription.d.ts","sourceRoot":"","sources":["../../../src/tile/createTileDescription.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAM1C,eAAO,MAAM,qBAAqB,GAAI,CAAC,EAAG,MAAM,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,qGAYlE,CAAC"}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { ITileGroupProps } from './types';
3
+ export declare const createTileGroup: <T>(Base: React.ComponentType<T>) => React.ForwardRefExoticComponent<ITileGroupProps & React.RefAttributes<T>>;
4
+ //# sourceMappingURL=createTileGroup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createTileGroup.d.ts","sourceRoot":"","sources":["../../../src/tile/createTileGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqD,MAAM,OAAO,CAAC;AAK1E,OAAO,KAAK,EAAE,eAAe,EAAiB,MAAM,SAAS,CAAC;AAgB9D,eAAO,MAAM,eAAe,GAAI,CAAC,EAAG,MAAM,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,8EAgH5D,CAAC"}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { ITileIndicatorProps } from './types';
3
+ export declare const createTileIndicator: <T>(Base: React.ComponentType<T>) => React.ForwardRefExoticComponent<ITileIndicatorProps & React.RefAttributes<unknown>>;
4
+ //# sourceMappingURL=createTileIndicator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createTileIndicator.d.ts","sourceRoot":"","sources":["../../../src/tile/createTileIndicator.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAG1C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAInD,eAAO,MAAM,mBAAmB,GAAI,CAAC,EAAG,MAAM,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,wFA8BjE,CAAC"}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { ITileLeadingSlotProps } from './types';
3
+ export declare const createTileLeadingSlot: <T>(Base: React.ComponentType<T>) => React.ForwardRefExoticComponent<ITileLeadingSlotProps & React.RefAttributes<unknown>>;
4
+ //# sourceMappingURL=createTileLeadingSlot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createTileLeadingSlot.d.ts","sourceRoot":"","sources":["../../../src/tile/createTileLeadingSlot.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAE1C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAIrD,eAAO,MAAM,qBAAqB,GAAI,CAAC,EAAG,MAAM,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,0FAuBnE,CAAC"}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { ITileProps } from './types';
3
+ export declare const createTileRoot: <T>(BasePressable: React.ComponentType<T>) => React.ForwardRefExoticComponent<ITileProps & React.RefAttributes<unknown>>;
4
+ //# sourceMappingURL=createTileRoot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createTileRoot.d.ts","sourceRoot":"","sources":["../../../src/tile/createTileRoot.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAMnD,OAAO,KAAK,EAAE,UAAU,EAA6B,MAAM,SAAS,CAAC;AAQrE,eAAO,MAAM,cAAc,GAAI,CAAC,EAAG,eAAe,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,+EA6GpE,CAAC"}
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ export declare const createTileTitle: <T>(Base: React.ComponentType<T>) => React.ForwardRefExoticComponent<import("react-native").TextProps & React.RefAttributes<unknown>>;
3
+ //# sourceMappingURL=createTileTitle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createTileTitle.d.ts","sourceRoot":"","sources":["../../../src/tile/createTileTitle.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAM1C,eAAO,MAAM,eAAe,GAAI,CAAC,EAAG,MAAM,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,qGAY5D,CAAC"}
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ /**
3
+ * Generic trailing content (chevron, amount, chip, status). Distinct from `Tile.Indicator`,
4
+ * which is purpose-built for the radio/checkbox selection affordance.
5
+ *
6
+ * Trailing content is meaningful by default (`aria-hidden` falsy), unlike the indicator.
7
+ */
8
+ export declare const createTileTrailingSlot: <T>(Base: React.ComponentType<T>) => React.ForwardRefExoticComponent<import("react-native").ViewProps & React.RefAttributes<unknown>>;
9
+ //# sourceMappingURL=createTileTrailingSlot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createTileTrailingSlot.d.ts","sourceRoot":"","sources":["../../../src/tile/createTileTrailingSlot.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAM1C;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GAAI,CAAC,EAAG,MAAM,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,qGAYnE,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type React from 'react';
2
+ import type { ITileComponentType } from './types';
3
+ export type { ITileComponentType, ITileContentProps, ITileContextValue, ITileDescriptionProps, ITileGroupMultipleProps, ITileGroupProps, ITileGroupSingleProps, ITileGroupContextValue, ITileIndicatorProps, ITileLeadingSlotProps, ITilePressablePassthrough, ITileProps, ITileTitleProps, ITileTrailingSlotProps, TileGroupType, TileGroupValue, } from './types';
4
+ export { TileProvider, useTileContext } from './context';
5
+ export declare function createTile<Pressable, Leading, Content, Title, Description, Indicator, TrailingSlot, Group>(BaseComponents: {
6
+ Pressable: React.ComponentType<Pressable>;
7
+ LeadingSlot: React.ComponentType<Leading>;
8
+ Content: React.ComponentType<Content>;
9
+ Title: React.ComponentType<Title>;
10
+ Description: React.ComponentType<Description>;
11
+ Indicator: React.ComponentType<Indicator>;
12
+ TrailingSlot: React.ComponentType<TrailingSlot>;
13
+ Group: React.ComponentType<Group>;
14
+ }): ITileComponentType<Pressable, Leading, Content, Title, Description, Indicator, TrailingSlot, Group>;
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tile/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,qBAAqB,EACrB,yBAAyB,EACzB,UAAU,EACV,eAAe,EACf,sBAAsB,EACtB,aAAa,EACb,cAAc,GACf,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEzD,wBAAgB,UAAU,CACxB,SAAS,EACT,OAAO,EACP,OAAO,EACP,KAAK,EACL,WAAW,EACX,SAAS,EACT,YAAY,EACZ,KAAK,EACL,cAAc,EAAE;IAChB,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAC1C,WAAW,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC1C,OAAO,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACtC,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAClC,WAAW,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IAC9C,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAC1C,YAAY,EAAE,KAAK,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IAChD,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;CACnC,GA2BO,kBAAkB,CACtB,SAAS,EACT,OAAO,EACP,OAAO,EACP,KAAK,EACL,WAAW,EACX,SAAS,EACT,YAAY,EACZ,KAAK,CACN,CACF"}
@@ -0,0 +1,119 @@
1
+ import type { ForwardRefExoticComponent, PropsWithoutRef, ReactNode, RefAttributes } from 'react';
2
+ import type { PressableProps, TextProps, ViewProps } from 'react-native';
3
+ import type { WithStyleContextProps } from '@cdx-ui/utils';
4
+ export type TileGroupType = 'single' | 'multiple';
5
+ export type TileGroupValue = string | string[] | undefined;
6
+ interface ITileGroupBaseProps extends ViewProps, WithStyleContextProps {
7
+ /** Disables the whole group. */
8
+ isDisabled?: boolean;
9
+ /** Accessible name for the group (radiogroup / group). */
10
+ 'aria-label'?: string;
11
+ }
12
+ export interface ITileGroupSingleProps extends ITileGroupBaseProps {
13
+ /** Single-select (radio semantics). One value at a time. */
14
+ type: 'single';
15
+ /** Controlled selected value. */
16
+ value?: string;
17
+ /** Uncontrolled initial value. */
18
+ defaultValue?: string;
19
+ /** Called when selection changes. */
20
+ onValueChange?: (value: string) => void;
21
+ }
22
+ export interface ITileGroupMultipleProps extends ITileGroupBaseProps {
23
+ /** Multi-select (checkbox semantics). Zero to `max` values at a time. */
24
+ type: 'multiple';
25
+ /** Controlled selected values. */
26
+ value?: string[];
27
+ /** Uncontrolled initial values. */
28
+ defaultValue?: string[];
29
+ /** Called when selection changes. */
30
+ onValueChange?: (value: string[]) => void;
31
+ /** Maximum selections allowed. @default Infinity */
32
+ max?: number;
33
+ }
34
+ /**
35
+ * Discriminated union: `type` narrows `value` / `defaultValue` / `onValueChange`,
36
+ * and `max` is only valid on `type="multiple"`.
37
+ */
38
+ export type ITileGroupProps = ITileGroupSingleProps | ITileGroupMultipleProps;
39
+ export interface ITileGroupContextValue {
40
+ type: TileGroupType;
41
+ /** Current selection (string for single, array for multiple). */
42
+ value: string | string[] | undefined;
43
+ toggleValue: (tileValue: string) => void;
44
+ isSelected: (tileValue: string) => boolean;
45
+ /** Group-level disabled or multi-select at max (unselected tiles). */
46
+ isTileDisabledByGroup: (tileValue: string) => boolean;
47
+ isGroupDisabled: boolean;
48
+ max: number;
49
+ }
50
+ export interface ITileContextValue {
51
+ /** This tile's `value`. */
52
+ value: string;
53
+ isSelected: boolean;
54
+ /** Effective disabled (group rules + tile `disabled`). */
55
+ isDisabled: boolean;
56
+ selectionType: TileGroupType;
57
+ }
58
+ export type ITilePressablePassthrough = Partial<Pick<PressableProps, 'onPressIn' | 'onPressOut' | 'onHoverIn' | 'onHoverOut'>>;
59
+ export interface ITileProps extends PressableProps, ITilePressablePassthrough, WithStyleContextProps {
60
+ /**
61
+ * Identifies this tile within `Tile.Group`. Must be unique within the group.
62
+ * Standalone tiles still require a value (useful for form submission, analytics, etc.).
63
+ */
64
+ value: string;
65
+ /**
66
+ * Disables this tile (in addition to group rules such as multi-select max).
67
+ */
68
+ disabled?: boolean;
69
+ /**
70
+ * Controlled selected state for **standalone** usage (no parent `Tile.Group`).
71
+ * Ignored when the tile is rendered inside a `Tile.Group` — selection is owned by the group.
72
+ */
73
+ isSelected?: boolean;
74
+ /**
75
+ * Initial selected state for **standalone**, uncontrolled usage.
76
+ */
77
+ defaultSelected?: boolean;
78
+ /**
79
+ * Called when standalone selection state changes. Group context overrides this — when inside
80
+ * a `Tile.Group`, use the group's `onValueChange` instead.
81
+ */
82
+ onSelectedChange?: (isSelected: boolean) => void;
83
+ }
84
+ export interface ITileLeadingSlotProps extends ViewProps {
85
+ /**
86
+ * Leading content is decorative by default for screen readers.
87
+ * @default true
88
+ */
89
+ 'aria-hidden'?: boolean;
90
+ }
91
+ export type ITileContentProps = ViewProps;
92
+ export type ITileTitleProps = TextProps;
93
+ export type ITileDescriptionProps = TextProps;
94
+ export interface ITileIndicatorProps extends ViewProps {
95
+ /**
96
+ * Explicit indicator visual. When inside a `Tile.Group`, auto-infers from `type`
97
+ * (`single` → radio, `multiple` → checkbox). For standalone tiles, defaults to `'checkbox'`
98
+ * to match the standalone `checkbox` ARIA role; override with `indicatorType="radio"` if
99
+ * a radio-style visual is needed.
100
+ */
101
+ indicatorType?: 'radio' | 'checkbox';
102
+ children?: ReactNode;
103
+ }
104
+ /**
105
+ * Generic trailing content slot. Use for chevrons, amounts, chips, status text — anything that
106
+ * is **not** the radio/checkbox selection affordance. For that, use `Tile.Indicator`.
107
+ */
108
+ export type ITileTrailingSlotProps = ViewProps;
109
+ export type ITileComponentType<RootRef, LeadingSlot, Content, Title, Description, Indicator, TrailingSlot, Group> = ForwardRefExoticComponent<RefAttributes<RootRef> & ITileProps> & {
110
+ Group: ForwardRefExoticComponent<RefAttributes<Group> & PropsWithoutRef<Group> & ITileGroupProps>;
111
+ LeadingSlot: ForwardRefExoticComponent<RefAttributes<LeadingSlot> & PropsWithoutRef<LeadingSlot> & ITileLeadingSlotProps>;
112
+ Content: ForwardRefExoticComponent<RefAttributes<Content> & PropsWithoutRef<Content> & ITileContentProps>;
113
+ Title: ForwardRefExoticComponent<RefAttributes<Title> & PropsWithoutRef<Title> & ITileTitleProps>;
114
+ Description: ForwardRefExoticComponent<RefAttributes<Description> & PropsWithoutRef<Description> & ITileDescriptionProps>;
115
+ Indicator: ForwardRefExoticComponent<RefAttributes<Indicator> & PropsWithoutRef<Indicator> & ITileIndicatorProps>;
116
+ TrailingSlot: ForwardRefExoticComponent<RefAttributes<TrailingSlot> & PropsWithoutRef<TrailingSlot> & ITileTrailingSlotProps>;
117
+ };
118
+ export {};
119
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/tile/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cdx-ui/primitives",
3
- "version": "0.0.1-beta.4",
3
+ "version": "0.0.1-beta.41",
4
4
  "main": "lib/commonjs/index.js",
5
5
  "module": "lib/module/index.js",
6
6
  "react-native": "src/index.ts",
@@ -51,13 +51,16 @@
51
51
  }
52
52
  },
53
53
  "dependencies": {
54
+ "@react-aria/utils": "^3.33.0",
54
55
  "@react-aria/visually-hidden": "3.8.30",
55
56
  "@react-native-aria/checkbox": "0.2.10",
56
57
  "@react-native-aria/focus": "^0.2.9",
57
58
  "@react-native-aria/interactions": "^0.2.16",
59
+ "@react-native-aria/radio": "0.2.13",
58
60
  "@react-stately/checkbox": "3.7.4",
61
+ "@react-stately/radio": "3.12.0",
59
62
  "@react-stately/toggle": "3.9.4",
60
- "@cdx-ui/utils": "0.0.1-beta.4"
63
+ "@cdx-ui/utils": "0.0.1-beta.41"
61
64
  },
62
65
  "devDependencies": {
63
66
  "@types/react": "*",
package/src/CLAUDE.md ADDED
@@ -0,0 +1,32 @@
1
+ # Primitive Authoring
2
+
3
+ Auto-loaded when working in `packages/primitives/src/**`.
4
+
5
+ Primitives in `@cdx-ui/primitives` are unstyled behavioral components that handle accessibility and interactions. Read the full guides before making changes:
6
+
7
+ - `docs/internal/practices/composition.md` — compound component structure
8
+ - `docs/internal/practices/types.md` — `I*Props` convention, extending RN base types
9
+ - `docs/internal/practices/accessibility.md` — ARIA roles, keyboard nav, screen reader support
10
+ - `docs/internal/practices/as-child.md` — `asChild` prop pattern
11
+
12
+ ## Pattern summary
13
+
14
+ Each primitive follows the factory function pattern (see `createButtonRoot.tsx` as the canonical example):
15
+
16
+ 1. **Factory function** — `export const createComponentPart = <T,>(BaseComponent: ComponentType<T>) => forwardRef(...)` — accepts a host element type, returns a wrapped component with behavior
17
+ 2. **Interaction hooks** — `useFocus`, `useFocusRing`, `useHover`, `usePress` from `@react-native-aria/*`
18
+ 3. **Data attributes** — `dataAttributes({ hover, focus, active, disabled, focusVisible })` emitted on the rendered element for Uniwind `data-[state]` selectors
19
+ 4. **Context provider** — interaction state exposed via context so child primitives can react to parent state
20
+ 5. **Barrel export** — `index.tsx` re-exports the factory, context, and types
21
+
22
+ ## Key rules
23
+
24
+ - **Unstyled** — no visual styling (no `className`, no color/spacing classes). Only behavioral and a11y concerns.
25
+ - **`I*Props` convention** — interface types prefixed with `I` (e.g., `IButtonProps`, `ICheckboxProps`), exported from `types.ts`
26
+ - **`InterfaceComponentProps`** extends the appropriate RN base type (`PressableProps`, `ViewProps`, etc.) with interaction state booleans (`isHovered`, `isActive`, `isFocused`, `isFocusVisible`, `isDisabled`)
27
+ - **`dataAttributes()` helper** — always use the helper from `../utils/dataAttributes` to emit `data-*` props; it handles platform differences (native vs web)
28
+ - **`composeEventHandlers`** from `@cdx-ui/utils` — merge consumer handlers with internal handlers; never silently override
29
+ - **`forwardRef`** on every component — refs forwarded to the underlying host element
30
+ - **ARIA roles** — set `role` with a sensible default (e.g., `role={props?.role || 'button'}`)
31
+ - **Render children as function** — support `children` as `(state: InteractionState) => ReactNode` for state-driven rendering
32
+ - **Consumable independently** of `@cdx-ui/components` — no imports from the styled layer
@@ -4,7 +4,16 @@ import { useAvatarContext } from './context';
4
4
  import type { IAvatarTextProps } from './types';
5
5
 
6
6
  function getInitials(name: string): string {
7
- const words = name.trim().split(/\s+/);
7
+ const trimmed = name.trim();
8
+ const words = trimmed.split(/\s+/);
9
+
10
+ // Pre-composed initials (e.g. "JD", "AB") — single token, at most 2 chars.
11
+ // Figma Code Connect surfaces the raw text property which is already initials;
12
+ // passing them through a derivation step would truncate to the first letter.
13
+ if (words.length === 1 && trimmed.length <= 2) {
14
+ return trimmed.toUpperCase();
15
+ }
16
+
8
17
  let result = '';
9
18
  for (const word of words) {
10
19
  if (word.length > 0) {
@@ -5,6 +5,7 @@ import { useButtonContext } from './context';
5
5
  import type { IButtonTextProps } from './types';
6
6
 
7
7
  // TODO: Rename to ButtonLabel
8
+ // TODO: Can we remove the dataAttributes here?
8
9
 
9
10
  export const createButtonText = <T,>(BaseButtonText: React.ComponentType<T>) =>
10
11
  forwardRef<unknown, IButtonTextProps>(({ children, ...props }, ref) => {
@@ -6,8 +6,10 @@ import { CheckboxProvider } from './context';
6
6
  import type { ICheckboxProps } from './types';
7
7
  import { useCheckboxRoot } from './useCheckboxRoot';
8
8
 
9
- // TODO: Label is taking focus on keyboard navigation
10
-
9
+ /**
10
+ * Web uses a native checkbox input (VisuallyHidden) for ARIA + focus management. The outer
11
+ * `Pressable` must not be in the tab order or each control consumes two Tab stops (wrapper + input).
12
+ */
11
13
  export const createCheckboxRoot = <T,>(BaseCheckbox: React.ComponentType<T>) =>
12
14
  forwardRef(({ children, ...props }: ICheckboxProps, ref?: React.Ref<T>) => {
13
15
  const {
@@ -41,6 +43,8 @@ export const createCheckboxRoot = <T,>(BaseCheckbox: React.ComponentType<T>) =>
41
43
  <BaseCheckbox
42
44
  {...(combinedProps as T)}
43
45
  ref={mergedRef}
46
+ // Native input is the only tab stop; Pressable is still clickable (mouse / screen reader).
47
+ tabIndex={-1}
44
48
  role="label"
45
49
  // eslint-disable-next-line react-native-a11y/has-valid-accessibility-role
46
50
  accessibilityRole="label"
@@ -0,0 +1,144 @@
1
+ import React, { forwardRef } from 'react';
2
+ import type { PressableProps } from 'react-native';
3
+ import { composeEventHandlers, mergeRefs } from '@cdx-ui/utils';
4
+ import { useFocus, useFocusRing } from '@react-native-aria/focus';
5
+ import { useHover, usePress } from '@react-native-aria/interactions';
6
+ import { dataAttributes } from '../utils/dataAttributes';
7
+ import type { IChipPressablePassthrough, IChipProps } from './types';
8
+
9
+ const rowStyle = {
10
+ flexDirection: 'row' as const,
11
+ alignItems: 'center' as const,
12
+ alignSelf: 'flex-start' as const,
13
+ };
14
+
15
+ const chipSlotAttrs = dataAttributes({ slot: 'chip' });
16
+
17
+ export const createChipRoot = <V, P>(
18
+ BaseView: React.ComponentType<V>,
19
+ BasePressable: React.ComponentType<P>,
20
+ ) =>
21
+ forwardRef(
22
+ (
23
+ {
24
+ asChild = false,
25
+ children,
26
+ onPress,
27
+ disabled = false,
28
+ accessibilityRole,
29
+ style,
30
+ ...restProps
31
+ }: IChipProps,
32
+ ref: React.Ref<unknown>,
33
+ ) => {
34
+ const childOnPress = React.isValidElement(children)
35
+ ? ((children.props as { onPress?: unknown }).onPress as IChipProps['onPress'] | undefined)
36
+ : undefined;
37
+
38
+ const asChildInteractive = asChild && React.isValidElement(children);
39
+ const isPressableRoot = !!onPress && !asChildInteractive;
40
+
41
+ const pressState = usePress({
42
+ isDisabled: !isPressableRoot || disabled,
43
+ });
44
+ const isPressed = pressState.isPressed;
45
+ const pressProps = pressState.pressProps as Pick<PressableProps, 'onPressIn' | 'onPressOut'>;
46
+
47
+ const { hoverProps, isHovered } = useHover();
48
+ const { isFocused, focusProps } = useFocus();
49
+ const { isFocusVisible, focusProps: focusRingProps } = useFocusRing() as {
50
+ isFocusVisible: boolean;
51
+ focusProps: typeof focusProps;
52
+ };
53
+
54
+ if (asChildInteractive) {
55
+ const child = children as React.ReactElement<Record<string, unknown>>;
56
+
57
+ const childDisabled = !!(child.props as { disabled?: boolean }).disabled;
58
+ const resolvedDisabled = disabled || childDisabled;
59
+
60
+ const cloneProps: Record<string, unknown> = {
61
+ ...restProps,
62
+ ...chipSlotAttrs,
63
+ ...dataAttributes({
64
+ active: false,
65
+ hover: false,
66
+ disabled: resolvedDisabled,
67
+ focused: false,
68
+ focusVisible: false,
69
+ }),
70
+ ...(resolvedDisabled && { accessibilityState: { disabled: true } }),
71
+ disabled: resolvedDisabled,
72
+ ref: mergeRefs(ref, child.props.ref as React.Ref<unknown>),
73
+ style: [rowStyle, style, child.props.style],
74
+ };
75
+
76
+ if (resolvedDisabled) {
77
+ cloneProps.onPress = undefined;
78
+ } else if (onPress) {
79
+ cloneProps.onPress = composeEventHandlers(childOnPress, onPress);
80
+ }
81
+
82
+ return React.cloneElement(child, cloneProps);
83
+ }
84
+
85
+ if (isPressableRoot) {
86
+ const interactionAttrs = dataAttributes({
87
+ active: isPressed,
88
+ hover: isHovered,
89
+ disabled,
90
+ focused: isFocused,
91
+ focusVisible: isFocusVisible,
92
+ });
93
+
94
+ const {
95
+ onPressIn: onPressInProp,
96
+ onPressOut: onPressOutProp,
97
+ onHoverIn: onHoverInProp,
98
+ onHoverOut: onHoverOutProp,
99
+ onFocus: onFocusProp,
100
+ onBlur: onBlurProp,
101
+ } = restProps as IChipPressablePassthrough & Pick<PressableProps, 'onFocus' | 'onBlur'>;
102
+
103
+ return (
104
+ <BasePressable
105
+ {...(restProps as P)}
106
+ {...chipSlotAttrs}
107
+ {...interactionAttrs}
108
+ accessibilityRole={accessibilityRole ?? 'button'}
109
+ {...(disabled && { accessibilityState: { disabled: true } })}
110
+ disabled={disabled}
111
+ ref={ref as React.Ref<P>}
112
+ style={[rowStyle, style]}
113
+ onPress={disabled ? undefined : onPress}
114
+ onPressIn={composeEventHandlers(onPressInProp, pressProps.onPressIn)}
115
+ onPressOut={composeEventHandlers(onPressOutProp, pressProps.onPressOut)}
116
+ onHoverIn={composeEventHandlers(onHoverInProp, hoverProps.onHoverIn)}
117
+ onHoverOut={composeEventHandlers(onHoverOutProp, hoverProps.onHoverOut)}
118
+ onFocus={composeEventHandlers(
119
+ composeEventHandlers(onFocusProp, focusProps.onFocus),
120
+ focusRingProps.onFocus,
121
+ )}
122
+ onBlur={composeEventHandlers(
123
+ composeEventHandlers(onBlurProp, focusProps.onBlur),
124
+ focusRingProps.onBlur,
125
+ )}
126
+ >
127
+ {children}
128
+ </BasePressable>
129
+ );
130
+ }
131
+
132
+ return (
133
+ <BaseView
134
+ {...(restProps as V)}
135
+ {...chipSlotAttrs}
136
+ {...(disabled ? dataAttributes({ disabled: true }) : undefined)}
137
+ ref={ref as React.Ref<V>}
138
+ style={[rowStyle, style]}
139
+ >
140
+ {children}
141
+ </BaseView>
142
+ );
143
+ },
144
+ );
@@ -0,0 +1,18 @@
1
+ import type React from 'react';
2
+ import type { PressableProps, ViewProps } from 'react-native';
3
+ import { createChipRoot } from './createChipRoot';
4
+ import type { IChipComponentType } from './types';
5
+
6
+ export type { IChipComponentType, IChipPressablePassthrough, IChipProps } from './types';
7
+
8
+ export function createChip({
9
+ View,
10
+ Pressable,
11
+ }: {
12
+ View: React.ComponentType<ViewProps>;
13
+ Pressable: React.ComponentType<PressableProps>;
14
+ }) {
15
+ const Chip = createChipRoot(View, Pressable);
16
+ Chip.displayName = 'ChipPrimitive';
17
+ return Chip as IChipComponentType<ViewProps | PressableProps>;
18
+ }
@@ -0,0 +1,23 @@
1
+ import type { ForwardRefExoticComponent, RefAttributes } from 'react';
2
+ import type { PressableProps, ViewProps } from 'react-native';
3
+
4
+ export type IChipPressablePassthrough = Partial<
5
+ Pick<PressableProps, 'onPressIn' | 'onPressOut' | 'onHoverIn' | 'onHoverOut'>
6
+ >;
7
+
8
+ export interface IChipProps extends ViewProps, IChipPressablePassthrough {
9
+ /**
10
+ * When set (and `asChild` is not used with a valid element), root renders as pressable.
11
+ */
12
+ onPress?: PressableProps['onPress'];
13
+ /** Disables press handling when the root is pressable. */
14
+ disabled?: boolean;
15
+ /**
16
+ * Merge slot + interaction props onto a single child instead of rendering the default pressable root.
17
+ */
18
+ asChild?: boolean;
19
+ }
20
+
21
+ export type IChipComponentType<RootRef> = ForwardRefExoticComponent<
22
+ RefAttributes<RootRef> & IChipProps
23
+ >;
@@ -20,7 +20,10 @@ export const createFieldLabel = <T,>(BaseFormLabel: React.ComponentType<T>) =>
20
20
  {...(props as T)}
21
21
  id={labelId}
22
22
  htmlFor={htmlFor}
23
- {...dataAttributes({ invalid: field.isInvalid, required: field.isRequired })}
23
+ {...dataAttributes({
24
+ invalid: field.isInvalid,
25
+ required: field.isRequired,
26
+ })}
24
27
  >
25
28
  {children}
26
29
  {field.isRequired ? requiredIndicator : null}
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './avatar';
2
2
  export * from './button';
3
+ export * from './chip';
3
4
  export * from './checkbox';
4
5
  export * from './dialog';
5
6
  export * from './field';
@@ -7,9 +8,12 @@ export * from './form';
7
8
  export * from './input';
8
9
  export * from './otp-input';
9
10
  export * from './link';
11
+ export * from './list-item';
10
12
  export { type EdgeInsets, OverlayInsetsProvider } from './overlay';
11
13
  export * from './select';
12
14
  export * from './switch';
15
+ export * from './tile';
13
16
  export * from './progress';
17
+ export * from './radio';
14
18
  export type { InteractionState } from './types';
15
19
  export { dataAttributes } from './utils/dataAttributes';
@@ -49,8 +49,14 @@ export const createInputField = <T,>(BaseInputField: React.ComponentType<T>) =>
49
49
 
50
50
  const field = useFormControlContext();
51
51
 
52
+ const reportLabelFocus = (focused: boolean) => {
53
+ const active = focused && !(isDisabled || inputProps.disabled);
54
+ field.setIsLabelFocused?.(active);
55
+ };
56
+
52
57
  const handleFocus = (focusState: boolean, callback: any) => {
53
58
  setIsFocused(focusState);
59
+ reportLabelFocus(focusState);
54
60
  callback();
55
61
  };
56
62
 
@@ -0,0 +1,5 @@
1
+ import { createContext } from '@cdx-ui/utils';
2
+ import type { IListItemContextValue } from './types';
3
+
4
+ export const [ListItemProvider, useListItemContext] =
5
+ createContext<IListItemContextValue>('ListItemContext');
@@ -0,0 +1,23 @@
1
+ import React, { forwardRef } from 'react';
2
+ import { dataAttributes } from '../utils/dataAttributes';
3
+ import type { IListItemContentProps } from './types';
4
+
5
+ const contentStyle = {
6
+ flex: 1,
7
+ flexDirection: 'column' as const,
8
+ minWidth: 0,
9
+ };
10
+
11
+ export const createListItemContent = <T,>(Base: React.ComponentType<T>) =>
12
+ forwardRef(({ children, style, ...props }: IListItemContentProps, ref: React.Ref<unknown>) => (
13
+ <Base
14
+ {...(props as T)}
15
+ {...dataAttributes({
16
+ slot: 'list-item-content',
17
+ })}
18
+ ref={ref as React.Ref<T>}
19
+ style={[contentStyle, style]}
20
+ >
21
+ {children}
22
+ </Base>
23
+ ));