@wordpress/components 29.13.1-next.719a03cbe.0 → 30.1.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 (280) hide show
  1. package/CHANGELOG.md +34 -3
  2. package/build/autocomplete/index.js +4 -0
  3. package/build/autocomplete/index.js.map +1 -1
  4. package/build/calendar/date-calendar/index.js +13 -4
  5. package/build/calendar/date-calendar/index.js.map +1 -1
  6. package/build/calendar/date-range-calendar/index.js +8 -4
  7. package/build/calendar/date-range-calendar/index.js.map +1 -1
  8. package/build/calendar/types.js.map +1 -1
  9. package/build/color-picker/styles.js +7 -7
  10. package/build/color-picker/styles.js.map +1 -1
  11. package/build/icon/index.js +2 -0
  12. package/build/icon/index.js.map +1 -1
  13. package/build/index.js +0 -19
  14. package/build/index.js.map +1 -1
  15. package/build/palette-edit/index.js +1 -1
  16. package/build/palette-edit/index.js.map +1 -1
  17. package/build/private-apis.js +9 -1
  18. package/build/private-apis.js.map +1 -1
  19. package/build/range-control/index.js +1 -1
  20. package/build/range-control/index.js.map +1 -1
  21. package/build/range-control/styles/range-control-styles.js +35 -35
  22. package/build/range-control/styles/range-control-styles.js.map +1 -1
  23. package/build/range-control/tooltip.js +15 -15
  24. package/build/range-control/tooltip.js.map +1 -1
  25. package/build/range-control/types.js.map +1 -1
  26. package/build/select-control/index.js +1 -1
  27. package/build/select-control/index.js.map +1 -1
  28. package/build/textarea-control/index.js +7 -1
  29. package/build/textarea-control/index.js.map +1 -1
  30. package/build/toggle-group-control/toggle-group-control/as-button-group.js.map +1 -1
  31. package/build/utils/hooks/use-controlled-value.js +8 -4
  32. package/build/utils/hooks/use-controlled-value.js.map +1 -1
  33. package/build/validated-form-controls/components/checkbox-control.js +52 -0
  34. package/build/validated-form-controls/components/checkbox-control.js.map +1 -0
  35. package/build/validated-form-controls/components/combobox-control.js +64 -0
  36. package/build/validated-form-controls/components/combobox-control.js.map +1 -0
  37. package/build/validated-form-controls/components/custom-select-control.js +71 -0
  38. package/build/validated-form-controls/components/custom-select-control.js.map +1 -0
  39. package/build/validated-form-controls/components/index.js +138 -0
  40. package/build/validated-form-controls/components/index.js.map +1 -0
  41. package/build/validated-form-controls/components/input-control.js +50 -0
  42. package/build/validated-form-controls/components/input-control.js.map +1 -0
  43. package/build/validated-form-controls/components/number-control.js +53 -0
  44. package/build/validated-form-controls/components/number-control.js.map +1 -0
  45. package/build/validated-form-controls/components/radio-control.js +51 -0
  46. package/build/validated-form-controls/components/radio-control.js.map +1 -0
  47. package/build/validated-form-controls/components/range-control.js +51 -0
  48. package/build/validated-form-controls/components/range-control.js.map +1 -0
  49. package/build/validated-form-controls/components/select-control.js +53 -0
  50. package/build/validated-form-controls/components/select-control.js.map +1 -0
  51. package/build/validated-form-controls/components/text-control.js +51 -0
  52. package/build/validated-form-controls/components/text-control.js.map +1 -0
  53. package/build/validated-form-controls/components/textarea-control.js +50 -0
  54. package/build/validated-form-controls/components/textarea-control.js.map +1 -0
  55. package/build/validated-form-controls/components/toggle-control.js +60 -0
  56. package/build/validated-form-controls/components/toggle-control.js.map +1 -0
  57. package/build/validated-form-controls/components/toggle-group-control.js +69 -0
  58. package/build/validated-form-controls/components/toggle-group-control.js.map +1 -0
  59. package/build/validated-form-controls/components/types.js +6 -0
  60. package/build/validated-form-controls/components/types.js.map +1 -0
  61. package/build/validated-form-controls/control-with-error.js +137 -0
  62. package/build/validated-form-controls/control-with-error.js.map +1 -0
  63. package/build/validated-form-controls/index.js +28 -0
  64. package/build/validated-form-controls/index.js.map +1 -0
  65. package/build-module/autocomplete/index.js +4 -0
  66. package/build-module/autocomplete/index.js.map +1 -1
  67. package/build-module/calendar/date-calendar/index.js +11 -3
  68. package/build-module/calendar/date-calendar/index.js.map +1 -1
  69. package/build-module/calendar/date-range-calendar/index.js +8 -4
  70. package/build-module/calendar/date-range-calendar/index.js.map +1 -1
  71. package/build-module/calendar/types.js.map +1 -1
  72. package/build-module/color-picker/styles.js +7 -7
  73. package/build-module/color-picker/styles.js.map +1 -1
  74. package/build-module/icon/index.js +2 -0
  75. package/build-module/icon/index.js.map +1 -1
  76. package/build-module/index.js +0 -1
  77. package/build-module/index.js.map +1 -1
  78. package/build-module/palette-edit/index.js +2 -2
  79. package/build-module/palette-edit/index.js.map +1 -1
  80. package/build-module/private-apis.js +9 -1
  81. package/build-module/private-apis.js.map +1 -1
  82. package/build-module/range-control/index.js +1 -1
  83. package/build-module/range-control/index.js.map +1 -1
  84. package/build-module/range-control/styles/range-control-styles.js +35 -35
  85. package/build-module/range-control/styles/range-control-styles.js.map +1 -1
  86. package/build-module/range-control/tooltip.js +15 -15
  87. package/build-module/range-control/tooltip.js.map +1 -1
  88. package/build-module/range-control/types.js.map +1 -1
  89. package/build-module/select-control/index.js +1 -1
  90. package/build-module/select-control/index.js.map +1 -1
  91. package/build-module/textarea-control/index.js +7 -1
  92. package/build-module/textarea-control/index.js.map +1 -1
  93. package/build-module/toggle-group-control/toggle-group-control/as-button-group.js.map +1 -1
  94. package/build-module/utils/hooks/use-controlled-value.js +9 -5
  95. package/build-module/utils/hooks/use-controlled-value.js.map +1 -1
  96. package/build-module/validated-form-controls/components/checkbox-control.js +44 -0
  97. package/build-module/validated-form-controls/components/checkbox-control.js.map +1 -0
  98. package/build-module/validated-form-controls/components/combobox-control.js +56 -0
  99. package/build-module/validated-form-controls/components/combobox-control.js.map +1 -0
  100. package/build-module/validated-form-controls/components/custom-select-control.js +63 -0
  101. package/build-module/validated-form-controls/components/custom-select-control.js.map +1 -0
  102. package/build-module/validated-form-controls/components/index.js +13 -0
  103. package/build-module/validated-form-controls/components/index.js.map +1 -0
  104. package/build-module/validated-form-controls/components/input-control.js +42 -0
  105. package/build-module/validated-form-controls/components/input-control.js.map +1 -0
  106. package/build-module/validated-form-controls/components/number-control.js +45 -0
  107. package/build-module/validated-form-controls/components/number-control.js.map +1 -0
  108. package/build-module/validated-form-controls/components/radio-control.js +43 -0
  109. package/build-module/validated-form-controls/components/radio-control.js.map +1 -0
  110. package/build-module/validated-form-controls/components/range-control.js +43 -0
  111. package/build-module/validated-form-controls/components/range-control.js.map +1 -0
  112. package/build-module/validated-form-controls/components/select-control.js +45 -0
  113. package/build-module/validated-form-controls/components/select-control.js.map +1 -0
  114. package/build-module/validated-form-controls/components/text-control.js +43 -0
  115. package/build-module/validated-form-controls/components/text-control.js.map +1 -0
  116. package/build-module/validated-form-controls/components/textarea-control.js +42 -0
  117. package/build-module/validated-form-controls/components/textarea-control.js.map +1 -0
  118. package/build-module/validated-form-controls/components/toggle-control.js +52 -0
  119. package/build-module/validated-form-controls/components/toggle-control.js.map +1 -0
  120. package/build-module/validated-form-controls/components/toggle-group-control.js +62 -0
  121. package/build-module/validated-form-controls/components/toggle-group-control.js.map +1 -0
  122. package/build-module/validated-form-controls/components/types.js +2 -0
  123. package/build-module/validated-form-controls/components/types.js.map +1 -0
  124. package/build-module/validated-form-controls/control-with-error.js +129 -0
  125. package/build-module/validated-form-controls/control-with-error.js.map +1 -0
  126. package/build-module/validated-form-controls/index.js +3 -0
  127. package/build-module/validated-form-controls/index.js.map +1 -0
  128. package/build-style/style-rtl.css +81 -71
  129. package/build-style/style.css +81 -71
  130. package/build-types/autocomplete/index.d.ts.map +1 -1
  131. package/build-types/box-control/utils.d.ts +7 -7
  132. package/build-types/calendar/date-calendar/index.d.ts.map +1 -1
  133. package/build-types/calendar/date-range-calendar/index.d.ts.map +1 -1
  134. package/build-types/calendar/types.d.ts +2 -2
  135. package/build-types/calendar/types.d.ts.map +1 -1
  136. package/build-types/calendar/utils/use-localization-props.d.ts +3 -3
  137. package/build-types/color-picker/styles.d.ts.map +1 -1
  138. package/build-types/custom-gradient-picker/constants.d.ts +2 -2
  139. package/build-types/dimension-control/sizes.d.ts +5 -5
  140. package/build-types/font-size-picker/constants.d.ts +2 -2
  141. package/build-types/font-size-picker/constants.d.ts.map +1 -1
  142. package/build-types/icon/index.d.ts.map +1 -1
  143. package/build-types/index.d.ts +0 -1
  144. package/build-types/index.d.ts.map +1 -1
  145. package/build-types/private-apis.d.ts.map +1 -1
  146. package/build-types/range-control/types.d.ts +2 -2
  147. package/build-types/range-control/types.d.ts.map +1 -1
  148. package/build-types/select-control/stories/index.story.d.ts.map +1 -1
  149. package/build-types/text-control/stories/index.story.d.ts.map +1 -1
  150. package/build-types/textarea-control/index.d.ts.map +1 -1
  151. package/build-types/toggle-group-control/toggle-group-control/as-button-group.d.ts.map +1 -1
  152. package/build-types/utils/hooks/use-controlled-value.d.ts +2 -2
  153. package/build-types/utils/hooks/use-controlled-value.d.ts.map +1 -1
  154. package/build-types/validated-form-controls/components/checkbox-control.d.ts +9 -0
  155. package/build-types/validated-form-controls/components/checkbox-control.d.ts.map +1 -0
  156. package/build-types/validated-form-controls/components/combobox-control.d.ts +21 -0
  157. package/build-types/validated-form-controls/components/combobox-control.d.ts.map +1 -0
  158. package/build-types/validated-form-controls/components/custom-select-control.d.ts +4 -0
  159. package/build-types/validated-form-controls/components/custom-select-control.d.ts.map +1 -0
  160. package/build-types/validated-form-controls/components/index.d.ts +13 -0
  161. package/build-types/validated-form-controls/components/index.d.ts.map +1 -0
  162. package/build-types/validated-form-controls/components/input-control.d.ts +4 -0
  163. package/build-types/validated-form-controls/components/input-control.d.ts.map +1 -0
  164. package/build-types/validated-form-controls/components/number-control.d.ts +17 -0
  165. package/build-types/validated-form-controls/components/number-control.d.ts.map +1 -0
  166. package/build-types/validated-form-controls/components/radio-control.d.ts +11 -0
  167. package/build-types/validated-form-controls/components/radio-control.d.ts.map +1 -0
  168. package/build-types/validated-form-controls/components/range-control.d.ts +36 -0
  169. package/build-types/validated-form-controls/components/range-control.d.ts.map +1 -0
  170. package/build-types/validated-form-controls/components/select-control.d.ts +9 -0
  171. package/build-types/validated-form-controls/components/select-control.d.ts.map +1 -0
  172. package/build-types/validated-form-controls/components/stories/checkbox-control.story.d.ts +12 -0
  173. package/build-types/validated-form-controls/components/stories/checkbox-control.story.d.ts.map +1 -0
  174. package/build-types/validated-form-controls/components/stories/combobox-control.story.d.ts +12 -0
  175. package/build-types/validated-form-controls/components/stories/combobox-control.story.d.ts.map +1 -0
  176. package/build-types/validated-form-controls/components/stories/custom-select-control.story.d.ts +12 -0
  177. package/build-types/validated-form-controls/components/stories/custom-select-control.story.d.ts.map +1 -0
  178. package/build-types/validated-form-controls/components/stories/input-control.story.d.ts +18 -0
  179. package/build-types/validated-form-controls/components/stories/input-control.story.d.ts.map +1 -0
  180. package/build-types/validated-form-controls/components/stories/number-control.story.d.ts +12 -0
  181. package/build-types/validated-form-controls/components/stories/number-control.story.d.ts.map +1 -0
  182. package/build-types/validated-form-controls/components/stories/overview.story.d.ts +19 -0
  183. package/build-types/validated-form-controls/components/stories/overview.story.d.ts.map +1 -0
  184. package/build-types/validated-form-controls/components/stories/radio-control.story.d.ts +12 -0
  185. package/build-types/validated-form-controls/components/stories/radio-control.story.d.ts.map +1 -0
  186. package/build-types/validated-form-controls/components/stories/range-control.story.d.ts +9 -0
  187. package/build-types/validated-form-controls/components/stories/range-control.story.d.ts.map +1 -0
  188. package/build-types/validated-form-controls/components/stories/select-control.story.d.ts +12 -0
  189. package/build-types/validated-form-controls/components/stories/select-control.story.d.ts.map +1 -0
  190. package/build-types/validated-form-controls/components/stories/story-utils.d.ts +9 -0
  191. package/build-types/validated-form-controls/components/stories/story-utils.d.ts.map +1 -0
  192. package/build-types/validated-form-controls/components/stories/text-control.story.d.ts +9 -0
  193. package/build-types/validated-form-controls/components/stories/text-control.story.d.ts.map +1 -0
  194. package/build-types/validated-form-controls/components/stories/textarea-control.story.d.ts +9 -0
  195. package/build-types/validated-form-controls/components/stories/textarea-control.story.d.ts.map +1 -0
  196. package/build-types/validated-form-controls/components/stories/toggle-control.story.d.ts +9 -0
  197. package/build-types/validated-form-controls/components/stories/toggle-control.story.d.ts.map +1 -0
  198. package/build-types/validated-form-controls/components/stories/toggle-group-control.story.d.ts +9 -0
  199. package/build-types/validated-form-controls/components/stories/toggle-group-control.story.d.ts.map +1 -0
  200. package/build-types/validated-form-controls/components/text-control.d.ts +8 -0
  201. package/build-types/validated-form-controls/components/text-control.d.ts.map +1 -0
  202. package/build-types/validated-form-controls/components/textarea-control.d.ts +7 -0
  203. package/build-types/validated-form-controls/components/textarea-control.d.ts.map +1 -0
  204. package/build-types/validated-form-controls/components/toggle-control.d.ts +7 -0
  205. package/build-types/validated-form-controls/components/toggle-control.d.ts.map +1 -0
  206. package/build-types/validated-form-controls/components/toggle-group-control.d.ts +15 -0
  207. package/build-types/validated-form-controls/components/toggle-group-control.d.ts.map +1 -0
  208. package/build-types/validated-form-controls/components/types.d.ts +27 -0
  209. package/build-types/validated-form-controls/components/types.d.ts.map +1 -0
  210. package/build-types/validated-form-controls/control-with-error.d.ts +36 -0
  211. package/build-types/validated-form-controls/control-with-error.d.ts.map +1 -0
  212. package/build-types/validated-form-controls/index.d.ts +3 -0
  213. package/build-types/validated-form-controls/index.d.ts.map +1 -0
  214. package/package.json +19 -19
  215. package/src/autocomplete/index.tsx +4 -0
  216. package/src/calendar/date-calendar/README.md +57 -46
  217. package/src/calendar/date-calendar/index.tsx +22 -8
  218. package/src/calendar/date-range-calendar/README.md +63 -52
  219. package/src/calendar/date-range-calendar/index.tsx +23 -11
  220. package/src/calendar/types.ts +2 -2
  221. package/src/color-picker/styles.ts +10 -0
  222. package/src/dimension-control/test/__snapshots__/index.test.js.snap +8 -8
  223. package/src/icon/index.tsx +2 -0
  224. package/src/index.ts +0 -1
  225. package/src/modal/style.scss +2 -2
  226. package/src/palette-edit/index.tsx +3 -3
  227. package/src/private-apis.ts +13 -0
  228. package/src/range-control/index.tsx +1 -1
  229. package/src/range-control/styles/range-control-styles.ts +3 -3
  230. package/src/range-control/tooltip.tsx +13 -13
  231. package/src/range-control/types.ts +2 -2
  232. package/src/select-control/index.tsx +1 -1
  233. package/src/style.scss +2 -2
  234. package/src/text-control/stories/index.story.tsx +1 -0
  235. package/src/text-control/style.scss +6 -1
  236. package/src/textarea-control/index.tsx +8 -1
  237. package/src/toggle-group-control/toggle-group-control/as-button-group.tsx +3 -1
  238. package/src/utils/hooks/use-controlled-value.ts +16 -8
  239. package/src/utils/theme-variables.scss +3 -0
  240. package/src/validated-form-controls/components/checkbox-control.tsx +64 -0
  241. package/src/validated-form-controls/components/combobox-control.tsx +77 -0
  242. package/src/validated-form-controls/components/custom-select-control.tsx +86 -0
  243. package/src/validated-form-controls/components/index.ts +12 -0
  244. package/src/validated-form-controls/components/input-control.tsx +59 -0
  245. package/src/validated-form-controls/components/number-control.tsx +61 -0
  246. package/src/validated-form-controls/components/radio-control.tsx +60 -0
  247. package/src/validated-form-controls/components/range-control.tsx +60 -0
  248. package/src/validated-form-controls/components/select-control.tsx +75 -0
  249. package/src/validated-form-controls/components/stories/checkbox-control.story.tsx +57 -0
  250. package/src/validated-form-controls/components/stories/combobox-control.story.tsx +64 -0
  251. package/src/validated-form-controls/components/stories/custom-select-control.story.tsx +64 -0
  252. package/src/validated-form-controls/components/stories/input-control.story.tsx +132 -0
  253. package/src/validated-form-controls/components/stories/number-control.story.tsx +62 -0
  254. package/src/validated-form-controls/components/stories/overview.mdx +52 -0
  255. package/src/validated-form-controls/components/stories/overview.story.tsx +100 -0
  256. package/src/validated-form-controls/components/stories/radio-control.story.tsx +64 -0
  257. package/src/validated-form-controls/components/stories/range-control.story.tsx +60 -0
  258. package/src/validated-form-controls/components/stories/select-control.story.tsx +60 -0
  259. package/src/validated-form-controls/components/stories/story-utils.tsx +46 -0
  260. package/src/validated-form-controls/components/stories/text-control.story.tsx +55 -0
  261. package/src/validated-form-controls/components/stories/textarea-control.story.tsx +52 -0
  262. package/src/validated-form-controls/components/stories/toggle-control.story.tsx +55 -0
  263. package/src/validated-form-controls/components/stories/toggle-group-control.story.tsx +66 -0
  264. package/src/validated-form-controls/components/text-control.tsx +60 -0
  265. package/src/validated-form-controls/components/textarea-control.tsx +59 -0
  266. package/src/validated-form-controls/components/toggle-control.tsx +69 -0
  267. package/src/validated-form-controls/components/toggle-group-control.tsx +82 -0
  268. package/src/validated-form-controls/components/types.ts +28 -0
  269. package/src/validated-form-controls/control-with-error.tsx +198 -0
  270. package/src/validated-form-controls/index.ts +2 -0
  271. package/src/validated-form-controls/style.scss +75 -0
  272. package/tsconfig.tsbuildinfo +1 -1
  273. package/build/calendar/utils/use-controlled-value.js +0 -58
  274. package/build/calendar/utils/use-controlled-value.js.map +0 -1
  275. package/build-module/calendar/utils/use-controlled-value.js +0 -51
  276. package/build-module/calendar/utils/use-controlled-value.js.map +0 -1
  277. package/build-types/calendar/utils/use-controlled-value.d.ts +0 -27
  278. package/build-types/calendar/utils/use-controlled-value.d.ts.map +0 -1
  279. package/src/calendar/utils/use-controlled-value.ts +0 -61
  280. package/src/dimension-control/style.scss +0 -22
@@ -18,7 +18,12 @@
18
18
  margin: 0;
19
19
  background: $components-color-background;
20
20
  color: $components-color-foreground;
21
- @include input-control( $components-color-accent);
21
+ @include input-control( $components-color-accent );
22
+ border-color: $components-color-border;
23
+
24
+ &::placeholder {
25
+ color: $components-color-dark-gray-placeholder;
26
+ }
22
27
 
23
28
  &.is-next-40px-default-size {
24
29
  height: $grid-unit-50;
@@ -1,3 +1,8 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import clsx from 'clsx';
5
+
1
6
  /**
2
7
  * WordPress dependencies
3
8
  */
@@ -32,6 +37,8 @@ function UnforwardedTextareaControl(
32
37
  const onChangeValue = ( event: React.ChangeEvent< HTMLTextAreaElement > ) =>
33
38
  onChange( event.target.value );
34
39
 
40
+ const classes = clsx( 'components-textarea-control', className );
41
+
35
42
  return (
36
43
  <BaseControl
37
44
  __nextHasNoMarginBottom={ __nextHasNoMarginBottom }
@@ -40,7 +47,7 @@ function UnforwardedTextareaControl(
40
47
  hideLabelFromVision={ hideLabelFromVision }
41
48
  id={ id }
42
49
  help={ help }
43
- className={ className }
50
+ className={ classes }
44
51
  >
45
52
  <StyledTextarea
46
53
  className="components-textarea-control__input"
@@ -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
  }
@@ -24,5 +24,8 @@ $components-color-gray-600: var(--wp-components-color-gray-600, $gray-600);
24
24
  $components-color-gray-700: var(--wp-components-color-gray-700, $gray-700);
25
25
  $components-color-gray-800: var(--wp-components-color-gray-800, $gray-800);
26
26
 
27
+ $components-color-dark-gray-placeholder: color-mix(in srgb, $components-color-foreground, transparent 38%);
28
+ $components-color-light-gray-placeholder: color-mix(in srgb, $components-color-background, transparent 35%);
29
+
27
30
  // Semantic aliases (prefer these over raw gray values when applicable).
28
31
  $components-color-border: #{ $components-color-gray-600 };
@@ -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
+ );
@@ -0,0 +1,61 @@
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 NumberControl from '../../number-control';
12
+ import type { ValidatedControlProps } from './types';
13
+ import type { NumberControlProps } from '../../number-control/types';
14
+
15
+ type Value = NumberControlProps[ 'value' ];
16
+
17
+ const UnforwardedValidatedNumberControl = (
18
+ {
19
+ required,
20
+ customValidator,
21
+ onChange,
22
+ markWhenOptional,
23
+ ...restProps
24
+ }: Omit<
25
+ React.ComponentProps< typeof NumberControl >,
26
+ '__next40pxDefaultSize'
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
+ return (
36
+ <ControlWithError
37
+ required={ required }
38
+ markWhenOptional={ markWhenOptional }
39
+ customValidator={ () => {
40
+ return customValidator?.( valueRef.current );
41
+ } }
42
+ getValidityTarget={ () => validityTargetRef.current }
43
+ >
44
+ <NumberControl
45
+ __next40pxDefaultSize
46
+ ref={ mergedRefs }
47
+ // TODO: Upstream limitation - When form is submitted when value is undefined, it will
48
+ // automatically set a clamped value (as defined by `min` attribute, so 0 by default).
49
+ onChange={ ( value, ...args ) => {
50
+ valueRef.current = value;
51
+ onChange?.( value, ...args );
52
+ } }
53
+ { ...restProps }
54
+ />
55
+ </ControlWithError>
56
+ );
57
+ };
58
+
59
+ export const ValidatedNumberControl = forwardRef(
60
+ UnforwardedValidatedNumberControl
61
+ );
@@ -0,0 +1,60 @@
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 RadioControl from '../../radio-control';
13
+ import type { RadioControlProps } from '../../radio-control/types';
14
+
15
+ type Value = RadioControlProps[ 'selected' ];
16
+
17
+ const UnforwardedValidatedRadioControl = (
18
+ {
19
+ required,
20
+ customValidator,
21
+ onChange,
22
+ markWhenOptional,
23
+ ...restProps
24
+ }: React.ComponentProps< typeof RadioControl > &
25
+ ValidatedControlProps< Value >,
26
+ forwardedRef: React.ForwardedRef< HTMLDivElement >
27
+ ) => {
28
+ const validityTargetRef = useRef< HTMLDivElement >( null );
29
+ const mergedRefs = useMergeRefs( [ forwardedRef, validityTargetRef ] );
30
+ const valueRef = useRef< Value >( restProps.selected );
31
+
32
+ return (
33
+ <ControlWithError
34
+ required={ required }
35
+ markWhenOptional={ markWhenOptional }
36
+ // TODO: Upstream limitation - RadioControl does not accept a ref.
37
+ ref={ mergedRefs }
38
+ customValidator={ () => {
39
+ return customValidator?.( valueRef.current );
40
+ } }
41
+ getValidityTarget={ () =>
42
+ validityTargetRef.current?.querySelector< HTMLInputElement >(
43
+ 'input[type="radio"]'
44
+ )
45
+ }
46
+ >
47
+ <RadioControl
48
+ onChange={ ( value ) => {
49
+ valueRef.current = value;
50
+ onChange?.( value );
51
+ } }
52
+ { ...restProps }
53
+ />
54
+ </ControlWithError>
55
+ );
56
+ };
57
+
58
+ export const ValidatedRadioControl = forwardRef(
59
+ UnforwardedValidatedRadioControl
60
+ );
@@ -0,0 +1,60 @@
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 RangeControl from '../../range-control';
13
+ import type { RangeControlProps } from '../../range-control/types';
14
+
15
+ type Value = RangeControlProps[ 'value' ];
16
+
17
+ const UnforwardedValidatedRangeControl = (
18
+ {
19
+ required,
20
+ customValidator,
21
+ onChange,
22
+ markWhenOptional,
23
+ ...restProps
24
+ }: Omit<
25
+ React.ComponentProps< typeof RangeControl >,
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
+ return (
36
+ <ControlWithError
37
+ required={ required }
38
+ markWhenOptional={ markWhenOptional }
39
+ customValidator={ () => {
40
+ return customValidator?.( valueRef.current );
41
+ } }
42
+ getValidityTarget={ () => validityTargetRef.current }
43
+ >
44
+ <RangeControl
45
+ __next40pxDefaultSize
46
+ __nextHasNoMarginBottom
47
+ ref={ mergedRefs }
48
+ onChange={ ( value ) => {
49
+ valueRef.current = value;
50
+ onChange?.( value );
51
+ } }
52
+ { ...restProps }
53
+ />
54
+ </ControlWithError>
55
+ );
56
+ };
57
+
58
+ export const ValidatedRangeControl = forwardRef(
59
+ UnforwardedValidatedRangeControl
60
+ );
@@ -0,0 +1,75 @@
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 SelectControl from '../../select-control';
12
+ import type { ValidatedControlProps } from './types';
13
+ import type { SelectControlProps as _SelectControlProps } from '../../select-control/types';
14
+
15
+ // Only support single value selection
16
+ type SelectControlProps = Omit<
17
+ _SelectControlProps,
18
+ 'multiple' | 'onChange' | 'value'
19
+ > & {
20
+ onChange?: ( value: string ) => void;
21
+ value?: string;
22
+ };
23
+
24
+ type Value = SelectControlProps[ 'value' ];
25
+
26
+ const UnforwardedValidatedSelectControl = (
27
+ {
28
+ required,
29
+ customValidator,
30
+ onChange,
31
+ markWhenOptional,
32
+ ...restProps
33
+ }: Omit<
34
+ React.ComponentProps< typeof SelectControl >,
35
+ | '__next40pxDefaultSize'
36
+ | '__nextHasNoMarginBottom'
37
+ | 'multiple'
38
+ | 'onChange'
39
+ | 'value'
40
+ > & {
41
+ value?: string;
42
+ onChange: ( value: string ) => void;
43
+ } & ValidatedControlProps< Value >,
44
+ forwardedRef: React.ForwardedRef< HTMLSelectElement >
45
+ ) => {
46
+ const validityTargetRef = useRef< HTMLSelectElement >( null );
47
+ const mergedRefs = useMergeRefs( [ forwardedRef, validityTargetRef ] );
48
+ const valueRef = useRef< Value >( restProps.value );
49
+
50
+ return (
51
+ <ControlWithError
52
+ required={ required }
53
+ markWhenOptional={ markWhenOptional }
54
+ customValidator={ () => {
55
+ return customValidator?.( valueRef.current );
56
+ } }
57
+ getValidityTarget={ () => validityTargetRef.current }
58
+ >
59
+ <SelectControl
60
+ __nextHasNoMarginBottom
61
+ __next40pxDefaultSize
62
+ ref={ mergedRefs }
63
+ onChange={ ( value ) => {
64
+ valueRef.current = value;
65
+ onChange?.( value );
66
+ } }
67
+ { ...restProps }
68
+ />
69
+ </ControlWithError>
70
+ );
71
+ };
72
+
73
+ export const ValidatedSelectControl = forwardRef(
74
+ UnforwardedValidatedSelectControl
75
+ );