@cdx-ui/primitives 0.1.7 → 0.2.1

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 (321) hide show
  1. package/lib/commonjs/calendar/CalendarRoot.js +3 -1
  2. package/lib/commonjs/calendar/CalendarRoot.js.map +1 -1
  3. package/lib/commonjs/calendar/context.js.map +1 -1
  4. package/lib/commonjs/color/Color.js +69 -0
  5. package/lib/commonjs/color/Color.js.map +1 -0
  6. package/lib/commonjs/color/index.js +13 -0
  7. package/lib/commonjs/color/index.js.map +1 -0
  8. package/lib/commonjs/color/types.js +2 -0
  9. package/lib/commonjs/color/types.js.map +1 -0
  10. package/lib/commonjs/color-area/ColorAreaAccessibility.js +100 -0
  11. package/lib/commonjs/color-area/ColorAreaAccessibility.js.map +1 -0
  12. package/lib/commonjs/color-area/ColorAreaAccessibility.web.js +58 -0
  13. package/lib/commonjs/color-area/ColorAreaAccessibility.web.js.map +1 -0
  14. package/lib/commonjs/color-area/ColorAreaRoot.js +240 -0
  15. package/lib/commonjs/color-area/ColorAreaRoot.js.map +1 -0
  16. package/lib/commonjs/color-area/ColorAreaThumb.js +71 -0
  17. package/lib/commonjs/color-area/ColorAreaThumb.js.map +1 -0
  18. package/lib/commonjs/color-area/context.js +11 -0
  19. package/lib/commonjs/color-area/context.js.map +1 -0
  20. package/lib/commonjs/color-area/index.js +27 -0
  21. package/lib/commonjs/color-area/index.js.map +1 -0
  22. package/lib/commonjs/color-area/types.js +6 -0
  23. package/lib/commonjs/color-area/types.js.map +1 -0
  24. package/lib/commonjs/color-area/utils.js +51 -0
  25. package/lib/commonjs/color-area/utils.js.map +1 -0
  26. package/lib/commonjs/color-field/ColorFieldInput.js +67 -0
  27. package/lib/commonjs/color-field/ColorFieldInput.js.map +1 -0
  28. package/lib/commonjs/color-field/ColorFieldRoot.js +104 -0
  29. package/lib/commonjs/color-field/ColorFieldRoot.js.map +1 -0
  30. package/lib/commonjs/color-field/context.js +11 -0
  31. package/lib/commonjs/color-field/context.js.map +1 -0
  32. package/lib/commonjs/color-field/index.js +27 -0
  33. package/lib/commonjs/color-field/index.js.map +1 -0
  34. package/lib/commonjs/color-field/types.js +6 -0
  35. package/lib/commonjs/color-field/types.js.map +1 -0
  36. package/lib/commonjs/color-field/utils.js +60 -0
  37. package/lib/commonjs/color-field/utils.js.map +1 -0
  38. package/lib/commonjs/color-picker/ColorPickerRoot.js +69 -0
  39. package/lib/commonjs/color-picker/ColorPickerRoot.js.map +1 -0
  40. package/lib/commonjs/color-picker/ColorPickerTrigger.js +98 -0
  41. package/lib/commonjs/color-picker/ColorPickerTrigger.js.map +1 -0
  42. package/lib/commonjs/color-picker/context.js +32 -0
  43. package/lib/commonjs/color-picker/context.js.map +1 -0
  44. package/lib/commonjs/color-picker/index.js +51 -0
  45. package/lib/commonjs/color-picker/index.js.map +1 -0
  46. package/lib/commonjs/color-picker/types.js +6 -0
  47. package/lib/commonjs/color-picker/types.js.map +1 -0
  48. package/lib/commonjs/color-slider/ColorSliderRail.js +119 -0
  49. package/lib/commonjs/color-slider/ColorSliderRail.js.map +1 -0
  50. package/lib/commonjs/color-slider/ColorSliderRoot.js +153 -0
  51. package/lib/commonjs/color-slider/ColorSliderRoot.js.map +1 -0
  52. package/lib/commonjs/color-slider/ColorSliderThumb.js +265 -0
  53. package/lib/commonjs/color-slider/ColorSliderThumb.js.map +1 -0
  54. package/lib/commonjs/color-slider/context.js +11 -0
  55. package/lib/commonjs/color-slider/context.js.map +1 -0
  56. package/lib/commonjs/color-slider/index.js +34 -0
  57. package/lib/commonjs/color-slider/index.js.map +1 -0
  58. package/lib/commonjs/color-slider/types.js +6 -0
  59. package/lib/commonjs/color-slider/types.js.map +1 -0
  60. package/lib/commonjs/color-slider/utils.js +75 -0
  61. package/lib/commonjs/color-slider/utils.js.map +1 -0
  62. package/lib/commonjs/color-swatch-picker/ColorSwatchPickerItem.js +46 -0
  63. package/lib/commonjs/color-swatch-picker/ColorSwatchPickerItem.js.map +1 -0
  64. package/lib/commonjs/color-swatch-picker/ColorSwatchPickerRoot.js +71 -0
  65. package/lib/commonjs/color-swatch-picker/ColorSwatchPickerRoot.js.map +1 -0
  66. package/lib/commonjs/color-swatch-picker/context.js +22 -0
  67. package/lib/commonjs/color-swatch-picker/context.js.map +1 -0
  68. package/lib/commonjs/color-swatch-picker/index.js +33 -0
  69. package/lib/commonjs/color-swatch-picker/index.js.map +1 -0
  70. package/lib/commonjs/color-swatch-picker/types.js +6 -0
  71. package/lib/commonjs/color-swatch-picker/types.js.map +1 -0
  72. package/lib/commonjs/date-field/DateFieldRoot.js +5 -1
  73. package/lib/commonjs/date-field/DateFieldRoot.js.map +1 -1
  74. package/lib/commonjs/date-field/DateFieldSegment.js +7 -1
  75. package/lib/commonjs/date-field/DateFieldSegment.js.map +1 -1
  76. package/lib/commonjs/date-field/context.js.map +1 -1
  77. package/lib/commonjs/date-picker/DatePickerRoot.js +59 -13
  78. package/lib/commonjs/date-picker/DatePickerRoot.js.map +1 -1
  79. package/lib/commonjs/date-picker/context.js.map +1 -1
  80. package/lib/commonjs/index.js +80 -0
  81. package/lib/commonjs/index.js.map +1 -1
  82. package/lib/commonjs/react-native-web.d.js +2 -0
  83. package/lib/commonjs/react-native-web.d.js.map +1 -0
  84. package/lib/commonjs/slider/useSliderPointer.js +2 -0
  85. package/lib/commonjs/slider/useSliderPointer.js.map +1 -1
  86. package/lib/commonjs/utils/createPortal.web.js +10 -1
  87. package/lib/commonjs/utils/createPortal.web.js.map +1 -1
  88. package/lib/commonjs/utils/textAncestor.js +25 -0
  89. package/lib/commonjs/utils/textAncestor.js.map +1 -0
  90. package/lib/commonjs/utils/textAncestor.web.js +27 -0
  91. package/lib/commonjs/utils/textAncestor.web.js.map +1 -0
  92. package/lib/module/calendar/CalendarRoot.js +3 -1
  93. package/lib/module/calendar/CalendarRoot.js.map +1 -1
  94. package/lib/module/calendar/context.js.map +1 -1
  95. package/lib/module/color/Color.js +65 -0
  96. package/lib/module/color/Color.js.map +1 -0
  97. package/lib/module/color/index.js +4 -0
  98. package/lib/module/color/index.js.map +1 -0
  99. package/lib/module/color/types.js +2 -0
  100. package/lib/module/color/types.js.map +1 -0
  101. package/lib/module/color-area/ColorAreaAccessibility.js +96 -0
  102. package/lib/module/color-area/ColorAreaAccessibility.js.map +1 -0
  103. package/lib/module/color-area/ColorAreaAccessibility.web.js +54 -0
  104. package/lib/module/color-area/ColorAreaAccessibility.web.js.map +1 -0
  105. package/lib/module/color-area/ColorAreaRoot.js +236 -0
  106. package/lib/module/color-area/ColorAreaRoot.js.map +1 -0
  107. package/lib/module/color-area/ColorAreaThumb.js +67 -0
  108. package/lib/module/color-area/ColorAreaThumb.js.map +1 -0
  109. package/lib/module/color-area/context.js +5 -0
  110. package/lib/module/color-area/context.js.map +1 -0
  111. package/lib/module/color-area/index.js +6 -0
  112. package/lib/module/color-area/index.js.map +1 -0
  113. package/lib/module/color-area/types.js +4 -0
  114. package/lib/module/color-area/types.js.map +1 -0
  115. package/lib/module/color-area/utils.js +45 -0
  116. package/lib/module/color-area/utils.js.map +1 -0
  117. package/lib/module/color-field/ColorFieldInput.js +63 -0
  118. package/lib/module/color-field/ColorFieldInput.js.map +1 -0
  119. package/lib/module/color-field/ColorFieldRoot.js +100 -0
  120. package/lib/module/color-field/ColorFieldRoot.js.map +1 -0
  121. package/lib/module/color-field/context.js +5 -0
  122. package/lib/module/color-field/context.js.map +1 -0
  123. package/lib/module/color-field/index.js +6 -0
  124. package/lib/module/color-field/index.js.map +1 -0
  125. package/lib/module/color-field/types.js +4 -0
  126. package/lib/module/color-field/types.js.map +1 -0
  127. package/lib/module/color-field/utils.js +55 -0
  128. package/lib/module/color-field/utils.js.map +1 -0
  129. package/lib/module/color-picker/ColorPickerRoot.js +65 -0
  130. package/lib/module/color-picker/ColorPickerRoot.js.map +1 -0
  131. package/lib/module/color-picker/ColorPickerTrigger.js +94 -0
  132. package/lib/module/color-picker/ColorPickerTrigger.js.map +1 -0
  133. package/lib/module/color-picker/context.js +25 -0
  134. package/lib/module/color-picker/context.js.map +1 -0
  135. package/lib/module/color-picker/index.js +6 -0
  136. package/lib/module/color-picker/index.js.map +1 -0
  137. package/lib/module/color-picker/types.js +4 -0
  138. package/lib/module/color-picker/types.js.map +1 -0
  139. package/lib/module/color-slider/ColorSliderRail.js +115 -0
  140. package/lib/module/color-slider/ColorSliderRail.js.map +1 -0
  141. package/lib/module/color-slider/ColorSliderRoot.js +149 -0
  142. package/lib/module/color-slider/ColorSliderRoot.js.map +1 -0
  143. package/lib/module/color-slider/ColorSliderThumb.js +261 -0
  144. package/lib/module/color-slider/ColorSliderThumb.js.map +1 -0
  145. package/lib/module/color-slider/context.js +5 -0
  146. package/lib/module/color-slider/context.js.map +1 -0
  147. package/lib/module/color-slider/index.js +7 -0
  148. package/lib/module/color-slider/index.js.map +1 -0
  149. package/lib/module/color-slider/types.js +4 -0
  150. package/lib/module/color-slider/types.js.map +1 -0
  151. package/lib/module/color-slider/utils.js +66 -0
  152. package/lib/module/color-slider/utils.js.map +1 -0
  153. package/lib/module/color-swatch-picker/ColorSwatchPickerItem.js +42 -0
  154. package/lib/module/color-swatch-picker/ColorSwatchPickerItem.js.map +1 -0
  155. package/lib/module/color-swatch-picker/ColorSwatchPickerRoot.js +67 -0
  156. package/lib/module/color-swatch-picker/ColorSwatchPickerRoot.js.map +1 -0
  157. package/lib/module/color-swatch-picker/context.js +15 -0
  158. package/lib/module/color-swatch-picker/context.js.map +1 -0
  159. package/lib/module/color-swatch-picker/index.js +6 -0
  160. package/lib/module/color-swatch-picker/index.js.map +1 -0
  161. package/lib/module/color-swatch-picker/types.js +4 -0
  162. package/lib/module/color-swatch-picker/types.js.map +1 -0
  163. package/lib/module/date-field/DateFieldRoot.js +6 -2
  164. package/lib/module/date-field/DateFieldRoot.js.map +1 -1
  165. package/lib/module/date-field/DateFieldSegment.js +7 -1
  166. package/lib/module/date-field/DateFieldSegment.js.map +1 -1
  167. package/lib/module/date-field/context.js.map +1 -1
  168. package/lib/module/date-picker/DatePickerRoot.js +62 -16
  169. package/lib/module/date-picker/DatePickerRoot.js.map +1 -1
  170. package/lib/module/date-picker/context.js.map +1 -1
  171. package/lib/module/index.js +7 -0
  172. package/lib/module/index.js.map +1 -1
  173. package/lib/module/react-native-web.d.js +2 -0
  174. package/lib/module/react-native-web.d.js.map +1 -0
  175. package/lib/module/slider/useSliderPointer.js +2 -0
  176. package/lib/module/slider/useSliderPointer.js.map +1 -1
  177. package/lib/module/utils/createPortal.web.js +9 -1
  178. package/lib/module/utils/createPortal.web.js.map +1 -1
  179. package/lib/module/utils/textAncestor.js +20 -0
  180. package/lib/module/utils/textAncestor.js.map +1 -0
  181. package/lib/module/utils/textAncestor.web.js +22 -0
  182. package/lib/module/utils/textAncestor.web.js.map +1 -0
  183. package/lib/typescript/calendar/CalendarRoot.d.ts.map +1 -1
  184. package/lib/typescript/calendar/context.d.ts +1 -0
  185. package/lib/typescript/calendar/context.d.ts.map +1 -1
  186. package/lib/typescript/calendar/types.d.ts +7 -0
  187. package/lib/typescript/calendar/types.d.ts.map +1 -1
  188. package/lib/typescript/color/Color.d.ts +3 -0
  189. package/lib/typescript/color/Color.d.ts.map +1 -0
  190. package/lib/typescript/color/index.d.ts +3 -0
  191. package/lib/typescript/color/index.d.ts.map +1 -0
  192. package/lib/typescript/color/types.d.ts +13 -0
  193. package/lib/typescript/color/types.d.ts.map +1 -0
  194. package/lib/typescript/color-area/ColorAreaAccessibility.d.ts +8 -0
  195. package/lib/typescript/color-area/ColorAreaAccessibility.d.ts.map +1 -0
  196. package/lib/typescript/color-area/ColorAreaAccessibility.web.d.ts +8 -0
  197. package/lib/typescript/color-area/ColorAreaAccessibility.web.d.ts.map +1 -0
  198. package/lib/typescript/color-area/ColorAreaRoot.d.ts +7 -0
  199. package/lib/typescript/color-area/ColorAreaRoot.d.ts.map +1 -0
  200. package/lib/typescript/color-area/ColorAreaThumb.d.ts +6 -0
  201. package/lib/typescript/color-area/ColorAreaThumb.d.ts.map +1 -0
  202. package/lib/typescript/color-area/context.d.ts +6 -0
  203. package/lib/typescript/color-area/context.d.ts.map +1 -0
  204. package/lib/typescript/color-area/index.d.ts +5 -0
  205. package/lib/typescript/color-area/index.d.ts.map +1 -0
  206. package/lib/typescript/color-area/types.d.ts +65 -0
  207. package/lib/typescript/color-area/types.d.ts.map +1 -0
  208. package/lib/typescript/color-area/utils.d.ts +5 -0
  209. package/lib/typescript/color-area/utils.d.ts.map +1 -0
  210. package/lib/typescript/color-field/ColorFieldInput.d.ts +5 -0
  211. package/lib/typescript/color-field/ColorFieldInput.d.ts.map +1 -0
  212. package/lib/typescript/color-field/ColorFieldRoot.d.ts +7 -0
  213. package/lib/typescript/color-field/ColorFieldRoot.d.ts.map +1 -0
  214. package/lib/typescript/color-field/context.d.ts +6 -0
  215. package/lib/typescript/color-field/context.d.ts.map +1 -0
  216. package/lib/typescript/color-field/index.d.ts +7 -0
  217. package/lib/typescript/color-field/index.d.ts.map +1 -0
  218. package/lib/typescript/color-field/types.d.ts +39 -0
  219. package/lib/typescript/color-field/types.d.ts.map +1 -0
  220. package/lib/typescript/color-field/utils.d.ts +5 -0
  221. package/lib/typescript/color-field/utils.d.ts.map +1 -0
  222. package/lib/typescript/color-picker/ColorPickerRoot.d.ts +7 -0
  223. package/lib/typescript/color-picker/ColorPickerRoot.d.ts.map +1 -0
  224. package/lib/typescript/color-picker/ColorPickerTrigger.d.ts +4 -0
  225. package/lib/typescript/color-picker/ColorPickerTrigger.d.ts.map +1 -0
  226. package/lib/typescript/color-picker/context.d.ts +19 -0
  227. package/lib/typescript/color-picker/context.d.ts.map +1 -0
  228. package/lib/typescript/color-picker/index.d.ts +5 -0
  229. package/lib/typescript/color-picker/index.d.ts.map +1 -0
  230. package/lib/typescript/color-picker/types.d.ts +24 -0
  231. package/lib/typescript/color-picker/types.d.ts.map +1 -0
  232. package/lib/typescript/color-slider/ColorSliderRail.d.ts +6 -0
  233. package/lib/typescript/color-slider/ColorSliderRail.d.ts.map +1 -0
  234. package/lib/typescript/color-slider/ColorSliderRoot.d.ts +7 -0
  235. package/lib/typescript/color-slider/ColorSliderRoot.d.ts.map +1 -0
  236. package/lib/typescript/color-slider/ColorSliderThumb.d.ts +6 -0
  237. package/lib/typescript/color-slider/ColorSliderThumb.d.ts.map +1 -0
  238. package/lib/typescript/color-slider/context.d.ts +6 -0
  239. package/lib/typescript/color-slider/context.d.ts.map +1 -0
  240. package/lib/typescript/color-slider/index.d.ts +6 -0
  241. package/lib/typescript/color-slider/index.d.ts.map +1 -0
  242. package/lib/typescript/color-slider/types.d.ts +82 -0
  243. package/lib/typescript/color-slider/types.d.ts.map +1 -0
  244. package/lib/typescript/color-slider/utils.d.ts +12 -0
  245. package/lib/typescript/color-slider/utils.d.ts.map +1 -0
  246. package/lib/typescript/color-swatch-picker/ColorSwatchPickerItem.d.ts +6 -0
  247. package/lib/typescript/color-swatch-picker/ColorSwatchPickerItem.d.ts.map +1 -0
  248. package/lib/typescript/color-swatch-picker/ColorSwatchPickerRoot.d.ts +7 -0
  249. package/lib/typescript/color-swatch-picker/ColorSwatchPickerRoot.d.ts.map +1 -0
  250. package/lib/typescript/color-swatch-picker/context.d.ts +8 -0
  251. package/lib/typescript/color-swatch-picker/context.d.ts.map +1 -0
  252. package/lib/typescript/color-swatch-picker/index.d.ts +5 -0
  253. package/lib/typescript/color-swatch-picker/index.d.ts.map +1 -0
  254. package/lib/typescript/color-swatch-picker/types.d.ts +26 -0
  255. package/lib/typescript/color-swatch-picker/types.d.ts.map +1 -0
  256. package/lib/typescript/date-field/DateFieldRoot.d.ts.map +1 -1
  257. package/lib/typescript/date-field/DateFieldSegment.d.ts.map +1 -1
  258. package/lib/typescript/date-field/context.d.ts +2 -0
  259. package/lib/typescript/date-field/context.d.ts.map +1 -1
  260. package/lib/typescript/date-picker/DatePickerRoot.d.ts +29 -3
  261. package/lib/typescript/date-picker/DatePickerRoot.d.ts.map +1 -1
  262. package/lib/typescript/date-picker/context.d.ts +1 -0
  263. package/lib/typescript/date-picker/context.d.ts.map +1 -1
  264. package/lib/typescript/index.d.ts +7 -0
  265. package/lib/typescript/index.d.ts.map +1 -1
  266. package/lib/typescript/slider/useSliderPointer.d.ts.map +1 -1
  267. package/lib/typescript/utils/createPortal.web.d.ts +6 -2
  268. package/lib/typescript/utils/createPortal.web.d.ts.map +1 -1
  269. package/lib/typescript/utils/textAncestor.d.ts +13 -0
  270. package/lib/typescript/utils/textAncestor.d.ts.map +1 -0
  271. package/lib/typescript/utils/textAncestor.web.d.ts +15 -0
  272. package/lib/typescript/utils/textAncestor.web.d.ts.map +1 -0
  273. package/package.json +4 -3
  274. package/src/calendar/CalendarRoot.tsx +3 -0
  275. package/src/calendar/context.tsx +1 -0
  276. package/src/calendar/types.ts +7 -0
  277. package/src/color/Color.ts +95 -0
  278. package/src/color/index.ts +2 -0
  279. package/src/color/types.ts +19 -0
  280. package/src/color-area/ColorAreaAccessibility.tsx +94 -0
  281. package/src/color-area/ColorAreaAccessibility.web.tsx +52 -0
  282. package/src/color-area/ColorAreaRoot.tsx +326 -0
  283. package/src/color-area/ColorAreaThumb.tsx +56 -0
  284. package/src/color-area/context.tsx +5 -0
  285. package/src/color-area/index.ts +10 -0
  286. package/src/color-area/types.ts +69 -0
  287. package/src/color-area/utils.ts +51 -0
  288. package/src/color-field/ColorFieldInput.tsx +66 -0
  289. package/src/color-field/ColorFieldRoot.tsx +132 -0
  290. package/src/color-field/context.tsx +5 -0
  291. package/src/color-field/index.ts +11 -0
  292. package/src/color-field/types.ts +46 -0
  293. package/src/color-field/utils.ts +75 -0
  294. package/src/color-picker/ColorPickerRoot.tsx +91 -0
  295. package/src/color-picker/ColorPickerTrigger.tsx +96 -0
  296. package/src/color-picker/context.tsx +47 -0
  297. package/src/color-picker/index.ts +12 -0
  298. package/src/color-picker/types.ts +25 -0
  299. package/src/color-slider/ColorSliderRail.tsx +130 -0
  300. package/src/color-slider/ColorSliderRoot.tsx +222 -0
  301. package/src/color-slider/ColorSliderThumb.tsx +294 -0
  302. package/src/color-slider/context.tsx +5 -0
  303. package/src/color-slider/index.ts +16 -0
  304. package/src/color-slider/types.ts +94 -0
  305. package/src/color-slider/utils.ts +79 -0
  306. package/src/color-swatch-picker/ColorSwatchPickerItem.tsx +54 -0
  307. package/src/color-swatch-picker/ColorSwatchPickerRoot.tsx +94 -0
  308. package/src/color-swatch-picker/context.tsx +22 -0
  309. package/src/color-swatch-picker/index.ts +4 -0
  310. package/src/color-swatch-picker/types.ts +29 -0
  311. package/src/date-field/DateFieldRoot.tsx +4 -1
  312. package/src/date-field/DateFieldSegment.tsx +19 -3
  313. package/src/date-field/context.tsx +2 -0
  314. package/src/date-picker/DatePickerRoot.tsx +127 -18
  315. package/src/date-picker/context.tsx +1 -0
  316. package/src/index.ts +7 -0
  317. package/src/react-native-web.d.ts +6 -0
  318. package/src/slider/useSliderPointer.ts +3 -0
  319. package/src/utils/createPortal.web.ts +9 -3
  320. package/src/utils/textAncestor.ts +19 -0
  321. package/src/utils/textAncestor.web.ts +19 -0
@@ -0,0 +1,66 @@
1
+ import { forwardRef, useEffect, useState } from 'react';
2
+ import { TextInput } from 'react-native';
3
+ import { InputField } from '../input';
4
+ import { useColorFieldContext } from './context';
5
+ import type { IColorFieldInputProps } from './types';
6
+
7
+ export type ColorFieldInputProps = IColorFieldInputProps;
8
+
9
+ export const ColorFieldInput = forwardRef<TextInput, ColorFieldInputProps>(
10
+ (
11
+ {
12
+ onChangeText,
13
+ onFocus,
14
+ onBlur,
15
+ editable,
16
+ keyboardType,
17
+ autoCapitalize = 'none',
18
+ autoCorrect = false,
19
+ ...props
20
+ },
21
+ ref,
22
+ ) => {
23
+ const { value, colorSpace, disabled, readOnly, invalid, required, commitText, formatValue } =
24
+ useColorFieldContext();
25
+ const [text, setText] = useState(formatValue);
26
+ const [isEditing, setIsEditing] = useState(false);
27
+
28
+ useEffect(() => {
29
+ if (!isEditing) {
30
+ setText(formatValue());
31
+ }
32
+ }, [formatValue, isEditing, value]);
33
+
34
+ return (
35
+ <InputField
36
+ ref={ref}
37
+ {...props}
38
+ value={text}
39
+ editable={editable ?? !(disabled || readOnly)}
40
+ disabled={disabled}
41
+ isDisabled={disabled}
42
+ isReadOnly={readOnly}
43
+ isInvalid={invalid}
44
+ isRequired={required}
45
+ keyboardType={keyboardType ?? (colorSpace ? 'decimal-pad' : 'default')}
46
+ autoCapitalize={autoCapitalize}
47
+ autoCorrect={autoCorrect}
48
+ onChangeText={(nextText) => {
49
+ onChangeText?.(nextText);
50
+ setText(nextText);
51
+ commitText(nextText);
52
+ }}
53
+ onFocus={(event) => {
54
+ setIsEditing(true);
55
+ onFocus?.(event);
56
+ }}
57
+ onBlur={(event) => {
58
+ setIsEditing(false);
59
+ onBlur?.(event);
60
+ }}
61
+ />
62
+ );
63
+ },
64
+ );
65
+
66
+ ColorFieldInput.displayName = 'ColorFieldInput';
@@ -0,0 +1,132 @@
1
+ import { forwardRef, useCallback, useMemo, useRef } from 'react';
2
+ import { View } from 'react-native';
3
+ import { useControllableState, useFormControl } from '@cdx-ui/utils';
4
+ import { useOptionalColorPickerContext } from '../color-picker';
5
+ import type { Color } from '../color';
6
+ import { Slot } from '../slot';
7
+ import { dataAttributes, mergeDataAttributes } from '../utils/dataAttributes';
8
+ import { ColorFieldProvider } from './context';
9
+ import type { ColorFieldConfiguration, ColorFieldContextValue, IColorFieldProps } from './types';
10
+ import { formatColorFieldValue, parseColorFieldValue } from './utils';
11
+
12
+ export type ColorFieldRootProps = IColorFieldProps & {
13
+ readonly asChild?: boolean;
14
+ };
15
+
16
+ export const ColorFieldRoot = forwardRef<View, ColorFieldRootProps>(
17
+ (
18
+ {
19
+ asChild,
20
+ value: valueProp,
21
+ defaultValue,
22
+ onValueChange,
23
+ colorSpace,
24
+ channel,
25
+ isDisabled,
26
+ isReadOnly,
27
+ isInvalid,
28
+ isRequired,
29
+ children,
30
+ ...props
31
+ },
32
+ ref,
33
+ ) => {
34
+ const picker = useOptionalColorPickerContext();
35
+ const usesPickerContext =
36
+ picker !== null && valueProp === undefined && defaultValue === undefined;
37
+ const [localValue, setLocalValue] = useControllableState<Color>({
38
+ prop: valueProp,
39
+ defaultProp: defaultValue,
40
+ onChange: onValueChange,
41
+ });
42
+ const value = usesPickerContext ? picker.value : localValue;
43
+ const valueRef = useRef(value);
44
+ valueRef.current = value;
45
+
46
+ const formControl = useFormControl({
47
+ isDisabled,
48
+ isReadOnly,
49
+ isInvalid,
50
+ isRequired,
51
+ });
52
+ const disabled = Boolean(formControl.disabled);
53
+ const readOnly = Boolean(formControl.readOnly);
54
+ const invalid = Boolean(formControl['aria-invalid']);
55
+ const required = Boolean(formControl.required);
56
+ const configuration = useMemo<ColorFieldConfiguration>(
57
+ () =>
58
+ channel
59
+ ? ({ colorSpace, channel } as ColorFieldConfiguration)
60
+ : { colorSpace: undefined, channel: undefined },
61
+ [channel, colorSpace],
62
+ );
63
+
64
+ const commitText = useCallback(
65
+ (text: string) => {
66
+ if (disabled || readOnly) {
67
+ return undefined;
68
+ }
69
+
70
+ const nextValue = parseColorFieldValue(text, valueRef.current, configuration);
71
+ if (!nextValue) {
72
+ return undefined;
73
+ }
74
+
75
+ valueRef.current = nextValue;
76
+ if (usesPickerContext) {
77
+ onValueChange?.(nextValue);
78
+ picker.onValueChange(nextValue);
79
+ } else {
80
+ setLocalValue(nextValue);
81
+ }
82
+ return nextValue;
83
+ },
84
+ [configuration, disabled, onValueChange, picker, readOnly, setLocalValue, usesPickerContext],
85
+ );
86
+
87
+ const formatValue = useCallback(
88
+ () => formatColorFieldValue(valueRef.current, configuration),
89
+ [configuration],
90
+ );
91
+
92
+ const contextValue = useMemo<ColorFieldContextValue>(
93
+ () => ({
94
+ ...configuration,
95
+ value,
96
+ disabled,
97
+ readOnly,
98
+ invalid,
99
+ required,
100
+ commitText,
101
+ formatValue,
102
+ }),
103
+ [commitText, configuration, disabled, formatValue, invalid, readOnly, required, value],
104
+ );
105
+
106
+ const Comp = asChild ? Slot : View;
107
+
108
+ return (
109
+ <ColorFieldProvider value={contextValue}>
110
+ <Comp
111
+ ref={ref}
112
+ {...props}
113
+ {...mergeDataAttributes(
114
+ props,
115
+ dataAttributes({
116
+ disabled,
117
+ invalid,
118
+ readonly: readOnly,
119
+ required,
120
+ colorSpace: configuration.colorSpace,
121
+ channel: configuration.channel,
122
+ }),
123
+ )}
124
+ >
125
+ {children}
126
+ </Comp>
127
+ </ColorFieldProvider>
128
+ );
129
+ },
130
+ );
131
+
132
+ ColorFieldRoot.displayName = 'ColorFieldRoot';
@@ -0,0 +1,5 @@
1
+ import { createContext } from '@cdx-ui/utils';
2
+ import type { ColorFieldContextValue } from './types';
3
+
4
+ export const [ColorFieldProvider, useColorFieldContext] =
5
+ createContext<ColorFieldContextValue>('ColorFieldContext');
@@ -0,0 +1,11 @@
1
+ export { ColorFieldRoot } from './ColorFieldRoot';
2
+ export type { ColorFieldRootProps } from './ColorFieldRoot';
3
+ export { ColorFieldInput } from './ColorFieldInput';
4
+ export type { ColorFieldInputProps } from './ColorFieldInput';
5
+ export { useColorFieldContext } from './context';
6
+ export type {
7
+ ColorFieldCommonProps,
8
+ ColorFieldConfiguration,
9
+ IColorFieldInputProps,
10
+ IColorFieldProps,
11
+ } from './types';
@@ -0,0 +1,46 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { ViewProps } from 'react-native';
3
+ import type { IInputProps } from '../input';
4
+ import type { Color } from '../color';
5
+
6
+ export type ColorFieldConfiguration =
7
+ | {
8
+ readonly colorSpace?: undefined;
9
+ readonly channel?: undefined;
10
+ }
11
+ | {
12
+ readonly colorSpace: 'rgb';
13
+ readonly channel: 'red' | 'green' | 'blue';
14
+ }
15
+ | {
16
+ readonly colorSpace: 'hsl';
17
+ readonly channel: 'hue' | 'saturation' | 'lightness';
18
+ };
19
+
20
+ export interface ColorFieldCommonProps extends Omit<ViewProps, 'children'> {
21
+ /** Current controlled color. */
22
+ readonly value?: Color;
23
+ /** Initial color for uncontrolled usage. */
24
+ readonly defaultValue?: Color;
25
+ /** Called when the input contains a valid color or channel value. */
26
+ readonly onValueChange?: (value: Color) => void;
27
+ readonly isDisabled?: boolean;
28
+ readonly isReadOnly?: boolean;
29
+ readonly isInvalid?: boolean;
30
+ readonly isRequired?: boolean;
31
+ readonly children?: ReactNode;
32
+ }
33
+
34
+ export type IColorFieldProps = ColorFieldCommonProps & ColorFieldConfiguration;
35
+
36
+ export type IColorFieldInputProps = Omit<IInputProps, 'value' | 'defaultValue'>;
37
+
38
+ export type ColorFieldContextValue = ColorFieldConfiguration & {
39
+ readonly value: Color | undefined;
40
+ readonly disabled: boolean;
41
+ readonly readOnly: boolean;
42
+ readonly invalid: boolean;
43
+ readonly required: boolean;
44
+ readonly commitText: (text: string) => Color | undefined;
45
+ readonly formatValue: () => string;
46
+ };
@@ -0,0 +1,75 @@
1
+ import { parseColor, type Color } from '../color';
2
+ import type { ColorFieldConfiguration } from './types';
3
+
4
+ const CHANNEL_VALUE_PATTERN = /^([+-]?(?:\d+(?:\.\d+)?|\.\d+))\s*([°%])?$/u;
5
+
6
+ function formatNumber(value: number): string {
7
+ return Number.isInteger(value) ? String(value) : value.toFixed(1);
8
+ }
9
+
10
+ export function formatColorFieldValue(
11
+ value: Color | undefined,
12
+ configuration: ColorFieldConfiguration,
13
+ ): string {
14
+ if (!value) {
15
+ return '';
16
+ }
17
+
18
+ if (!configuration.channel) {
19
+ return value.toString('hex');
20
+ }
21
+
22
+ const channelValue = value.getChannel(configuration.colorSpace, configuration.channel);
23
+ const formattedValue = formatNumber(channelValue);
24
+
25
+ if (configuration.channel === 'hue') {
26
+ return `${formattedValue}°`;
27
+ }
28
+
29
+ if (configuration.colorSpace === 'hsl') {
30
+ return `${formattedValue}%`;
31
+ }
32
+
33
+ return formattedValue;
34
+ }
35
+
36
+ export function parseColorFieldValue(
37
+ text: string,
38
+ currentValue: Color | undefined,
39
+ configuration: ColorFieldConfiguration,
40
+ ): Color | undefined {
41
+ const normalizedText = text.trim();
42
+
43
+ if (!configuration.channel) {
44
+ return parseColor(normalizedText);
45
+ }
46
+
47
+ if (!currentValue) {
48
+ return undefined;
49
+ }
50
+
51
+ const match = CHANNEL_VALUE_PATTERN.exec(normalizedText);
52
+ if (!match) {
53
+ return undefined;
54
+ }
55
+
56
+ const value = Number(match[1]);
57
+ const unit = match[2];
58
+ if (!Number.isFinite(value)) {
59
+ return undefined;
60
+ }
61
+
62
+ if (configuration.colorSpace === 'rgb') {
63
+ if (unit || value < 0 || value > 255) {
64
+ return undefined;
65
+ }
66
+ } else if (configuration.channel === 'hue') {
67
+ if (unit === '%' || value < 0 || value > 360) {
68
+ return undefined;
69
+ }
70
+ } else if (unit === '°' || value < 0 || value > 100) {
71
+ return undefined;
72
+ }
73
+
74
+ return currentValue.withChannel(configuration.colorSpace, configuration.channel, value);
75
+ }
@@ -0,0 +1,91 @@
1
+ import { forwardRef, useCallback, useMemo, useRef, type ComponentRef } from 'react';
2
+ import { View } from 'react-native';
3
+ import { mergeRefs, useControllableState } from '@cdx-ui/utils';
4
+ import type { Color } from '../color';
5
+ import { Slot } from '../slot';
6
+ import { dataAttributes, mergeDataAttributes } from '../utils/dataAttributes';
7
+ import { ColorPickerProvider, ColorPickerRootProvider } from './context';
8
+ import type { IColorPickerProps } from './types';
9
+
10
+ export interface ColorPickerRootProps extends IColorPickerProps {
11
+ readonly asChild?: boolean;
12
+ }
13
+
14
+ export const ColorPickerRoot = forwardRef<ComponentRef<typeof View>, ColorPickerRootProps>(
15
+ (
16
+ {
17
+ asChild,
18
+ value: valueProp,
19
+ defaultValue,
20
+ onValueChange,
21
+ isOpen: openProp,
22
+ defaultOpen = false,
23
+ onOpenChange,
24
+ children,
25
+ ...props
26
+ },
27
+ ref,
28
+ ) => {
29
+ const [value, setValueState] = useControllableState<Color>({
30
+ prop: valueProp,
31
+ defaultProp: defaultValue,
32
+ onChange: onValueChange,
33
+ });
34
+ const [open, setOpenState] = useControllableState<boolean>({
35
+ prop: openProp,
36
+ defaultProp: defaultOpen,
37
+ onChange: onOpenChange,
38
+ });
39
+ const anchorRef = useRef<ComponentRef<typeof View>>(null);
40
+ const triggerRef = useRef<ComponentRef<typeof View>>(null);
41
+
42
+ const setValue = useCallback(
43
+ (nextValue: Color) => {
44
+ setValueState(nextValue);
45
+ },
46
+ [setValueState],
47
+ );
48
+ const setOpen = useCallback(
49
+ (nextOpen: boolean) => {
50
+ setOpenState(nextOpen);
51
+ },
52
+ [setOpenState],
53
+ );
54
+
55
+ const contextValue = useMemo(
56
+ () => ({
57
+ value,
58
+ onValueChange: setValue,
59
+ open: open ?? false,
60
+ setOpen,
61
+ anchorRef,
62
+ triggerRef,
63
+ }),
64
+ [open, setOpen, setValue, value],
65
+ );
66
+
67
+ const Comp = asChild ? Slot : View;
68
+
69
+ return (
70
+ <ColorPickerRootProvider value={contextValue}>
71
+ <ColorPickerProvider value={contextValue}>
72
+ <Comp
73
+ ref={mergeRefs(ref, anchorRef)}
74
+ {...props}
75
+ {...mergeDataAttributes(
76
+ props,
77
+ dataAttributes({
78
+ open: contextValue.open,
79
+ state: contextValue.open ? 'open' : 'closed',
80
+ }),
81
+ )}
82
+ >
83
+ {children}
84
+ </Comp>
85
+ </ColorPickerProvider>
86
+ </ColorPickerRootProvider>
87
+ );
88
+ },
89
+ );
90
+
91
+ ColorPickerRoot.displayName = 'ColorPickerRoot';
@@ -0,0 +1,96 @@
1
+ import { forwardRef, type ComponentRef } from 'react';
2
+ import { Platform, Pressable, 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 { Slot } from '../slot';
7
+ import { dataAttributes, mergeDataAttributes } from '../utils/dataAttributes';
8
+ import { useColorPickerRootContext } from './context';
9
+ import type { IColorPickerTriggerProps } from './types';
10
+
11
+ export type ColorPickerTriggerProps = IColorPickerTriggerProps;
12
+
13
+ export const ColorPickerTrigger = forwardRef<
14
+ ComponentRef<typeof Pressable>,
15
+ ColorPickerTriggerProps
16
+ >(
17
+ (
18
+ {
19
+ asChild,
20
+ children,
21
+ isDisabled,
22
+ isHovered: isHoveredProp,
23
+ isActive: isActiveProp,
24
+ isFocused: isFocusedProp,
25
+ isFocusVisible: isFocusVisibleProp,
26
+ accessibilityLabel = 'Open color picker',
27
+ onPress,
28
+ onPressIn,
29
+ onPressOut,
30
+ onHoverIn,
31
+ onHoverOut,
32
+ onFocus,
33
+ onBlur,
34
+ ...props
35
+ },
36
+ ref,
37
+ ) => {
38
+ const { open, setOpen, triggerRef } = useColorPickerRootContext();
39
+ const disabled = Boolean(isDisabled || props.disabled);
40
+ const { isFocused, focusProps } = useFocus();
41
+ const { isFocusVisible, focusProps: focusRingProps } = useFocusRing() as {
42
+ isFocusVisible: boolean;
43
+ focusProps: typeof focusProps;
44
+ };
45
+ const { isPressed, pressProps } = usePress({ isDisabled: disabled }) as {
46
+ isPressed: boolean;
47
+ pressProps: Pick<PressableProps, 'onPressIn' | 'onPressOut'>;
48
+ };
49
+ const { isHovered, hoverProps } = useHover({ isDisabled: disabled });
50
+ const Comp = asChild ? Slot : Pressable;
51
+ const platformAccessibilityProps =
52
+ Platform.OS === 'web'
53
+ ? {
54
+ role: 'button' as const,
55
+ 'aria-haspopup': 'dialog' as const,
56
+ 'aria-expanded': open,
57
+ 'aria-disabled': disabled || undefined,
58
+ }
59
+ : {
60
+ accessibilityRole: 'button' as const,
61
+ accessibilityState: { disabled, expanded: open },
62
+ };
63
+
64
+ return (
65
+ <Comp
66
+ ref={mergeRefs(ref, triggerRef)}
67
+ disabled={disabled}
68
+ accessibilityLabel={accessibilityLabel}
69
+ {...props}
70
+ {...platformAccessibilityProps}
71
+ {...mergeDataAttributes(
72
+ props,
73
+ dataAttributes({
74
+ state: open ? 'open' : 'closed',
75
+ disabled,
76
+ hover: isHoveredProp || isHovered,
77
+ active: isActiveProp || isPressed,
78
+ focus: isFocusedProp || isFocused,
79
+ focusVisible: isFocusVisibleProp || isFocusVisible,
80
+ }),
81
+ )}
82
+ onPress={composeEventHandlers(onPress, () => setOpen(!open))}
83
+ onPressIn={composeEventHandlers(onPressIn, pressProps.onPressIn)}
84
+ onPressOut={composeEventHandlers(onPressOut, pressProps.onPressOut)}
85
+ onHoverIn={composeEventHandlers(onHoverIn, hoverProps.onHoverIn)}
86
+ onHoverOut={composeEventHandlers(onHoverOut, hoverProps.onHoverOut)}
87
+ onFocus={composeEventHandlers(onFocus, focusProps.onFocus, focusRingProps.onFocus)}
88
+ onBlur={composeEventHandlers(onBlur, focusProps.onBlur, focusRingProps.onBlur)}
89
+ >
90
+ {children}
91
+ </Comp>
92
+ );
93
+ },
94
+ );
95
+
96
+ ColorPickerTrigger.displayName = 'ColorPickerTrigger';
@@ -0,0 +1,47 @@
1
+ import { createContext, useContext, type RefObject } from 'react';
2
+ import type { View } from 'react-native';
3
+ import type { Color } from '../color';
4
+
5
+ export interface ColorPickerContextValue {
6
+ value: Color | undefined;
7
+ onValueChange: (value: Color) => void;
8
+ }
9
+
10
+ const ColorPickerContext = createContext<ColorPickerContextValue | null>(null);
11
+
12
+ export const ColorPickerProvider = ColorPickerContext.Provider;
13
+
14
+ export interface ColorPickerRootContextValue extends ColorPickerContextValue {
15
+ open: boolean;
16
+ setOpen: (open: boolean) => void;
17
+ anchorRef: RefObject<View | null>;
18
+ triggerRef: RefObject<View | null>;
19
+ }
20
+
21
+ const ColorPickerRootContext = createContext<ColorPickerRootContextValue | null>(null);
22
+
23
+ export const ColorPickerRootProvider = ColorPickerRootContext.Provider;
24
+
25
+ export function useColorPickerContext(): ColorPickerContextValue {
26
+ const context = useContext(ColorPickerContext);
27
+
28
+ if (!context) {
29
+ throw new Error('Color picker compound components must be used within ColorPicker');
30
+ }
31
+
32
+ return context;
33
+ }
34
+
35
+ export function useOptionalColorPickerContext(): ColorPickerContextValue | null {
36
+ return useContext(ColorPickerContext);
37
+ }
38
+
39
+ export function useColorPickerRootContext(): ColorPickerRootContextValue {
40
+ const context = useContext(ColorPickerRootContext);
41
+
42
+ if (!context) {
43
+ throw new Error('ColorPicker compound components must be used within ColorPickerRoot');
44
+ }
45
+
46
+ return context;
47
+ }
@@ -0,0 +1,12 @@
1
+ export {
2
+ ColorPickerProvider,
3
+ ColorPickerRootProvider,
4
+ useColorPickerContext,
5
+ useColorPickerRootContext,
6
+ useOptionalColorPickerContext,
7
+ type ColorPickerContextValue,
8
+ type ColorPickerRootContextValue,
9
+ } from './context';
10
+ export { ColorPickerRoot, type ColorPickerRootProps } from './ColorPickerRoot';
11
+ export { ColorPickerTrigger, type ColorPickerTriggerProps } from './ColorPickerTrigger';
12
+ export type { IColorPickerProps, IColorPickerTriggerProps } from './types';
@@ -0,0 +1,25 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { ViewProps } from 'react-native';
3
+ import type { IButtonProps } from '../button';
4
+ import type { Color } from '../color';
5
+
6
+ export interface IColorPickerProps extends Omit<ViewProps, 'children'> {
7
+ /** Current controlled color. */
8
+ readonly value?: Color;
9
+ /** Initial color for uncontrolled usage. */
10
+ readonly defaultValue?: Color;
11
+ /** Called when a nested color control changes the current color. */
12
+ readonly onValueChange?: (value: Color) => void;
13
+ /** Controlled popover open state. */
14
+ readonly isOpen?: boolean;
15
+ /** Initial popover open state for uncontrolled usage. @default `false` */
16
+ readonly defaultOpen?: boolean;
17
+ /** Called when the popover open state changes. */
18
+ readonly onOpenChange?: (open: boolean) => void;
19
+ readonly children?: ReactNode;
20
+ }
21
+
22
+ export interface IColorPickerTriggerProps extends Omit<IButtonProps, 'children'> {
23
+ readonly asChild?: boolean;
24
+ readonly children?: ReactNode;
25
+ }