@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,94 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { PressableProps, ViewProps } from 'react-native';
3
+ import type { Color } from '../color';
4
+
5
+ export type ColorSliderOrientation = 'horizontal' | 'vertical';
6
+
7
+ export type ColorSliderConfiguration =
8
+ | {
9
+ readonly colorSpace: 'rgb';
10
+ readonly channel: 'red' | 'green' | 'blue';
11
+ }
12
+ | {
13
+ readonly colorSpace: 'hsl';
14
+ readonly channel: 'hue' | 'saturation' | 'lightness';
15
+ }
16
+ | {
17
+ readonly colorSpace: 'hsb';
18
+ readonly channel: 'hue' | 'saturation' | 'brightness';
19
+ };
20
+
21
+ export interface ColorSliderCommonProps extends Omit<ViewProps, 'children'> {
22
+ /** Current controlled color. */
23
+ readonly value?: Color;
24
+ /** Initial color for uncontrolled usage. */
25
+ readonly defaultValue?: Color;
26
+ /** Called while the selected channel changes. */
27
+ readonly onValueChange?: (value: Color) => void;
28
+ /** Called when a pointer, keyboard, or screen reader interaction completes. */
29
+ readonly onValueChangeComplete?: (value: Color) => void;
30
+ /** Slider axis. @default `'horizontal'` */
31
+ readonly orientation?: ColorSliderOrientation;
32
+ /** Channel increment. Defaults to the channel's natural increment. */
33
+ readonly step?: number;
34
+ /** Shift-arrow and page-key increment. @default `10` */
35
+ readonly pageStep?: number;
36
+ /** Disables pointer, keyboard, and screen reader interaction. @default `false` */
37
+ readonly isDisabled?: boolean;
38
+ readonly children?: ReactNode;
39
+ }
40
+
41
+ export type IColorSliderProps = ColorSliderCommonProps & ColorSliderConfiguration;
42
+
43
+ export interface IColorSliderRailProps extends ViewProps {
44
+ readonly asChild?: boolean;
45
+ readonly children?: ReactNode;
46
+ }
47
+
48
+ export interface IColorSliderThumbProps extends PressableProps {
49
+ readonly asChild?: boolean;
50
+ readonly children?: ReactNode;
51
+ }
52
+
53
+ export interface ColorSliderSize {
54
+ readonly width: number;
55
+ readonly height: number;
56
+ }
57
+
58
+ export interface ColorSliderLayout extends ColorSliderSize {
59
+ readonly x: number;
60
+ readonly y: number;
61
+ }
62
+
63
+ export type ColorSliderContextValue = ColorSliderConfiguration & {
64
+ readonly value: Color;
65
+ readonly channelValue: number;
66
+ readonly valueLabel: string;
67
+ readonly min: number;
68
+ readonly max: number;
69
+ readonly step: number;
70
+ readonly pageStep: number;
71
+ readonly percent: number;
72
+ readonly orientation: ColorSliderOrientation;
73
+ readonly isDisabled: boolean;
74
+ readonly isDragging: boolean;
75
+ readonly accessibilityLabel?: string;
76
+ readonly layout: ColorSliderLayout | null;
77
+ readonly thumbSize: ColorSliderSize;
78
+ readonly gradientColors: readonly string[];
79
+ readonly setLayout: (layout: ColorSliderLayout) => void;
80
+ readonly setThumbSize: (size: ColorSliderSize) => void;
81
+ readonly setIsDragging: (dragging: boolean) => void;
82
+ readonly setChannelValue: (value: number, complete?: boolean) => void;
83
+ readonly setValueFromRatio: (ratio: number, complete?: boolean) => void;
84
+ };
85
+
86
+ export interface ColorSliderKeyboardEvent {
87
+ readonly nativeEvent?: {
88
+ readonly key?: string;
89
+ readonly shiftKey?: boolean;
90
+ };
91
+ readonly key?: string;
92
+ readonly shiftKey?: boolean;
93
+ preventDefault?: () => void;
94
+ }
@@ -0,0 +1,79 @@
1
+ import type { Color } from '../color';
2
+ import type { ColorSliderConfiguration } from './types';
3
+
4
+ const HUE_STOPS = [0, 60, 120, 180, 240, 300, 360] as const;
5
+
6
+ export function clampColorSliderValue(value: number, min: number, max: number): number {
7
+ return Math.min(max, Math.max(min, value));
8
+ }
9
+
10
+ export function getColorSliderRange({ colorSpace, channel }: ColorSliderConfiguration): {
11
+ min: number;
12
+ max: number;
13
+ } {
14
+ if (colorSpace === 'rgb') {
15
+ return { min: 0, max: 255 };
16
+ }
17
+ if (channel === 'hue') {
18
+ return { min: 0, max: 360 };
19
+ }
20
+ return { min: 0, max: 100 };
21
+ }
22
+
23
+ export function getColorSliderChannelValue(
24
+ color: Color,
25
+ configuration: ColorSliderConfiguration,
26
+ ): number {
27
+ if (configuration.colorSpace === 'rgb') {
28
+ return color.getChannel('rgb', configuration.channel);
29
+ }
30
+ if (configuration.colorSpace === 'hsl') {
31
+ return color.getChannel('hsl', configuration.channel);
32
+ }
33
+ return color.getChannel('hsb', configuration.channel);
34
+ }
35
+
36
+ export function withColorSliderChannel(
37
+ color: Color,
38
+ configuration: ColorSliderConfiguration,
39
+ value: number,
40
+ ): Color {
41
+ if (configuration.colorSpace === 'rgb') {
42
+ return color.withChannel('rgb', configuration.channel, value);
43
+ }
44
+ if (configuration.colorSpace === 'hsl') {
45
+ return color.withChannel('hsl', configuration.channel, value);
46
+ }
47
+ return color.withChannel('hsb', configuration.channel, value);
48
+ }
49
+
50
+ export function formatColorSliderValue(
51
+ value: number,
52
+ configuration: ColorSliderConfiguration,
53
+ ): string {
54
+ const formatted = Number.isInteger(value) ? String(value) : value.toFixed(1);
55
+ if (configuration.channel === 'hue') {
56
+ return `${formatted}°`;
57
+ }
58
+ if (configuration.colorSpace !== 'rgb') {
59
+ return `${formatted}%`;
60
+ }
61
+ return formatted;
62
+ }
63
+
64
+ export function getColorSliderGradientColors(
65
+ color: Color,
66
+ configuration: ColorSliderConfiguration,
67
+ ): readonly string[] {
68
+ if (configuration.channel === 'hue') {
69
+ return HUE_STOPS.map((value) =>
70
+ withColorSliderChannel(color, configuration, value).toString('hex'),
71
+ );
72
+ }
73
+
74
+ const { min, max } = getColorSliderRange(configuration);
75
+ return [
76
+ withColorSliderChannel(color, configuration, min).toString('hex'),
77
+ withColorSliderChannel(color, configuration, max).toString('hex'),
78
+ ];
79
+ }
@@ -0,0 +1,54 @@
1
+ import { forwardRef, useEffect, useMemo, type ComponentRef } from 'react';
2
+ import { Pressable } from 'react-native';
3
+ import { RadioRoot } from '../radio';
4
+ import { ColorSwatchPickerItemProvider, useColorSwatchPickerContext } from './context';
5
+ import type { IColorSwatchPickerItemProps } from './types';
6
+
7
+ export interface ColorSwatchPickerItemProps extends IColorSwatchPickerItemProps {
8
+ asChild?: boolean;
9
+ }
10
+
11
+ export const ColorSwatchPickerItem = forwardRef<
12
+ ComponentRef<typeof Pressable>,
13
+ ColorSwatchPickerItemProps
14
+ >(
15
+ (
16
+ {
17
+ asChild,
18
+ color,
19
+ isDisabled,
20
+ disabled,
21
+ accessibilityLabel,
22
+ 'aria-label': ariaLabelProp,
23
+ children,
24
+ ...props
25
+ },
26
+ ref,
27
+ ) => {
28
+ const { registerColor } = useColorSwatchPickerContext();
29
+ const colorValue = color.toString('hex');
30
+ const label = ariaLabelProp ?? accessibilityLabel ?? colorValue;
31
+ const contextValue = useMemo(() => ({ color }), [color]);
32
+
33
+ useEffect(() => registerColor(color), [color, registerColor]);
34
+
35
+ return (
36
+ <ColorSwatchPickerItemProvider value={contextValue}>
37
+ <RadioRoot
38
+ ref={ref}
39
+ asChild={asChild}
40
+ value={colorValue}
41
+ isDisabled={!!(isDisabled || disabled)}
42
+ disabled={disabled}
43
+ aria-label={label}
44
+ accessibilityLabel={label}
45
+ {...props}
46
+ >
47
+ {children}
48
+ </RadioRoot>
49
+ </ColorSwatchPickerItemProvider>
50
+ );
51
+ },
52
+ );
53
+
54
+ ColorSwatchPickerItem.displayName = 'ColorSwatchPickerItem';
@@ -0,0 +1,94 @@
1
+ import { forwardRef, useCallback, useMemo, useRef, type ComponentRef } from 'react';
2
+ import { View } from 'react-native';
3
+ import { useControllableState } from '@cdx-ui/utils';
4
+ import { RadioGroup } from '../radio';
5
+ import { useOptionalColorPickerContext } from '../color-picker';
6
+ import type { Color } from '../color';
7
+ import { ColorSwatchPickerProvider } from './context';
8
+ import type { IColorSwatchPickerProps } from './types';
9
+
10
+ export interface ColorSwatchPickerRootProps extends IColorSwatchPickerProps {
11
+ asChild?: boolean;
12
+ }
13
+
14
+ export const ColorSwatchPickerRoot = forwardRef<
15
+ ComponentRef<typeof View>,
16
+ ColorSwatchPickerRootProps
17
+ >(
18
+ (
19
+ {
20
+ asChild,
21
+ value: valueProp,
22
+ defaultValue,
23
+ onValueChange,
24
+ isDisabled,
25
+ accessibilityLabel,
26
+ children,
27
+ ...props
28
+ },
29
+ ref,
30
+ ) => {
31
+ const picker = useOptionalColorPickerContext();
32
+ const usesPickerContext =
33
+ picker !== null && valueProp === undefined && defaultValue === undefined;
34
+
35
+ const [localValue, setLocalValue] = useControllableState<Color>({
36
+ prop: valueProp,
37
+ defaultProp: defaultValue,
38
+ onChange: onValueChange,
39
+ });
40
+
41
+ const value = usesPickerContext ? picker.value : localValue;
42
+ const colorsRef = useRef(new Map<string, Color>());
43
+
44
+ const registerColor = useCallback((color: Color) => {
45
+ const key = color.toString('hex');
46
+ colorsRef.current.set(key, color);
47
+
48
+ return () => {
49
+ if (colorsRef.current.get(key) === color) {
50
+ colorsRef.current.delete(key);
51
+ }
52
+ };
53
+ }, []);
54
+
55
+ const handleValueChange = useCallback(
56
+ (key: string) => {
57
+ const color = colorsRef.current.get(key);
58
+
59
+ if (!color) {
60
+ return;
61
+ }
62
+
63
+ if (usesPickerContext) {
64
+ onValueChange?.(color);
65
+ picker.onValueChange(color);
66
+ return;
67
+ }
68
+
69
+ setLocalValue(color);
70
+ },
71
+ [onValueChange, picker, setLocalValue, usesPickerContext],
72
+ );
73
+
74
+ const contextValue = useMemo(() => ({ registerColor }), [registerColor]);
75
+
76
+ return (
77
+ <ColorSwatchPickerProvider value={contextValue}>
78
+ <RadioGroup
79
+ ref={ref}
80
+ asChild={asChild}
81
+ value={value?.toString('hex')}
82
+ onChange={handleValueChange}
83
+ isDisabled={isDisabled}
84
+ aria-label={props['aria-label'] ?? accessibilityLabel}
85
+ {...props}
86
+ >
87
+ {children}
88
+ </RadioGroup>
89
+ </ColorSwatchPickerProvider>
90
+ );
91
+ },
92
+ );
93
+
94
+ ColorSwatchPickerRoot.displayName = 'ColorSwatchPickerRoot';
@@ -0,0 +1,22 @@
1
+ import { createContext as createReactContext, useContext } from 'react';
2
+ import { createContext } from '@cdx-ui/utils';
3
+ import type { ColorSwatchPickerContextValue, ColorSwatchPickerItemContextValue } from './types';
4
+
5
+ export const [ColorSwatchPickerProvider, useColorSwatchPickerContext] =
6
+ createContext<ColorSwatchPickerContextValue>('ColorSwatchPickerContext');
7
+
8
+ const ColorSwatchPickerItemContext = createReactContext<ColorSwatchPickerItemContextValue | null>(
9
+ null,
10
+ );
11
+
12
+ export const ColorSwatchPickerItemProvider = ColorSwatchPickerItemContext.Provider;
13
+
14
+ export function useColorSwatchPickerItemContext(): ColorSwatchPickerItemContextValue {
15
+ const context = useContext(ColorSwatchPickerItemContext);
16
+
17
+ if (!context) {
18
+ throw new Error('ColorSwatchPicker item slots must be used within ColorSwatchPicker.Item');
19
+ }
20
+
21
+ return context;
22
+ }
@@ -0,0 +1,4 @@
1
+ export { ColorSwatchPickerRoot, type ColorSwatchPickerRootProps } from './ColorSwatchPickerRoot';
2
+ export { ColorSwatchPickerItem, type ColorSwatchPickerItemProps } from './ColorSwatchPickerItem';
3
+ export { useColorSwatchPickerContext, useColorSwatchPickerItemContext } from './context';
4
+ export type { IColorSwatchPickerItemProps, IColorSwatchPickerProps } from './types';
@@ -0,0 +1,29 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { PressableProps, ViewProps } from 'react-native';
3
+ import type { Color } from '../color';
4
+
5
+ export interface IColorSwatchPickerProps extends Omit<ViewProps, 'children'> {
6
+ value?: Color;
7
+ defaultValue?: Color;
8
+ onValueChange?: (value: Color) => void;
9
+ isDisabled?: boolean;
10
+ children?: ReactNode;
11
+ }
12
+
13
+ export interface IColorSwatchPickerItemProps extends Omit<PressableProps, 'children'> {
14
+ color: Color;
15
+ isDisabled?: boolean;
16
+ isHovered?: boolean;
17
+ isActive?: boolean;
18
+ isFocused?: boolean;
19
+ isFocusVisible?: boolean;
20
+ children?: ReactNode;
21
+ }
22
+
23
+ export interface ColorSwatchPickerContextValue {
24
+ registerColor: (color: Color) => () => void;
25
+ }
26
+
27
+ export interface ColorSwatchPickerItemContextValue {
28
+ color: Color;
29
+ }
@@ -1,7 +1,7 @@
1
1
  import { forwardRef, useMemo, type ComponentRef, type ReactNode } from 'react';
2
2
  import { View, type ViewProps } from 'react-native';
3
3
  import { getDateFieldSegments, resolveDateComponentLabels } from '@cdx-ui/formatters';
4
- import { useControllableState, useFormControl } from '@cdx-ui/utils';
4
+ import { useControllableState, useFormControl, useFormControlContext } from '@cdx-ui/utils';
5
5
  import { Slot } from '../slot';
6
6
  import { dataAttributes, mergeDataAttributes } from '../utils/dataAttributes';
7
7
  import { DateFieldContext, type DateFieldValue } from './context';
@@ -39,6 +39,7 @@ export const DateFieldRoot = forwardRef<ComponentRef<typeof View>, DateFieldRoot
39
39
  isInvalid,
40
40
  isRequired,
41
41
  });
42
+ const { errorMessage } = useFormControlContext();
42
43
 
43
44
  const [value, setValue] = useControllableState<DateFieldValue>({
44
45
  prop: valueProp,
@@ -75,6 +76,7 @@ export const DateFieldRoot = forwardRef<ComponentRef<typeof View>, DateFieldRoot
75
76
  disabled: !!formControl.disabled,
76
77
  readOnly: !!formControl.readOnly,
77
78
  invalid: !!formControl['aria-invalid'],
79
+ errorMessage,
78
80
  ...segmentState,
79
81
  }),
80
82
  [
@@ -87,6 +89,7 @@ export const DateFieldRoot = forwardRef<ComponentRef<typeof View>, DateFieldRoot
87
89
  formControl.disabled,
88
90
  formControl.readOnly,
89
91
  formControl['aria-invalid'],
92
+ errorMessage,
90
93
  segmentState,
91
94
  ],
92
95
  );
@@ -23,8 +23,16 @@ export const DateFieldSegment = forwardRef<ComponentRef<typeof Text>, DateFieldS
23
23
  ({ asChild, segment, segmentIndex: segmentIndexProp, style, ...props }, ref) => {
24
24
  const contextSegmentIndex = useDateFieldSegmentIndex();
25
25
  const segmentIndex = segmentIndexProp ?? contextSegmentIndex;
26
- const { disabled, readOnly, focusedSegmentIndex, focusSegment, getSegmentDisplayText, labels } =
27
- useDateFieldContext();
26
+ const {
27
+ disabled,
28
+ readOnly,
29
+ invalid,
30
+ errorMessage,
31
+ focusedSegmentIndex,
32
+ focusSegment,
33
+ getSegmentDisplayText,
34
+ labels,
35
+ } = useDateFieldContext();
28
36
  const isFocused = focusedSegmentIndex === segmentIndex;
29
37
  const displayText = getSegmentDisplayText(segmentIndex);
30
38
 
@@ -52,11 +60,19 @@ export const DateFieldSegment = forwardRef<ComponentRef<typeof Text>, DateFieldS
52
60
  );
53
61
 
54
62
  if (segment.isEditable && !asChild) {
63
+ // `aria-invalid` only reaches web screen readers; native ones need it in the name and hint.
64
+ const announceInvalid = invalid && Platform.OS !== 'web';
55
65
  return (
56
66
  <Pressable
57
67
  accessibilityRole="spinbutton"
58
- accessibilityLabel={getDateSegmentAccessibilityLabel(segment.type, labels)}
68
+ accessibilityLabel={getDateSegmentAccessibilityLabel(
69
+ segment.type,
70
+ labels,
71
+ announceInvalid,
72
+ )}
73
+ accessibilityHint={announceInvalid ? errorMessage : undefined}
59
74
  accessibilityState={{ disabled, selected: isFocused }}
75
+ aria-invalid={invalid || undefined}
60
76
  disabled={disabled || readOnly}
61
77
  onPress={handlePress}
62
78
  onPressIn={preventWebFocusSteal}
@@ -20,6 +20,8 @@ export interface DateFieldContextValue {
20
20
  disabled: boolean;
21
21
  readOnly: boolean;
22
22
  invalid: boolean;
23
+ /** Message the enclosing `Field` shows for the invalid state, if any. */
24
+ errorMessage?: string;
23
25
  focusedSegmentIndex: number | null;
24
26
  focusSegment: (index: number) => void;
25
27
  blurSegment: (index: number) => void;
@@ -2,15 +2,28 @@ import {
2
2
  forwardRef,
3
3
  useCallback,
4
4
  useEffect,
5
+ useLayoutEffect,
5
6
  useMemo,
6
7
  useRef,
7
8
  type ComponentRef,
8
9
  type ReactNode,
9
10
  } from 'react';
10
11
  import { View, type ViewProps } from 'react-native';
11
- import type { DateComponentLabels, DateId } from '@cdx-ui/formatters';
12
- import { resolveDateComponentLabels } from '@cdx-ui/formatters';
13
- import { mergeRefs, useControllableState } from '@cdx-ui/utils';
12
+ import {
13
+ formatDateValidationMessage,
14
+ getDateValidationReason,
15
+ resolveDateComponentLabels,
16
+ type DateComponentLabels,
17
+ type DateId,
18
+ type DateValidationReason,
19
+ } from '@cdx-ui/formatters';
20
+ import {
21
+ FormControlContext,
22
+ mergeRefs,
23
+ useControllableState,
24
+ useFormControlContext,
25
+ useReportFormControlValidation,
26
+ } from '@cdx-ui/utils';
14
27
  import { DateFieldRoot } from '../date-field/DateFieldRoot';
15
28
  import { Slot } from '../slot';
16
29
  import { dataAttributes, mergeDataAttributes } from '../utils/dataAttributes';
@@ -29,12 +42,41 @@ export interface DatePickerRootProps extends Omit<ViewProps, 'children'> {
29
42
  onOpenChange?: (open: boolean) => void;
30
43
  isDisabled?: boolean;
31
44
  isReadOnly?: boolean;
45
+ /**
46
+ * Forces the invalid state. OR-ed with the picker's own validation: setting `true` marks the
47
+ * field invalid, but `false` never hides a `minValue` / `maxValue` / `isDateUnavailable` violation.
48
+ */
32
49
  isInvalid?: boolean;
33
50
  isRequired?: boolean;
34
- /** Earliest selectable date, applied to the embedded calendar. Build with `dateId(...)`. */
51
+ /**
52
+ * Earliest selectable date, applied to the embedded calendar and to typed entry. Build with
53
+ * `dateId(...)`.
54
+ */
35
55
  minValue?: DateId;
36
- /** Latest selectable date, applied to the embedded calendar. Build with `dateId(...)`. */
56
+ /**
57
+ * Latest selectable date, applied to the embedded calendar and to typed entry. Build with
58
+ * `dateId(...)`.
59
+ */
37
60
  maxValue?: DateId;
61
+ /**
62
+ * Returns `true` for dates that cannot be selected, such as weekends or holidays. The calendar
63
+ * renders them disabled; a typed unavailable date is kept and emitted but renders invalid. Pass
64
+ * a stable (memoized) function.
65
+ */
66
+ isDateUnavailable?: (date: DateId) => boolean;
67
+ /**
68
+ * Called when the committed value starts or stops violating `minValue`, `maxValue`, or
69
+ * `isDateUnavailable`, and again when the formatted message changes while the reason stays
70
+ * the same — a new bound, `locale`, or `labels` while the value is still `beforeMin`, for
71
+ * example. Receives the reason and its `labels` message formatted in `locale`, or `undefined`
72
+ * for both once the value is valid or cleared. Fires before paint, so state set here renders
73
+ * in the same frame as the invalid styling. Not needed to show the message: an empty
74
+ * `Field.Error` anywhere in the enclosing `Field` already renders it.
75
+ */
76
+ onValidationChange?: (
77
+ reason: DateValidationReason | undefined,
78
+ message: string | undefined,
79
+ ) => void;
38
80
  name?: string;
39
81
  locale?: string;
40
82
  labels?: Partial<DateComponentLabels>;
@@ -57,6 +99,8 @@ export const DatePickerRoot = forwardRef<ComponentRef<typeof View>, DatePickerRo
57
99
  isRequired,
58
100
  minValue,
59
101
  maxValue,
102
+ isDateUnavailable,
103
+ onValidationChange,
60
104
  locale = 'en-US',
61
105
  labels: labelsProp,
62
106
  ...props
@@ -83,6 +127,59 @@ export const DatePickerRoot = forwardRef<ComponentRef<typeof View>, DatePickerRo
83
127
  defaultProp: value,
84
128
  });
85
129
 
130
+ const validationReason = useMemo(
131
+ () =>
132
+ value === undefined
133
+ ? undefined
134
+ : getDateValidationReason(value, { minValue, maxValue, isDateUnavailable }),
135
+ [isDateUnavailable, maxValue, minValue, value],
136
+ );
137
+ const resolvedInvalid = !!isInvalid || validationReason !== undefined;
138
+ const validationMessage = useMemo(
139
+ () =>
140
+ validationReason === undefined
141
+ ? undefined
142
+ : formatDateValidationMessage(
143
+ labels,
144
+ validationReason,
145
+ { minValue, maxValue },
146
+ { locale },
147
+ ),
148
+ [labels, locale, maxValue, minValue, validationReason],
149
+ );
150
+
151
+ const onValidationChangeRef = useRef(onValidationChange);
152
+ onValidationChangeRef.current = onValidationChange;
153
+ const reportedValidationRef = useRef<{
154
+ reason: DateValidationReason | undefined;
155
+ message: string | undefined;
156
+ }>({ reason: undefined, message: undefined });
157
+ useLayoutEffect(() => {
158
+ const reported = reportedValidationRef.current;
159
+ if (reported.reason === validationReason && reported.message === validationMessage) {
160
+ return;
161
+ }
162
+ reportedValidationRef.current = { reason: validationReason, message: validationMessage };
163
+ onValidationChangeRef.current?.(validationReason, validationMessage);
164
+ }, [validationMessage, validationReason]);
165
+
166
+ const reportsToField = useReportFormControlValidation(resolvedInvalid, validationMessage);
167
+
168
+ // Without an enclosing `Field` there is nothing to report to, so provide the picker's
169
+ // validation to its own children (`Field.Error`, `Field.Helper`, the input group).
170
+ const parentFormControl = useFormControlContext();
171
+ const standaloneFormControl = useMemo(
172
+ () =>
173
+ reportsToField
174
+ ? undefined
175
+ : {
176
+ ...parentFormControl,
177
+ isInvalid: !!parentFormControl.isInvalid || resolvedInvalid,
178
+ errorMessage: validationMessage,
179
+ },
180
+ [parentFormControl, reportsToField, resolvedInvalid, validationMessage],
181
+ );
182
+
86
183
  const surfacesRef = useRef<Set<PickerSurfaceType>>(new Set());
87
184
  const anchorRef = useRef<ComponentRef<typeof View>>(null);
88
185
  const triggerRef = useRef<ComponentRef<typeof View>>(null);
@@ -133,6 +230,7 @@ export const DatePickerRoot = forwardRef<ComponentRef<typeof View>, DatePickerRo
133
230
  disabled,
134
231
  minValue,
135
232
  maxValue,
233
+ isDateUnavailable,
136
234
  locale,
137
235
  labels,
138
236
  registerSurface,
@@ -149,6 +247,7 @@ export const DatePickerRoot = forwardRef<ComponentRef<typeof View>, DatePickerRo
149
247
  disabled,
150
248
  minValue,
151
249
  maxValue,
250
+ isDateUnavailable,
152
251
  locale,
153
252
  labels,
154
253
  registerSurface,
@@ -157,6 +256,22 @@ export const DatePickerRoot = forwardRef<ComponentRef<typeof View>, DatePickerRo
157
256
 
158
257
  const Comp = asChild ? Slot : View;
159
258
 
259
+ const field = (
260
+ <DateFieldRoot
261
+ value={value}
262
+ onValueChange={(next) => setValue(next as DateId | undefined)}
263
+ mode="date"
264
+ locale={locale}
265
+ labels={labelsProp}
266
+ isDisabled={disabled}
267
+ isReadOnly={isReadOnly}
268
+ isInvalid={resolvedInvalid}
269
+ isRequired={isRequired}
270
+ >
271
+ {children}
272
+ </DateFieldRoot>
273
+ );
274
+
160
275
  return (
161
276
  <DatePickerContext.Provider value={contextValue}>
162
277
  <Comp
@@ -164,19 +279,13 @@ export const DatePickerRoot = forwardRef<ComponentRef<typeof View>, DatePickerRo
164
279
  {...props}
165
280
  {...mergeDataAttributes(props, dataAttributes({ disabled, open }))}
166
281
  >
167
- <DateFieldRoot
168
- value={value}
169
- onValueChange={(next) => setValue(next as DateId | undefined)}
170
- mode="date"
171
- locale={locale}
172
- labels={labelsProp}
173
- isDisabled={disabled}
174
- isReadOnly={isReadOnly}
175
- isInvalid={isInvalid}
176
- isRequired={isRequired}
177
- >
178
- {children}
179
- </DateFieldRoot>
282
+ {standaloneFormControl ? (
283
+ <FormControlContext.Provider value={standaloneFormControl}>
284
+ {field}
285
+ </FormControlContext.Provider>
286
+ ) : (
287
+ field
288
+ )}
180
289
  </Comp>
181
290
  </DatePickerContext.Provider>
182
291
  );
@@ -14,6 +14,7 @@ export interface DatePickerContextValue {
14
14
  disabled: boolean;
15
15
  minValue?: DateId;
16
16
  maxValue?: DateId;
17
+ isDateUnavailable?: (date: DateId) => boolean;
17
18
  locale: string;
18
19
  labels: DateComponentLabels;
19
20
  registerSurface: (type: PickerSurfaceType) => void;