@wordpress/components 29.13.1-next.719a03cbe.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 (233) hide show
  1. package/CHANGELOG.md +14 -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/icon/index.js +2 -0
  10. package/build/icon/index.js.map +1 -1
  11. package/build/index.js +0 -19
  12. package/build/index.js.map +1 -1
  13. package/build/private-apis.js +5 -1
  14. package/build/private-apis.js.map +1 -1
  15. package/build/select-control/index.js +1 -1
  16. package/build/select-control/index.js.map +1 -1
  17. package/build/toggle-group-control/toggle-group-control/as-button-group.js.map +1 -1
  18. package/build/utils/hooks/use-controlled-value.js +8 -4
  19. package/build/utils/hooks/use-controlled-value.js.map +1 -1
  20. package/build/validated-form-controls/components/checkbox-control.js +52 -0
  21. package/build/validated-form-controls/components/checkbox-control.js.map +1 -0
  22. package/build/validated-form-controls/components/combobox-control.js +64 -0
  23. package/build/validated-form-controls/components/combobox-control.js.map +1 -0
  24. package/build/validated-form-controls/components/custom-select-control.js +71 -0
  25. package/build/validated-form-controls/components/custom-select-control.js.map +1 -0
  26. package/build/validated-form-controls/components/index.js +138 -0
  27. package/build/validated-form-controls/components/index.js.map +1 -0
  28. package/build/validated-form-controls/components/input-control.js +50 -0
  29. package/build/validated-form-controls/components/input-control.js.map +1 -0
  30. package/build/validated-form-controls/components/number-control.js +53 -0
  31. package/build/validated-form-controls/components/number-control.js.map +1 -0
  32. package/build/validated-form-controls/components/radio-control.js +51 -0
  33. package/build/validated-form-controls/components/radio-control.js.map +1 -0
  34. package/build/validated-form-controls/components/range-control.js +51 -0
  35. package/build/validated-form-controls/components/range-control.js.map +1 -0
  36. package/build/validated-form-controls/components/select-control.js +53 -0
  37. package/build/validated-form-controls/components/select-control.js.map +1 -0
  38. package/build/validated-form-controls/components/text-control.js +51 -0
  39. package/build/validated-form-controls/components/text-control.js.map +1 -0
  40. package/build/validated-form-controls/components/textarea-control.js +50 -0
  41. package/build/validated-form-controls/components/textarea-control.js.map +1 -0
  42. package/build/validated-form-controls/components/toggle-control.js +60 -0
  43. package/build/validated-form-controls/components/toggle-control.js.map +1 -0
  44. package/build/validated-form-controls/components/toggle-group-control.js +69 -0
  45. package/build/validated-form-controls/components/toggle-group-control.js.map +1 -0
  46. package/build/validated-form-controls/components/types.js +6 -0
  47. package/build/validated-form-controls/components/types.js.map +1 -0
  48. package/build/validated-form-controls/control-with-error.js +137 -0
  49. package/build/validated-form-controls/control-with-error.js.map +1 -0
  50. package/build/validated-form-controls/index.js +28 -0
  51. package/build/validated-form-controls/index.js.map +1 -0
  52. package/build-module/autocomplete/index.js +4 -0
  53. package/build-module/autocomplete/index.js.map +1 -1
  54. package/build-module/calendar/date-calendar/index.js +11 -3
  55. package/build-module/calendar/date-calendar/index.js.map +1 -1
  56. package/build-module/calendar/date-range-calendar/index.js +8 -4
  57. package/build-module/calendar/date-range-calendar/index.js.map +1 -1
  58. package/build-module/calendar/types.js.map +1 -1
  59. package/build-module/icon/index.js +2 -0
  60. package/build-module/icon/index.js.map +1 -1
  61. package/build-module/index.js +0 -1
  62. package/build-module/index.js.map +1 -1
  63. package/build-module/private-apis.js +5 -1
  64. package/build-module/private-apis.js.map +1 -1
  65. package/build-module/select-control/index.js +1 -1
  66. package/build-module/select-control/index.js.map +1 -1
  67. package/build-module/toggle-group-control/toggle-group-control/as-button-group.js.map +1 -1
  68. package/build-module/utils/hooks/use-controlled-value.js +9 -5
  69. package/build-module/utils/hooks/use-controlled-value.js.map +1 -1
  70. package/build-module/validated-form-controls/components/checkbox-control.js +44 -0
  71. package/build-module/validated-form-controls/components/checkbox-control.js.map +1 -0
  72. package/build-module/validated-form-controls/components/combobox-control.js +56 -0
  73. package/build-module/validated-form-controls/components/combobox-control.js.map +1 -0
  74. package/build-module/validated-form-controls/components/custom-select-control.js +63 -0
  75. package/build-module/validated-form-controls/components/custom-select-control.js.map +1 -0
  76. package/build-module/validated-form-controls/components/index.js +13 -0
  77. package/build-module/validated-form-controls/components/index.js.map +1 -0
  78. package/build-module/validated-form-controls/components/input-control.js +42 -0
  79. package/build-module/validated-form-controls/components/input-control.js.map +1 -0
  80. package/build-module/validated-form-controls/components/number-control.js +45 -0
  81. package/build-module/validated-form-controls/components/number-control.js.map +1 -0
  82. package/build-module/validated-form-controls/components/radio-control.js +43 -0
  83. package/build-module/validated-form-controls/components/radio-control.js.map +1 -0
  84. package/build-module/validated-form-controls/components/range-control.js +43 -0
  85. package/build-module/validated-form-controls/components/range-control.js.map +1 -0
  86. package/build-module/validated-form-controls/components/select-control.js +45 -0
  87. package/build-module/validated-form-controls/components/select-control.js.map +1 -0
  88. package/build-module/validated-form-controls/components/text-control.js +43 -0
  89. package/build-module/validated-form-controls/components/text-control.js.map +1 -0
  90. package/build-module/validated-form-controls/components/textarea-control.js +42 -0
  91. package/build-module/validated-form-controls/components/textarea-control.js.map +1 -0
  92. package/build-module/validated-form-controls/components/toggle-control.js +52 -0
  93. package/build-module/validated-form-controls/components/toggle-control.js.map +1 -0
  94. package/build-module/validated-form-controls/components/toggle-group-control.js +62 -0
  95. package/build-module/validated-form-controls/components/toggle-group-control.js.map +1 -0
  96. package/build-module/validated-form-controls/components/types.js +2 -0
  97. package/build-module/validated-form-controls/components/types.js.map +1 -0
  98. package/build-module/validated-form-controls/control-with-error.js +129 -0
  99. package/build-module/validated-form-controls/control-with-error.js.map +1 -0
  100. package/build-module/validated-form-controls/index.js +3 -0
  101. package/build-module/validated-form-controls/index.js.map +1 -0
  102. package/build-style/style-rtl.css +60 -17
  103. package/build-style/style.css +60 -17
  104. package/build-types/autocomplete/index.d.ts.map +1 -1
  105. package/build-types/calendar/date-calendar/index.d.ts.map +1 -1
  106. package/build-types/calendar/date-range-calendar/index.d.ts.map +1 -1
  107. package/build-types/calendar/types.d.ts +2 -2
  108. package/build-types/calendar/types.d.ts.map +1 -1
  109. package/build-types/color-picker/styles.d.ts.map +1 -1
  110. package/build-types/icon/index.d.ts.map +1 -1
  111. package/build-types/index.d.ts +0 -1
  112. package/build-types/index.d.ts.map +1 -1
  113. package/build-types/private-apis.d.ts.map +1 -1
  114. package/build-types/select-control/stories/index.story.d.ts.map +1 -1
  115. package/build-types/toggle-group-control/toggle-group-control/as-button-group.d.ts.map +1 -1
  116. package/build-types/utils/hooks/use-controlled-value.d.ts +2 -2
  117. package/build-types/utils/hooks/use-controlled-value.d.ts.map +1 -1
  118. package/build-types/validated-form-controls/components/checkbox-control.d.ts +9 -0
  119. package/build-types/validated-form-controls/components/checkbox-control.d.ts.map +1 -0
  120. package/build-types/validated-form-controls/components/combobox-control.d.ts +21 -0
  121. package/build-types/validated-form-controls/components/combobox-control.d.ts.map +1 -0
  122. package/build-types/validated-form-controls/components/custom-select-control.d.ts +4 -0
  123. package/build-types/validated-form-controls/components/custom-select-control.d.ts.map +1 -0
  124. package/build-types/validated-form-controls/components/index.d.ts +13 -0
  125. package/build-types/validated-form-controls/components/index.d.ts.map +1 -0
  126. package/build-types/validated-form-controls/components/input-control.d.ts +4 -0
  127. package/build-types/validated-form-controls/components/input-control.d.ts.map +1 -0
  128. package/build-types/validated-form-controls/components/number-control.d.ts +17 -0
  129. package/build-types/validated-form-controls/components/number-control.d.ts.map +1 -0
  130. package/build-types/validated-form-controls/components/radio-control.d.ts +11 -0
  131. package/build-types/validated-form-controls/components/radio-control.d.ts.map +1 -0
  132. package/build-types/validated-form-controls/components/range-control.d.ts +36 -0
  133. package/build-types/validated-form-controls/components/range-control.d.ts.map +1 -0
  134. package/build-types/validated-form-controls/components/select-control.d.ts +9 -0
  135. package/build-types/validated-form-controls/components/select-control.d.ts.map +1 -0
  136. package/build-types/validated-form-controls/components/stories/checkbox-control.story.d.ts +12 -0
  137. package/build-types/validated-form-controls/components/stories/checkbox-control.story.d.ts.map +1 -0
  138. package/build-types/validated-form-controls/components/stories/combobox-control.story.d.ts +12 -0
  139. package/build-types/validated-form-controls/components/stories/combobox-control.story.d.ts.map +1 -0
  140. package/build-types/validated-form-controls/components/stories/custom-select-control.story.d.ts +12 -0
  141. package/build-types/validated-form-controls/components/stories/custom-select-control.story.d.ts.map +1 -0
  142. package/build-types/validated-form-controls/components/stories/input-control.story.d.ts +18 -0
  143. package/build-types/validated-form-controls/components/stories/input-control.story.d.ts.map +1 -0
  144. package/build-types/validated-form-controls/components/stories/number-control.story.d.ts +12 -0
  145. package/build-types/validated-form-controls/components/stories/number-control.story.d.ts.map +1 -0
  146. package/build-types/validated-form-controls/components/stories/overview.story.d.ts +19 -0
  147. package/build-types/validated-form-controls/components/stories/overview.story.d.ts.map +1 -0
  148. package/build-types/validated-form-controls/components/stories/radio-control.story.d.ts +12 -0
  149. package/build-types/validated-form-controls/components/stories/radio-control.story.d.ts.map +1 -0
  150. package/build-types/validated-form-controls/components/stories/range-control.story.d.ts +9 -0
  151. package/build-types/validated-form-controls/components/stories/range-control.story.d.ts.map +1 -0
  152. package/build-types/validated-form-controls/components/stories/select-control.story.d.ts +12 -0
  153. package/build-types/validated-form-controls/components/stories/select-control.story.d.ts.map +1 -0
  154. package/build-types/validated-form-controls/components/stories/story-utils.d.ts +9 -0
  155. package/build-types/validated-form-controls/components/stories/story-utils.d.ts.map +1 -0
  156. package/build-types/validated-form-controls/components/stories/text-control.story.d.ts +9 -0
  157. package/build-types/validated-form-controls/components/stories/text-control.story.d.ts.map +1 -0
  158. package/build-types/validated-form-controls/components/stories/textarea-control.story.d.ts +9 -0
  159. package/build-types/validated-form-controls/components/stories/textarea-control.story.d.ts.map +1 -0
  160. package/build-types/validated-form-controls/components/stories/toggle-control.story.d.ts +9 -0
  161. package/build-types/validated-form-controls/components/stories/toggle-control.story.d.ts.map +1 -0
  162. package/build-types/validated-form-controls/components/stories/toggle-group-control.story.d.ts +9 -0
  163. package/build-types/validated-form-controls/components/stories/toggle-group-control.story.d.ts.map +1 -0
  164. package/build-types/validated-form-controls/components/text-control.d.ts +8 -0
  165. package/build-types/validated-form-controls/components/text-control.d.ts.map +1 -0
  166. package/build-types/validated-form-controls/components/textarea-control.d.ts +7 -0
  167. package/build-types/validated-form-controls/components/textarea-control.d.ts.map +1 -0
  168. package/build-types/validated-form-controls/components/toggle-control.d.ts +7 -0
  169. package/build-types/validated-form-controls/components/toggle-control.d.ts.map +1 -0
  170. package/build-types/validated-form-controls/components/toggle-group-control.d.ts +15 -0
  171. package/build-types/validated-form-controls/components/toggle-group-control.d.ts.map +1 -0
  172. package/build-types/validated-form-controls/components/types.d.ts +27 -0
  173. package/build-types/validated-form-controls/components/types.d.ts.map +1 -0
  174. package/build-types/validated-form-controls/control-with-error.d.ts +36 -0
  175. package/build-types/validated-form-controls/control-with-error.d.ts.map +1 -0
  176. package/build-types/validated-form-controls/index.d.ts +3 -0
  177. package/build-types/validated-form-controls/index.d.ts.map +1 -0
  178. package/package.json +19 -19
  179. package/src/autocomplete/index.tsx +4 -0
  180. package/src/calendar/date-calendar/README.md +57 -46
  181. package/src/calendar/date-calendar/index.tsx +22 -8
  182. package/src/calendar/date-range-calendar/README.md +63 -52
  183. package/src/calendar/date-range-calendar/index.tsx +23 -11
  184. package/src/calendar/types.ts +2 -2
  185. package/src/dimension-control/test/__snapshots__/index.test.js.snap +8 -8
  186. package/src/icon/index.tsx +2 -0
  187. package/src/index.ts +0 -1
  188. package/src/private-apis.ts +5 -0
  189. package/src/select-control/index.tsx +1 -1
  190. package/src/style.scss +2 -2
  191. package/src/toggle-group-control/toggle-group-control/as-button-group.tsx +3 -1
  192. package/src/utils/hooks/use-controlled-value.ts +16 -8
  193. package/src/validated-form-controls/components/checkbox-control.tsx +64 -0
  194. package/src/validated-form-controls/components/combobox-control.tsx +77 -0
  195. package/src/validated-form-controls/components/custom-select-control.tsx +86 -0
  196. package/src/validated-form-controls/components/index.ts +12 -0
  197. package/src/validated-form-controls/components/input-control.tsx +59 -0
  198. package/src/validated-form-controls/components/number-control.tsx +61 -0
  199. package/src/validated-form-controls/components/radio-control.tsx +60 -0
  200. package/src/validated-form-controls/components/range-control.tsx +60 -0
  201. package/src/validated-form-controls/components/select-control.tsx +75 -0
  202. package/src/validated-form-controls/components/stories/checkbox-control.story.tsx +57 -0
  203. package/src/validated-form-controls/components/stories/combobox-control.story.tsx +64 -0
  204. package/src/validated-form-controls/components/stories/custom-select-control.story.tsx +64 -0
  205. package/src/validated-form-controls/components/stories/input-control.story.tsx +132 -0
  206. package/src/validated-form-controls/components/stories/number-control.story.tsx +62 -0
  207. package/src/validated-form-controls/components/stories/overview.mdx +52 -0
  208. package/src/validated-form-controls/components/stories/overview.story.tsx +100 -0
  209. package/src/validated-form-controls/components/stories/radio-control.story.tsx +64 -0
  210. package/src/validated-form-controls/components/stories/range-control.story.tsx +60 -0
  211. package/src/validated-form-controls/components/stories/select-control.story.tsx +60 -0
  212. package/src/validated-form-controls/components/stories/story-utils.tsx +46 -0
  213. package/src/validated-form-controls/components/stories/text-control.story.tsx +55 -0
  214. package/src/validated-form-controls/components/stories/textarea-control.story.tsx +52 -0
  215. package/src/validated-form-controls/components/stories/toggle-control.story.tsx +55 -0
  216. package/src/validated-form-controls/components/stories/toggle-group-control.story.tsx +66 -0
  217. package/src/validated-form-controls/components/text-control.tsx +60 -0
  218. package/src/validated-form-controls/components/textarea-control.tsx +59 -0
  219. package/src/validated-form-controls/components/toggle-control.tsx +69 -0
  220. package/src/validated-form-controls/components/toggle-group-control.tsx +82 -0
  221. package/src/validated-form-controls/components/types.ts +28 -0
  222. package/src/validated-form-controls/control-with-error.tsx +198 -0
  223. package/src/validated-form-controls/index.ts +2 -0
  224. package/src/validated-form-controls/style.scss +75 -0
  225. package/tsconfig.tsbuildinfo +1 -1
  226. package/build/calendar/utils/use-controlled-value.js +0 -58
  227. package/build/calendar/utils/use-controlled-value.js.map +0 -1
  228. package/build-module/calendar/utils/use-controlled-value.js +0 -51
  229. package/build-module/calendar/utils/use-controlled-value.js.map +0 -1
  230. package/build-types/calendar/utils/use-controlled-value.d.ts +0 -27
  231. package/build-types/calendar/utils/use-controlled-value.d.ts.map +0 -1
  232. package/src/calendar/utils/use-controlled-value.ts +0 -61
  233. package/src/dimension-control/style.scss +0 -22
@@ -3,14 +3,18 @@
3
3
  */
4
4
  import { DayPicker } from 'react-day-picker';
5
5
  import { enUS } from 'react-day-picker/locale';
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { useCallback } from '@wordpress/element';
6
10
  /**
7
11
  * Internal dependencies
8
12
  */
9
13
  import { COMMON_PROPS } from '../utils/constants';
10
14
  import { clampNumberOfMonths } from '../utils/misc';
11
- import { useControlledValue } from '../utils/use-controlled-value';
15
+ import { useControlledValue } from '../../utils/hooks';
12
16
  import { useLocalizationProps } from '../utils/use-localization-props';
13
- import type { DateCalendarProps } from '../types';
17
+ import type { DateCalendarProps, OnSelectHandler } from '../types';
14
18
 
15
19
  /**
16
20
  * `DateCalendar` is a React component that provides a customizable calendar
@@ -35,11 +39,21 @@ export const DateCalendar = ( {
35
39
  mode: 'single',
36
40
  } );
37
41
 
38
- const [ selected, setSelected ] = useControlledValue< Date | undefined >( {
39
- defaultValue: defaultSelected,
40
- value: selectedProp,
41
- onChange: onSelect,
42
- } );
42
+ const onChange: OnSelectHandler< typeof selectedProp > = useCallback(
43
+ ( selected, triggerDate, modifiers, e ) => {
44
+ // Convert internal `null` to `undefined` for the public event handler.
45
+ onSelect?.( selected ?? undefined, triggerDate, modifiers, e );
46
+ },
47
+ [ onSelect ]
48
+ );
49
+
50
+ const [ selected, setSelected ] = useControlledValue< typeof selectedProp >(
51
+ {
52
+ defaultValue: defaultSelected,
53
+ value: selectedProp,
54
+ onChange,
55
+ }
56
+ );
43
57
 
44
58
  return (
45
59
  <DayPicker
@@ -48,7 +62,7 @@ export const DateCalendar = ( {
48
62
  { ...props }
49
63
  mode="single"
50
64
  numberOfMonths={ clampNumberOfMonths( numberOfMonths ) }
51
- selected={ selected }
65
+ selected={ selected ?? undefined }
52
66
  onSelect={ setSelected }
53
67
  />
54
68
  );
@@ -1,5 +1,7 @@
1
1
  # `DateRangeCalendar`
2
2
 
3
+ 🔒 This component is locked as a [private API](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-private-apis/). We do not yet recommend using this outside of the Gutenberg project.
4
+
3
5
  `DateRangeCalendar` is a React component that provides a customizable calendar interface for **date range** selection.
4
6
 
5
7
  The component is built with accessibility in mind and follows ARIA best practices for calendar widgets. It provides keyboard navigation, screen reader support, and customizable labels for internationalization.
@@ -7,7 +9,7 @@ The component is built with accessibility in mind and follows ARIA best practice
7
9
  ## Usage example
8
10
 
9
11
  ```tsx
10
- import { DateRangeCalendar } from '@automattic/components';
12
+ import { DateRangeCalendar } from '@wordpress/components';
11
13
 
12
14
  type DateRange = {
13
15
  from: Date | undefined;
@@ -30,16 +32,16 @@ These props are shared between both single date and date range calendar modes.
30
32
 
31
33
  ### `required`
32
34
 
33
- - Type: `boolean`
34
- - Required: No
35
- - Default: `false`
35
+ - Type: `boolean`
36
+ - Required: No
37
+ - Default: `false`
36
38
 
37
39
  Whether the selection is required. When `true`, there always needs to be a date selected.
38
40
 
39
41
  ### `selected`
40
42
 
41
- - Type: `DateRange | undefined | null`
42
- - Required: No
43
+ - Type: `DateRange | undefined | null`
44
+ - Required: No
43
45
 
44
46
  The selected date range. A `DateRange` object has the following shape:
45
47
 
@@ -52,101 +54,101 @@ The selected date range. A `DateRange` object has the following shape:
52
54
 
53
55
  ### `onSelect`
54
56
 
55
- - Type: `(selected: DateRange | undefined, triggerDate: Date, modifiers: Modifiers, e: React.MouseEvent | React.KeyboardEvent) => void`
56
- - Required: No
57
+ - Type: `(selected: DateRange | undefined, triggerDate: Date, modifiers: Modifiers, e: React.MouseEvent | React.KeyboardEvent) => void`
58
+ - Required: No
57
59
 
58
60
  Event handler when the selection changes. The `selected` parameter will contain the new date range.
59
61
 
60
62
  ### `defaultSelected`
61
63
 
62
- - Type: `DateRange`
63
- - Required: No
64
+ - Type: `DateRange`
65
+ - Required: No
64
66
 
65
67
  The default selected range (for uncontrolled usage).
66
68
 
67
69
  ### `excludeDisabled`
68
70
 
69
- - Type: `boolean`
70
- - Required: No
71
+ - Type: `boolean`
72
+ - Required: No
71
73
 
72
74
  When `true`, the range will reset when including a disabled day. This is useful to prevent users from selecting ranges that include unavailable dates.
73
75
 
74
76
  ### `min`
75
77
 
76
- - Type: `number`
77
- - Required: No
78
+ - Type: `number`
79
+ - Required: No
78
80
 
79
81
  The minimum number of days to include in the range. If a user tries to select a range shorter than this, the selection will be adjusted to meet the minimum requirement.
80
82
 
81
83
  ### `max`
82
84
 
83
- - Type: `number`
84
- - Required: No
85
+ - Type: `number`
86
+ - Required: No
85
87
 
86
88
  The maximum number of days to include in the range. If a user tries to select a range longer than this, the selection will be adjusted to meet the maximum requirement.
87
89
 
88
90
  ### `defaultMonth`
89
91
 
90
- - Type: `Date`
91
- - Required: No
92
- - Default: Current month
92
+ - Type: `Date`
93
+ - Required: No
94
+ - Default: Current month
93
95
 
94
96
  The initial month to show in the calendar view (uncontrolled).
95
97
 
96
98
  ### `month`
97
99
 
98
- - Type: `Date`
99
- - Required: No
100
+ - Type: `Date`
101
+ - Required: No
100
102
 
101
103
  The month displayed in the calendar view (controlled). Use together with `onMonthChange` to change the month programmatically.
102
104
 
103
105
  ### `numberOfMonths`
104
106
 
105
- - Type: `number`
106
- - Required: No
107
- - Default: `1`
107
+ - Type: `number`
108
+ - Required: No
109
+ - Default: `1`
108
110
 
109
111
  The number of months displayed at once.
110
112
 
111
113
  ### `startMonth`
112
114
 
113
- - Type: `Date`
114
- - Required: No
115
+ - Type: `Date`
116
+ - Required: No
115
117
 
116
118
  The earliest month to start the month navigation.
117
119
 
118
120
  ### `endMonth`
119
121
 
120
- - Type: `Date`
121
- - Required: No
122
+ - Type: `Date`
123
+ - Required: No
122
124
 
123
125
  The latest month to end the month navigation.
124
126
 
125
127
  ### `autoFocus`
126
128
 
127
- - Type: `boolean`
128
- - Required: No
129
+ - Type: `boolean`
130
+ - Required: No
129
131
 
130
132
  Focus the first selected day (if set) or today's date (if not disabled). Use this prop when you need to focus the calendar after a user action (e.g. opening the dialog with the calendar).
131
133
 
132
134
  ### `disabled`
133
135
 
134
- - Type: `Matcher | Matcher[] | undefined`
135
- - Required: No
136
+ - Type: `Matcher | Matcher[] | undefined`
137
+ - Required: No
136
138
 
137
139
  Specify which days are disabled. Using `true` will disable all dates. See the [Matcher Types](#matcher-types) section for more details.
138
140
 
139
141
  ### `disableNavigation`
140
142
 
141
- - Type: `boolean`
142
- - Required: No
143
+ - Type: `boolean`
144
+ - Required: No
143
145
 
144
146
  Disable the navigation buttons.
145
147
 
146
148
  ### `labels`
147
149
 
148
- - Type: `object`
149
- - Required: No
150
+ - Type: `object`
151
+ - Required: No
150
152
 
151
153
  Use custom labels for internationalization. All labels are optional and have sensible defaults:
152
154
 
@@ -166,9 +168,9 @@ Use custom labels for internationalization. All labels are optional and have sen
166
168
 
167
169
  ### `locale`
168
170
 
169
- - Type: `Locale`
170
- - Required: No
171
- - Default: `enUS` from `@date-fns/locale`
171
+ - Type: `Locale`
172
+ - Required: No
173
+ - Default: `enUS` from `@date-fns/locale`
172
174
 
173
175
  The locale object used to localize dates. Pass a locale from `@date-fns/locale` to localize the calendar.
174
176
 
@@ -176,30 +178,30 @@ The locale object used to localize dates. Pass a locale from `@date-fns/locale`
176
178
 
177
179
  ### `weekStartsOn`
178
180
 
179
- - Type: `0 | 1 | 2 | 3 | 4 | 5 | 6 | undefined`
180
- - Required: No
181
- - Default: Based on the `locale` prop
181
+ - Type: `0 | 1 | 2 | 3 | 4 | 5 | 6 | undefined`
182
+ - Required: No
183
+ - Default: Based on the `locale` prop
182
184
 
183
185
  The index of the first day of the week (0 - Sunday). Overrides the locale's setting.
184
186
 
185
187
  ### `onMonthChange`
186
188
 
187
- - Type: `(month: Date) => void`
188
- - Required: No
189
+ - Type: `(month: Date) => void`
190
+ - Required: No
189
191
 
190
192
  Event fired when the user navigates between months.
191
193
 
192
194
  ### `timeZone`
193
195
 
194
- - Type: `string`
195
- - Required: No
196
+ - Type: `string`
197
+ - Required: No
196
198
 
197
199
  The time zone (IANA or UTC offset) to use in the calendar. See [Wikipedia](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) for possible values.
198
200
 
199
201
  When working with time zones, use the `TZDate` object exported by this package instead of the native `Date` object.
200
202
 
201
203
  ```tsx
202
- import { DateRangeCalendar, TZDate } from '@automattic/components';
204
+ import { DateRangeCalendar, TZDate } from '@wordpress/components';
203
205
 
204
206
  export function WithTimeZone() {
205
207
  const timeZone = 'America/New_York';
@@ -207,15 +209,21 @@ export function WithTimeZone() {
207
209
  from: new TZDate( 2024, 12, 10, timeZone ), // Use `TZDate` instead of `Date`
208
210
  to: new TZDate( 2024, 12, 8, timeZone ), // Use `TZDate` instead of `Date`
209
211
  } );
210
- return <DateRangeCalendar timeZone={ timeZone } selected={ selected } onSelect={ setSelected } />;
212
+ return (
213
+ <DateRangeCalendar
214
+ timeZone={ timeZone }
215
+ selected={ selected }
216
+ onSelect={ setSelected }
217
+ />
218
+ );
211
219
  }
212
220
  ```
213
221
 
214
222
  ### `role`
215
223
 
216
- - Type: `'application' | 'dialog' | undefined`
217
- - Required: No
218
- - Default: `'application'`
224
+ - Type: `'application' | 'dialog' | undefined`
225
+ - Required: No
226
+ - Default: `'application'`
219
227
 
220
228
  The role attribute to add to the container element.
221
229
 
@@ -238,7 +246,10 @@ const dateMatcher: Matcher = new Date(); // Will match today's date
238
246
  ### Array Matcher
239
247
 
240
248
  ```typescript
241
- const arrayMatcher: Matcher = [ new Date( 2019, 1, 2 ), new Date( 2019, 1, 4 ) ]; // Will match the days in the array
249
+ const arrayMatcher: Matcher = [
250
+ new Date( 2019, 1, 2 ),
251
+ new Date( 2019, 1, 4 ),
252
+ ]; // Will match the days in the array
242
253
  ```
243
254
 
244
255
  ### Date After Matcher
@@ -7,15 +7,19 @@ import { enUS } from 'react-day-picker/locale';
7
7
  /**
8
8
  * WordPress dependencies
9
9
  */
10
- import { useMemo, useState } from '@wordpress/element';
10
+ import { useMemo, useState, useCallback } from '@wordpress/element';
11
11
  /**
12
12
  * Internal dependencies
13
13
  */
14
14
  import { COMMON_PROPS, MODIFIER_CLASSNAMES } from '../utils/constants';
15
15
  import { clampNumberOfMonths } from '../utils/misc';
16
- import { useControlledValue } from '../utils/use-controlled-value';
16
+ import { useControlledValue } from '../../utils/hooks';
17
17
  import { useLocalizationProps } from '../utils/use-localization-props';
18
- import type { DateRangeCalendarProps, DateRange } from '../types';
18
+ import type {
19
+ DateRangeCalendarProps,
20
+ DateRange,
21
+ OnSelectHandler,
22
+ } from '../types';
19
23
 
20
24
  export function usePreviewRange( {
21
25
  selected,
@@ -151,13 +155,21 @@ export const DateRangeCalendar = ( {
151
155
  mode: 'range',
152
156
  } );
153
157
 
154
- const [ selected, setSelected ] = useControlledValue<
155
- DateRange | undefined
156
- >( {
157
- defaultValue: defaultSelected,
158
- value: selectedProp,
159
- onChange: onSelect,
160
- } );
158
+ const onChange: OnSelectHandler< typeof selectedProp > = useCallback(
159
+ ( selected, triggerDate, modifiers, e ) => {
160
+ // Convert internal `null` to `undefined` for the public event handler.
161
+ onSelect?.( selected ?? undefined, triggerDate, modifiers, e );
162
+ },
163
+ [ onSelect ]
164
+ );
165
+
166
+ const [ selected, setSelected ] = useControlledValue< typeof selectedProp >(
167
+ {
168
+ defaultValue: defaultSelected,
169
+ value: selectedProp,
170
+ onChange,
171
+ }
172
+ );
161
173
 
162
174
  const [ hoveredDate, setHoveredDate ] = useState< Date | undefined >(
163
175
  undefined
@@ -192,7 +204,7 @@ export const DateRangeCalendar = ( {
192
204
  excludeDisabled={ excludeDisabled }
193
205
  min={ min }
194
206
  max={ max }
195
- selected={ selected }
207
+ selected={ selected ?? undefined }
196
208
  onSelect={ setSelected }
197
209
  onDayMouseEnter={ ( date ) => setHoveredDate( date ) }
198
210
  onDayMouseLeave={ () => setHoveredDate( undefined ) }
@@ -153,7 +153,7 @@ type DayOfWeek = {
153
153
  * @param {Modifiers} modifiers - The modifiers associated with the event.
154
154
  * @param {React.MouseEvent | React.KeyboardEvent} e - The event object.
155
155
  */
156
- type OnSelectHandler< T > = (
156
+ export type OnSelectHandler< T > = (
157
157
  selected: T,
158
158
  triggerDate: Date,
159
159
  modifiers: Modifiers,
@@ -284,7 +284,7 @@ export interface BaseProps
284
284
  * When working with time zones, use the `TZDate` object exported by this
285
285
  * package instead of the native `Date` object.
286
286
  * @example
287
- * import { DateCalendar, TZDate } from "@automattic/components";
287
+ * import { DateCalendar, TZDate } from "@wordpress/components";
288
288
  *
289
289
  * export function WithTimeZone() {
290
290
  * const timeZone = "America/New_York";
@@ -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
  >
@@ -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
  }
package/src/index.ts CHANGED
@@ -57,7 +57,6 @@ export {
57
57
  CardHeader,
58
58
  CardMedia,
59
59
  } from './card';
60
- export { DateCalendar, DateRangeCalendar, TZDate } from './calendar';
61
60
  export { default as CheckboxControl } from './checkbox-control';
62
61
  export { default as ClipboardButton } from './clipboard-button';
63
62
  export { default as __experimentalPaletteEdit } from './palette-edit';
@@ -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 }
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
@@ -21,7 +21,6 @@
21
21
  @import "./combobox-control/style.scss";
22
22
  @import "./color-palette/style.scss";
23
23
  @import "./custom-gradient-picker/style.scss";
24
- @import "./dimension-control/style.scss";
25
24
  @import "./draggable/style.scss";
26
25
  @import "./drop-zone/style.scss";
27
26
  @import "./dropdown/style.scss";
@@ -56,3 +55,4 @@
56
55
  @import "./toolbar/toolbar-button/style.scss";
57
56
  @import "./toolbar/toolbar-group/style.scss";
58
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
+ );