@wordpress/components 23.7.0 → 23.9.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 (274) hide show
  1. package/CHANGELOG.md +52 -6
  2. package/build/checkbox-control/index.js +2 -2
  3. package/build/checkbox-control/index.js.map +1 -1
  4. package/build/color-palette/index.native.js +12 -0
  5. package/build/color-palette/index.native.js.map +1 -1
  6. package/build/custom-gradient-picker/index.native.js +3 -1
  7. package/build/custom-gradient-picker/index.native.js.map +1 -1
  8. package/build/custom-gradient-picker/serializer.js +0 -4
  9. package/build/custom-gradient-picker/serializer.js.map +1 -1
  10. package/build/draggable/index.js +6 -1
  11. package/build/draggable/index.js.map +1 -1
  12. package/build/drop-zone/index.js +8 -8
  13. package/build/drop-zone/index.js.map +1 -1
  14. package/build/index.js.map +1 -1
  15. package/build/mobile/bottom-sheet/cell.native.js +6 -6
  16. package/build/mobile/bottom-sheet/cell.native.js.map +1 -1
  17. package/build/mobile/color-settings/palette.screen.native.js +0 -8
  18. package/build/mobile/color-settings/palette.screen.native.js.map +1 -1
  19. package/build/mobile/global-styles-context/utils.native.js +21 -4
  20. package/build/mobile/global-styles-context/utils.native.js.map +1 -1
  21. package/build/mobile/keyboard-aware-flat-list/index.android.js +0 -4
  22. package/build/mobile/keyboard-aware-flat-list/index.android.js.map +1 -1
  23. package/build/mobile/keyboard-aware-flat-list/index.ios.js +100 -55
  24. package/build/mobile/keyboard-aware-flat-list/index.ios.js.map +1 -1
  25. package/build/mobile/keyboard-aware-flat-list/use-keyboard-offset.native.js +82 -0
  26. package/build/mobile/keyboard-aware-flat-list/use-keyboard-offset.native.js.map +1 -0
  27. package/build/mobile/keyboard-aware-flat-list/use-scroll-to-text-input.native.js +85 -0
  28. package/build/mobile/keyboard-aware-flat-list/use-scroll-to-text-input.native.js.map +1 -0
  29. package/build/mobile/keyboard-aware-flat-list/use-text-input-caret-position.native.js +44 -0
  30. package/build/mobile/keyboard-aware-flat-list/use-text-input-caret-position.native.js.map +1 -0
  31. package/build/mobile/keyboard-aware-flat-list/use-text-input-offset.native.js +53 -0
  32. package/build/mobile/keyboard-aware-flat-list/use-text-input-offset.native.js.map +1 -0
  33. package/build/mobile/segmented-control/index.native.js +4 -2
  34. package/build/mobile/segmented-control/index.native.js.map +1 -1
  35. package/build/navigator/navigator-provider/component.js +4 -2
  36. package/build/navigator/navigator-provider/component.js.map +1 -1
  37. package/build/navigator/navigator-screen/component.js +4 -3
  38. package/build/navigator/navigator-screen/component.js.map +1 -1
  39. package/build/popover/index.js +1 -8
  40. package/build/popover/index.js.map +1 -1
  41. package/build/private-apis.js +4 -1
  42. package/build/private-apis.js.map +1 -1
  43. package/build/query-controls/author-select.js +2 -1
  44. package/build/query-controls/author-select.js.map +1 -1
  45. package/build/query-controls/category-select.js +3 -1
  46. package/build/query-controls/category-select.js.map +1 -1
  47. package/build/query-controls/index.js +7 -1
  48. package/build/query-controls/index.js.map +1 -1
  49. package/build/sandbox/index.native.js +55 -29
  50. package/build/sandbox/index.native.js.map +1 -1
  51. package/build/slot-fill/index.js +20 -7
  52. package/build/slot-fill/index.js.map +1 -1
  53. package/build/spinner/styles.js +4 -4
  54. package/build/spinner/styles.js.map +1 -1
  55. package/build/tree-grid/index.js +3 -3
  56. package/build/tree-grid/index.js.map +1 -1
  57. package/build/view/component.js +1 -2
  58. package/build/view/component.js.map +1 -1
  59. package/build-module/checkbox-control/index.js +2 -2
  60. package/build-module/checkbox-control/index.js.map +1 -1
  61. package/build-module/color-palette/index.native.js +13 -1
  62. package/build-module/color-palette/index.native.js.map +1 -1
  63. package/build-module/custom-gradient-picker/index.native.js +3 -1
  64. package/build-module/custom-gradient-picker/index.native.js.map +1 -1
  65. package/build-module/custom-gradient-picker/serializer.js +0 -4
  66. package/build-module/custom-gradient-picker/serializer.js.map +1 -1
  67. package/build-module/draggable/index.js +6 -1
  68. package/build-module/draggable/index.js.map +1 -1
  69. package/build-module/drop-zone/index.js +8 -8
  70. package/build-module/drop-zone/index.js.map +1 -1
  71. package/build-module/index.js.map +1 -1
  72. package/build-module/mobile/bottom-sheet/cell.native.js +6 -5
  73. package/build-module/mobile/bottom-sheet/cell.native.js.map +1 -1
  74. package/build-module/mobile/color-settings/palette.screen.native.js +0 -8
  75. package/build-module/mobile/color-settings/palette.screen.native.js.map +1 -1
  76. package/build-module/mobile/global-styles-context/utils.native.js +21 -3
  77. package/build-module/mobile/global-styles-context/utils.native.js.map +1 -1
  78. package/build-module/mobile/keyboard-aware-flat-list/index.android.js +0 -4
  79. package/build-module/mobile/keyboard-aware-flat-list/index.android.js.map +1 -1
  80. package/build-module/mobile/keyboard-aware-flat-list/index.ios.js +97 -54
  81. package/build-module/mobile/keyboard-aware-flat-list/index.ios.js.map +1 -1
  82. package/build-module/mobile/keyboard-aware-flat-list/use-keyboard-offset.native.js +73 -0
  83. package/build-module/mobile/keyboard-aware-flat-list/use-keyboard-offset.native.js.map +1 -0
  84. package/build-module/mobile/keyboard-aware-flat-list/use-scroll-to-text-input.native.js +76 -0
  85. package/build-module/mobile/keyboard-aware-flat-list/use-scroll-to-text-input.native.js.map +1 -0
  86. package/build-module/mobile/keyboard-aware-flat-list/use-text-input-caret-position.native.js +33 -0
  87. package/build-module/mobile/keyboard-aware-flat-list/use-text-input-caret-position.native.js.map +1 -0
  88. package/build-module/mobile/keyboard-aware-flat-list/use-text-input-offset.native.js +40 -0
  89. package/build-module/mobile/keyboard-aware-flat-list/use-text-input-offset.native.js.map +1 -0
  90. package/build-module/mobile/segmented-control/index.native.js +4 -2
  91. package/build-module/mobile/segmented-control/index.native.js.map +1 -1
  92. package/build-module/navigator/navigator-provider/component.js +4 -2
  93. package/build-module/navigator/navigator-provider/component.js.map +1 -1
  94. package/build-module/navigator/navigator-screen/component.js +4 -3
  95. package/build-module/navigator/navigator-screen/component.js.map +1 -1
  96. package/build-module/popover/index.js +1 -8
  97. package/build-module/popover/index.js.map +1 -1
  98. package/build-module/private-apis.js +3 -1
  99. package/build-module/private-apis.js.map +1 -1
  100. package/build-module/query-controls/author-select.js +2 -1
  101. package/build-module/query-controls/author-select.js.map +1 -1
  102. package/build-module/query-controls/category-select.js +3 -1
  103. package/build-module/query-controls/category-select.js.map +1 -1
  104. package/build-module/query-controls/index.js +7 -2
  105. package/build-module/query-controls/index.js.map +1 -1
  106. package/build-module/sandbox/index.native.js +56 -31
  107. package/build-module/sandbox/index.native.js.map +1 -1
  108. package/build-module/slot-fill/index.js +16 -6
  109. package/build-module/slot-fill/index.js.map +1 -1
  110. package/build-module/spinner/styles.js +4 -4
  111. package/build-module/spinner/styles.js.map +1 -1
  112. package/build-module/tree-grid/index.js +3 -3
  113. package/build-module/tree-grid/index.js.map +1 -1
  114. package/build-module/view/component.js +1 -2
  115. package/build-module/view/component.js.map +1 -1
  116. package/build-style/style-rtl.css +26 -16
  117. package/build-style/style.css +26 -16
  118. package/build-types/angle-picker-control/styles/angle-picker-control-styles.d.ts +1 -1
  119. package/build-types/border-box-control/border-box-control/hook.d.ts +2 -2
  120. package/build-types/border-box-control/border-box-control-linked-button/hook.d.ts +2 -2
  121. package/build-types/border-box-control/border-box-control-split-controls/hook.d.ts +2 -2
  122. package/build-types/border-box-control/border-box-control-visualizer/hook.d.ts +2 -2
  123. package/build-types/border-control/border-control/hook.d.ts +2 -2
  124. package/build-types/border-control/border-control-dropdown/hook.d.ts +2 -2
  125. package/build-types/border-control/border-control-style-picker/hook.d.ts +2 -2
  126. package/build-types/box-control/styles/box-control-styles.d.ts +5 -5
  127. package/build-types/button/deprecated.d.ts +8 -8
  128. package/build-types/card/card/hook.d.ts +2 -2
  129. package/build-types/card/card-body/hook.d.ts +2 -2
  130. package/build-types/card/card-divider/hook.d.ts +2 -2
  131. package/build-types/card/card-footer/hook.d.ts +2 -2
  132. package/build-types/card/card-header/hook.d.ts +2 -2
  133. package/build-types/card/card-media/hook.d.ts +2 -2
  134. package/build-types/checkbox-control/index.d.ts.map +1 -1
  135. package/build-types/color-palette/styles.d.ts +1 -1
  136. package/build-types/color-picker/styles.d.ts +7 -7
  137. package/build-types/combobox-control/styles.d.ts +1 -1
  138. package/build-types/custom-gradient-picker/serializer.d.ts +1 -5
  139. package/build-types/custom-gradient-picker/serializer.d.ts.map +1 -1
  140. package/build-types/custom-gradient-picker/types.d.ts +0 -2
  141. package/build-types/custom-gradient-picker/types.d.ts.map +1 -1
  142. package/build-types/date-time/date/styles.d.ts +2 -2
  143. package/build-types/date-time/date-time/styles.d.ts +1 -1
  144. package/build-types/date-time/time/styles.d.ts +8 -8
  145. package/build-types/draggable/index.d.ts +1 -1
  146. package/build-types/draggable/index.d.ts.map +1 -1
  147. package/build-types/draggable/stories/index.d.ts +8 -0
  148. package/build-types/draggable/stories/index.d.ts.map +1 -1
  149. package/build-types/draggable/types.d.ts +7 -0
  150. package/build-types/draggable/types.d.ts.map +1 -1
  151. package/build-types/drop-zone/index.d.ts.map +1 -1
  152. package/build-types/elevation/hook.d.ts +2 -2
  153. package/build-types/external-link/styles/external-link-styles.d.ts +1 -1
  154. package/build-types/flex/flex/hook.d.ts +2 -2
  155. package/build-types/flex/flex-block/hook.d.ts +2 -2
  156. package/build-types/flex/flex-item/hook.d.ts +2 -2
  157. package/build-types/focal-point-picker/styles/focal-point-picker-style.d.ts +2 -2
  158. package/build-types/form-token-field/styles.d.ts +1 -1
  159. package/build-types/grid/hook.d.ts +2 -2
  160. package/build-types/h-stack/hook.d.ts +2 -2
  161. package/build-types/heading/hook.d.ts +2 -2
  162. package/build-types/index.d.ts +129 -0
  163. package/build-types/index.d.ts.map +1 -0
  164. package/build-types/input-control/styles/input-control-styles.d.ts +2 -2
  165. package/build-types/item-group/item/hook.d.ts +2 -2
  166. package/build-types/item-group/item-group/hook.d.ts +2 -2
  167. package/build-types/navigation/styles/navigation-styles.d.ts +2 -2
  168. package/build-types/navigator/navigator-back-button/component.d.ts +1 -1
  169. package/build-types/navigator/navigator-back-button/hook.d.ts +3 -3
  170. package/build-types/navigator/navigator-button/component.d.ts +1 -1
  171. package/build-types/navigator/navigator-button/hook.d.ts +3 -3
  172. package/build-types/navigator/navigator-provider/component.d.ts.map +1 -1
  173. package/build-types/navigator/navigator-screen/component.d.ts +1 -1
  174. package/build-types/navigator/navigator-screen/component.d.ts.map +1 -1
  175. package/build-types/navigator/navigator-to-parent-button/component.d.ts +1 -1
  176. package/build-types/navigator/stories/index.d.ts +1 -0
  177. package/build-types/navigator/stories/index.d.ts.map +1 -1
  178. package/build-types/navigator/types.d.ts +2 -2
  179. package/build-types/navigator/types.d.ts.map +1 -1
  180. package/build-types/number-control/index.d.ts +2 -2
  181. package/build-types/number-control/stories/index.d.ts +2 -2
  182. package/build-types/palette-edit/styles.d.ts +18 -12
  183. package/build-types/palette-edit/styles.d.ts.map +1 -1
  184. package/build-types/popover/index.d.ts +1 -1
  185. package/build-types/popover/index.d.ts.map +1 -1
  186. package/build-types/popover/stories/e2e/index.d.ts +1 -1
  187. package/build-types/private-apis.d.ts +2 -3
  188. package/build-types/private-apis.d.ts.map +1 -1
  189. package/build-types/query-controls/author-select.d.ts.map +1 -1
  190. package/build-types/query-controls/category-select.d.ts.map +1 -1
  191. package/build-types/query-controls/index.d.ts.map +1 -1
  192. package/build-types/range-control/index.d.ts +1 -1
  193. package/build-types/range-control/styles/range-control-styles.d.ts +2 -2
  194. package/build-types/resizable-box/index.d.ts +1 -1
  195. package/build-types/resizable-box/resize-tooltip/index.d.ts +1 -1
  196. package/build-types/resizable-box/stories/index.d.ts +2 -2
  197. package/build-types/scrollable/hook.d.ts +2 -2
  198. package/build-types/search-control/index.d.ts +1 -1
  199. package/build-types/search-control/stories/index.d.ts +2 -2
  200. package/build-types/slot-fill/index.d.ts +13 -1
  201. package/build-types/slot-fill/index.d.ts.map +1 -1
  202. package/build-types/spacer/hook.d.ts +2 -2
  203. package/build-types/spinner/index.d.ts +1 -1
  204. package/build-types/spinner/styles.d.ts.map +1 -1
  205. package/build-types/surface/hook.d.ts +2 -2
  206. package/build-types/text/hook.d.ts +2 -2
  207. package/build-types/text-control/index.d.ts +1 -1
  208. package/build-types/toolbar/toolbar-button/index.d.ts +8 -8
  209. package/build-types/tools-panel/tools-panel/hook.d.ts +2 -2
  210. package/build-types/tools-panel/tools-panel-header/hook.d.ts +2 -2
  211. package/build-types/tools-panel/tools-panel-item/hook.d.ts +2 -2
  212. package/build-types/tree-grid/index.d.ts.map +1 -1
  213. package/build-types/truncate/hook.d.ts +2 -2
  214. package/build-types/ui/context/wordpress-component.d.ts +1 -1
  215. package/build-types/ui/context/wordpress-component.d.ts.map +1 -1
  216. package/build-types/ui/control-group/hook.d.ts +2 -2
  217. package/build-types/ui/control-label/hook.d.ts +2 -2
  218. package/build-types/ui/form-group/form-group.d.ts +2 -2
  219. package/build-types/ui/form-group/use-form-group.d.ts +2 -2
  220. package/build-types/unit-control/index.d.ts +1 -1
  221. package/build-types/unit-control/styles/unit-control-styles.d.ts +2 -2
  222. package/build-types/v-stack/hook.d.ts +2 -2
  223. package/build-types/view/component.d.ts +1 -1
  224. package/build-types/view/component.d.ts.map +1 -1
  225. package/package.json +22 -22
  226. package/src/autocomplete/README.md +4 -2
  227. package/src/checkbox-control/index.tsx +6 -2
  228. package/src/color-palette/index.native.js +20 -1
  229. package/src/color-picker/test/index.tsx +99 -99
  230. package/src/custom-gradient-picker/index.native.js +1 -1
  231. package/src/custom-gradient-picker/serializer.ts +2 -6
  232. package/src/custom-gradient-picker/types.ts +0 -18
  233. package/src/dimension-control/README.md +1 -1
  234. package/src/draggable/README.md +8 -1
  235. package/src/draggable/index.tsx +6 -1
  236. package/src/draggable/stories/index.tsx +69 -33
  237. package/src/draggable/types.ts +7 -0
  238. package/src/drop-zone/index.tsx +12 -8
  239. package/src/drop-zone/style.scss +1 -1
  240. package/src/{index.js → index.ts} +1 -0
  241. package/src/mobile/bottom-sheet/cell.native.js +4 -5
  242. package/src/mobile/color-settings/palette.screen.native.js +0 -7
  243. package/src/mobile/global-styles-context/utils.native.js +18 -3
  244. package/src/mobile/keyboard-aware-flat-list/index.android.js +0 -4
  245. package/src/mobile/keyboard-aware-flat-list/index.ios.js +118 -67
  246. package/src/mobile/keyboard-aware-flat-list/test/use-keyboard-offset.native.js +203 -0
  247. package/src/mobile/keyboard-aware-flat-list/test/use-scroll-to-text-input.native.js +140 -0
  248. package/src/mobile/keyboard-aware-flat-list/test/use-text-input-caret-position.native.js +82 -0
  249. package/src/mobile/keyboard-aware-flat-list/test/use-text-input-offset.native.js +147 -0
  250. package/src/mobile/keyboard-aware-flat-list/use-keyboard-offset.native.js +87 -0
  251. package/src/mobile/keyboard-aware-flat-list/use-scroll-to-text-input.native.js +105 -0
  252. package/src/mobile/keyboard-aware-flat-list/use-text-input-caret-position.native.js +36 -0
  253. package/src/mobile/keyboard-aware-flat-list/use-text-input-offset.native.js +54 -0
  254. package/src/mobile/segmented-control/index.native.js +2 -2
  255. package/src/modal/style.scss +20 -12
  256. package/src/navigator/navigator-provider/component.tsx +2 -0
  257. package/src/navigator/navigator-screen/component.tsx +5 -2
  258. package/src/navigator/stories/index.tsx +68 -0
  259. package/src/navigator/test/index.tsx +52 -0
  260. package/src/navigator/types.ts +2 -1
  261. package/src/popover/index.tsx +2 -15
  262. package/src/{private-apis.js → private-apis.ts} +2 -0
  263. package/src/query-controls/author-select.tsx +1 -0
  264. package/src/query-controls/category-select.tsx +1 -0
  265. package/src/query-controls/index.tsx +4 -2
  266. package/src/sandbox/index.native.js +78 -37
  267. package/src/slot-fill/index.js +14 -6
  268. package/src/snackbar/style.scss +2 -1
  269. package/src/spinner/styles.ts +2 -0
  270. package/src/tree-grid/index.tsx +7 -2
  271. package/src/ui/context/wordpress-component.ts +1 -1
  272. package/src/view/component.tsx +2 -2
  273. package/tsconfig.json +3 -4
  274. package/tsconfig.tsbuildinfo +1 -1
@@ -50,6 +50,7 @@ export function CheckboxControl(
50
50
  checked,
51
51
  indeterminate,
52
52
  help,
53
+ id: idProp,
53
54
  onChange,
54
55
  ...additionalProps
55
56
  } = props;
@@ -81,8 +82,11 @@ export function CheckboxControl(
81
82
  },
82
83
  [ checked, indeterminate ]
83
84
  );
84
- const instanceId = useInstanceId( CheckboxControl );
85
- const id = `inspector-checkbox-control-${ instanceId }`;
85
+ const id = useInstanceId(
86
+ CheckboxControl,
87
+ 'inspector-checkbox-control',
88
+ idProp
89
+ );
86
90
  const onChangeValue = ( event: ChangeEvent< HTMLInputElement > ) =>
87
91
  onChange( event.target.checked );
88
92
 
@@ -15,7 +15,7 @@ import {
15
15
  /**
16
16
  * WordPress dependencies
17
17
  */
18
- import { __ } from '@wordpress/i18n';
18
+ import { __, sprintf } from '@wordpress/i18n';
19
19
  import { useRef, useEffect } from '@wordpress/element';
20
20
  import { usePreferredColorSchemeStyle } from '@wordpress/compose';
21
21
 
@@ -175,6 +175,22 @@ function ColorPalette( {
175
175
  }
176
176
  }
177
177
 
178
+ function getColorGradientName( value ) {
179
+ const fallbackName = sprintf(
180
+ /* translators: %s: the hex color value */
181
+ __( 'Unlabeled color. %s' ),
182
+ value
183
+ );
184
+ const foundColorName = isGradientSegment
185
+ ? defaultSettings.gradients?.find(
186
+ ( gradient ) => gradient.gradient === value
187
+ )
188
+ : defaultSettings.allColors?.find(
189
+ ( color ) => color.color === value
190
+ );
191
+ return foundColorName ? foundColorName?.name : fallbackName;
192
+ }
193
+
178
194
  function onColorPress( color ) {
179
195
  deselectCustomGradient();
180
196
  performAnimation( color );
@@ -251,6 +267,8 @@ function ColorPalette( {
251
267
  const scaleValue = isSelected( color )
252
268
  ? scaleInterpolation
253
269
  : 1;
270
+ const colorName = getColorGradientName( color );
271
+
254
272
  return (
255
273
  <View key={ `${ color }-${ isSelected( color ) }` }>
256
274
  <TouchableWithoutFeedback
@@ -260,6 +278,7 @@ function ColorPalette( {
260
278
  selected: isSelected( color ),
261
279
  } }
262
280
  accessibilityHint={ color }
281
+ accessibilityLabel={ colorName }
263
282
  testID={ color }
264
283
  >
265
284
  <Animated.View
@@ -1,49 +1,14 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { render, fireEvent, waitFor } from '@testing-library/react';
4
+ import { screen, render } from '@testing-library/react';
5
+ import userEvent from '@testing-library/user-event';
5
6
 
6
7
  /**
7
8
  * Internal dependencies
8
9
  */
9
10
  import { ColorPicker } from '..';
10
11
 
11
- /**
12
- * Ordinarily we'd try to select the component by role but the slider role appears
13
- * on several elements and we'd end up encoding assumptions about order when
14
- * trying to select the appropriate element. We might as well just use the class name
15
- * on the container which will be more durable if, for example, the order changes.
16
- */
17
- function getSaturation( container: HTMLElement ) {
18
- return container.querySelector(
19
- '.react-colorful__saturation .react-colorful__interactive'
20
- );
21
- }
22
-
23
- type PageXPageY = { pageX: number; pageY: number };
24
-
25
- // Fix to pass `pageX` and `pageY`
26
- // See https://github.com/testing-library/react-testing-library/issues/268
27
- class FakeMouseEvent extends MouseEvent {
28
- constructor( type: MouseEvent[ 'type' ], values?: PageXPageY ) {
29
- super( type, { buttons: 1, bubbles: true, ...values } );
30
-
31
- Object.assign( this, {
32
- pageX: values?.pageX ?? 0,
33
- pageY: values?.pageY ?? 0,
34
- } );
35
- }
36
- }
37
-
38
- function moveReactColorfulSlider(
39
- sliderElement: Element,
40
- from: PageXPageY,
41
- to: PageXPageY
42
- ) {
43
- fireEvent( sliderElement, new FakeMouseEvent( 'mousedown', from ) );
44
- fireEvent( sliderElement, new FakeMouseEvent( 'mousemove', to ) );
45
- }
46
-
47
12
  const hslaMatcher = expect.objectContaining( {
48
13
  h: expect.any( Number ),
49
14
  s: expect.any( Number ),
@@ -73,99 +38,134 @@ const legacyColorMatcher = {
73
38
  describe( 'ColorPicker', () => {
74
39
  describe( 'legacy props', () => {
75
40
  it( 'should fire onChangeComplete with the legacy color format', async () => {
41
+ const user = userEvent.setup();
76
42
  const onChangeComplete = jest.fn();
77
- const color = '#fff';
43
+ const color = '#000';
78
44
 
79
- const { container } = render(
45
+ render(
80
46
  <ColorPicker
81
47
  onChangeComplete={ onChangeComplete }
82
48
  color={ color }
49
+ enableAlpha={ false }
83
50
  />
84
51
  );
85
52
 
86
- const saturation = getSaturation( container );
87
-
88
- if ( saturation === null ) {
89
- throw new Error( 'The saturation slider could not be found' );
90
- }
53
+ const formatSelector = screen.getByRole( 'combobox' );
54
+ expect( formatSelector ).toBeVisible();
91
55
 
92
- expect( saturation ).toBeInTheDocument();
56
+ await user.selectOptions( formatSelector, 'hex' );
93
57
 
94
- moveReactColorfulSlider(
95
- saturation,
96
- { pageX: 0, pageY: 0 },
97
- { pageX: 10, pageY: 10 }
98
- );
58
+ const hexInput = screen.getByRole( 'textbox' );
59
+ expect( hexInput ).toBeVisible();
99
60
 
100
- await waitFor( () =>
101
- expect( onChangeComplete ).toHaveBeenCalled()
102
- );
61
+ await user.clear( hexInput );
62
+ await user.type( hexInput, '1ab' );
103
63
 
104
- expect( onChangeComplete ).toHaveBeenCalledWith(
64
+ expect( onChangeComplete ).toHaveBeenCalledTimes( 3 );
65
+ expect( onChangeComplete ).toHaveBeenLastCalledWith(
105
66
  legacyColorMatcher
106
67
  );
107
68
  } );
108
69
  } );
70
+ describe( 'Hex input', () => {
71
+ it( 'should fire onChange with the correct value from the hex input', async () => {
72
+ const user = userEvent.setup();
73
+ const onChange = jest.fn();
74
+ const color = '#000';
75
+
76
+ render(
77
+ <ColorPicker
78
+ onChange={ onChange }
79
+ color={ color }
80
+ enableAlpha={ false }
81
+ />
82
+ );
83
+
84
+ const formatSelector = screen.getByRole( 'combobox' );
85
+ expect( formatSelector ).toBeVisible();
86
+
87
+ await user.selectOptions( formatSelector, 'hex' );
109
88
 
110
- it( 'should fire onChange with the string value', async () => {
111
- const onChange = jest.fn();
112
- const color = 'rgba(1, 1, 1, 0.5)';
89
+ const hexInput = screen.getByRole( 'textbox' );
90
+ expect( hexInput ).toBeVisible();
113
91
 
114
- const { container } = render(
115
- <ColorPicker onChange={ onChange } color={ color } enableAlpha />
116
- );
92
+ await user.clear( hexInput );
93
+ await user.type( hexInput, '1ab' );
117
94
 
118
- const saturation = getSaturation( container );
95
+ expect( onChange ).toHaveBeenCalledTimes( 3 );
96
+ expect( onChange ).toHaveBeenLastCalledWith( '#11aabb' );
97
+ } );
98
+ } );
119
99
 
120
- if ( saturation === null ) {
121
- throw new Error( 'The saturation slider could not be found' );
122
- }
100
+ describe.each( [
101
+ [ 'red', 'Red', '#7dffff' ],
102
+ [ 'green', 'Green', '#ff7dff' ],
103
+ [ 'blue', 'Blue', '#ffff7d' ],
104
+ ] )( 'RGB inputs', ( colorInput, inputLabel, expected ) => {
105
+ it( `should fire onChange with the correct value when the ${ colorInput } value is updated`, async () => {
106
+ const user = userEvent.setup();
107
+ const onChange = jest.fn();
108
+ const color = '#fff';
123
109
 
124
- expect( saturation ).toBeInTheDocument();
110
+ render(
111
+ <ColorPicker
112
+ onChange={ onChange }
113
+ color={ color }
114
+ enableAlpha={ false }
115
+ />
116
+ );
125
117
 
126
- moveReactColorfulSlider(
127
- saturation,
128
- { pageX: 0, pageY: 0 },
129
- { pageX: 10, pageY: 10 }
130
- );
118
+ const formatSelector = screen.getByRole( 'combobox' );
119
+ expect( formatSelector ).toBeVisible();
131
120
 
132
- await waitFor( () => expect( onChange ).toHaveBeenCalled() );
121
+ await user.selectOptions( formatSelector, 'rgb' );
133
122
 
134
- expect( onChange ).toHaveBeenCalledWith(
135
- expect.stringMatching( /^#([a-fA-F0-9]{8})$/ )
136
- );
137
- } );
123
+ const inputElement = screen.getByRole( 'spinbutton', {
124
+ name: inputLabel,
125
+ } );
126
+ expect( inputElement ).toBeVisible();
138
127
 
139
- it( 'should fire onChange with the HSL value', async () => {
140
- const onChange = jest.fn();
141
- const color = 'hsla(125, 20%, 50%, 0.5)';
128
+ await user.clear( inputElement );
129
+ await user.type( inputElement, '125' );
142
130
 
143
- const { container } = render(
144
- <ColorPicker
145
- onChange={ onChange }
146
- color={ color }
147
- enableAlpha={ false }
148
- />
149
- );
131
+ expect( onChange ).toHaveBeenCalledTimes( 4 );
132
+ expect( onChange ).toHaveBeenLastCalledWith( expected );
133
+ } );
134
+ } );
150
135
 
151
- const saturation = getSaturation( container );
136
+ describe.each( [
137
+ [ 'hue', 'Hue', '#aad52a' ],
138
+ [ 'saturation', 'Saturation', '#20dfdf' ],
139
+ [ 'lightness', 'Lightness', '#95eaea' ],
140
+ ] )( 'HSL inputs', ( colorInput, inputLabel, expected ) => {
141
+ it( `should fire onChange with the correct value when the ${ colorInput } value is updated`, async () => {
142
+ const user = userEvent.setup();
143
+ const onChange = jest.fn();
144
+ const color = '#2ad5d5';
145
+
146
+ render(
147
+ <ColorPicker
148
+ onChange={ onChange }
149
+ color={ color }
150
+ enableAlpha={ false }
151
+ />
152
+ );
152
153
 
153
- if ( saturation === null ) {
154
- throw new Error( 'The saturation slider could not be found' );
155
- }
154
+ const formatSelector = screen.getByRole( 'combobox' );
155
+ expect( formatSelector ).toBeVisible();
156
156
 
157
- expect( saturation ).toBeInTheDocument();
157
+ await user.selectOptions( formatSelector, 'hsl' );
158
158
 
159
- moveReactColorfulSlider(
160
- saturation,
161
- { pageX: 0, pageY: 0 },
162
- { pageX: 10, pageY: 10 }
163
- );
159
+ const inputElement = screen.getByRole( 'spinbutton', {
160
+ name: inputLabel,
161
+ } );
162
+ expect( inputElement ).toBeVisible();
164
163
 
165
- await waitFor( () => expect( onChange ).toHaveBeenCalled() );
164
+ await user.clear( inputElement );
165
+ await user.type( inputElement, '75' );
166
166
 
167
- expect( onChange ).toHaveBeenCalledWith(
168
- expect.stringMatching( /^#([a-fA-F0-9]{6})$/ )
169
- );
167
+ expect( onChange ).toHaveBeenCalledTimes( 3 );
168
+ expect( onChange ).toHaveBeenLastCalledWith( expected );
169
+ } );
170
170
  } );
171
171
  } );
@@ -25,7 +25,7 @@ function CustomGradientPicker( { setColor, currentValue, isGradientColor } ) {
25
25
  const [ currentColor, setCurrentColor ] = useState( currentValue );
26
26
 
27
27
  const { getGradientType, gradients, gradientOptions } = colorsUtils;
28
- const gradientAST = getGradientAstWithDefault( currentColor );
28
+ const { gradientAST } = getGradientAstWithDefault( currentColor );
29
29
  const gradientType = getGradientType( currentColor );
30
30
 
31
31
  function isLinearGradient( type ) {
@@ -2,15 +2,11 @@
2
2
  * External dependencies
3
3
  */
4
4
  import type gradientParser from 'gradient-parser';
5
- /**
6
- * Internal dependencies
7
- */
8
- import type { ColorStopTypeAndValue } from './types';
9
5
 
10
6
  export function serializeGradientColor( {
11
7
  type,
12
8
  value,
13
- }: ColorStopTypeAndValue ) {
9
+ }: gradientParser.ColorStop ) {
14
10
  if ( type === 'literal' ) {
15
11
  return value;
16
12
  }
@@ -38,7 +34,7 @@ export function serializeGradientColorStop( {
38
34
  return `${ serializeGradientColor( {
39
35
  type,
40
36
  value,
41
- } as ColorStopTypeAndValue ) } ${ serializeGradientPosition( length ) }`;
37
+ } as gradientParser.ColorStop ) } ${ serializeGradientPosition( length ) }`;
42
38
  }
43
39
 
44
40
  export function serializeGradientOrientation(
@@ -48,24 +48,6 @@ export type GradientTypePickerProps = {
48
48
 
49
49
  export type ControlPoint = { color: string; position: number };
50
50
 
51
- // When dealing with unions of objects, using `Pick` will result
52
- // in a new type where each desired prop is a union of the values for that prop
53
- // across all of the original union members. This does not maintain the specific
54
- // combinations of props present in the original union.
55
- // To avoid this, the `DistributivePick` type will
56
- // "distribute" the `Pick` across the union. This allows the `Pick`
57
- // to act on each member individually, maintaining the relationships between the
58
- // resulting props.
59
- // https://stackoverflow.com/questions/57103834/typescript-omit-a-property-from-all-interfaces-in-a-union-but-keep-the-union-s
60
- type DistributivePick< T, K extends keyof T > = T extends any
61
- ? Pick< T, K >
62
- : never;
63
-
64
- export type ColorStopTypeAndValue = DistributivePick<
65
- gradientParser.ColorStop,
66
- 'type' | 'value'
67
- >;
68
-
69
51
  export type CustomGradientBarProps = {
70
52
  background: React.CSSProperties[ 'background' ];
71
53
  hasGradient: boolean;
@@ -9,8 +9,8 @@ This feature is still experimental. “Experimental” means this is an early im
9
9
  ## Usage
10
10
 
11
11
  ```jsx
12
- import { useState } from 'react';
13
12
  import { __experimentalDimensionControl as DimensionControl } from '@wordpress/components';
13
+ import { useState } from '@wordpress/element';
14
14
 
15
15
  export default function MyCustomDimensionControl() {
16
16
  const [ paddingSize, setPaddingSize ] = useState( '' );
@@ -8,9 +8,16 @@ Note that the drag handle needs to declare the `draggable="true"` property and b
8
8
 
9
9
  The component accepts the following props:
10
10
 
11
+ ### `appendToOwnerDocument`: `boolean`
12
+
13
+ Whether to append the cloned element to the `ownerDocument` body. By default, elements sourced by id are appended to the element's wrapper.
14
+
15
+ - Required: No
16
+ - Default: `false`
17
+
11
18
  ### `elementId`: `string`
12
19
 
13
- The HTML id of the element to clone on drag
20
+ The HTML id of the element to clone on drag.
14
21
 
15
22
  - Required: Yes
16
23
 
@@ -63,6 +63,7 @@ export function Draggable( {
63
63
  onDragStart,
64
64
  onDragOver,
65
65
  onDragEnd,
66
+ appendToOwnerDocument = false,
66
67
  cloneClassname,
67
68
  elementId,
68
69
  transferData,
@@ -173,7 +174,11 @@ export function Draggable( {
173
174
  cloneWrapper.appendChild( clone );
174
175
 
175
176
  // Inject the cloneWrapper into the DOM.
176
- elementWrapper?.appendChild( cloneWrapper );
177
+ if ( appendToOwnerDocument ) {
178
+ ownerDocument.body.appendChild( cloneWrapper );
179
+ } else {
180
+ elementWrapper?.appendChild( cloneWrapper );
181
+ }
177
182
  }
178
183
 
179
184
  // Mark the current cursor coordinates.
@@ -7,6 +7,7 @@ import type { DragEvent } from 'react';
7
7
  /**
8
8
  * WordPress dependencies
9
9
  */
10
+ import { useInstanceId } from '@wordpress/compose';
10
11
  import { useState } from '@wordpress/element';
11
12
  import { Icon, more } from '@wordpress/icons';
12
13
 
@@ -32,46 +33,68 @@ export default meta;
32
33
 
33
34
  const DefaultTemplate: ComponentStory< typeof Draggable > = ( args ) => {
34
35
  const [ isDragging, setDragging ] = useState( false );
36
+ const instanceId = useInstanceId( DefaultTemplate );
35
37
 
36
38
  // Allow for the use of ID in the example.
37
39
  return (
38
40
  <div>
39
- <p>Is Dragging? { isDragging ? 'Yes' : 'No!' }</p>
41
+ <p
42
+ style={ {
43
+ padding: '1em',
44
+ position: 'relative',
45
+ zIndex: 1000,
46
+ backgroundColor: 'whitesmoke',
47
+ } }
48
+ >
49
+ Is Dragging? { isDragging ? 'Yes' : 'No!' }
50
+ </p>
40
51
  <div
41
- /* eslint-disable no-restricted-syntax, eslint-comments/disable-enable-pair */
42
- id="draggable-example-box"
43
- style={ { display: 'inline-flex' } }
52
+ style={ {
53
+ zIndex: 100,
54
+ position: 'relative',
55
+ } }
44
56
  >
45
- <Draggable { ...args } elementId="draggable-example-box">
46
- { ( { onDraggableStart, onDraggableEnd } ) => {
47
- const handleOnDragStart = ( event: DragEvent ) => {
48
- setDragging( true );
49
- onDraggableStart( event );
50
- };
51
- const handleOnDragEnd = ( event: DragEvent ) => {
52
- setDragging( false );
53
- onDraggableEnd( event );
54
- };
55
-
56
- return (
57
- <div
58
- onDragStart={ handleOnDragStart }
59
- onDragEnd={ handleOnDragEnd }
60
- draggable
61
- style={ {
62
- alignItems: 'center',
63
- display: 'flex',
64
- justifyContent: 'center',
65
- width: 100,
66
- height: 100,
67
- background: '#ddd',
68
- } }
69
- >
70
- <Icon icon={ more } />
71
- </div>
72
- );
57
+ <div
58
+ id={ `draggable-example-box-${ instanceId }` }
59
+ style={ {
60
+ display: 'inline-flex',
61
+ position: 'relative',
73
62
  } }
74
- </Draggable>
63
+ >
64
+ <Draggable
65
+ { ...args }
66
+ elementId={ `draggable-example-box-${ instanceId }` }
67
+ >
68
+ { ( { onDraggableStart, onDraggableEnd } ) => {
69
+ const handleOnDragStart = ( event: DragEvent ) => {
70
+ setDragging( true );
71
+ onDraggableStart( event );
72
+ };
73
+ const handleOnDragEnd = ( event: DragEvent ) => {
74
+ setDragging( false );
75
+ onDraggableEnd( event );
76
+ };
77
+
78
+ return (
79
+ <div
80
+ onDragStart={ handleOnDragStart }
81
+ onDragEnd={ handleOnDragEnd }
82
+ draggable
83
+ style={ {
84
+ alignItems: 'center',
85
+ display: 'flex',
86
+ justifyContent: 'center',
87
+ width: 100,
88
+ height: 100,
89
+ background: '#ddd',
90
+ } }
91
+ >
92
+ <Icon icon={ more } />
93
+ </div>
94
+ );
95
+ } }
96
+ </Draggable>
97
+ </div>
75
98
  </div>
76
99
  </div>
77
100
  );
@@ -81,3 +104,16 @@ export const Default: ComponentStory< typeof Draggable > = DefaultTemplate.bind(
81
104
  {}
82
105
  );
83
106
  Default.args = {};
107
+
108
+ /**
109
+ * `appendToOwnerDocument` is used to append the element being dragged to the body of the owner document.
110
+ *
111
+ * This is useful when the element being dragged should not receive styles from its parent.
112
+ * For example, when the element's parent sets a `z-index` value that would cause the dragged
113
+ * element to be rendered behind other elements.
114
+ */
115
+ export const AppendElementToOwnerDocument: ComponentStory< typeof Draggable > =
116
+ DefaultTemplate.bind( {} );
117
+ AppendElementToOwnerDocument.args = {
118
+ appendToOwnerDocument: true,
119
+ };
@@ -17,6 +17,13 @@ export type DraggableProps = {
17
17
  */
18
18
  onDraggableEnd: ( event: DragEvent ) => void;
19
19
  } ) => JSX.Element | null;
20
+ /**
21
+ * Whether to append the cloned element to the `ownerDocument` body.
22
+ * By default, elements sourced by id are appended to the element's wrapper.
23
+ *
24
+ * @default false
25
+ */
26
+ appendToOwnerDocument?: boolean;
20
27
  /**
21
28
  * Classname for the cloned element.
22
29
  */
@@ -120,30 +120,34 @@ export function DropZoneComponent( {
120
120
 
121
121
  let children;
122
122
  const backdrop = {
123
- hidden: { scaleY: 0, opacity: 0 },
123
+ hidden: { opacity: 0 },
124
124
  show: {
125
- scaleY: 1,
126
125
  opacity: 1,
127
126
  transition: {
128
127
  type: 'tween',
129
128
  duration: 0.2,
130
- delay: 0.1,
131
- delayChildren: 0.2,
129
+ delay: 0,
130
+ delayChildren: 0.1,
132
131
  },
133
132
  },
134
133
  exit: {
135
- scaleY: 1,
136
134
  opacity: 0,
137
135
  transition: {
138
- duration: 0.3,
136
+ duration: 0.2,
139
137
  delayChildren: 0,
140
138
  },
141
139
  },
142
140
  };
143
141
 
144
142
  const foreground = {
145
- hidden: { opacity: 0, scale: 0.75 },
146
- show: { opacity: 1, scale: 1 },
143
+ hidden: { opacity: 0, scale: 0.9 },
144
+ show: {
145
+ opacity: 1,
146
+ scale: 1,
147
+ transition: {
148
+ duration: 0.1,
149
+ },
150
+ },
147
151
  exit: { opacity: 0, scale: 0.9 },
148
152
  };
149
153
 
@@ -38,7 +38,7 @@
38
38
  }
39
39
 
40
40
  .components-drop-zone__content-icon {
41
- margin: 0 auto;
41
+ margin: 0 auto $grid-unit-10;
42
42
  line-height: 0;
43
43
  fill: currentColor;
44
44
  pointer-events: none;
@@ -90,6 +90,7 @@ export { default as GuidePage } from './guide/page';
90
90
  export { Heading as __experimentalHeading } from './heading';
91
91
  export { HStack as __experimentalHStack } from './h-stack';
92
92
  export { default as Icon } from './icon';
93
+ export type { IconType } from './icon';
93
94
  export { default as IconButton } from './button/deprecated';
94
95
  export {
95
96
  ItemGroup as __experimentalItemGroup,
@@ -10,7 +10,6 @@ import {
10
10
  AccessibilityInfo,
11
11
  Platform,
12
12
  } from 'react-native';
13
- import { isEmpty, get } from 'lodash';
14
13
 
15
14
  /**
16
15
  * WordPress dependencies
@@ -273,8 +272,8 @@ class BottomSheetCell extends Component {
273
272
  return accessibilityLabel || label;
274
273
  }
275
274
 
276
- if ( isEmpty( value ) ) {
277
- return isEmpty( help )
275
+ if ( ! value ) {
276
+ return ! help
278
277
  ? sprintf(
279
278
  /* translators: accessibility text. Empty state of a inline textinput cell. %s: The cell's title */
280
279
  _x( '%s. Empty', 'inline textinput cell' ),
@@ -288,7 +287,7 @@ class BottomSheetCell extends Component {
288
287
  help
289
288
  );
290
289
  }
291
- return isEmpty( help )
290
+ return ! help
292
291
  ? sprintf(
293
292
  /* translators: accessibility text. Inline textinput title and value.%1: Cell title, %2: cell value. */
294
293
  _x( '%1$s, %2$s', 'inline textinput cell' ),
@@ -323,7 +322,7 @@ class BottomSheetCell extends Component {
323
322
  const opacity =
324
323
  activeOpacity !== undefined
325
324
  ? activeOpacity
326
- : get( platformStyles, 'activeOpacity.opacity' );
325
+ : platformStyles.activeOpacity?.opacity;
327
326
 
328
327
  return (
329
328
  <TouchableRipple