@wordpress/components 19.3.0 → 19.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (318) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/CONTRIBUTING.md +1 -1
  3. package/README.md +8 -4
  4. package/build/base-field/hook.js +1 -1
  5. package/build/base-field/hook.js.map +1 -1
  6. package/build/button/deprecated.js +2 -1
  7. package/build/button/deprecated.js.map +1 -1
  8. package/build/button/index.js +2 -1
  9. package/build/button/index.js.map +1 -1
  10. package/build/card/card/component.js +1 -1
  11. package/build/card/card/component.js.map +1 -1
  12. package/build/card/card/hook.js +1 -1
  13. package/build/card/card/hook.js.map +1 -1
  14. package/build/card/card-body/hook.js +1 -1
  15. package/build/card/card-body/hook.js.map +1 -1
  16. package/build/card/card-divider/hook.js +1 -1
  17. package/build/card/card-divider/hook.js.map +1 -1
  18. package/build/card/card-footer/hook.js +1 -1
  19. package/build/card/card-footer/hook.js.map +1 -1
  20. package/build/card/card-header/hook.js +1 -1
  21. package/build/card/card-header/hook.js.map +1 -1
  22. package/build/card/card-media/hook.js +1 -1
  23. package/build/card/card-media/hook.js.map +1 -1
  24. package/build/circular-option-picker/index.js +2 -0
  25. package/build/circular-option-picker/index.js.map +1 -1
  26. package/build/color-indicator/index.js +2 -0
  27. package/build/color-indicator/index.js.map +1 -1
  28. package/build/color-palette/index.js +2 -0
  29. package/build/color-palette/index.js.map +1 -1
  30. package/build/color-picker/color-display.js.map +1 -1
  31. package/build/color-picker/color-input.js.map +1 -1
  32. package/build/color-picker/component.js +1 -1
  33. package/build/color-picker/component.js.map +1 -1
  34. package/build/color-picker/use-deprecated-props.js +2 -0
  35. package/build/color-picker/use-deprecated-props.js.map +1 -1
  36. package/build/date-time/time.js +1 -1
  37. package/build/date-time/time.js.map +1 -1
  38. package/build/dropdown/index.js +3 -3
  39. package/build/dropdown/index.js.map +1 -1
  40. package/build/elevation/hook.js +5 -5
  41. package/build/elevation/hook.js.map +1 -1
  42. package/build/flex/flex/hook.js +4 -4
  43. package/build/flex/flex/hook.js.map +1 -1
  44. package/build/grid/hook.js +2 -2
  45. package/build/grid/hook.js.map +1 -1
  46. package/build/item-group/item/hook.js +1 -1
  47. package/build/item-group/item/hook.js.map +1 -1
  48. package/build/mobile/inserter-button/index.native.js +3 -3
  49. package/build/mobile/inserter-button/index.native.js.map +1 -1
  50. package/build/mobile/inserter-button/sparkles.js +25 -0
  51. package/build/mobile/inserter-button/sparkles.js.map +1 -0
  52. package/build/modal/index.js +1 -12
  53. package/build/modal/index.js.map +1 -1
  54. package/build/navigator/context.js +2 -2
  55. package/build/navigator/context.js.map +1 -1
  56. package/build/navigator/navigator-provider/component.js +18 -25
  57. package/build/navigator/navigator-provider/component.js.map +1 -1
  58. package/build/navigator/navigator-screen/component.js +39 -13
  59. package/build/navigator/navigator-screen/component.js.map +1 -1
  60. package/build/navigator/use-navigator.js +4 -4
  61. package/build/navigator/use-navigator.js.map +1 -1
  62. package/build/placeholder/index.js +4 -4
  63. package/build/placeholder/index.js.map +1 -1
  64. package/build/scrollable/hook.js +1 -1
  65. package/build/scrollable/hook.js.map +1 -1
  66. package/build/slot-fill/bubbles-virtually/fill.js +11 -2
  67. package/build/slot-fill/bubbles-virtually/fill.js.map +1 -1
  68. package/build/spinner/index.js +44 -5
  69. package/build/spinner/index.js.map +1 -1
  70. package/build/spinner/styles.js +56 -0
  71. package/build/spinner/styles.js.map +1 -0
  72. package/build/surface/hook.js +1 -1
  73. package/build/surface/hook.js.map +1 -1
  74. package/build/text/hook.js +5 -5
  75. package/build/text/hook.js.map +1 -1
  76. package/build/tip/index.js +4 -8
  77. package/build/tip/index.js.map +1 -1
  78. package/build/toggle-group-control/toggle-group-control/component.js +1 -1
  79. package/build/toggle-group-control/toggle-group-control/component.js.map +1 -1
  80. package/build/tools-panel/tools-panel/hook.js +7 -7
  81. package/build/tools-panel/tools-panel/hook.js.map +1 -1
  82. package/build/tools-panel/tools-panel-header/hook.js +3 -3
  83. package/build/tools-panel/tools-panel-header/hook.js.map +1 -1
  84. package/build/tools-panel/tools-panel-item/hook.js +1 -1
  85. package/build/tools-panel/tools-panel-item/hook.js.map +1 -1
  86. package/build/tree-grid/index.js +13 -6
  87. package/build/tree-grid/index.js.map +1 -1
  88. package/build/truncate/hook.js +2 -2
  89. package/build/truncate/hook.js.map +1 -1
  90. package/build/utils/config-values.js +1 -1
  91. package/build/utils/config-values.js.map +1 -1
  92. package/build-module/base-field/hook.js +1 -1
  93. package/build-module/base-field/hook.js.map +1 -1
  94. package/build-module/button/deprecated.js +2 -1
  95. package/build-module/button/deprecated.js.map +1 -1
  96. package/build-module/button/index.js +2 -1
  97. package/build-module/button/index.js.map +1 -1
  98. package/build-module/card/card/component.js +1 -1
  99. package/build-module/card/card/component.js.map +1 -1
  100. package/build-module/card/card/hook.js +1 -1
  101. package/build-module/card/card/hook.js.map +1 -1
  102. package/build-module/card/card-body/hook.js +1 -1
  103. package/build-module/card/card-body/hook.js.map +1 -1
  104. package/build-module/card/card-divider/hook.js +1 -1
  105. package/build-module/card/card-divider/hook.js.map +1 -1
  106. package/build-module/card/card-footer/hook.js +1 -1
  107. package/build-module/card/card-footer/hook.js.map +1 -1
  108. package/build-module/card/card-header/hook.js +1 -1
  109. package/build-module/card/card-header/hook.js.map +1 -1
  110. package/build-module/card/card-media/hook.js +1 -1
  111. package/build-module/card/card-media/hook.js.map +1 -1
  112. package/build-module/circular-option-picker/index.js +1 -0
  113. package/build-module/circular-option-picker/index.js.map +1 -1
  114. package/build-module/color-indicator/index.js +1 -0
  115. package/build-module/color-indicator/index.js.map +1 -1
  116. package/build-module/color-palette/index.js +1 -0
  117. package/build-module/color-palette/index.js.map +1 -1
  118. package/build-module/color-picker/color-display.js.map +1 -1
  119. package/build-module/color-picker/color-input.js.map +1 -1
  120. package/build-module/color-picker/component.js +1 -1
  121. package/build-module/color-picker/component.js.map +1 -1
  122. package/build-module/color-picker/use-deprecated-props.js +2 -0
  123. package/build-module/color-picker/use-deprecated-props.js.map +1 -1
  124. package/build-module/date-time/time.js +1 -1
  125. package/build-module/date-time/time.js.map +1 -1
  126. package/build-module/dropdown/index.js +3 -3
  127. package/build-module/dropdown/index.js.map +1 -1
  128. package/build-module/elevation/hook.js +5 -5
  129. package/build-module/elevation/hook.js.map +1 -1
  130. package/build-module/flex/flex/hook.js +4 -4
  131. package/build-module/flex/flex/hook.js.map +1 -1
  132. package/build-module/grid/hook.js +2 -2
  133. package/build-module/grid/hook.js.map +1 -1
  134. package/build-module/item-group/item/hook.js +1 -1
  135. package/build-module/item-group/item/hook.js.map +1 -1
  136. package/build-module/mobile/inserter-button/index.native.js +1 -1
  137. package/build-module/mobile/inserter-button/index.native.js.map +1 -1
  138. package/build-module/mobile/inserter-button/sparkles.js +16 -0
  139. package/build-module/mobile/inserter-button/sparkles.js.map +1 -0
  140. package/build-module/modal/index.js +1 -11
  141. package/build-module/modal/index.js.map +1 -1
  142. package/build-module/navigator/context.js +2 -2
  143. package/build-module/navigator/context.js.map +1 -1
  144. package/build-module/navigator/navigator-provider/component.js +18 -25
  145. package/build-module/navigator/navigator-provider/component.js.map +1 -1
  146. package/build-module/navigator/navigator-screen/component.js +39 -15
  147. package/build-module/navigator/navigator-screen/component.js.map +1 -1
  148. package/build-module/navigator/use-navigator.js +4 -4
  149. package/build-module/navigator/use-navigator.js.map +1 -1
  150. package/build-module/placeholder/index.js +4 -4
  151. package/build-module/placeholder/index.js.map +1 -1
  152. package/build-module/scrollable/hook.js +1 -1
  153. package/build-module/scrollable/hook.js.map +1 -1
  154. package/build-module/slot-fill/bubbles-virtually/fill.js +11 -2
  155. package/build-module/slot-fill/bubbles-virtually/fill.js.map +1 -1
  156. package/build-module/spinner/index.js +40 -5
  157. package/build-module/spinner/index.js.map +1 -1
  158. package/build-module/spinner/styles.js +49 -0
  159. package/build-module/spinner/styles.js.map +1 -0
  160. package/build-module/surface/hook.js +1 -1
  161. package/build-module/surface/hook.js.map +1 -1
  162. package/build-module/text/hook.js +5 -5
  163. package/build-module/text/hook.js.map +1 -1
  164. package/build-module/tip/index.js +4 -8
  165. package/build-module/tip/index.js.map +1 -1
  166. package/build-module/toggle-group-control/toggle-group-control/component.js +1 -1
  167. package/build-module/toggle-group-control/toggle-group-control/component.js.map +1 -1
  168. package/build-module/tools-panel/tools-panel/hook.js +7 -7
  169. package/build-module/tools-panel/tools-panel/hook.js.map +1 -1
  170. package/build-module/tools-panel/tools-panel-header/hook.js +3 -3
  171. package/build-module/tools-panel/tools-panel-header/hook.js.map +1 -1
  172. package/build-module/tools-panel/tools-panel-item/hook.js +1 -1
  173. package/build-module/tools-panel/tools-panel-item/hook.js.map +1 -1
  174. package/build-module/tree-grid/index.js +12 -6
  175. package/build-module/tree-grid/index.js.map +1 -1
  176. package/build-module/truncate/hook.js +2 -2
  177. package/build-module/truncate/hook.js.map +1 -1
  178. package/build-module/utils/config-values.js +1 -1
  179. package/build-module/utils/config-values.js.map +1 -1
  180. package/build-style/style-rtl.css +12 -2
  181. package/build-style/style.css +12 -2
  182. package/build-types/button/index.d.ts.map +1 -1
  183. package/build-types/circular-option-picker/index.d.ts +31 -0
  184. package/build-types/circular-option-picker/index.d.ts.map +1 -0
  185. package/build-types/color-palette/index.d.ts +16 -0
  186. package/build-types/color-palette/index.d.ts.map +1 -0
  187. package/build-types/color-palette/styles.d.ts +8 -0
  188. package/build-types/color-palette/styles.d.ts.map +1 -0
  189. package/build-types/color-picker/color-display.d.ts +14 -0
  190. package/build-types/color-picker/color-display.d.ts.map +1 -0
  191. package/build-types/color-picker/color-input.d.ts +14 -0
  192. package/build-types/color-picker/color-input.d.ts.map +1 -0
  193. package/build-types/color-picker/component.d.ts +11 -0
  194. package/build-types/color-picker/component.d.ts.map +1 -0
  195. package/build-types/color-picker/hex-input.d.ts +13 -0
  196. package/build-types/color-picker/hex-input.d.ts.map +1 -0
  197. package/build-types/color-picker/hsl-input.d.ts +13 -0
  198. package/build-types/color-picker/hsl-input.d.ts.map +1 -0
  199. package/build-types/color-picker/index.d.ts +5 -0
  200. package/build-types/color-picker/index.d.ts.map +1 -0
  201. package/build-types/color-picker/input-with-slider.d.ts +12 -0
  202. package/build-types/color-picker/input-with-slider.d.ts.map +1 -0
  203. package/build-types/color-picker/legacy-adapter.d.ts +6 -0
  204. package/build-types/color-picker/legacy-adapter.d.ts.map +1 -0
  205. package/build-types/color-picker/picker.d.ts +10 -0
  206. package/build-types/color-picker/picker.d.ts.map +1 -0
  207. package/build-types/color-picker/rgb-input.d.ts +13 -0
  208. package/build-types/color-picker/rgb-input.d.ts.map +1 -0
  209. package/build-types/color-picker/styles.d.ts +76 -0
  210. package/build-types/color-picker/styles.d.ts.map +1 -0
  211. package/build-types/color-picker/types.d.ts +2 -0
  212. package/build-types/color-picker/types.d.ts.map +1 -0
  213. package/build-types/color-picker/use-deprecated-props.d.ts +49 -0
  214. package/build-types/color-picker/use-deprecated-props.d.ts.map +1 -0
  215. package/build-types/dropdown/index.d.ts +1 -13
  216. package/build-types/dropdown/index.d.ts.map +1 -1
  217. package/build-types/elevation/hook.d.ts.map +1 -1
  218. package/build-types/flex/flex/hook.d.ts.map +1 -1
  219. package/build-types/grid/hook.d.ts.map +1 -1
  220. package/build-types/navigator/navigator-provider/component.d.ts +4 -4
  221. package/build-types/navigator/navigator-provider/component.d.ts.map +1 -1
  222. package/build-types/navigator/navigator-screen/component.d.ts +4 -4
  223. package/build-types/navigator/navigator-screen/component.d.ts.map +1 -1
  224. package/build-types/navigator/types.d.ts +5 -3
  225. package/build-types/navigator/types.d.ts.map +1 -1
  226. package/build-types/resizable-box/index.d.ts +1 -1
  227. package/build-types/resizable-box/resize-tooltip/index.d.ts +1 -1
  228. package/build-types/slot-fill/bubbles-virtually/fill.d.ts.map +1 -1
  229. package/build-types/spinner/index.d.ts +18 -1
  230. package/build-types/spinner/index.d.ts.map +1 -1
  231. package/build-types/spinner/styles.d.ts +13 -0
  232. package/build-types/spinner/styles.d.ts.map +1 -0
  233. package/build-types/surface/hook.d.ts.map +1 -1
  234. package/build-types/text/hook.d.ts.map +1 -1
  235. package/build-types/tip/index.d.ts.map +1 -1
  236. package/build-types/tools-panel/tools-panel/hook.d.ts.map +1 -1
  237. package/build-types/tools-panel/tools-panel-item/hook.d.ts.map +1 -1
  238. package/build-types/unit-control/index.d.ts +3 -2
  239. package/build-types/unit-control/index.d.ts.map +1 -1
  240. package/build-types/unit-control/types.d.ts +2 -1
  241. package/build-types/unit-control/types.d.ts.map +1 -1
  242. package/build-types/utils/config-values.d.ts +1 -1
  243. package/package.json +16 -17
  244. package/src/base-field/hook.js +1 -1
  245. package/src/button/deprecated.js +1 -0
  246. package/src/button/index.js +1 -0
  247. package/src/card/card/component.js +1 -1
  248. package/src/card/card/hook.js +1 -1
  249. package/src/card/card-body/hook.js +1 -1
  250. package/src/card/card-divider/hook.js +1 -1
  251. package/src/card/card-footer/hook.js +1 -1
  252. package/src/card/card-header/hook.js +1 -1
  253. package/src/card/card-media/hook.js +1 -1
  254. package/src/circular-option-picker/index.js +1 -0
  255. package/src/color-indicator/index.js +2 -0
  256. package/src/color-palette/index.js +1 -0
  257. package/src/color-palette/test/__snapshots__/index.js.snap +0 -1
  258. package/src/color-picker/color-display.tsx +1 -1
  259. package/src/color-picker/color-input.tsx +1 -1
  260. package/src/color-picker/component.tsx +1 -1
  261. package/src/color-picker/use-deprecated-props.ts +2 -0
  262. package/src/combobox-control/stories/index.js +6 -2
  263. package/src/combobox-control/style.scss +2 -2
  264. package/src/date-time/README.md +4 -4
  265. package/src/date-time/test/time.js +2 -2
  266. package/src/date-time/time.js +2 -2
  267. package/src/dropdown/index.js +14 -13
  268. package/src/elevation/hook.js +1 -0
  269. package/src/flex/flex/hook.js +1 -0
  270. package/src/grid/hook.js +1 -0
  271. package/src/item-group/item/hook.ts +1 -1
  272. package/src/item-group/stories/index.js +2 -2
  273. package/src/mobile/inserter-button/index.native.js +1 -2
  274. package/src/mobile/inserter-button/sparkles.js +15 -0
  275. package/src/mobile/link-settings/test/edit.native.js +5 -5
  276. package/src/modal/index.js +1 -10
  277. package/src/navigator/context.ts +2 -2
  278. package/src/navigator/navigator-provider/README.md +11 -9
  279. package/src/navigator/navigator-provider/component.tsx +16 -25
  280. package/src/navigator/navigator-screen/component.tsx +55 -15
  281. package/src/navigator/stories/index.js +19 -5
  282. package/src/navigator/test/index.js +77 -25
  283. package/src/navigator/types.ts +5 -3
  284. package/src/navigator/use-navigator.ts +3 -3
  285. package/src/placeholder/index.js +8 -6
  286. package/src/placeholder/style.scss +12 -0
  287. package/src/placeholder/test/index.js +18 -1
  288. package/src/scrollable/hook.js +1 -1
  289. package/src/slot-fill/bubbles-virtually/fill.js +12 -1
  290. package/src/spinner/README.md +10 -10
  291. package/src/spinner/index.js +42 -3
  292. package/src/spinner/stories/index.js +36 -3
  293. package/src/spinner/styles.js +47 -0
  294. package/src/surface/hook.js +1 -0
  295. package/src/text/hook.js +1 -0
  296. package/src/tip/index.js +2 -4
  297. package/src/toggle-group-control/toggle-group-control/component.tsx +1 -1
  298. package/src/tools-panel/stories/index.js +20 -1
  299. package/src/tools-panel/test/__snapshots__/index.js.snap +0 -1
  300. package/src/tools-panel/test/index.js +31 -1
  301. package/src/tools-panel/tools-panel/hook.ts +14 -9
  302. package/src/tools-panel/tools-panel-header/hook.ts +3 -3
  303. package/src/tools-panel/tools-panel-item/hook.ts +1 -0
  304. package/src/tree-grid/index.js +19 -5
  305. package/src/truncate/hook.js +1 -1
  306. package/src/unit-control/types.ts +2 -1
  307. package/src/utils/config-values.js +1 -1
  308. package/src/utils/hooks/stories/use-cx.js +121 -44
  309. package/tsconfig.json +3 -0
  310. package/tsconfig.tsbuildinfo +1 -1
  311. package/build/spinner/styles/spinner-styles.js +0 -40
  312. package/build/spinner/styles/spinner-styles.js.map +0 -1
  313. package/build-module/spinner/styles/spinner-styles.js +0 -28
  314. package/build-module/spinner/styles/spinner-styles.js.map +0 -1
  315. package/build-types/spinner/styles/spinner-styles.d.ts +0 -5
  316. package/build-types/spinner/styles/spinner-styles.d.ts.map +0 -1
  317. package/src/spinner/styles/spinner-styles.js +0 -47
  318. package/src/ui/visually-hidden/README.md +0 -21
@@ -1,10 +1,43 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { css } from '@emotion/react';
5
+
1
6
  /**
2
7
  * Internal dependencies
3
8
  */
9
+ import { useCx } from '../../utils';
10
+ import { space } from '../../ui/utils/space';
4
11
  import Spinner from '../';
5
12
 
6
- export default { title: 'Components/Spinner', component: Spinner };
13
+ const sizes = {
14
+ default: undefined,
15
+ medium: space( 20 ),
16
+ large: space( 40 ),
17
+ };
18
+
19
+ export default {
20
+ title: 'Components/Spinner',
21
+ component: Spinner,
22
+ argTypes: {
23
+ size: {
24
+ options: Object.keys( sizes ),
25
+ mapping: sizes,
26
+ control: { type: 'select' },
27
+ },
28
+ },
29
+ };
30
+
31
+ const Template = ( { size } ) => {
32
+ const cx = useCx();
33
+ const spinnerClassname = cx( css`
34
+ width: ${ size };
35
+ height: ${ size };
36
+ ` );
37
+ return <Spinner className={ spinnerClassname } />;
38
+ };
7
39
 
8
- export const _default = () => {
9
- return <Spinner />;
40
+ export const Default = Template.bind( {} );
41
+ Default.args = {
42
+ size: 'default',
10
43
  };
@@ -0,0 +1,47 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import styled from '@emotion/styled';
5
+ import { css, keyframes } from '@emotion/react';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { COLORS, CONFIG } from '../utils';
11
+
12
+ const spinAnimation = keyframes`
13
+ from {
14
+ transform: rotate(0deg);
15
+ }
16
+ to {
17
+ transform: rotate(360deg);
18
+ }
19
+ `;
20
+
21
+ export const StyledSpinner = styled.svg`
22
+ width: ${ CONFIG.spinnerSize }px;
23
+ height: ${ CONFIG.spinnerSize }px;
24
+ display: inline-block;
25
+ margin: 5px 11px 0;
26
+ position: relative;
27
+ color: var( --wp-admin-theme-color );
28
+ overflow: visible;
29
+ `;
30
+
31
+ const commonPathProps = css`
32
+ fill: transparent;
33
+ stroke-width: 1.5px;
34
+ `;
35
+
36
+ export const SpinnerTrack = styled.circle`
37
+ ${ commonPathProps };
38
+ stroke: ${ COLORS.gray[ 300 ] };
39
+ `;
40
+
41
+ export const SpinnerIndicator = styled.path`
42
+ ${ commonPathProps };
43
+ stroke: currentColor;
44
+ stroke-linecap: round;
45
+ transform-origin: 50% 50%;
46
+ animation: 1.4s linear infinite both ${ spinAnimation };
47
+ `;
@@ -54,6 +54,7 @@ export function useSurface( props ) {
54
54
  borderRight,
55
55
  borderTop,
56
56
  className,
57
+ cx,
57
58
  variant,
58
59
  ] );
59
60
 
package/src/text/hook.js CHANGED
@@ -126,6 +126,7 @@ export default function useText( props ) {
126
126
  align,
127
127
  className,
128
128
  color,
129
+ cx,
129
130
  display,
130
131
  isBlock,
131
132
  isCaption,
package/src/tip/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { SVG, Path } from '@wordpress/primitives';
4
+ import { Icon, tip } from '@wordpress/icons';
5
5
 
6
6
  /**
7
7
  * @typedef Props
@@ -15,9 +15,7 @@ import { SVG, Path } from '@wordpress/primitives';
15
15
  function Tip( props ) {
16
16
  return (
17
17
  <div className="components-tip">
18
- <SVG width="24" height="24" viewBox="0 0 24 24">
19
- <Path d="M12 15.8c-3.7 0-6.8-3-6.8-6.8s3-6.8 6.8-6.8c3.7 0 6.8 3 6.8 6.8s-3.1 6.8-6.8 6.8zm0-12C9.1 3.8 6.8 6.1 6.8 9s2.4 5.2 5.2 5.2c2.9 0 5.2-2.4 5.2-5.2S14.9 3.8 12 3.8zM8 17.5h8V19H8zM10 20.5h4V22h-4z" />
20
- </SVG>
18
+ <Icon icon={ tip } />
21
19
  <p>{ props.children }</p>
22
20
  </div>
23
21
  );
@@ -81,7 +81,7 @@ function ToggleGroupControl(
81
81
  'medium',
82
82
  className
83
83
  ),
84
- [ className, isBlock ]
84
+ [ className, cx, isBlock ]
85
85
  );
86
86
  return (
87
87
  <BaseControl help={ help }>
@@ -135,13 +135,15 @@ export const WithNonToolsPanelItems = () => {
135
135
  );
136
136
  };
137
137
 
138
- export const WithOptionalItemsPlusIcon = () => {
138
+ export const WithOptionalItemsPlusIcon = ( { isShownByDefault } ) => {
139
139
  const [ height, setHeight ] = useState();
140
140
  const [ width, setWidth ] = useState();
141
+ const [ minWidth, setMinWidth ] = useState();
141
142
 
142
143
  const resetAll = () => {
143
144
  setHeight( undefined );
144
145
  setWidth( undefined );
146
+ setMinWidth( undefined );
145
147
  };
146
148
 
147
149
  return (
@@ -150,7 +152,20 @@ export const WithOptionalItemsPlusIcon = () => {
150
152
  <ToolsPanel
151
153
  label="Tools Panel (optional items only)"
152
154
  resetAll={ resetAll }
155
+ key={ isShownByDefault }
153
156
  >
157
+ <SingleColumnItem
158
+ hasValue={ () => !! minWidth }
159
+ label="Minimum width"
160
+ onDeselect={ () => setMinWidth( undefined ) }
161
+ isShownByDefault={ isShownByDefault }
162
+ >
163
+ <UnitControl
164
+ label="Minimum width"
165
+ value={ minWidth }
166
+ onChange={ ( next ) => setMinWidth( next ) }
167
+ />
168
+ </SingleColumnItem>
154
169
  <SingleColumnItem
155
170
  hasValue={ () => !! width }
156
171
  label="Width"
@@ -181,6 +196,10 @@ export const WithOptionalItemsPlusIcon = () => {
181
196
  );
182
197
  };
183
198
 
199
+ WithOptionalItemsPlusIcon.args = {
200
+ isShownByDefault: false,
201
+ };
202
+
184
203
  const { Fill: ToolsPanelItems, Slot } = createSlotFill( 'ToolsPanelSlot' );
185
204
  const panelId = 'unique-tools-panel-id';
186
205
 
@@ -175,7 +175,6 @@ exports[`ToolsPanel first and last panel items should apply first/last classes t
175
175
  aria-hidden="true"
176
176
  focusable="false"
177
177
  height="24"
178
- role="img"
179
178
  viewBox="0 0 24 24"
180
179
  width="24"
181
180
  xmlns="http://www.w3.org/2000/svg"
@@ -942,6 +942,17 @@ describe( 'ToolsPanel', () => {
942
942
  } );
943
943
 
944
944
  describe( 'panel header icon toggle', () => {
945
+ const defaultControls = {
946
+ attributes: { value: false },
947
+ hasValue: jest.fn().mockImplementation( () => {
948
+ return !! defaultControls.attributes.value;
949
+ } ),
950
+ label: 'Default',
951
+ onDeselect: jest.fn(),
952
+ onSelect: jest.fn(),
953
+ isShownByDefault: true,
954
+ };
955
+
945
956
  const optionalControls = {
946
957
  attributes: { value: false },
947
958
  hasValue: jest.fn().mockImplementation( () => {
@@ -953,7 +964,26 @@ describe( 'ToolsPanel', () => {
953
964
  isShownByDefault: false,
954
965
  };
955
966
 
956
- it( 'should render appropriate icons for the dropdown menu', async () => {
967
+ it( 'should render appropriate icon for the dropdown menu where there are default controls', async () => {
968
+ render(
969
+ <ToolsPanel { ...defaultProps }>
970
+ <ToolsPanelItem { ...defaultControls }>
971
+ <div>Default control</div>
972
+ </ToolsPanelItem>
973
+ <ToolsPanelItem { ...optionalControls }>
974
+ <div>Optional control</div>
975
+ </ToolsPanelItem>
976
+ </ToolsPanel>
977
+ );
978
+
979
+ const optionsDisplayedIcon = screen.getByRole( 'button', {
980
+ name: 'View options',
981
+ } );
982
+
983
+ expect( optionsDisplayedIcon ).toBeInTheDocument();
984
+ } );
985
+
986
+ it( 'should render appropriate icons for the dropdown menu where there are no default controls', async () => {
957
987
  render(
958
988
  <ToolsPanel { ...defaultProps }>
959
989
  <ToolsPanelItem { ...optionalControls }>
@@ -48,6 +48,10 @@ const generateMenuItems = ( {
48
48
  return menuItems;
49
49
  };
50
50
 
51
+ const isMenuItemTypeEmpty = (
52
+ obj?: ToolsPanelMenuItems[ ToolsPanelMenuItemKey ]
53
+ ) => obj && Object.keys( obj ).length === 0;
54
+
51
55
  export function useToolsPanel(
52
56
  props: WordPressComponentProps< ToolsPanelProps, 'div' >
53
57
  ) {
@@ -167,24 +171,24 @@ export function useToolsPanel(
167
171
  ] = useState( false );
168
172
 
169
173
  useEffect( () => {
170
- if ( menuItems.optional ) {
171
- const optionalItems = Object.entries( menuItems.optional );
172
- const allControlsHidden =
173
- optionalItems.length > 0 &&
174
- ! optionalItems.some( ( [ , isSelected ] ) => isSelected );
174
+ if (
175
+ isMenuItemTypeEmpty( menuItems?.default ) &&
176
+ ! isMenuItemTypeEmpty( menuItems?.optional )
177
+ ) {
178
+ const allControlsHidden = ! Object.entries(
179
+ menuItems.optional
180
+ ).some( ( [ , isSelected ] ) => isSelected );
175
181
  setAreAllOptionalControlsHidden( allControlsHidden );
176
182
  }
177
- }, [ menuItems.optional, setAreAllOptionalControlsHidden ] );
183
+ }, [ menuItems, setAreAllOptionalControlsHidden ] );
178
184
 
179
185
  const cx = useCx();
180
186
  const classes = useMemo( () => {
181
- const hasDefaultMenuItems =
182
- menuItems?.default && !! Object.keys( menuItems?.default ).length;
183
187
  const wrapperStyle =
184
188
  hasInnerWrapper &&
185
189
  styles.ToolsPanelWithInnerWrapper( DEFAULT_COLUMNS );
186
190
  const emptyStyle =
187
- ! hasDefaultMenuItems &&
191
+ isMenuItemTypeEmpty( menuItems?.default ) &&
188
192
  areAllOptionalControlsHidden &&
189
193
  styles.ToolsPanelHiddenInnerWrapper;
190
194
 
@@ -192,6 +196,7 @@ export function useToolsPanel(
192
196
  }, [
193
197
  areAllOptionalControlsHidden,
194
198
  className,
199
+ cx,
195
200
  hasInnerWrapper,
196
201
  menuItems,
197
202
  ] );
@@ -23,15 +23,15 @@ export function useToolsPanelHeader(
23
23
  const cx = useCx();
24
24
  const classes = useMemo( () => {
25
25
  return cx( styles.ToolsPanelHeader, className );
26
- }, [ className ] );
26
+ }, [ className, cx ] );
27
27
 
28
28
  const dropdownMenuClassName = useMemo( () => {
29
29
  return cx( styles.DropdownMenu );
30
- }, [] );
30
+ }, [ cx ] );
31
31
 
32
32
  const headingClassName = useMemo( () => {
33
33
  return cx( styles.ToolsPanelHeading );
34
- }, [] );
34
+ }, [ cx ] );
35
35
 
36
36
  const {
37
37
  menuItems,
@@ -148,6 +148,7 @@ export function useToolsPanelItem(
148
148
  isShown,
149
149
  shouldRenderPlaceholder,
150
150
  className,
151
+ cx,
151
152
  firstDisplayedItem,
152
153
  lastDisplayedItem,
153
154
  __experimentalFirstVisibleItemClass,
@@ -78,6 +78,11 @@ function TreeGrid(
78
78
  const activeRow = activeElement.closest( '[role="row"]' );
79
79
  const focusablesInRow = getRowFocusables( activeRow );
80
80
  const currentColumnIndex = focusablesInRow.indexOf( activeElement );
81
+ const canExpandCollapse = 0 === currentColumnIndex;
82
+ const cannotFocusNextColumn =
83
+ canExpandCollapse &&
84
+ activeRow.getAttribute( 'aria-expanded' ) === 'false' &&
85
+ keyCode === RIGHT;
81
86
 
82
87
  if ( includes( [ LEFT, RIGHT ], keyCode ) ) {
83
88
  // Calculate to the next element.
@@ -91,8 +96,8 @@ function TreeGrid(
91
96
  );
92
97
  }
93
98
 
94
- // Focus is either at the left or right edge of the grid.
95
- if ( nextIndex === currentColumnIndex ) {
99
+ // Focus is at the left most column.
100
+ if ( canExpandCollapse ) {
96
101
  if ( keyCode === LEFT ) {
97
102
  // Left:
98
103
  // If a row is focused, and it is expanded, collapses the current row.
@@ -105,7 +110,10 @@ function TreeGrid(
105
110
  }
106
111
  // If a row is focused, and it is collapsed, moves to the parent row (if there is one).
107
112
  const level = Math.max(
108
- parseInt( activeRow?.ariaLevel ?? 1, 10 ) - 1,
113
+ parseInt(
114
+ activeRow?.getAttribute( 'aria-level' ) ?? 1,
115
+ 10
116
+ ) - 1,
109
117
  1
110
118
  );
111
119
  const rows = Array.from(
@@ -115,7 +123,10 @@ function TreeGrid(
115
123
  const currentRowIndex = rows.indexOf( activeRow );
116
124
  for ( let i = currentRowIndex; i >= 0; i-- ) {
117
125
  if (
118
- parseInt( rows[ i ].ariaLevel, 10 ) === level
126
+ parseInt(
127
+ rows[ i ].getAttribute( 'aria-level' ),
128
+ 10
129
+ ) === level
119
130
  ) {
120
131
  parentRow = rows[ i ];
121
132
  break;
@@ -149,7 +160,10 @@ function TreeGrid(
149
160
  return;
150
161
  }
151
162
 
152
- // Focus the next element.
163
+ // Focus the next element. If at most left column and row is collapsed, moving right is not allowed as this will expand. However, if row is collapsed, moving left is allowed.
164
+ if ( cannotFocusNextColumn ) {
165
+ return;
166
+ }
153
167
  focusablesInRow[ nextIndex ].focus();
154
168
 
155
169
  // Prevent key use for anything else. This ensures Voiceover
@@ -59,7 +59,7 @@ export default function useTruncate( props ) {
59
59
  shouldTruncate && !! numberOfLines && sx.numberOfLines,
60
60
  className
61
61
  );
62
- }, [ className, numberOfLines, shouldTruncate ] );
62
+ }, [ className, cx, numberOfLines, shouldTruncate ] );
63
63
 
64
64
  return { ...otherProps, className: classes, children: truncatedContent };
65
65
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import type { SyntheticEvent } from 'react';
4
+ import type { CSSProperties, SyntheticEvent } from 'react';
5
5
 
6
6
  /**
7
7
  * Internal dependencies
@@ -79,6 +79,7 @@ export type UnitSelectControlProps = {
79
79
 
80
80
  export type UnitControlProps = UnitSelectControlProps & {
81
81
  __unstableStateReducer?: StateReducer;
82
+ __unstableInputWidth?: CSSProperties[ 'width' ];
82
83
  /**
83
84
  * If `true`, the unit `<select>` is hidden.
84
85
  *
@@ -44,7 +44,7 @@ export default {
44
44
  borderWidth: '1px',
45
45
  borderWidthFocus: '1.5px',
46
46
  borderWidthTab: '4px',
47
- spinnerSize: '18px',
47
+ spinnerSize: 16,
48
48
  fontSize: '13px',
49
49
  fontSizeH1: 'calc(2.44 * 13px)',
50
50
  fontSizeH2: 'calc(1.95 * 13px)',
@@ -1,68 +1,145 @@
1
1
  /**
2
- * Internal dependencies
2
+ * External dependencies
3
3
  */
4
- import { useCx } from '..';
5
- import StyleProvider from '../../../style-provider';
4
+ import { css } from '@emotion/react';
6
5
 
7
6
  /**
8
7
  * WordPress dependencies
9
8
  */
10
- import { useState, createPortal } from '@wordpress/element';
9
+ import { __unstableIframe as Iframe } from '@wordpress/block-editor';
10
+ import { useMemo } from '@wordpress/element';
11
+
11
12
  /**
12
- * External dependencies
13
+ * Internal dependencies
13
14
  */
14
- import { css } from '@emotion/react';
15
+ import { useCx } from '..';
16
+ import StyleProvider from '../../../style-provider';
17
+ import {
18
+ createSlotFill,
19
+ Provider as SlotFillProvider,
20
+ } from '../../../slot-fill';
15
21
 
16
22
  export default {
17
23
  title: 'Components (Experimental)/useCx',
18
24
  };
19
25
 
20
- const IFrame = ( { children } ) => {
21
- const [ iframeDocument, setIframeDocument ] = useState();
26
+ const Example = ( { serializedStyles, children } ) => {
27
+ const cx = useCx();
28
+ const classes = cx( serializedStyles );
29
+ return <span className={ classes }>{ children }</span>;
30
+ };
31
+
32
+ const ExampleWithUseMemoWrong = ( { serializedStyles, children } ) => {
33
+ const cx = useCx();
34
+ // Wrong: using 'useMemo' without adding 'cx' to the dependency list.
35
+ // eslint-disable-next-line react-hooks/exhaustive-deps
36
+ const classes = useMemo( () => cx( serializedStyles ), [
37
+ serializedStyles,
38
+ ] );
39
+ return <span className={ classes }>{ children }</span>;
40
+ };
22
41
 
23
- const handleRef = ( node ) => {
24
- if ( ! node ) {
25
- return null;
26
- }
42
+ const ExampleWithUseMemoRight = ( { serializedStyles, children } ) => {
43
+ const cx = useCx();
44
+ // Right: using 'useMemo' with 'cx' listed as a dependency.
45
+ const classes = useMemo( () => cx( serializedStyles ), [
46
+ cx,
47
+ serializedStyles,
48
+ ] );
49
+ return <span className={ classes }>{ children }</span>;
50
+ };
27
51
 
28
- function setIfReady() {
29
- const { contentDocument } = node;
30
- const { readyState } = contentDocument;
52
+ export const _slotFill = () => {
53
+ const { Fill, Slot } = createSlotFill( 'UseCxExampleSlot' );
31
54
 
32
- if ( readyState !== 'interactive' && readyState !== 'complete' ) {
33
- return false;
34
- }
55
+ const redText = css`
56
+ color: red;
57
+ `;
58
+ const blueText = css`
59
+ color: blue;
60
+ `;
61
+ const greenText = css`
62
+ color: green;
63
+ `;
35
64
 
36
- setIframeDocument( contentDocument );
37
- }
65
+ return (
66
+ <SlotFillProvider>
67
+ <StyleProvider document={ document }>
68
+ <Iframe>
69
+ <Iframe>
70
+ <Example serializedStyles={ redText }>
71
+ This text is inside an iframe and should be red
72
+ </Example>
73
+ <Fill name="test-slot">
74
+ <Example serializedStyles={ blueText }>
75
+ This text is also inside the iframe, but is
76
+ relocated by a slot/fill and should be blue
77
+ </Example>
78
+ </Fill>
79
+ <Fill name="outside-frame">
80
+ <Example serializedStyles={ greenText }>
81
+ This text is also inside the iframe, but is
82
+ relocated by a slot/fill and should be green
83
+ </Example>
84
+ </Fill>
85
+ </Iframe>
86
+ <StyleProvider document={ document }>
87
+ <Slot bubblesVirtually name="test-slot" />
88
+ </StyleProvider>
89
+ </Iframe>
90
+ <Slot bubblesVirtually name="outside-frame" />
91
+ </StyleProvider>
92
+ </SlotFillProvider>
93
+ );
94
+ };
38
95
 
39
- if ( setIfReady() ) {
40
- return;
41
- }
96
+ export const _slotFillSimple = () => {
97
+ const { Fill, Slot } = createSlotFill( 'UseCxExampleSlotTwo' );
42
98
 
43
- node.addEventListener( 'load', () => {
44
- // iframe isn't immediately ready in Firefox
45
- setIfReady();
46
- } );
47
- };
99
+ const redText = css`
100
+ color: red;
101
+ `;
48
102
 
49
103
  return (
50
- <iframe ref={ handleRef } title="use-cx-test-frame">
51
- { iframeDocument &&
52
- createPortal(
53
- <StyleProvider document={ iframeDocument }>
54
- { children }
55
- </StyleProvider>,
56
- iframeDocument.body
57
- ) }
58
- </iframe>
104
+ <SlotFillProvider>
105
+ <Iframe>
106
+ <Fill name="test-slot">
107
+ <Example serializedStyles={ redText }>
108
+ This text should be red
109
+ </Example>
110
+ </Fill>
111
+ </Iframe>
112
+ <Slot bubblesVirtually name="test-slot" />
113
+ </SlotFillProvider>
59
114
  );
60
115
  };
61
116
 
62
- const Example = ( { args, children } ) => {
63
- const cx = useCx();
64
- const classes = cx( ...args );
65
- return <span className={ classes }>{ children }</span>;
117
+ export const _useMemoBadPractices = () => {
118
+ const redText = css`
119
+ color: red;
120
+ `;
121
+ const blueText = css`
122
+ color: blue;
123
+ `;
124
+
125
+ return (
126
+ <>
127
+ <Example serializedStyles={ redText }>
128
+ This text should be red
129
+ </Example>
130
+ <ExampleWithUseMemoRight serializedStyles={ blueText }>
131
+ This text should be blue
132
+ </ExampleWithUseMemoRight>
133
+ <Iframe>
134
+ <Example serializedStyles={ redText }>
135
+ This text should be red
136
+ </Example>
137
+ <ExampleWithUseMemoWrong serializedStyles={ blueText }>
138
+ This text should be blue but it&apos;s not!
139
+ </ExampleWithUseMemoWrong>
140
+ </Iframe>
141
+ </>
142
+ );
66
143
  };
67
144
 
68
145
  export const _default = () => {
@@ -70,10 +147,10 @@ export const _default = () => {
70
147
  color: red;
71
148
  `;
72
149
  return (
73
- <IFrame>
74
- <Example args={ [ redText ] }>
150
+ <Iframe>
151
+ <Example serializedStyles={ redText }>
75
152
  This text is inside an iframe and is red!
76
153
  </Example>
77
- </IFrame>
154
+ </Iframe>
78
155
  );
79
156
  };
package/tsconfig.json CHANGED
@@ -28,6 +28,9 @@
28
28
  "src/base-field/**/*",
29
29
  "src/button/**/*",
30
30
  "src/card/**/*",
31
+ "src/circular-option-picker/**/*",
32
+ "src/color-palette/**/*",
33
+ "src/color-picker/**/*",
31
34
  "src/confirm-dialog/**/*",
32
35
  "src/dashicon/**/*",
33
36
  "src/disabled/**/*",