@wordpress/components 19.3.0 → 19.4.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 (308) 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/modal/index.js +1 -12
  49. package/build/modal/index.js.map +1 -1
  50. package/build/navigator/context.js +2 -2
  51. package/build/navigator/context.js.map +1 -1
  52. package/build/navigator/navigator-provider/component.js +18 -25
  53. package/build/navigator/navigator-provider/component.js.map +1 -1
  54. package/build/navigator/navigator-screen/component.js +39 -13
  55. package/build/navigator/navigator-screen/component.js.map +1 -1
  56. package/build/navigator/use-navigator.js +4 -4
  57. package/build/navigator/use-navigator.js.map +1 -1
  58. package/build/placeholder/index.js +4 -4
  59. package/build/placeholder/index.js.map +1 -1
  60. package/build/scrollable/hook.js +1 -1
  61. package/build/scrollable/hook.js.map +1 -1
  62. package/build/slot-fill/bubbles-virtually/fill.js +11 -2
  63. package/build/slot-fill/bubbles-virtually/fill.js.map +1 -1
  64. package/build/spinner/index.js +44 -5
  65. package/build/spinner/index.js.map +1 -1
  66. package/build/spinner/styles.js +56 -0
  67. package/build/spinner/styles.js.map +1 -0
  68. package/build/surface/hook.js +1 -1
  69. package/build/surface/hook.js.map +1 -1
  70. package/build/text/hook.js +5 -5
  71. package/build/text/hook.js.map +1 -1
  72. package/build/tip/index.js +4 -8
  73. package/build/tip/index.js.map +1 -1
  74. package/build/toggle-group-control/toggle-group-control/component.js +1 -1
  75. package/build/toggle-group-control/toggle-group-control/component.js.map +1 -1
  76. package/build/tools-panel/tools-panel/hook.js +7 -7
  77. package/build/tools-panel/tools-panel/hook.js.map +1 -1
  78. package/build/tools-panel/tools-panel-header/hook.js +3 -3
  79. package/build/tools-panel/tools-panel-header/hook.js.map +1 -1
  80. package/build/tools-panel/tools-panel-item/hook.js +1 -1
  81. package/build/tools-panel/tools-panel-item/hook.js.map +1 -1
  82. package/build/tree-grid/index.js +13 -6
  83. package/build/tree-grid/index.js.map +1 -1
  84. package/build/truncate/hook.js +2 -2
  85. package/build/truncate/hook.js.map +1 -1
  86. package/build/utils/config-values.js +1 -1
  87. package/build/utils/config-values.js.map +1 -1
  88. package/build-module/base-field/hook.js +1 -1
  89. package/build-module/base-field/hook.js.map +1 -1
  90. package/build-module/button/deprecated.js +2 -1
  91. package/build-module/button/deprecated.js.map +1 -1
  92. package/build-module/button/index.js +2 -1
  93. package/build-module/button/index.js.map +1 -1
  94. package/build-module/card/card/component.js +1 -1
  95. package/build-module/card/card/component.js.map +1 -1
  96. package/build-module/card/card/hook.js +1 -1
  97. package/build-module/card/card/hook.js.map +1 -1
  98. package/build-module/card/card-body/hook.js +1 -1
  99. package/build-module/card/card-body/hook.js.map +1 -1
  100. package/build-module/card/card-divider/hook.js +1 -1
  101. package/build-module/card/card-divider/hook.js.map +1 -1
  102. package/build-module/card/card-footer/hook.js +1 -1
  103. package/build-module/card/card-footer/hook.js.map +1 -1
  104. package/build-module/card/card-header/hook.js +1 -1
  105. package/build-module/card/card-header/hook.js.map +1 -1
  106. package/build-module/card/card-media/hook.js +1 -1
  107. package/build-module/card/card-media/hook.js.map +1 -1
  108. package/build-module/circular-option-picker/index.js +1 -0
  109. package/build-module/circular-option-picker/index.js.map +1 -1
  110. package/build-module/color-indicator/index.js +1 -0
  111. package/build-module/color-indicator/index.js.map +1 -1
  112. package/build-module/color-palette/index.js +1 -0
  113. package/build-module/color-palette/index.js.map +1 -1
  114. package/build-module/color-picker/color-display.js.map +1 -1
  115. package/build-module/color-picker/color-input.js.map +1 -1
  116. package/build-module/color-picker/component.js +1 -1
  117. package/build-module/color-picker/component.js.map +1 -1
  118. package/build-module/color-picker/use-deprecated-props.js +2 -0
  119. package/build-module/color-picker/use-deprecated-props.js.map +1 -1
  120. package/build-module/date-time/time.js +1 -1
  121. package/build-module/date-time/time.js.map +1 -1
  122. package/build-module/dropdown/index.js +3 -3
  123. package/build-module/dropdown/index.js.map +1 -1
  124. package/build-module/elevation/hook.js +5 -5
  125. package/build-module/elevation/hook.js.map +1 -1
  126. package/build-module/flex/flex/hook.js +4 -4
  127. package/build-module/flex/flex/hook.js.map +1 -1
  128. package/build-module/grid/hook.js +2 -2
  129. package/build-module/grid/hook.js.map +1 -1
  130. package/build-module/item-group/item/hook.js +1 -1
  131. package/build-module/item-group/item/hook.js.map +1 -1
  132. package/build-module/modal/index.js +1 -11
  133. package/build-module/modal/index.js.map +1 -1
  134. package/build-module/navigator/context.js +2 -2
  135. package/build-module/navigator/context.js.map +1 -1
  136. package/build-module/navigator/navigator-provider/component.js +18 -25
  137. package/build-module/navigator/navigator-provider/component.js.map +1 -1
  138. package/build-module/navigator/navigator-screen/component.js +39 -15
  139. package/build-module/navigator/navigator-screen/component.js.map +1 -1
  140. package/build-module/navigator/use-navigator.js +4 -4
  141. package/build-module/navigator/use-navigator.js.map +1 -1
  142. package/build-module/placeholder/index.js +4 -4
  143. package/build-module/placeholder/index.js.map +1 -1
  144. package/build-module/scrollable/hook.js +1 -1
  145. package/build-module/scrollable/hook.js.map +1 -1
  146. package/build-module/slot-fill/bubbles-virtually/fill.js +11 -2
  147. package/build-module/slot-fill/bubbles-virtually/fill.js.map +1 -1
  148. package/build-module/spinner/index.js +40 -5
  149. package/build-module/spinner/index.js.map +1 -1
  150. package/build-module/spinner/styles.js +49 -0
  151. package/build-module/spinner/styles.js.map +1 -0
  152. package/build-module/surface/hook.js +1 -1
  153. package/build-module/surface/hook.js.map +1 -1
  154. package/build-module/text/hook.js +5 -5
  155. package/build-module/text/hook.js.map +1 -1
  156. package/build-module/tip/index.js +4 -8
  157. package/build-module/tip/index.js.map +1 -1
  158. package/build-module/toggle-group-control/toggle-group-control/component.js +1 -1
  159. package/build-module/toggle-group-control/toggle-group-control/component.js.map +1 -1
  160. package/build-module/tools-panel/tools-panel/hook.js +7 -7
  161. package/build-module/tools-panel/tools-panel/hook.js.map +1 -1
  162. package/build-module/tools-panel/tools-panel-header/hook.js +3 -3
  163. package/build-module/tools-panel/tools-panel-header/hook.js.map +1 -1
  164. package/build-module/tools-panel/tools-panel-item/hook.js +1 -1
  165. package/build-module/tools-panel/tools-panel-item/hook.js.map +1 -1
  166. package/build-module/tree-grid/index.js +12 -6
  167. package/build-module/tree-grid/index.js.map +1 -1
  168. package/build-module/truncate/hook.js +2 -2
  169. package/build-module/truncate/hook.js.map +1 -1
  170. package/build-module/utils/config-values.js +1 -1
  171. package/build-module/utils/config-values.js.map +1 -1
  172. package/build-style/style-rtl.css +12 -2
  173. package/build-style/style.css +12 -2
  174. package/build-types/button/index.d.ts.map +1 -1
  175. package/build-types/circular-option-picker/index.d.ts +31 -0
  176. package/build-types/circular-option-picker/index.d.ts.map +1 -0
  177. package/build-types/color-palette/index.d.ts +16 -0
  178. package/build-types/color-palette/index.d.ts.map +1 -0
  179. package/build-types/color-palette/styles.d.ts +8 -0
  180. package/build-types/color-palette/styles.d.ts.map +1 -0
  181. package/build-types/color-picker/color-display.d.ts +14 -0
  182. package/build-types/color-picker/color-display.d.ts.map +1 -0
  183. package/build-types/color-picker/color-input.d.ts +14 -0
  184. package/build-types/color-picker/color-input.d.ts.map +1 -0
  185. package/build-types/color-picker/component.d.ts +11 -0
  186. package/build-types/color-picker/component.d.ts.map +1 -0
  187. package/build-types/color-picker/hex-input.d.ts +13 -0
  188. package/build-types/color-picker/hex-input.d.ts.map +1 -0
  189. package/build-types/color-picker/hsl-input.d.ts +13 -0
  190. package/build-types/color-picker/hsl-input.d.ts.map +1 -0
  191. package/build-types/color-picker/index.d.ts +5 -0
  192. package/build-types/color-picker/index.d.ts.map +1 -0
  193. package/build-types/color-picker/input-with-slider.d.ts +12 -0
  194. package/build-types/color-picker/input-with-slider.d.ts.map +1 -0
  195. package/build-types/color-picker/legacy-adapter.d.ts +6 -0
  196. package/build-types/color-picker/legacy-adapter.d.ts.map +1 -0
  197. package/build-types/color-picker/picker.d.ts +10 -0
  198. package/build-types/color-picker/picker.d.ts.map +1 -0
  199. package/build-types/color-picker/rgb-input.d.ts +13 -0
  200. package/build-types/color-picker/rgb-input.d.ts.map +1 -0
  201. package/build-types/color-picker/styles.d.ts +76 -0
  202. package/build-types/color-picker/styles.d.ts.map +1 -0
  203. package/build-types/color-picker/types.d.ts +2 -0
  204. package/build-types/color-picker/types.d.ts.map +1 -0
  205. package/build-types/color-picker/use-deprecated-props.d.ts +49 -0
  206. package/build-types/color-picker/use-deprecated-props.d.ts.map +1 -0
  207. package/build-types/dropdown/index.d.ts +1 -13
  208. package/build-types/dropdown/index.d.ts.map +1 -1
  209. package/build-types/elevation/hook.d.ts.map +1 -1
  210. package/build-types/flex/flex/hook.d.ts.map +1 -1
  211. package/build-types/grid/hook.d.ts.map +1 -1
  212. package/build-types/navigator/navigator-provider/component.d.ts +4 -4
  213. package/build-types/navigator/navigator-provider/component.d.ts.map +1 -1
  214. package/build-types/navigator/navigator-screen/component.d.ts +4 -4
  215. package/build-types/navigator/navigator-screen/component.d.ts.map +1 -1
  216. package/build-types/navigator/types.d.ts +5 -3
  217. package/build-types/navigator/types.d.ts.map +1 -1
  218. package/build-types/resizable-box/index.d.ts +1 -1
  219. package/build-types/resizable-box/resize-tooltip/index.d.ts +1 -1
  220. package/build-types/slot-fill/bubbles-virtually/fill.d.ts.map +1 -1
  221. package/build-types/spinner/index.d.ts +18 -1
  222. package/build-types/spinner/index.d.ts.map +1 -1
  223. package/build-types/spinner/styles.d.ts +13 -0
  224. package/build-types/spinner/styles.d.ts.map +1 -0
  225. package/build-types/surface/hook.d.ts.map +1 -1
  226. package/build-types/text/hook.d.ts.map +1 -1
  227. package/build-types/tip/index.d.ts.map +1 -1
  228. package/build-types/tools-panel/tools-panel/hook.d.ts.map +1 -1
  229. package/build-types/tools-panel/tools-panel-item/hook.d.ts.map +1 -1
  230. package/build-types/unit-control/index.d.ts +3 -2
  231. package/build-types/unit-control/index.d.ts.map +1 -1
  232. package/build-types/unit-control/types.d.ts +2 -1
  233. package/build-types/unit-control/types.d.ts.map +1 -1
  234. package/build-types/utils/config-values.d.ts +1 -1
  235. package/package.json +16 -17
  236. package/src/base-field/hook.js +1 -1
  237. package/src/button/deprecated.js +1 -0
  238. package/src/button/index.js +1 -0
  239. package/src/card/card/component.js +1 -1
  240. package/src/card/card/hook.js +1 -1
  241. package/src/card/card-body/hook.js +1 -1
  242. package/src/card/card-divider/hook.js +1 -1
  243. package/src/card/card-footer/hook.js +1 -1
  244. package/src/card/card-header/hook.js +1 -1
  245. package/src/card/card-media/hook.js +1 -1
  246. package/src/circular-option-picker/index.js +1 -0
  247. package/src/color-indicator/index.js +2 -0
  248. package/src/color-palette/index.js +1 -0
  249. package/src/color-palette/test/__snapshots__/index.js.snap +0 -1
  250. package/src/color-picker/color-display.tsx +1 -1
  251. package/src/color-picker/color-input.tsx +1 -1
  252. package/src/color-picker/component.tsx +1 -1
  253. package/src/color-picker/use-deprecated-props.ts +2 -0
  254. package/src/combobox-control/stories/index.js +6 -2
  255. package/src/combobox-control/style.scss +2 -2
  256. package/src/date-time/README.md +4 -4
  257. package/src/date-time/test/time.js +2 -2
  258. package/src/date-time/time.js +2 -2
  259. package/src/dropdown/index.js +14 -13
  260. package/src/elevation/hook.js +1 -0
  261. package/src/flex/flex/hook.js +1 -0
  262. package/src/grid/hook.js +1 -0
  263. package/src/item-group/item/hook.ts +1 -1
  264. package/src/item-group/stories/index.js +2 -2
  265. package/src/mobile/link-settings/test/edit.native.js +5 -5
  266. package/src/modal/index.js +1 -10
  267. package/src/navigator/context.ts +2 -2
  268. package/src/navigator/navigator-provider/README.md +11 -9
  269. package/src/navigator/navigator-provider/component.tsx +16 -25
  270. package/src/navigator/navigator-screen/component.tsx +55 -15
  271. package/src/navigator/stories/index.js +19 -5
  272. package/src/navigator/test/index.js +77 -25
  273. package/src/navigator/types.ts +5 -3
  274. package/src/navigator/use-navigator.ts +3 -3
  275. package/src/placeholder/index.js +8 -6
  276. package/src/placeholder/style.scss +12 -0
  277. package/src/placeholder/test/index.js +18 -1
  278. package/src/scrollable/hook.js +1 -1
  279. package/src/slot-fill/bubbles-virtually/fill.js +12 -1
  280. package/src/spinner/README.md +10 -10
  281. package/src/spinner/index.js +42 -3
  282. package/src/spinner/stories/index.js +36 -3
  283. package/src/spinner/styles.js +47 -0
  284. package/src/surface/hook.js +1 -0
  285. package/src/text/hook.js +1 -0
  286. package/src/tip/index.js +2 -4
  287. package/src/toggle-group-control/toggle-group-control/component.tsx +1 -1
  288. package/src/tools-panel/stories/index.js +20 -1
  289. package/src/tools-panel/test/__snapshots__/index.js.snap +0 -1
  290. package/src/tools-panel/test/index.js +31 -1
  291. package/src/tools-panel/tools-panel/hook.ts +14 -9
  292. package/src/tools-panel/tools-panel-header/hook.ts +3 -3
  293. package/src/tools-panel/tools-panel-item/hook.ts +1 -0
  294. package/src/tree-grid/index.js +19 -5
  295. package/src/truncate/hook.js +1 -1
  296. package/src/unit-control/types.ts +2 -1
  297. package/src/utils/config-values.js +1 -1
  298. package/src/utils/hooks/stories/use-cx.js +121 -44
  299. package/tsconfig.json +3 -0
  300. package/tsconfig.tsbuildinfo +1 -1
  301. package/build/spinner/styles/spinner-styles.js +0 -40
  302. package/build/spinner/styles/spinner-styles.js.map +0 -1
  303. package/build-module/spinner/styles/spinner-styles.js +0 -28
  304. package/build-module/spinner/styles/spinner-styles.js.map +0 -1
  305. package/build-types/spinner/styles/spinner-styles.d.ts +0 -5
  306. package/build-types/spinner/styles/spinner-styles.d.ts.map +0 -1
  307. package/src/spinner/styles/spinner-styles.js +0 -47
  308. package/src/ui/visually-hidden/README.md +0 -21
@@ -19,19 +19,33 @@ export default {
19
19
  };
20
20
 
21
21
  function NavigatorButton( { path, ...props } ) {
22
- const { push } = useNavigator();
22
+ const { goTo } = useNavigator();
23
+ const dataAttrName = 'data-navigator-focusable-id';
24
+ const dataAttrValue = path;
25
+
26
+ const dataAttrCssSelector = `[${ dataAttrName }="${ dataAttrValue }"]`;
27
+
28
+ const buttonProps = {
29
+ ...props,
30
+ [ dataAttrName ]: dataAttrValue,
31
+ };
32
+
23
33
  return (
24
34
  <Button
25
35
  variant="secondary"
26
- onClick={ () => push( path ) }
27
- { ...props }
36
+ onClick={ () =>
37
+ goTo( path, { focusTargetSelector: dataAttrCssSelector } )
38
+ }
39
+ { ...buttonProps }
28
40
  />
29
41
  );
30
42
  }
31
43
 
32
44
  function NavigatorBackButton( props ) {
33
- const { pop } = useNavigator();
34
- return <Button variant="secondary" onClick={ () => pop() } { ...props } />;
45
+ const { goBack } = useNavigator();
46
+ return (
47
+ <Button variant="secondary" onClick={ () => goBack() } { ...props } />
48
+ );
35
49
  }
36
50
 
37
51
  const MyNavigation = () => {
@@ -31,27 +31,51 @@ const PATHS = {
31
31
  };
32
32
 
33
33
  function NavigatorButton( { path, onClick, ...props } ) {
34
- const { push } = useNavigator();
34
+ const { goTo } = useNavigator();
35
35
  return (
36
36
  <button
37
37
  onClick={ () => {
38
- push( path );
39
- // Used to spy on the values passed to `navigator.push`
40
- onClick?.( { type: 'push', path } );
38
+ goTo( path );
39
+ // Used to spy on the values passed to `navigator.goTo`
40
+ onClick?.( { type: 'goTo', path } );
41
41
  } }
42
42
  { ...props }
43
43
  />
44
44
  );
45
45
  }
46
46
 
47
+ function NavigatorButtonWithFocusRestoration( { path, onClick, ...props } ) {
48
+ const { goTo } = useNavigator();
49
+ const dataAttrName = 'data-navigator-focusable-id';
50
+ const dataAttrValue = path;
51
+
52
+ const dataAttrCssSelector = `[${ dataAttrName }="${ dataAttrValue }"]`;
53
+
54
+ const buttonProps = {
55
+ ...props,
56
+ [ dataAttrName ]: dataAttrValue,
57
+ };
58
+
59
+ return (
60
+ <button
61
+ onClick={ () => {
62
+ goTo( path, { focusTargetSelector: dataAttrCssSelector } );
63
+ // Used to spy on the values passed to `navigator.goTo`
64
+ onClick?.( { type: 'goTo', path } );
65
+ } }
66
+ { ...buttonProps }
67
+ />
68
+ );
69
+ }
70
+
47
71
  function NavigatorBackButton( { onClick, ...props } ) {
48
- const { pop } = useNavigator();
72
+ const { goBack } = useNavigator();
49
73
  return (
50
74
  <button
51
75
  onClick={ () => {
52
- pop();
53
- // Used to spy on the values passed to `navigator.push`
54
- onClick?.( { type: 'pop' } );
76
+ goBack();
77
+ // Used to spy on the values passed to `navigator.goBack`
78
+ onClick?.( { type: 'goBack' } );
55
79
  } }
56
80
  { ...props }
57
81
  />
@@ -65,28 +89,28 @@ const MyNavigation = ( {
65
89
  <NavigatorProvider initialPath={ initialPath }>
66
90
  <NavigatorScreen path={ PATHS.HOME }>
67
91
  <p>This is the home screen.</p>
68
- <NavigatorButton
69
- path={ PATHS.CHILD }
70
- onClick={ onNavigatorButtonClick }
71
- >
72
- Navigate to child screen.
73
- </NavigatorButton>
74
92
  <NavigatorButton
75
93
  path={ PATHS.NOT_FOUND }
76
94
  onClick={ onNavigatorButtonClick }
77
95
  >
78
96
  Navigate to non-existing screen.
79
97
  </NavigatorButton>
98
+ <NavigatorButtonWithFocusRestoration
99
+ path={ PATHS.CHILD }
100
+ onClick={ onNavigatorButtonClick }
101
+ >
102
+ Navigate to child screen.
103
+ </NavigatorButtonWithFocusRestoration>
80
104
  </NavigatorScreen>
81
105
 
82
106
  <NavigatorScreen path={ PATHS.CHILD }>
83
107
  <p>This is the child screen.</p>
84
- <NavigatorButton
108
+ <NavigatorButtonWithFocusRestoration
85
109
  path={ PATHS.NESTED }
86
110
  onClick={ onNavigatorButtonClick }
87
111
  >
88
112
  Navigate to nested screen.
89
- </NavigatorButton>
113
+ </NavigatorButtonWithFocusRestoration>
90
114
  <NavigatorBackButton onClick={ onNavigatorButtonClick }>
91
115
  Go back
92
116
  </NavigatorBackButton>
@@ -246,28 +270,28 @@ describe( 'Navigator', () => {
246
270
  expect( getHomeScreen() ).toBeInTheDocument();
247
271
  expect( getToChildScreenButton() ).toBeInTheDocument();
248
272
 
249
- // Check the values passed to `navigator.push()`
273
+ // Check the values passed to `navigator.goTo()`
250
274
  expect( spy ).toHaveBeenCalledTimes( 6 );
251
275
  expect( spy ).toHaveBeenNthCalledWith( 1, {
252
276
  path: PATHS.CHILD,
253
- type: 'push',
277
+ type: 'goTo',
254
278
  } );
255
279
  expect( spy ).toHaveBeenNthCalledWith( 2, {
256
- type: 'pop',
280
+ type: 'goBack',
257
281
  } );
258
282
  expect( spy ).toHaveBeenNthCalledWith( 3, {
259
283
  path: PATHS.CHILD,
260
- type: 'push',
284
+ type: 'goTo',
261
285
  } );
262
286
  expect( spy ).toHaveBeenNthCalledWith( 4, {
263
287
  path: PATHS.NESTED,
264
- type: 'push',
288
+ type: 'goTo',
265
289
  } );
266
290
  expect( spy ).toHaveBeenNthCalledWith( 5, {
267
- type: 'pop',
291
+ type: 'goBack',
268
292
  } );
269
293
  expect( spy ).toHaveBeenNthCalledWith( 6, {
270
- type: 'pop',
294
+ type: 'goBack',
271
295
  } );
272
296
  } );
273
297
 
@@ -291,11 +315,39 @@ describe( 'Navigator', () => {
291
315
  getNestedScreen( { throwIfNotFound: false } )
292
316
  ).not.toBeInTheDocument();
293
317
 
294
- // Check the values passed to `navigator.push()`
318
+ // Check the values passed to `navigator.goTo()`
295
319
  expect( spy ).toHaveBeenCalledTimes( 1 );
296
320
  expect( spy ).toHaveBeenNthCalledWith( 1, {
297
321
  path: PATHS.NOT_FOUND,
298
- type: 'push',
322
+ type: 'goTo',
299
323
  } );
300
324
  } );
325
+
326
+ it( 'should restore focus correctly', () => {
327
+ render( <MyNavigation /> );
328
+
329
+ expect( getHomeScreen() ).toBeInTheDocument();
330
+
331
+ // Navigate to child screen
332
+ fireEvent.click( getToChildScreenButton() );
333
+
334
+ expect( getChildScreen() ).toBeInTheDocument();
335
+
336
+ // Navigate to nested screen
337
+ fireEvent.click( getToNestedScreenButton() );
338
+
339
+ expect( getNestedScreen() ).toBeInTheDocument();
340
+
341
+ // Navigate back to child screen, check that focus was correctly restored
342
+ fireEvent.click( getBackButton() );
343
+
344
+ expect( getChildScreen() ).toBeInTheDocument();
345
+ expect( getToNestedScreenButton() ).toHaveFocus();
346
+
347
+ // Navigate back to home screen, check that focus was correctly restored
348
+ fireEvent.click( getBackButton() );
349
+
350
+ expect( getHomeScreen() ).toBeInTheDocument();
351
+ expect( getToChildScreenButton() ).toHaveFocus();
352
+ } );
301
353
  } );
@@ -3,7 +3,9 @@
3
3
  */
4
4
  import type { ReactNode } from 'react';
5
5
 
6
- type NavigateOptions = {};
6
+ type NavigateOptions = {
7
+ focusTargetSelector?: string;
8
+ };
7
9
 
8
10
  export type NavigatorLocation = NavigateOptions & {
9
11
  isInitial?: boolean;
@@ -13,8 +15,8 @@ export type NavigatorLocation = NavigateOptions & {
13
15
 
14
16
  export type NavigatorContext = {
15
17
  location: NavigatorLocation;
16
- push: ( path: string, options: NavigateOptions ) => void;
17
- pop: () => void;
18
+ goTo: ( path: string, options?: NavigateOptions ) => void;
19
+ goBack: () => void;
18
20
  };
19
21
 
20
22
  // Returned by the `useNavigator` hook
@@ -13,12 +13,12 @@ import type { Navigator } from './types';
13
13
  * Retrieves a `navigator` instance.
14
14
  */
15
15
  function useNavigator(): Navigator {
16
- const { location, push, pop } = useContext( NavigatorContext );
16
+ const { location, goTo, goBack } = useContext( NavigatorContext );
17
17
 
18
18
  return {
19
19
  location,
20
- push,
21
- pop,
20
+ goTo,
21
+ goBack,
22
22
  };
23
23
  }
24
24
 
@@ -73,12 +73,14 @@ function Placeholder( {
73
73
  <Icon icon={ icon } />
74
74
  { label }
75
75
  </div>
76
- { !! instructions && (
77
- <div className="components-placeholder__instructions">
78
- { instructions }
79
- </div>
80
- ) }
81
- <div className={ fieldsetClasses }>{ children }</div>
76
+ <fieldset className={ fieldsetClasses }>
77
+ { !! instructions && (
78
+ <legend className="components-placeholder__instructions">
79
+ { instructions }
80
+ </legend>
81
+ ) }
82
+ { children }
83
+ </fieldset>
82
84
  </div>
83
85
  );
84
86
  }
@@ -77,6 +77,18 @@
77
77
  }
78
78
  }
79
79
 
80
+ // Overrides for browser and editor fieldset styles.
81
+ .components-placeholder__fieldset.components-placeholder__fieldset {
82
+ border: none;
83
+ padding: 0;
84
+
85
+ .components-placeholder__instructions {
86
+ padding: 0;
87
+ font-weight: normal;
88
+ font-size: 1em;
89
+ }
90
+ }
91
+
80
92
  .components-placeholder__fieldset.is-column-layout,
81
93
  .components-placeholder__fieldset.is-column-layout form {
82
94
  flex-direction: column;
@@ -88,7 +88,7 @@ describe( 'Placeholder', () => {
88
88
  const element = <div>Fieldset</div>;
89
89
  const placeholder = shallow( <Placeholder children={ element } /> );
90
90
  const placeholderFieldset = placeholder.find(
91
- '.components-placeholder__fieldset'
91
+ 'fieldset.components-placeholder__fieldset'
92
92
  );
93
93
  const child = placeholderFieldset.childAt( 0 );
94
94
 
@@ -96,6 +96,23 @@ describe( 'Placeholder', () => {
96
96
  expect( child.matchesElement( element ) ).toBe( true );
97
97
  } );
98
98
 
99
+ it( 'should display a legend if instructions are passed', () => {
100
+ const element = <div>Fieldset</div>;
101
+ const instructions = 'Choose an option.';
102
+ const placeholder = shallow(
103
+ <Placeholder
104
+ children={ element }
105
+ instructions={ instructions }
106
+ />
107
+ );
108
+ const placeholderLegend = placeholder.find(
109
+ 'legend.components-placeholder__instructions'
110
+ );
111
+
112
+ expect( placeholderLegend.exists() ).toBe( true );
113
+ expect( placeholderLegend.text() ).toEqual( instructions );
114
+ } );
115
+
99
116
  it( 'should add an additional className to the top container', () => {
100
117
  const placeholder = shallow(
101
118
  <Placeholder className="wp-placeholder" />
@@ -36,7 +36,7 @@ export function useScrollable( props ) {
36
36
  scrollDirection === 'auto' && styles.scrollAuto,
37
37
  className
38
38
  ),
39
- [ className, scrollDirection, smoothScroll ]
39
+ [ className, cx, scrollDirection, smoothScroll ]
40
40
  );
41
41
 
42
42
  return { ...otherProps, className: classes };
@@ -8,6 +8,7 @@ import { useRef, useState, useEffect, createPortal } from '@wordpress/element';
8
8
  * Internal dependencies
9
9
  */
10
10
  import useSlot from './use-slot';
11
+ import StyleProvider from '../../style-provider';
11
12
 
12
13
  function useForceUpdate() {
13
14
  const [ , setState ] = useState( {} );
@@ -48,5 +49,15 @@ export default function Fill( { name, children } ) {
48
49
  children = children( slot.fillProps );
49
50
  }
50
51
 
51
- return createPortal( children, slot.ref.current );
52
+ // When using a `Fill`, the `children` will be rendered in the document of the
53
+ // `Slot`. This means that we need to wrap the `children` in a `StyleProvider`
54
+ // to make sure we're referencing the right document/iframe (instead of the
55
+ // context of the `Fill`'s parent).
56
+ const wrappedChildren = (
57
+ <StyleProvider document={ slot.ref.current.ownerDocument }>
58
+ { children }
59
+ </StyleProvider>
60
+ );
61
+
62
+ return createPortal( wrappedChildren, slot.ref.current );
52
63
  }
@@ -1,19 +1,19 @@
1
1
  # Spinner
2
2
 
3
- Spinners notify users that their action is being processed.
4
-
5
- ![Spinner component](https://wordpress.org/gutenberg/files/2019/07/spinner.png)
6
-
7
- ## Best practices
8
-
9
- The spinner component should:
10
-
11
- - Signal to users that the processing of their request is underway and will soon complete.
3
+ `Spinner` is a component used to notify users that their action is being processed.
12
4
 
13
5
  ## Usage
14
6
 
15
7
  ```jsx
16
8
  import { Spinner } from '@wordpress/components';
17
9
 
18
- const MySpinner = () => <Spinner />;
10
+ function Example() {
11
+ return <Spinner />;
12
+ }
19
13
  ```
14
+
15
+ ## Best practices
16
+
17
+ The spinner component should:
18
+
19
+ - Signal to users that the processing of their request is underway and will soon complete.
@@ -1,8 +1,47 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import classNames from 'classnames';
5
+
1
6
  /**
2
7
  * Internal dependencies
3
8
  */
4
- import { StyledSpinner } from './styles/spinner-styles';
9
+ import { StyledSpinner, SpinnerTrack, SpinnerIndicator } from './styles';
10
+
11
+ /**
12
+ * @typedef OwnProps
13
+ *
14
+ * @property {string} [className] Class name
15
+ */
16
+ /** @typedef {import('react').ComponentPropsWithoutRef<'svg'> & OwnProps} Props */
17
+
18
+ /**
19
+ * @param {Props} props
20
+ * @return {JSX.Element} Element
21
+ */
22
+ export default function Spinner( { className, ...props } ) {
23
+ return (
24
+ <StyledSpinner
25
+ className={ classNames( 'components-spinner', className ) }
26
+ viewBox="0 0 100 100"
27
+ xmlns="http://www.w3.org/2000/svg"
28
+ role="presentation"
29
+ focusable="false"
30
+ { ...props }
31
+ >
32
+ { /* Gray circular background */ }
33
+ <SpinnerTrack
34
+ cx="50"
35
+ cy="50"
36
+ r="50"
37
+ vectorEffect="non-scaling-stroke"
38
+ />
5
39
 
6
- export default function Spinner() {
7
- return <StyledSpinner className="components-spinner" />;
40
+ { /* Theme-colored arc */ }
41
+ <SpinnerIndicator
42
+ d="m 50 0 a 50 50 0 0 1 50 50"
43
+ vectorEffect="non-scaling-stroke"
44
+ />
45
+ </StyledSpinner>
46
+ );
8
47
  }
@@ -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"