@wordpress/components 29.12.0 → 30.0.0

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 (337) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/build/autocomplete/index.js +4 -0
  3. package/build/autocomplete/index.js.map +1 -1
  4. package/build/box-control/input-control.js +2 -2
  5. package/build/box-control/input-control.js.map +1 -1
  6. package/build/calendar/date-calendar/index.js +69 -0
  7. package/build/calendar/date-calendar/index.js.map +1 -0
  8. package/build/calendar/date-range-calendar/index.js +172 -0
  9. package/build/calendar/date-range-calendar/index.js.map +1 -0
  10. package/build/calendar/index.js +27 -0
  11. package/build/calendar/index.js.map +1 -0
  12. package/build/calendar/types.js +6 -0
  13. package/build/calendar/types.js.map +1 -0
  14. package/build/calendar/utils/constants.js +68 -0
  15. package/build/calendar/utils/constants.js.map +1 -0
  16. package/build/calendar/utils/day-cell.js +137 -0
  17. package/build/calendar/utils/day-cell.js.map +1 -0
  18. package/build/calendar/utils/misc.js +10 -0
  19. package/build/calendar/utils/misc.js.map +1 -0
  20. package/build/calendar/utils/use-localization-props.js +162 -0
  21. package/build/calendar/utils/use-localization-props.js.map +1 -0
  22. package/build/custom-gradient-picker/gradient-bar/control-points.js +1 -1
  23. package/build/custom-gradient-picker/gradient-bar/control-points.js.map +1 -1
  24. package/build/custom-select-control-v2/custom-select.js +3 -3
  25. package/build/custom-select-control-v2/custom-select.js.map +1 -1
  26. package/build/date-time/date/index.js +1 -1
  27. package/build/date-time/date/index.js.map +1 -1
  28. package/build/form-token-field/index.js +11 -1
  29. package/build/form-token-field/index.js.map +1 -1
  30. package/build/form-token-field/token.js +1 -1
  31. package/build/form-token-field/token.js.map +1 -1
  32. package/build/icon/index.js +2 -0
  33. package/build/icon/index.js.map +1 -1
  34. package/build/mobile/bottom-sheet/cell.native.js +2 -2
  35. package/build/mobile/bottom-sheet/cell.native.js.map +1 -1
  36. package/build/mobile/link-picker/index.native.js +1 -1
  37. package/build/mobile/link-picker/index.native.js.map +1 -1
  38. package/build/navigation/menu/menu-title-search.js +1 -1
  39. package/build/navigation/menu/menu-title-search.js.map +1 -1
  40. package/build/palette-edit/index.js +4 -4
  41. package/build/palette-edit/index.js.map +1 -1
  42. package/build/private-apis.js +5 -1
  43. package/build/private-apis.js.map +1 -1
  44. package/build/select-control/index.js +1 -1
  45. package/build/select-control/index.js.map +1 -1
  46. package/build/toggle-group-control/toggle-group-control/as-button-group.js.map +1 -1
  47. package/build/utils/hooks/use-controlled-value.js +8 -4
  48. package/build/utils/hooks/use-controlled-value.js.map +1 -1
  49. package/build/validated-form-controls/components/checkbox-control.js +52 -0
  50. package/build/validated-form-controls/components/checkbox-control.js.map +1 -0
  51. package/build/validated-form-controls/components/combobox-control.js +64 -0
  52. package/build/validated-form-controls/components/combobox-control.js.map +1 -0
  53. package/build/validated-form-controls/components/custom-select-control.js +71 -0
  54. package/build/validated-form-controls/components/custom-select-control.js.map +1 -0
  55. package/build/validated-form-controls/components/index.js +138 -0
  56. package/build/validated-form-controls/components/index.js.map +1 -0
  57. package/build/validated-form-controls/components/input-control.js +50 -0
  58. package/build/validated-form-controls/components/input-control.js.map +1 -0
  59. package/build/validated-form-controls/components/number-control.js +53 -0
  60. package/build/validated-form-controls/components/number-control.js.map +1 -0
  61. package/build/validated-form-controls/components/radio-control.js +51 -0
  62. package/build/validated-form-controls/components/radio-control.js.map +1 -0
  63. package/build/validated-form-controls/components/range-control.js +51 -0
  64. package/build/validated-form-controls/components/range-control.js.map +1 -0
  65. package/build/validated-form-controls/components/select-control.js +53 -0
  66. package/build/validated-form-controls/components/select-control.js.map +1 -0
  67. package/build/validated-form-controls/components/text-control.js +51 -0
  68. package/build/validated-form-controls/components/text-control.js.map +1 -0
  69. package/build/validated-form-controls/components/textarea-control.js +50 -0
  70. package/build/validated-form-controls/components/textarea-control.js.map +1 -0
  71. package/build/validated-form-controls/components/toggle-control.js +60 -0
  72. package/build/validated-form-controls/components/toggle-control.js.map +1 -0
  73. package/build/validated-form-controls/components/toggle-group-control.js +69 -0
  74. package/build/validated-form-controls/components/toggle-group-control.js.map +1 -0
  75. package/build/validated-form-controls/components/types.js +6 -0
  76. package/build/validated-form-controls/components/types.js.map +1 -0
  77. package/build/validated-form-controls/control-with-error.js +137 -0
  78. package/build/validated-form-controls/control-with-error.js.map +1 -0
  79. package/build/validated-form-controls/index.js +28 -0
  80. package/build/validated-form-controls/index.js.map +1 -0
  81. package/build-module/autocomplete/index.js +4 -0
  82. package/build-module/autocomplete/index.js.map +1 -1
  83. package/build-module/box-control/input-control.js +2 -2
  84. package/build-module/box-control/input-control.js.map +1 -1
  85. package/build-module/calendar/date-calendar/index.js +59 -0
  86. package/build-module/calendar/date-calendar/index.js.map +1 -0
  87. package/build-module/calendar/date-range-calendar/index.js +161 -0
  88. package/build-module/calendar/date-range-calendar/index.js.map +1 -0
  89. package/build-module/calendar/index.js +4 -0
  90. package/build-module/calendar/index.js.map +1 -0
  91. package/build-module/calendar/types.js +2 -0
  92. package/build-module/calendar/types.js.map +1 -0
  93. package/build-module/calendar/utils/constants.js +61 -0
  94. package/build-module/calendar/utils/constants.js.map +1 -0
  95. package/build-module/calendar/utils/day-cell.js +131 -0
  96. package/build-module/calendar/utils/day-cell.js.map +1 -0
  97. package/build-module/calendar/utils/misc.js +4 -0
  98. package/build-module/calendar/utils/misc.js.map +1 -0
  99. package/build-module/calendar/utils/use-localization-props.js +154 -0
  100. package/build-module/calendar/utils/use-localization-props.js.map +1 -0
  101. package/build-module/custom-gradient-picker/gradient-bar/control-points.js +1 -1
  102. package/build-module/custom-gradient-picker/gradient-bar/control-points.js.map +1 -1
  103. package/build-module/custom-select-control-v2/custom-select.js +4 -4
  104. package/build-module/custom-select-control-v2/custom-select.js.map +1 -1
  105. package/build-module/date-time/date/index.js +1 -1
  106. package/build-module/date-time/date/index.js.map +1 -1
  107. package/build-module/form-token-field/index.js +11 -1
  108. package/build-module/form-token-field/index.js.map +1 -1
  109. package/build-module/form-token-field/token.js +1 -1
  110. package/build-module/form-token-field/token.js.map +1 -1
  111. package/build-module/icon/index.js +2 -0
  112. package/build-module/icon/index.js.map +1 -1
  113. package/build-module/mobile/bottom-sheet/cell.native.js +2 -2
  114. package/build-module/mobile/bottom-sheet/cell.native.js.map +1 -1
  115. package/build-module/mobile/link-picker/index.native.js +1 -1
  116. package/build-module/mobile/link-picker/index.native.js.map +1 -1
  117. package/build-module/navigation/menu/menu-title-search.js +1 -1
  118. package/build-module/navigation/menu/menu-title-search.js.map +1 -1
  119. package/build-module/palette-edit/index.js +4 -4
  120. package/build-module/palette-edit/index.js.map +1 -1
  121. package/build-module/private-apis.js +5 -1
  122. package/build-module/private-apis.js.map +1 -1
  123. package/build-module/select-control/index.js +1 -1
  124. package/build-module/select-control/index.js.map +1 -1
  125. package/build-module/toggle-group-control/toggle-group-control/as-button-group.js.map +1 -1
  126. package/build-module/utils/hooks/use-controlled-value.js +9 -5
  127. package/build-module/utils/hooks/use-controlled-value.js.map +1 -1
  128. package/build-module/validated-form-controls/components/checkbox-control.js +44 -0
  129. package/build-module/validated-form-controls/components/checkbox-control.js.map +1 -0
  130. package/build-module/validated-form-controls/components/combobox-control.js +56 -0
  131. package/build-module/validated-form-controls/components/combobox-control.js.map +1 -0
  132. package/build-module/validated-form-controls/components/custom-select-control.js +63 -0
  133. package/build-module/validated-form-controls/components/custom-select-control.js.map +1 -0
  134. package/build-module/validated-form-controls/components/index.js +13 -0
  135. package/build-module/validated-form-controls/components/index.js.map +1 -0
  136. package/build-module/validated-form-controls/components/input-control.js +42 -0
  137. package/build-module/validated-form-controls/components/input-control.js.map +1 -0
  138. package/build-module/validated-form-controls/components/number-control.js +45 -0
  139. package/build-module/validated-form-controls/components/number-control.js.map +1 -0
  140. package/build-module/validated-form-controls/components/radio-control.js +43 -0
  141. package/build-module/validated-form-controls/components/radio-control.js.map +1 -0
  142. package/build-module/validated-form-controls/components/range-control.js +43 -0
  143. package/build-module/validated-form-controls/components/range-control.js.map +1 -0
  144. package/build-module/validated-form-controls/components/select-control.js +45 -0
  145. package/build-module/validated-form-controls/components/select-control.js.map +1 -0
  146. package/build-module/validated-form-controls/components/text-control.js +43 -0
  147. package/build-module/validated-form-controls/components/text-control.js.map +1 -0
  148. package/build-module/validated-form-controls/components/textarea-control.js +42 -0
  149. package/build-module/validated-form-controls/components/textarea-control.js.map +1 -0
  150. package/build-module/validated-form-controls/components/toggle-control.js +52 -0
  151. package/build-module/validated-form-controls/components/toggle-control.js.map +1 -0
  152. package/build-module/validated-form-controls/components/toggle-group-control.js +62 -0
  153. package/build-module/validated-form-controls/components/toggle-group-control.js.map +1 -0
  154. package/build-module/validated-form-controls/components/types.js +2 -0
  155. package/build-module/validated-form-controls/components/types.js.map +1 -0
  156. package/build-module/validated-form-controls/control-with-error.js +129 -0
  157. package/build-module/validated-form-controls/control-with-error.js.map +1 -0
  158. package/build-module/validated-form-controls/index.js +3 -0
  159. package/build-module/validated-form-controls/index.js.map +1 -0
  160. package/build-style/style-rtl.css +418 -22
  161. package/build-style/style.css +418 -22
  162. package/build-types/autocomplete/index.d.ts.map +1 -1
  163. package/build-types/box-control/input-control.d.ts.map +1 -1
  164. package/build-types/box-control/utils.d.ts +7 -7
  165. package/build-types/calendar/date-calendar/index.d.ts +11 -0
  166. package/build-types/calendar/date-calendar/index.d.ts.map +1 -0
  167. package/build-types/calendar/date-range-calendar/index.d.ts +14 -0
  168. package/build-types/calendar/date-range-calendar/index.d.ts.map +1 -0
  169. package/build-types/calendar/index.d.ts +4 -0
  170. package/build-types/calendar/index.d.ts.map +1 -0
  171. package/build-types/calendar/stories/date-calendar.story.d.ts +16 -0
  172. package/build-types/calendar/stories/date-calendar.story.d.ts.map +1 -0
  173. package/build-types/calendar/stories/date-range-calendar.story.d.ts +16 -0
  174. package/build-types/calendar/stories/date-range-calendar.story.d.ts.map +1 -0
  175. package/build-types/calendar/test/__utils__/index.d.ts +10 -0
  176. package/build-types/calendar/test/__utils__/index.d.ts.map +1 -0
  177. package/build-types/calendar/test/date-calendar.d.ts +2 -0
  178. package/build-types/calendar/test/date-calendar.d.ts.map +1 -0
  179. package/build-types/calendar/test/date-range-calendar.d.ts +2 -0
  180. package/build-types/calendar/test/date-range-calendar.d.ts.map +1 -0
  181. package/build-types/calendar/types.d.ts +317 -0
  182. package/build-types/calendar/types.d.ts.map +1 -0
  183. package/build-types/calendar/utils/constants.d.ts +52 -0
  184. package/build-types/calendar/utils/constants.d.ts.map +1 -0
  185. package/build-types/calendar/utils/day-cell.d.ts +21 -0
  186. package/build-types/calendar/utils/day-cell.d.ts.map +1 -0
  187. package/build-types/calendar/utils/misc.d.ts +2 -0
  188. package/build-types/calendar/utils/misc.d.ts.map +1 -0
  189. package/build-types/calendar/utils/use-localization-props.d.ts +64 -0
  190. package/build-types/calendar/utils/use-localization-props.d.ts.map +1 -0
  191. package/build-types/color-picker/styles.d.ts.map +1 -1
  192. package/build-types/custom-gradient-picker/constants.d.ts +6 -3
  193. package/build-types/custom-gradient-picker/constants.d.ts.map +1 -1
  194. package/build-types/custom-select-control-v2/custom-select.d.ts.map +1 -1
  195. package/build-types/dimension-control/sizes.d.ts +15 -3
  196. package/build-types/dimension-control/sizes.d.ts.map +1 -1
  197. package/build-types/font-size-picker/constants.d.ts +2 -2
  198. package/build-types/font-size-picker/constants.d.ts.map +1 -1
  199. package/build-types/form-token-field/index.d.ts.map +1 -1
  200. package/build-types/icon/index.d.ts.map +1 -1
  201. package/build-types/popover/overlay-middlewares.d.ts +6 -1
  202. package/build-types/popover/overlay-middlewares.d.ts.map +1 -1
  203. package/build-types/private-apis.d.ts.map +1 -1
  204. package/build-types/select-control/stories/index.story.d.ts.map +1 -1
  205. package/build-types/toggle-group-control/toggle-group-control/as-button-group.d.ts.map +1 -1
  206. package/build-types/utils/hooks/use-controlled-value.d.ts +2 -2
  207. package/build-types/utils/hooks/use-controlled-value.d.ts.map +1 -1
  208. package/build-types/validated-form-controls/components/checkbox-control.d.ts +9 -0
  209. package/build-types/validated-form-controls/components/checkbox-control.d.ts.map +1 -0
  210. package/build-types/validated-form-controls/components/combobox-control.d.ts +21 -0
  211. package/build-types/validated-form-controls/components/combobox-control.d.ts.map +1 -0
  212. package/build-types/validated-form-controls/components/custom-select-control.d.ts +4 -0
  213. package/build-types/validated-form-controls/components/custom-select-control.d.ts.map +1 -0
  214. package/build-types/validated-form-controls/components/index.d.ts +13 -0
  215. package/build-types/validated-form-controls/components/index.d.ts.map +1 -0
  216. package/build-types/validated-form-controls/components/input-control.d.ts +4 -0
  217. package/build-types/validated-form-controls/components/input-control.d.ts.map +1 -0
  218. package/build-types/validated-form-controls/components/number-control.d.ts +17 -0
  219. package/build-types/validated-form-controls/components/number-control.d.ts.map +1 -0
  220. package/build-types/validated-form-controls/components/radio-control.d.ts +11 -0
  221. package/build-types/validated-form-controls/components/radio-control.d.ts.map +1 -0
  222. package/build-types/validated-form-controls/components/range-control.d.ts +36 -0
  223. package/build-types/validated-form-controls/components/range-control.d.ts.map +1 -0
  224. package/build-types/validated-form-controls/components/select-control.d.ts +9 -0
  225. package/build-types/validated-form-controls/components/select-control.d.ts.map +1 -0
  226. package/build-types/validated-form-controls/components/stories/checkbox-control.story.d.ts +12 -0
  227. package/build-types/validated-form-controls/components/stories/checkbox-control.story.d.ts.map +1 -0
  228. package/build-types/validated-form-controls/components/stories/combobox-control.story.d.ts +12 -0
  229. package/build-types/validated-form-controls/components/stories/combobox-control.story.d.ts.map +1 -0
  230. package/build-types/validated-form-controls/components/stories/custom-select-control.story.d.ts +12 -0
  231. package/build-types/validated-form-controls/components/stories/custom-select-control.story.d.ts.map +1 -0
  232. package/build-types/validated-form-controls/components/stories/input-control.story.d.ts +18 -0
  233. package/build-types/validated-form-controls/components/stories/input-control.story.d.ts.map +1 -0
  234. package/build-types/validated-form-controls/components/stories/number-control.story.d.ts +12 -0
  235. package/build-types/validated-form-controls/components/stories/number-control.story.d.ts.map +1 -0
  236. package/build-types/validated-form-controls/components/stories/overview.story.d.ts +19 -0
  237. package/build-types/validated-form-controls/components/stories/overview.story.d.ts.map +1 -0
  238. package/build-types/validated-form-controls/components/stories/radio-control.story.d.ts +12 -0
  239. package/build-types/validated-form-controls/components/stories/radio-control.story.d.ts.map +1 -0
  240. package/build-types/validated-form-controls/components/stories/range-control.story.d.ts +9 -0
  241. package/build-types/validated-form-controls/components/stories/range-control.story.d.ts.map +1 -0
  242. package/build-types/validated-form-controls/components/stories/select-control.story.d.ts +12 -0
  243. package/build-types/validated-form-controls/components/stories/select-control.story.d.ts.map +1 -0
  244. package/build-types/validated-form-controls/components/stories/story-utils.d.ts +9 -0
  245. package/build-types/validated-form-controls/components/stories/story-utils.d.ts.map +1 -0
  246. package/build-types/validated-form-controls/components/stories/text-control.story.d.ts +9 -0
  247. package/build-types/validated-form-controls/components/stories/text-control.story.d.ts.map +1 -0
  248. package/build-types/validated-form-controls/components/stories/textarea-control.story.d.ts +9 -0
  249. package/build-types/validated-form-controls/components/stories/textarea-control.story.d.ts.map +1 -0
  250. package/build-types/validated-form-controls/components/stories/toggle-control.story.d.ts +9 -0
  251. package/build-types/validated-form-controls/components/stories/toggle-control.story.d.ts.map +1 -0
  252. package/build-types/validated-form-controls/components/stories/toggle-group-control.story.d.ts +9 -0
  253. package/build-types/validated-form-controls/components/stories/toggle-group-control.story.d.ts.map +1 -0
  254. package/build-types/validated-form-controls/components/text-control.d.ts +8 -0
  255. package/build-types/validated-form-controls/components/text-control.d.ts.map +1 -0
  256. package/build-types/validated-form-controls/components/textarea-control.d.ts +7 -0
  257. package/build-types/validated-form-controls/components/textarea-control.d.ts.map +1 -0
  258. package/build-types/validated-form-controls/components/toggle-control.d.ts +7 -0
  259. package/build-types/validated-form-controls/components/toggle-control.d.ts.map +1 -0
  260. package/build-types/validated-form-controls/components/toggle-group-control.d.ts +15 -0
  261. package/build-types/validated-form-controls/components/toggle-group-control.d.ts.map +1 -0
  262. package/build-types/validated-form-controls/components/types.d.ts +27 -0
  263. package/build-types/validated-form-controls/components/types.d.ts.map +1 -0
  264. package/build-types/validated-form-controls/control-with-error.d.ts +36 -0
  265. package/build-types/validated-form-controls/control-with-error.d.ts.map +1 -0
  266. package/build-types/validated-form-controls/index.d.ts +3 -0
  267. package/build-types/validated-form-controls/index.d.ts.map +1 -0
  268. package/package.json +21 -20
  269. package/src/autocomplete/index.tsx +4 -0
  270. package/src/box-control/input-control.tsx +14 -5
  271. package/src/calendar/date-calendar/README.md +261 -0
  272. package/src/calendar/date-calendar/index.tsx +69 -0
  273. package/src/calendar/date-range-calendar/README.md +298 -0
  274. package/src/calendar/date-range-calendar/index.tsx +215 -0
  275. package/src/calendar/index.tsx +3 -0
  276. package/src/calendar/stories/date-calendar.story.tsx +221 -0
  277. package/src/calendar/stories/date-range-calendar.story.tsx +230 -0
  278. package/src/calendar/style.scss +431 -0
  279. package/src/calendar/test/__utils__/index.ts +56 -0
  280. package/src/calendar/test/date-calendar.tsx +975 -0
  281. package/src/calendar/test/date-range-calendar.tsx +1701 -0
  282. package/src/calendar/types.ts +342 -0
  283. package/src/calendar/utils/constants.ts +62 -0
  284. package/src/calendar/utils/day-cell.tsx +133 -0
  285. package/src/calendar/utils/misc.ts +3 -0
  286. package/src/calendar/utils/use-localization-props.ts +169 -0
  287. package/src/custom-gradient-picker/gradient-bar/control-points.tsx +1 -1
  288. package/src/custom-select-control-v2/custom-select.tsx +6 -3
  289. package/src/date-time/date/index.tsx +1 -1
  290. package/src/dimension-control/test/__snapshots__/index.test.js.snap +8 -8
  291. package/src/form-token-field/index.tsx +12 -1
  292. package/src/form-token-field/token.tsx +1 -1
  293. package/src/icon/index.tsx +2 -0
  294. package/src/mobile/bottom-sheet/cell.native.js +2 -2
  295. package/src/mobile/link-picker/index.native.js +1 -1
  296. package/src/navigation/menu/menu-title-search.tsx +1 -1
  297. package/src/palette-edit/index.tsx +4 -4
  298. package/src/private-apis.ts +5 -0
  299. package/src/select-control/index.tsx +1 -1
  300. package/src/select-control/style.scss +0 -6
  301. package/src/style.scss +3 -2
  302. package/src/toggle-group-control/toggle-group-control/as-button-group.tsx +3 -1
  303. package/src/utils/hooks/use-controlled-value.ts +16 -8
  304. package/src/validated-form-controls/components/checkbox-control.tsx +64 -0
  305. package/src/validated-form-controls/components/combobox-control.tsx +77 -0
  306. package/src/validated-form-controls/components/custom-select-control.tsx +86 -0
  307. package/src/validated-form-controls/components/index.ts +12 -0
  308. package/src/validated-form-controls/components/input-control.tsx +59 -0
  309. package/src/validated-form-controls/components/number-control.tsx +61 -0
  310. package/src/validated-form-controls/components/radio-control.tsx +60 -0
  311. package/src/validated-form-controls/components/range-control.tsx +60 -0
  312. package/src/validated-form-controls/components/select-control.tsx +75 -0
  313. package/src/validated-form-controls/components/stories/checkbox-control.story.tsx +57 -0
  314. package/src/validated-form-controls/components/stories/combobox-control.story.tsx +64 -0
  315. package/src/validated-form-controls/components/stories/custom-select-control.story.tsx +64 -0
  316. package/src/validated-form-controls/components/stories/input-control.story.tsx +132 -0
  317. package/src/validated-form-controls/components/stories/number-control.story.tsx +62 -0
  318. package/src/validated-form-controls/components/stories/overview.mdx +52 -0
  319. package/src/validated-form-controls/components/stories/overview.story.tsx +100 -0
  320. package/src/validated-form-controls/components/stories/radio-control.story.tsx +64 -0
  321. package/src/validated-form-controls/components/stories/range-control.story.tsx +60 -0
  322. package/src/validated-form-controls/components/stories/select-control.story.tsx +60 -0
  323. package/src/validated-form-controls/components/stories/story-utils.tsx +46 -0
  324. package/src/validated-form-controls/components/stories/text-control.story.tsx +55 -0
  325. package/src/validated-form-controls/components/stories/textarea-control.story.tsx +52 -0
  326. package/src/validated-form-controls/components/stories/toggle-control.story.tsx +55 -0
  327. package/src/validated-form-controls/components/stories/toggle-group-control.story.tsx +66 -0
  328. package/src/validated-form-controls/components/text-control.tsx +60 -0
  329. package/src/validated-form-controls/components/textarea-control.tsx +59 -0
  330. package/src/validated-form-controls/components/toggle-control.tsx +69 -0
  331. package/src/validated-form-controls/components/toggle-group-control.tsx +82 -0
  332. package/src/validated-form-controls/components/types.ts +28 -0
  333. package/src/validated-form-controls/control-with-error.tsx +198 -0
  334. package/src/validated-form-controls/index.ts +2 -0
  335. package/src/validated-form-controls/style.scss +75 -0
  336. package/tsconfig.tsbuildinfo +1 -1
  337. package/src/dimension-control/style.scss +0 -22
@@ -58,7 +58,7 @@ function ControlPointButton( {
58
58
  aria-label={ sprintf(
59
59
  // translators: 1: gradient position e.g: 70. 2: gradient color code e.g: rgb(52,121,151).
60
60
  __(
61
- 'Gradient control point at position %1$s%% with color code %2$s.'
61
+ 'Gradient control point at position %1$d%% with color code %2$s.'
62
62
  ),
63
63
  position,
64
64
  color
@@ -7,7 +7,7 @@ import * as Ariakit from '@ariakit/react';
7
7
  * WordPress dependencies
8
8
  */
9
9
  import { createContext, useCallback, useMemo } from '@wordpress/element';
10
- import { __, sprintf } from '@wordpress/i18n';
10
+ import { __, _n, sprintf } from '@wordpress/i18n';
11
11
 
12
12
  /**
13
13
  * Internal dependencies
@@ -43,8 +43,11 @@ function defaultRenderSelectedValue(
43
43
  if ( Array.isArray( value ) ) {
44
44
  return value.length === 1
45
45
  ? value[ 0 ]
46
- : // translators: %s: number of items selected (it will always be 2 or more items)
47
- sprintf( __( '%s items selected' ), value.length );
46
+ : sprintf(
47
+ // translators: %d: number of items selected (it will always be 2 or more items)
48
+ _n( '%d item selected', '%d items selected', value.length ),
49
+ value.length
50
+ );
48
51
  }
49
52
 
50
53
  return value;
@@ -344,7 +344,7 @@ function getDayLabel( date: Date, isSelected: boolean, numEvents: number ) {
344
344
  );
345
345
  } else if ( isSelected ) {
346
346
  return sprintf(
347
- // translators: %s: The calendar date.
347
+ // translators: 1: The calendar date.
348
348
  __( '%1$s. Selected' ),
349
349
  localizedDate
350
350
  );
@@ -193,13 +193,13 @@ exports[`DimensionControl rendering renders with custom sizes 1`] = `
193
193
 
194
194
  <div>
195
195
  <div
196
- class="components-base-control emotion-0 emotion-1"
196
+ class="components-base-control components-select-control block-editor-dimension-control emotion-0 emotion-1"
197
197
  >
198
198
  <div
199
199
  class="components-base-control__field emotion-2 emotion-3"
200
200
  >
201
201
  <div
202
- class="components-flex components-input-base components-select-control block-editor-dimension-control emotion-4 emotion-5 emotion-6 emotion-7"
202
+ class="components-flex components-input-base emotion-4 emotion-5 emotion-6 emotion-7"
203
203
  data-wp-c16t="true"
204
204
  data-wp-component="InputBase"
205
205
  >
@@ -475,13 +475,13 @@ exports[`DimensionControl rendering renders with defaults 1`] = `
475
475
 
476
476
  <div>
477
477
  <div
478
- class="components-base-control emotion-0 emotion-1"
478
+ class="components-base-control components-select-control block-editor-dimension-control emotion-0 emotion-1"
479
479
  >
480
480
  <div
481
481
  class="components-base-control__field emotion-2 emotion-3"
482
482
  >
483
483
  <div
484
- class="components-flex components-input-base components-select-control block-editor-dimension-control emotion-4 emotion-5 emotion-6 emotion-7"
484
+ class="components-flex components-input-base emotion-4 emotion-5 emotion-6 emotion-7"
485
485
  data-wp-c16t="true"
486
486
  data-wp-component="InputBase"
487
487
  >
@@ -767,13 +767,13 @@ exports[`DimensionControl rendering renders with icon and custom icon label 1`]
767
767
 
768
768
  <div>
769
769
  <div
770
- class="components-base-control emotion-0 emotion-1"
770
+ class="components-base-control components-select-control block-editor-dimension-control emotion-0 emotion-1"
771
771
  >
772
772
  <div
773
773
  class="components-base-control__field emotion-2 emotion-3"
774
774
  >
775
775
  <div
776
- class="components-flex components-input-base components-select-control block-editor-dimension-control emotion-4 emotion-5 emotion-6 emotion-7"
776
+ class="components-flex components-input-base emotion-4 emotion-5 emotion-6 emotion-7"
777
777
  data-wp-c16t="true"
778
778
  data-wp-component="InputBase"
779
779
  >
@@ -1071,13 +1071,13 @@ exports[`DimensionControl rendering renders with icon and default icon label 1`]
1071
1071
 
1072
1072
  <div>
1073
1073
  <div
1074
- class="components-base-control emotion-0 emotion-1"
1074
+ class="components-base-control components-select-control block-editor-dimension-control emotion-0 emotion-1"
1075
1075
  >
1076
1076
  <div
1077
1077
  class="components-base-control__field emotion-2 emotion-3"
1078
1078
  >
1079
1079
  <div
1080
- class="components-flex components-input-base components-select-control block-editor-dimension-control emotion-4 emotion-5 emotion-6 emotion-7"
1080
+ class="components-flex components-input-base emotion-4 emotion-5 emotion-6 emotion-7"
1081
1081
  data-wp-c16t="true"
1082
1082
  data-wp-component="InputBase"
1083
1083
  >
@@ -241,6 +241,9 @@ export function FormTokenField( props: FormTokenFieldProps ) {
241
241
  case 'Escape':
242
242
  preventDefault = handleEscapeKey( event );
243
243
  break;
244
+ case 'Tab':
245
+ preventDefault = handleTabKey( event );
246
+ break;
244
247
  default:
245
248
  break;
246
249
  }
@@ -372,17 +375,25 @@ export function FormTokenField( props: FormTokenFieldProps ) {
372
375
  return true; // PreventDefault.
373
376
  }
374
377
 
375
- function handleEscapeKey( event: KeyboardEvent ) {
378
+ function collapseSuggestionsList( event: KeyboardEvent ) {
376
379
  if ( event.target instanceof HTMLInputElement ) {
377
380
  setIncompleteTokenValue( event.target.value );
378
381
  setIsExpanded( false );
379
382
  setSelectedSuggestionIndex( -1 );
380
383
  setSelectedSuggestionScroll( false );
381
384
  }
385
+ }
382
386
 
387
+ function handleEscapeKey( event: KeyboardEvent ) {
388
+ collapseSuggestionsList( event );
383
389
  return true; // PreventDefault.
384
390
  }
385
391
 
392
+ function handleTabKey( event: KeyboardEvent ) {
393
+ collapseSuggestionsList( event );
394
+ return false; // Do not prevent the default behavior.
395
+ }
396
+
386
397
  function handleCommaKey() {
387
398
  if ( inputHasValidValue() ) {
388
399
  addNewToken( incompleteTokenValue );
@@ -47,7 +47,7 @@ export default function Token( {
47
47
  const transformedValue = displayTransform( value );
48
48
  const termPositionAndCount = sprintf(
49
49
  /* translators: 1: term name, 2: term position in a set of terms, 3: total term set count. */
50
- __( '%1$s (%2$s of %3$s)' ),
50
+ __( '%1$s (%2$d of %3$d)' ),
51
51
  transformedValue,
52
52
  termPosition,
53
53
  termsCount
@@ -107,6 +107,8 @@ function Icon( {
107
107
  return cloneElement( icon, {
108
108
  // @ts-ignore Just forwarding the size prop along
109
109
  size,
110
+ width: size,
111
+ height: size,
110
112
  ...additionalProps,
111
113
  } );
112
114
  }
@@ -304,13 +304,13 @@ class BottomSheetCell extends Component {
304
304
  }
305
305
  return ! help
306
306
  ? sprintf(
307
- /* translators: accessibility text. Inline textinput title and value.%1: Cell title, %2: cell value. */
307
+ /* translators: accessibility text. Inline textinput title and value. %1: Cell title, %2: cell value. */
308
308
  _x( '%1$s, %2$s', 'inline textinput cell' ),
309
309
  label,
310
310
  value
311
311
  ) // Separating by ',' is necessary to make a pause on urls (non-capitalized text)
312
312
  : sprintf(
313
- /* translators: accessibility text. Inline textinput title, value and help text.%1: Cell title, %2: cell value, , %3: cell help. */
313
+ /* translators: accessibility text. Inline textinput title, value and help text. %1: Cell title, %2: cell value, , %3: cell help. */
314
314
  _x( '%1$s, %2$s, %3$s', 'inline textinput cell' ),
315
315
  label,
316
316
  value,
@@ -135,7 +135,7 @@ export const LinkPicker = ( {
135
135
  <BottomSheet.LinkSuggestionItemCell
136
136
  accessible
137
137
  accessibilityLabel={ sprintf(
138
- /* translators: Copy URL from the clipboard, https://sample.url */
138
+ /* translators: %s: Copy URL from the clipboard, https://sample.url */
139
139
  __( 'Copy URL from the clipboard, %s' ),
140
140
  clipboardUrl
141
141
  ) }
@@ -77,7 +77,7 @@ function MenuTitleSearch( {
77
77
  const placeholder = sprintf(
78
78
  /* translators: placeholder for menu search box. %s: menu title */
79
79
  __( 'Search %s' ),
80
- title?.toLowerCase()
80
+ title?.toLowerCase() || ''
81
81
  ).trim();
82
82
 
83
83
  return (
@@ -122,8 +122,8 @@ export function getNameAndSlugForPosition(
122
122
 
123
123
  return {
124
124
  name: sprintf(
125
- /* translators: %s: is an id for a custom color */
126
- __( 'Color %s' ),
125
+ /* translators: %d: is an id for a custom color */
126
+ __( 'Color %d' ),
127
127
  position
128
128
  ),
129
129
  slug: `${ slugPrefix }color-${ position }`,
@@ -223,7 +223,7 @@ function Option< T extends PaletteElement >( {
223
223
  aria-label={ sprintf(
224
224
  // translators: %s is a color or gradient name, e.g. "Red".
225
225
  __( 'Edit: %s' ),
226
- element.name.trim().length ? element.name : value
226
+ element.name.trim().length ? element.name : value || ''
227
227
  ) }
228
228
  style={ { padding: 0 } }
229
229
  >
@@ -267,7 +267,7 @@ function Option< T extends PaletteElement >( {
267
267
  __( 'Remove color: %s' ),
268
268
  element.name.trim().length
269
269
  ? element.name
270
- : value
270
+ : value || ''
271
271
  ) }
272
272
  onClick={ onRemove }
273
273
  />
@@ -11,6 +11,8 @@ import { withIgnoreIMEEvents } from './utils/with-ignore-ime-events';
11
11
  import { lock } from './lock-unlock';
12
12
  import Badge from './badge';
13
13
 
14
+ import { DateCalendar, DateRangeCalendar, TZDate } from './calendar';
15
+
14
16
  export const privateApis = {};
15
17
  lock( privateApis, {
16
18
  __experimentalPopoverLegacyPositionToPlacement,
@@ -22,4 +24,7 @@ lock( privateApis, {
22
24
  withIgnoreIMEEvents,
23
25
  Badge,
24
26
  normalizeTextString,
27
+ DateCalendar,
28
+ DateRangeCalendar,
29
+ TZDate,
25
30
  } );
@@ -107,11 +107,11 @@ function UnforwardedSelectControl< V extends string >(
107
107
  <BaseControl
108
108
  help={ help }
109
109
  id={ id }
110
+ className={ classes }
110
111
  __nextHasNoMarginBottom={ __nextHasNoMarginBottom }
111
112
  __associatedWPComponentName="SelectControl"
112
113
  >
113
114
  <StyledInputBase
114
- className={ classes }
115
115
  disabled={ disabled }
116
116
  hideLabelFromVision={ hideLabelFromVision }
117
117
  id={ id }
@@ -2,9 +2,3 @@
2
2
  outline: 0;
3
3
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important;
4
4
  }
5
-
6
- @media (max-width: #{ ($break-medium) }) {
7
- .components-base-control .components-base-control__field .components-select-control__input {
8
- font-size: 16px;
9
- }
10
- }
package/src/style.scss CHANGED
@@ -1,7 +1,7 @@
1
1
  // Include the default WP Components color variables.
2
2
  // TODO: Remove this once all admin-scheme variables are accounted for in the wp-components fallback values.
3
3
  :root {
4
- @include admin-scheme(#3858e9);
4
+ @include admin-scheme( #3858e9 );
5
5
  }
6
6
 
7
7
  // Variables
@@ -13,6 +13,7 @@
13
13
  @import "./badge/styles.scss";
14
14
  @import "./button-group/style.scss";
15
15
  @import "./button/style.scss";
16
+ @import "./calendar/style.scss";
16
17
  @import "./checkbox-control/style.scss";
17
18
  @import "./circular-option-picker/style.scss";
18
19
  @import "./palette-edit/style.scss";
@@ -20,7 +21,6 @@
20
21
  @import "./combobox-control/style.scss";
21
22
  @import "./color-palette/style.scss";
22
23
  @import "./custom-gradient-picker/style.scss";
23
- @import "./dimension-control/style.scss";
24
24
  @import "./draggable/style.scss";
25
25
  @import "./drop-zone/style.scss";
26
26
  @import "./dropdown/style.scss";
@@ -55,3 +55,4 @@
55
55
  @import "./toolbar/toolbar-button/style.scss";
56
56
  @import "./toolbar/toolbar-group/style.scss";
57
57
  @import "./tooltip/style.scss";
58
+ @import "./validated-form-controls/style.scss";
@@ -48,7 +48,9 @@ function UnforwardedToggleGroupControlAsButtonGroup(
48
48
  const { value, defaultValue } =
49
49
  useComputeControlledOrUncontrolledValue( valueProp );
50
50
 
51
- const [ selectedValue, setSelectedValue ] = useControlledValue( {
51
+ const [ selectedValue, setSelectedValue ] = useControlledValue<
52
+ typeof value
53
+ >( {
52
54
  defaultValue,
53
55
  value,
54
56
  onChange,
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { useState } from '@wordpress/element';
4
+ import { useCallback, useState } from '@wordpress/element';
5
5
 
6
6
  type Props< T > = {
7
7
  defaultValue?: T;
8
8
  value?: T;
9
- onChange?: ( value: T ) => void;
9
+ onChange?: ( value: T, ...args: any[] ) => void;
10
10
  };
11
11
 
12
12
  /**
@@ -28,17 +28,25 @@ export function useControlledValue< T >( {
28
28
  const [ state, setState ] = useState( initialValue );
29
29
  const value = hasValue ? valueProp : state;
30
30
 
31
- let setValue: ( nextValue: T ) => void;
31
+ const uncontrolledSetValue = useCallback(
32
+ ( nextValue: T, ...args: any[] ) => {
33
+ setState( nextValue );
34
+ onChange?.( nextValue, ...args );
35
+ },
36
+ [ onChange ]
37
+ );
38
+
39
+ let setValue: typeof onChange;
32
40
  if ( hasValue && typeof onChange === 'function' ) {
41
+ // Controlled mode.
33
42
  setValue = onChange;
34
43
  } else if ( ! hasValue && typeof onChange === 'function' ) {
35
- setValue = ( nextValue ) => {
36
- onChange( nextValue );
37
- setState( nextValue );
38
- };
44
+ // Uncontrolled mode, plus forwarding to the onChange prop.
45
+ setValue = uncontrolledSetValue;
39
46
  } else {
47
+ // Uncontrolled mode, only update internal state.
40
48
  setValue = setState;
41
49
  }
42
50
 
43
- return [ value, setValue as typeof setState ] as const;
51
+ return [ value, setValue ] as const;
44
52
  }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useMergeRefs } from '@wordpress/compose';
5
+ import { forwardRef, useRef } from '@wordpress/element';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { ControlWithError } from '../control-with-error';
11
+ import type { ValidatedControlProps } from './types';
12
+ import CheckboxControl from '../../checkbox-control';
13
+ import type { CheckboxControlProps } from '../../checkbox-control/types';
14
+
15
+ type Value = CheckboxControlProps[ 'checked' ];
16
+
17
+ const UnforwardedValidatedCheckboxControl = (
18
+ {
19
+ required,
20
+ customValidator,
21
+ onChange,
22
+ markWhenOptional,
23
+ ...restProps
24
+ }: Omit<
25
+ React.ComponentProps< typeof CheckboxControl >,
26
+ '__nextHasNoMarginBottom'
27
+ > &
28
+ ValidatedControlProps< Value >,
29
+ forwardedRef: React.ForwardedRef< HTMLInputElement >
30
+ ) => {
31
+ const validityTargetRef = useRef< HTMLDivElement >( null );
32
+ const mergedRefs = useMergeRefs( [ forwardedRef, validityTargetRef ] );
33
+ const valueRef = useRef< Value >( restProps.checked );
34
+
35
+ return (
36
+ <ControlWithError
37
+ required={ required }
38
+ markWhenOptional={ markWhenOptional }
39
+ ref={ mergedRefs }
40
+ customValidator={ () => {
41
+ return customValidator?.( valueRef.current );
42
+ } }
43
+ getValidityTarget={ () =>
44
+ validityTargetRef.current?.querySelector< HTMLInputElement >(
45
+ 'input[type="checkbox"]'
46
+ )
47
+ }
48
+ >
49
+ <CheckboxControl
50
+ __nextHasNoMarginBottom
51
+ onChange={ ( value ) => {
52
+ valueRef.current = value;
53
+ onChange?.( value );
54
+ } }
55
+ // TODO: Upstream limitation - CheckboxControl doesn't support uncontrolled mode, visually.
56
+ { ...restProps }
57
+ />
58
+ </ControlWithError>
59
+ );
60
+ };
61
+
62
+ export const ValidatedCheckboxControl = forwardRef(
63
+ UnforwardedValidatedCheckboxControl
64
+ );
@@ -0,0 +1,77 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useMergeRefs } from '@wordpress/compose';
5
+ import { forwardRef, useEffect, useRef } from '@wordpress/element';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { ControlWithError } from '../control-with-error';
11
+ import type { ValidatedControlProps } from './types';
12
+ import ComboboxControl from '../../combobox-control';
13
+ import type { ComboboxControlProps } from '../../combobox-control/types';
14
+
15
+ type Value = ComboboxControlProps[ 'value' ];
16
+
17
+ const UnforwardedValidatedComboboxControl = (
18
+ {
19
+ required,
20
+ customValidator,
21
+ onChange,
22
+ markWhenOptional,
23
+ ...restProps
24
+ }: Omit<
25
+ React.ComponentProps< typeof ComboboxControl >,
26
+ '__next40pxDefaultSize' | '__nextHasNoMarginBottom'
27
+ > &
28
+ ValidatedControlProps< Value >,
29
+ forwardedRef: React.ForwardedRef< HTMLInputElement >
30
+ ) => {
31
+ const validityTargetRef = useRef< HTMLInputElement >( null );
32
+ const mergedRefs = useMergeRefs( [ forwardedRef, validityTargetRef ] );
33
+ const valueRef = useRef< Value >( restProps.value );
34
+
35
+ // TODO: Upstream limitation - The `required` attribute is not passed down to the input,
36
+ // so we need to set it manually.
37
+ useEffect( () => {
38
+ const input =
39
+ validityTargetRef.current?.querySelector< HTMLInputElement >(
40
+ 'input[role="combobox"]'
41
+ );
42
+ if ( input ) {
43
+ input.required = required ?? false;
44
+ }
45
+ }, [ required ] );
46
+
47
+ return (
48
+ // TODO: Bug - Missing value error is not cleared immediately on change, waits for blur.
49
+ <ControlWithError
50
+ required={ required }
51
+ markWhenOptional={ markWhenOptional }
52
+ ref={ mergedRefs }
53
+ customValidator={ () => {
54
+ return customValidator?.( valueRef.current );
55
+ } }
56
+ getValidityTarget={ () =>
57
+ validityTargetRef.current?.querySelector< HTMLInputElement >(
58
+ 'input[role="combobox"]'
59
+ )
60
+ }
61
+ >
62
+ <ComboboxControl
63
+ __nextHasNoMarginBottom
64
+ __next40pxDefaultSize
65
+ { ...restProps }
66
+ onChange={ ( value ) => {
67
+ valueRef.current = value;
68
+ onChange?.( value );
69
+ } }
70
+ />
71
+ </ControlWithError>
72
+ );
73
+ };
74
+
75
+ export const ValidatedComboboxControl = forwardRef(
76
+ UnforwardedValidatedComboboxControl
77
+ );
@@ -0,0 +1,86 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { forwardRef, useRef } from '@wordpress/element';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import { ControlWithError } from '../control-with-error';
10
+ import type { ValidatedControlProps } from './types';
11
+ import CustomSelectControl from '../../custom-select-control';
12
+ import type {
13
+ CustomSelectOption,
14
+ CustomSelectProps,
15
+ } from '../../custom-select-control/types';
16
+
17
+ type CustomSelectControlProps = CustomSelectProps< CustomSelectOption >;
18
+
19
+ type Value = CustomSelectControlProps[ 'value' ];
20
+
21
+ const UnforwardedValidatedCustomSelectControl = (
22
+ {
23
+ required,
24
+ customValidator,
25
+ onChange,
26
+ markWhenOptional,
27
+ ...restProps
28
+ }: Omit<
29
+ React.ComponentProps< typeof CustomSelectControl >,
30
+ '__next40pxDefaultSize'
31
+ > &
32
+ ValidatedControlProps< Value >,
33
+ forwardedRef: React.ForwardedRef< HTMLDivElement >
34
+ ) => {
35
+ const validityTargetRef = useRef< HTMLSelectElement >( null );
36
+ const valueRef = useRef< Value >( restProps.value );
37
+
38
+ return (
39
+ <div
40
+ className="components-validated-control__wrapper-with-error-delegate"
41
+ ref={ forwardedRef }
42
+ >
43
+ <ControlWithError
44
+ required={ required }
45
+ markWhenOptional={ markWhenOptional }
46
+ customValidator={ () => {
47
+ return customValidator?.( valueRef.current );
48
+ } }
49
+ getValidityTarget={ () => validityTargetRef.current }
50
+ >
51
+ <CustomSelectControl
52
+ // TODO: Upstream limitation - Required isn't passed down correctly,
53
+ // so it needs to be set on a delegate element.
54
+ __next40pxDefaultSize
55
+ onChange={ ( value ) => {
56
+ valueRef.current = value.selectedItem;
57
+ onChange?.( value );
58
+ } }
59
+ { ...restProps }
60
+ />
61
+ </ControlWithError>
62
+ <select
63
+ className="components-validated-control__error-delegate"
64
+ ref={ validityTargetRef }
65
+ required={ required }
66
+ tabIndex={ -1 }
67
+ value={ restProps.value?.key ? 'hasvalue' : '' }
68
+ onChange={ () => {} }
69
+ onFocus={ ( e ) => {
70
+ e.target.previousElementSibling
71
+ ?.querySelector< HTMLButtonElement >(
72
+ '[role="combobox"]'
73
+ )
74
+ ?.focus();
75
+ } }
76
+ >
77
+ <option value="">No selection</option>
78
+ <option value="hasvalue">Has selection</option>
79
+ </select>
80
+ </div>
81
+ );
82
+ };
83
+
84
+ export const ValidatedCustomSelectControl = forwardRef(
85
+ UnforwardedValidatedCustomSelectControl
86
+ );
@@ -0,0 +1,12 @@
1
+ export * from './checkbox-control';
2
+ export * from './combobox-control';
3
+ export * from './custom-select-control';
4
+ export * from './input-control';
5
+ export * from './number-control';
6
+ export * from './radio-control';
7
+ export * from './range-control';
8
+ export * from './select-control';
9
+ export * from './text-control';
10
+ export * from './textarea-control';
11
+ export * from './toggle-control';
12
+ export * from './toggle-group-control';
@@ -0,0 +1,59 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { forwardRef, useRef } from '@wordpress/element';
5
+ import { useMergeRefs } from '@wordpress/compose';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { ControlWithError } from '../control-with-error';
11
+ import type { ValidatedControlProps } from './types';
12
+ import InputControl from '../../input-control';
13
+ import type { InputControlProps } from '../../input-control/types';
14
+
15
+ type Value = InputControlProps[ 'value' ];
16
+
17
+ const UnforwardedValidatedInputControl = (
18
+ {
19
+ required,
20
+ customValidator,
21
+ onChange,
22
+ markWhenOptional,
23
+ ...restProps
24
+ }: Omit<
25
+ React.ComponentProps< typeof InputControl >,
26
+ '__next40pxDefaultSize'
27
+ > &
28
+ ValidatedControlProps< InputControlProps[ 'value' ] >,
29
+ forwardedRef: React.ForwardedRef< HTMLInputElement >
30
+ ) => {
31
+ const validityTargetRef = useRef< HTMLInputElement >( null );
32
+ const mergedRefs = useMergeRefs( [ forwardedRef, validityTargetRef ] );
33
+ const valueRef = useRef< Value >( restProps.value );
34
+
35
+ return (
36
+ <ControlWithError
37
+ required={ required }
38
+ markWhenOptional={ markWhenOptional }
39
+ customValidator={ () => {
40
+ return customValidator?.( valueRef.current );
41
+ } }
42
+ getValidityTarget={ () => validityTargetRef.current }
43
+ >
44
+ <InputControl
45
+ __next40pxDefaultSize
46
+ ref={ mergedRefs }
47
+ onChange={ ( value, ...args ) => {
48
+ valueRef.current = value;
49
+ onChange?.( value, ...args );
50
+ } }
51
+ { ...restProps }
52
+ />
53
+ </ControlWithError>
54
+ );
55
+ };
56
+
57
+ export const ValidatedInputControl = forwardRef(
58
+ UnforwardedValidatedInputControl
59
+ );