@wordpress/components 23.0.0 → 23.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/CONTRIBUTING.md +0 -21
  3. package/build/autocomplete/index.js +1 -3
  4. package/build/autocomplete/index.js.map +1 -1
  5. package/build/border-box-control/border-box-control/component.js +0 -3
  6. package/build/border-box-control/border-box-control/component.js.map +1 -1
  7. package/build/border-box-control/border-box-control/hook.js +0 -2
  8. package/build/border-box-control/border-box-control/hook.js.map +1 -1
  9. package/build/border-box-control/border-box-control-split-controls/component.js +0 -2
  10. package/build/border-box-control/border-box-control-split-controls/component.js.map +1 -1
  11. package/build/border-box-control/border-box-control-split-controls/hook.js +0 -2
  12. package/build/border-box-control/border-box-control-split-controls/hook.js.map +1 -1
  13. package/build/border-control/border-control/component.js +0 -2
  14. package/build/border-control/border-control/component.js.map +1 -1
  15. package/build/border-control/border-control/hook.js +0 -2
  16. package/build/border-control/border-control/hook.js.map +1 -1
  17. package/build/border-control/border-control-dropdown/component.js +6 -11
  18. package/build/border-control/border-control-dropdown/component.js.map +1 -1
  19. package/build/border-control/border-control-dropdown/hook.js +0 -2
  20. package/build/border-control/border-control-dropdown/hook.js.map +1 -1
  21. package/build/color-palette/index.js +5 -8
  22. package/build/color-palette/index.js.map +1 -1
  23. package/build/dimension-control/index.js.map +1 -1
  24. package/build/dropdown/index.js +45 -10
  25. package/build/dropdown/index.js.map +1 -1
  26. package/build/gradient-picker/index.js +1 -2
  27. package/build/gradient-picker/index.js.map +1 -1
  28. package/build/higher-order/navigate-regions/index.js +4 -3
  29. package/build/higher-order/navigate-regions/index.js.map +1 -1
  30. package/build/index.js +0 -8
  31. package/build/index.js.map +1 -1
  32. package/build/mobile/bottom-sheet/picker-cell.native.js +1 -9
  33. package/build/mobile/bottom-sheet/picker-cell.native.js.map +1 -1
  34. package/build/mobile/global-styles-context/utils.native.js +30 -12
  35. package/build/mobile/global-styles-context/utils.native.js.map +1 -1
  36. package/build/tab-panel/index.js +5 -4
  37. package/build/tab-panel/index.js.map +1 -1
  38. package/build-module/autocomplete/index.js +1 -2
  39. package/build-module/autocomplete/index.js.map +1 -1
  40. package/build-module/border-box-control/border-box-control/component.js +0 -3
  41. package/build-module/border-box-control/border-box-control/component.js.map +1 -1
  42. package/build-module/border-box-control/border-box-control/hook.js +0 -2
  43. package/build-module/border-box-control/border-box-control/hook.js.map +1 -1
  44. package/build-module/border-box-control/border-box-control-split-controls/component.js +0 -2
  45. package/build-module/border-box-control/border-box-control-split-controls/component.js.map +1 -1
  46. package/build-module/border-box-control/border-box-control-split-controls/hook.js +0 -2
  47. package/build-module/border-box-control/border-box-control-split-controls/hook.js.map +1 -1
  48. package/build-module/border-control/border-control/component.js +0 -2
  49. package/build-module/border-control/border-control/component.js.map +1 -1
  50. package/build-module/border-control/border-control/hook.js +0 -2
  51. package/build-module/border-control/border-control/hook.js.map +1 -1
  52. package/build-module/border-control/border-control-dropdown/component.js +6 -11
  53. package/build-module/border-control/border-control-dropdown/component.js.map +1 -1
  54. package/build-module/border-control/border-control-dropdown/hook.js +0 -2
  55. package/build-module/border-control/border-control-dropdown/hook.js.map +1 -1
  56. package/build-module/color-palette/index.js +5 -8
  57. package/build-module/color-palette/index.js.map +1 -1
  58. package/build-module/dimension-control/index.js +1 -2
  59. package/build-module/dimension-control/index.js.map +1 -1
  60. package/build-module/dropdown/index.js +44 -10
  61. package/build-module/dropdown/index.js.map +1 -1
  62. package/build-module/gradient-picker/index.js +1 -2
  63. package/build-module/gradient-picker/index.js.map +1 -1
  64. package/build-module/higher-order/navigate-regions/index.js +4 -3
  65. package/build-module/higher-order/navigate-regions/index.js.map +1 -1
  66. package/build-module/index.js +0 -1
  67. package/build-module/index.js.map +1 -1
  68. package/build-module/mobile/bottom-sheet/picker-cell.native.js +1 -8
  69. package/build-module/mobile/bottom-sheet/picker-cell.native.js.map +1 -1
  70. package/build-module/mobile/global-styles-context/utils.native.js +31 -13
  71. package/build-module/mobile/global-styles-context/utils.native.js.map +1 -1
  72. package/build-module/tab-panel/index.js +5 -3
  73. package/build-module/tab-panel/index.js.map +1 -1
  74. package/build-style/style-rtl.css +18 -31
  75. package/build-style/style.css +18 -31
  76. package/build-types/border-box-control/border-box-control/component.d.ts +1 -1
  77. package/build-types/border-box-control/border-box-control/component.d.ts.map +1 -1
  78. package/build-types/border-box-control/border-box-control/hook.d.ts +0 -1
  79. package/build-types/border-box-control/border-box-control/hook.d.ts.map +1 -1
  80. package/build-types/border-box-control/border-box-control-split-controls/component.d.ts +1 -1
  81. package/build-types/border-box-control/border-box-control-split-controls/component.d.ts.map +1 -1
  82. package/build-types/border-box-control/border-box-control-split-controls/hook.d.ts +0 -1
  83. package/build-types/border-box-control/border-box-control-split-controls/hook.d.ts.map +1 -1
  84. package/build-types/border-box-control/stories/index.d.ts +1 -1
  85. package/build-types/border-control/border-control/component.d.ts +1 -1
  86. package/build-types/border-control/border-control/component.d.ts.map +1 -1
  87. package/build-types/border-control/border-control/hook.d.ts +0 -1
  88. package/build-types/border-control/border-control/hook.d.ts.map +1 -1
  89. package/build-types/border-control/border-control-dropdown/component.d.ts +1 -1
  90. package/build-types/border-control/border-control-dropdown/component.d.ts.map +1 -1
  91. package/build-types/border-control/border-control-dropdown/hook.d.ts +0 -1
  92. package/build-types/border-control/border-control-dropdown/hook.d.ts.map +1 -1
  93. package/build-types/border-control/stories/index.d.ts +6 -6
  94. package/build-types/border-control/stories/index.d.ts.map +1 -1
  95. package/build-types/border-control/types.d.ts +1 -1
  96. package/build-types/border-control/types.d.ts.map +1 -1
  97. package/build-types/color-palette/index.d.ts +2 -3
  98. package/build-types/color-palette/index.d.ts.map +1 -1
  99. package/build-types/color-palette/stories/index.d.ts +2 -9
  100. package/build-types/color-palette/stories/index.d.ts.map +1 -1
  101. package/build-types/color-palette/types.d.ts +3 -16
  102. package/build-types/color-palette/types.d.ts.map +1 -1
  103. package/build-types/disabled/stories/index.d.ts.map +1 -1
  104. package/build-types/dropdown/index.d.ts +29 -1
  105. package/build-types/dropdown/index.d.ts.map +1 -1
  106. package/build-types/dropdown/stories/index.d.ts +23 -0
  107. package/build-types/dropdown/stories/index.d.ts.map +1 -0
  108. package/build-types/dropdown/test/index.d.ts +2 -0
  109. package/build-types/dropdown/test/index.d.ts.map +1 -0
  110. package/build-types/dropdown/types.d.ts +101 -0
  111. package/build-types/dropdown/types.d.ts.map +1 -1
  112. package/build-types/icon/stories/index.d.ts +22 -0
  113. package/build-types/icon/stories/index.d.ts.map +1 -0
  114. package/build-types/tab-panel/index.d.ts.map +1 -1
  115. package/package.json +17 -17
  116. package/src/autocomplete/index.js +1 -3
  117. package/src/autocomplete/test/index.js +2 -0
  118. package/src/base-control/test/index.tsx +1 -0
  119. package/src/border-box-control/border-box-control/component.tsx +0 -7
  120. package/src/border-box-control/border-box-control/hook.ts +0 -2
  121. package/src/border-box-control/border-box-control-split-controls/component.tsx +0 -2
  122. package/src/border-box-control/border-box-control-split-controls/hook.ts +0 -2
  123. package/src/border-box-control/test/index.js +2 -0
  124. package/src/border-control/border-control/component.tsx +0 -4
  125. package/src/border-control/border-control/hook.ts +0 -2
  126. package/src/border-control/border-control-dropdown/component.tsx +11 -17
  127. package/src/border-control/border-control-dropdown/hook.ts +0 -2
  128. package/src/border-control/stories/index.tsx +0 -1
  129. package/src/border-control/test/index.js +70 -67
  130. package/src/border-control/types.ts +1 -4
  131. package/src/box-control/test/index.js +2 -0
  132. package/src/checkbox-control/test/index.tsx +2 -0
  133. package/src/color-palette/index.tsx +12 -12
  134. package/src/color-palette/stories/index.tsx +0 -13
  135. package/src/color-palette/test/index.tsx +2 -0
  136. package/src/color-palette/types.ts +3 -17
  137. package/src/color-picker/test/index.js +2 -0
  138. package/src/combobox-control/test/index.js +2 -0
  139. package/src/confirm-dialog/test/index.js +2 -0
  140. package/src/date-time/date/test/index.tsx +2 -0
  141. package/src/date-time/time/test/index.tsx +2 -0
  142. package/src/dimension-control/index.js +2 -3
  143. package/src/dimension-control/test/index.test.js +2 -0
  144. package/src/disabled/stories/index.tsx +6 -2
  145. package/src/disabled/test/index.tsx +2 -0
  146. package/src/dropdown/README.md +41 -46
  147. package/src/dropdown/{index.js → index.tsx} +57 -13
  148. package/src/dropdown/stories/{index.js → index.tsx} +21 -8
  149. package/src/dropdown/test/{index.js → index.tsx} +9 -9
  150. package/src/dropdown/types.ts +107 -0
  151. package/src/dropdown-menu/README.md +2 -3
  152. package/src/dropdown-menu/test/index.js +2 -0
  153. package/src/external-link/test/index.tsx +2 -0
  154. package/src/focal-point-picker/test/index.js +2 -0
  155. package/src/font-size-picker/test/index.tsx +2 -0
  156. package/src/form-file-upload/test/index.tsx +2 -0
  157. package/src/form-toggle/test/index.tsx +2 -0
  158. package/src/form-token-field/test/index.tsx +3 -0
  159. package/src/gradient-picker/index.js +1 -2
  160. package/src/gradient-picker/stories/index.js +0 -1
  161. package/src/guide/test/index.js +2 -0
  162. package/src/higher-order/navigate-regions/index.js +5 -2
  163. package/src/higher-order/navigate-regions/style.scss +13 -39
  164. package/src/higher-order/with-filters/test/index.js +70 -74
  165. package/src/higher-order/with-focus-outside/test/index.js +2 -0
  166. package/src/higher-order/with-focus-return/test/index.js +2 -0
  167. package/src/higher-order/with-notices/test/index.js +1 -0
  168. package/src/icon/stories/index.tsx +103 -0
  169. package/src/index.js +0 -1
  170. package/src/input-control/test/index.js +3 -0
  171. package/src/isolated-event-container/test/index.js +2 -0
  172. package/src/mobile/bottom-sheet/picker-cell.native.js +1 -6
  173. package/src/mobile/global-styles-context/utils.native.js +17 -16
  174. package/src/modal/test/index.tsx +1 -3
  175. package/src/navigable-container/test/navigable-menu.js +2 -0
  176. package/src/navigable-container/test/tababble-container.js +2 -0
  177. package/src/navigation/test/index.js +2 -0
  178. package/src/navigator/test/index.tsx +2 -0
  179. package/src/notice/test/index.js +8 -3
  180. package/src/number-control/test/index.tsx +2 -0
  181. package/src/panel/test/__snapshots__/body.js.snap +9 -0
  182. package/src/panel/test/body.js +71 -62
  183. package/src/placeholder/test/index.tsx +3 -0
  184. package/src/select-control/test/select-control.tsx +2 -0
  185. package/src/tab-panel/index.tsx +1 -2
  186. package/src/tab-panel/test/index.tsx +2 -0
  187. package/src/text-highlight/test/index.tsx +1 -0
  188. package/src/toggle-group-control/test/index.tsx +2 -0
  189. package/src/toolbar/style.scss +1 -1
  190. package/src/toolbar-group/test/index.js +2 -0
  191. package/src/tooltip/stories/index.js +68 -78
  192. package/src/tooltip/test/index.js +2 -0
  193. package/src/unit-control/test/index.tsx +3 -0
  194. package/src/utils/hooks/test/use-latest-ref.js +2 -0
  195. package/tsconfig.tsbuildinfo +1 -1
  196. package/src/icon/stories/index.js +0 -128
@@ -1,3 +1,20 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import type { ComponentPropsWithoutRef, CSSProperties, ReactNode } from 'react';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import type Popover from '../popover';
10
+ import type { PopoverProps } from '../popover/types';
11
+
12
+ type CallbackProps = {
13
+ isOpen: boolean;
14
+ onToggle: () => void;
15
+ onClose: () => void;
16
+ };
17
+
1
18
  export type DropdownContentWrapperProps = {
2
19
  /**
3
20
  * Amount of padding to apply on the dropdown content.
@@ -6,3 +23,93 @@ export type DropdownContentWrapperProps = {
6
23
  */
7
24
  paddingSize?: 'none' | 'small' | 'medium';
8
25
  };
26
+
27
+ export type DropdownProps = {
28
+ /**
29
+ * The className of the global container.
30
+ */
31
+ className?: string;
32
+ /**
33
+ * If you want to target the dropdown menu for styling purposes,
34
+ * you need to provide a contentClassName because it's not being rendered
35
+ * as a child of the container node.
36
+ */
37
+ contentClassName?: string;
38
+ /**
39
+ * Opt-in prop to show popovers fullscreen on mobile.
40
+ *
41
+ * @default false
42
+ */
43
+ expandOnMobile?: boolean;
44
+ /**
45
+ * By default, the first tabbable element in the popover will receive focus
46
+ * when it mounts. This is the same as setting this prop to "firstElement".
47
+ * Specifying a true value will focus the container instead.
48
+ * Specifying a false value disables the focus handling entirely
49
+ * (this should only be done when an appropriately accessible
50
+ * substitute behavior exists).
51
+ *
52
+ * @default 'firstElement'
53
+ */
54
+ focusOnMount?: 'firstElement' | boolean;
55
+ /**
56
+ * Set this to customize the text that is shown in the dropdown's header
57
+ * when it is fullscreen on mobile.
58
+ */
59
+ headerTitle?: string;
60
+ /**
61
+ * A callback invoked when the popover should be closed.
62
+ */
63
+ onClose?: () => void;
64
+ /**
65
+ * A callback invoked when the state of the popover changes
66
+ * from open to closed and vice versa.
67
+ * The callback receives a boolean as a parameter.
68
+ * If true, the popover will open.
69
+ * If false, the popover will close.
70
+ */
71
+ onToggle?: ( willOpen: boolean ) => void;
72
+ /**
73
+ * Properties of popoverProps object will be passed as props
74
+ * to the Popover component.
75
+ * Use this object to access properties/features
76
+ * of the Popover component that are not already exposed
77
+ * in the Dropdown component,
78
+ * e.g.: the ability to have the popover without an arrow.
79
+ */
80
+ popoverProps?: Omit<
81
+ ComponentPropsWithoutRef< typeof Popover >,
82
+ 'children'
83
+ >;
84
+ /**
85
+ * The direction in which the popover should open
86
+ * relative to its parent node.
87
+ * Specify a y- and an x-axis as a space-separated string.
88
+ * Supports "top", "bottom" y-axis,
89
+ * and "left", "center", "right" x-axis.
90
+ *
91
+ * @default 'top center'
92
+ */
93
+ position?: PopoverProps[ 'position' ];
94
+ /**
95
+ * A callback invoked to render the content of the dropdown menu.
96
+ * Its first argument is the same as the renderToggle prop.
97
+ */
98
+ renderContent: ( props: CallbackProps ) => ReactNode;
99
+ /**
100
+ * A callback invoked to render the Dropdown Toggle Button.
101
+ *
102
+ * The first argument of the callback is an object
103
+ * containing the following properties:
104
+ *
105
+ * - isOpen: whether the dropdown menu is opened or not
106
+ * - onToggle: A function switching the dropdown menu's state
107
+ * from open to closed and vice versa
108
+ * - onClose: A function that closes the menu if invoked
109
+ */
110
+ renderToggle: ( props: CallbackProps ) => ReactNode;
111
+ /**
112
+ * The style of the global container.
113
+ */
114
+ style?: CSSProperties;
115
+ };
@@ -101,14 +101,13 @@ const MyDropdownMenu = () => (
101
101
  Alternatively, specify a `children` function which returns elements valid for use in a DropdownMenu: `MenuItem`, `MenuItemsChoice`, or `MenuGroup`.
102
102
 
103
103
  ```jsx
104
- import { Fragment } from '@wordpress/element';
105
104
  import { DropdownMenu, MenuGroup, MenuItem } from '@wordpress/components';
106
105
  import { more, arrowUp, arrowDown, trash } from '@wordpress/icons';
107
106
 
108
107
  const MyDropdownMenu = () => (
109
108
  <DropdownMenu icon={ more } label="Select a direction">
110
109
  { ( { onClose } ) => (
111
- <Fragment>
110
+ <>
112
111
  <MenuGroup>
113
112
  <MenuItem icon={ arrowUp } onClick={ onClose }>
114
113
  Move Up
@@ -122,7 +121,7 @@ const MyDropdownMenu = () => (
122
121
  Remove
123
122
  </MenuItem>
124
123
  </MenuGroup>
125
- </Fragment>
124
+ </>
126
125
  ) }
127
126
  </DropdownMenu>
128
127
  );
@@ -15,6 +15,8 @@ import { arrowLeft, arrowRight, arrowUp, arrowDown } from '@wordpress/icons';
15
15
  import DropdownMenu from '../';
16
16
  import { MenuItem } from '../../';
17
17
 
18
+ jest.useFakeTimers();
19
+
18
20
  describe( 'DropdownMenu', () => {
19
21
  it( 'should not render when neither controls nor children are assigned', () => {
20
22
  render( <DropdownMenu /> );
@@ -9,6 +9,8 @@ import userEvent from '@testing-library/user-event';
9
9
  */
10
10
  import { ExternalLink } from '..';
11
11
 
12
+ jest.useFakeTimers();
13
+
12
14
  const setupUser = () =>
13
15
  userEvent.setup( {
14
16
  advanceTimers: jest.advanceTimersByTime,
@@ -9,6 +9,8 @@ import userEvent from '@testing-library/user-event';
9
9
  */
10
10
  import Picker from '..';
11
11
 
12
+ jest.useFakeTimers();
13
+
12
14
  describe( 'FocalPointPicker', () => {
13
15
  describe( 'focus and blur', () => {
14
16
  it( 'clicking the draggable area should focus it', async () => {
@@ -10,6 +10,8 @@ import userEvent from '@testing-library/user-event';
10
10
  import FontSizePicker from '../';
11
11
  import type { FontSize } from '../types';
12
12
 
13
+ jest.useFakeTimers();
14
+
13
15
  describe( 'FontSizePicker', () => {
14
16
  test.each( [
15
17
  // Use units when initial value uses units.
@@ -14,6 +14,8 @@ import FormFileUpload from '..';
14
14
  */
15
15
  const { File } = window;
16
16
 
17
+ jest.useFakeTimers();
18
+
17
19
  // @testing-library/user-event considers changing <input type="file"> to a string as a change, but it do not occur on real browsers, so the comparisons will be against this result
18
20
  const fakePath = expect.objectContaining( {
19
21
  target: expect.objectContaining( {
@@ -15,6 +15,8 @@ import { useState } from '@wordpress/element';
15
15
  import FormToggle, { noop } from '..';
16
16
  import type { FormToggleProps } from '../types';
17
17
 
18
+ jest.useFakeTimers();
19
+
18
20
  const getInput = () => screen.getByRole( 'checkbox' ) as HTMLInputElement;
19
21
 
20
22
  const ControlledFormToggle = ( { onChange }: FormToggleProps ) => {
@@ -21,6 +21,8 @@ import { useState } from '@wordpress/element';
21
21
  */
22
22
  import FormTokenField from '../';
23
23
 
24
+ jest.useFakeTimers();
25
+
24
26
  const FormTokenFieldWithState = ( {
25
27
  onChange,
26
28
  value,
@@ -486,6 +488,7 @@ describe( 'FormTokenField', () => {
486
488
 
487
489
  // This is testing implementation details, but I'm not sure there's
488
490
  // a better way.
491
+ // eslint-disable-next-line testing-library/no-node-access
489
492
  expect( input.parentElement?.parentElement ).toHaveClass(
490
493
  'test-classname'
491
494
  );
@@ -99,7 +99,6 @@ export default function GradientPicker( {
99
99
  value,
100
100
  clearable = true,
101
101
  disableCustomGradients = false,
102
- __experimentalHasMultipleOrigins,
103
102
  __experimentalIsRenderedInSidebar,
104
103
  } ) {
105
104
  const clearGradient = useCallback(
@@ -107,7 +106,7 @@ export default function GradientPicker( {
107
106
  [ onChange ]
108
107
  );
109
108
  const Component =
110
- __experimentalHasMultipleOrigins && gradients?.length
109
+ gradients?.length && gradients[ 0 ].gradients
111
110
  ? MultipleOrigin
112
111
  : SingleOrigin;
113
112
 
@@ -87,7 +87,6 @@ WithNoExistingGradients.args = {
87
87
  export const MultipleOrigins = Template.bind( {} );
88
88
  MultipleOrigins.args = {
89
89
  ...Default.args,
90
- __experimentalHasMultipleOrigins: true,
91
90
  gradients: [
92
91
  { name: 'Origin 1', gradients: GRADIENTS },
93
92
  { name: 'Origin 2', gradients: GRADIENTS },
@@ -9,6 +9,8 @@ import userEvent from '@testing-library/user-event';
9
9
  */
10
10
  import Guide from '../';
11
11
 
12
+ jest.useFakeTimers();
13
+
12
14
  describe( 'Guide', () => {
13
15
  it( 'renders nothing when there are no pages', () => {
14
16
  render( <Guide pages={ [] } /> );
@@ -42,14 +42,17 @@ export function useNavigateRegions( shortcuts = defaultShortcuts ) {
42
42
 
43
43
  function focusRegion( offset ) {
44
44
  const regions = Array.from(
45
- ref.current.querySelectorAll( '[role="region"]' )
45
+ ref.current.querySelectorAll( '[role="region"][tabindex="-1"]' )
46
46
  );
47
47
  if ( ! regions.length ) {
48
48
  return;
49
49
  }
50
50
  let nextRegion = regions[ 0 ];
51
+ // Based off the current element, use closest to determine the wrapping region since this operates up the DOM. Also, match tabindex to avoid edge cases with regions we do not want.
51
52
  const selectedIndex = regions.indexOf(
52
- ref.current.ownerDocument.activeElement
53
+ ref.current.ownerDocument.activeElement.closest(
54
+ '[role="region"][tabindex="-1"]'
55
+ )
53
56
  );
54
57
  if ( selectedIndex !== -1 ) {
55
58
  let nextIndex = selectedIndex + offset;
@@ -4,14 +4,17 @@
4
4
  }
5
5
 
6
6
  .is-focusing-regions {
7
- [role="region"]:focus {
7
+ [role="region"]:focus::after {
8
+ position: absolute;
9
+ top: 0;
10
+ left: 0;
11
+ right: 0;
12
+ bottom: 0;
13
+ content: "";
14
+ pointer-events: none;
8
15
  outline: 4px solid $components-color-accent;
9
16
  outline-offset: -4px;
10
-
11
- .interface-navigable-region__stacker {
12
- position: relative;
13
- z-index: z-index(".is-focusing-regions [role='region']:focus .interface-navigable-region__stacker");
14
- }
17
+ z-index: z-index(".is-focusing-regions {region} :focus::after");
15
18
  }
16
19
 
17
20
  // Fixes for edge cases.
@@ -25,40 +28,11 @@
25
28
  // regardles of the CSS used on other components.
26
29
 
27
30
  // Header top bar when Distraction free mode is on.
28
- &.is-distraction-free .interface-interface-skeleton__header {
29
- .interface-navigable-region__stacker,
30
- .edit-post-header {
31
- outline: inherit;
32
- outline-offset: inherit;
33
- }
34
- }
35
-
36
- // Sidebar toggle button shown when navigating regions.
37
- .interface-interface-skeleton__sidebar {
38
- .interface-navigable-region__stacker,
39
- .edit-post-layout__toggle-sidebar-panel {
40
- outline: inherit;
41
- outline-offset: inherit;
42
- }
43
- }
44
-
45
- // Publish sidebar toggle button shown when navigating regions.
46
- .interface-interface-skeleton__actions {
47
- .interface-navigable-region__stacker,
48
- .edit-post-layout__toggle-publish-panel {
49
- outline: inherit;
50
- outline-offset: inherit;
51
- }
52
- }
53
-
54
- // Publish sidebar.
55
- [role="region"].interface-interface-skeleton__actions:focus .editor-post-publish-panel {
31
+ &.is-distraction-free .interface-interface-skeleton__header .edit-post-header,
32
+ .interface-interface-skeleton__sidebar .edit-post-layout__toggle-sidebar-panel,
33
+ .interface-interface-skeleton__actions .edit-post-layout__toggle-publish-panel,
34
+ .editor-post-publish-panel {
56
35
  outline: 4px solid $components-color-accent;
57
36
  outline-offset: -4px;
58
37
  }
59
38
  }
60
-
61
- .interface-navigable-region__stacker {
62
- height: 100%;
63
- width: 100%;
64
- }
@@ -13,6 +13,8 @@ import { addFilter, removeAllFilters, removeFilter } from '@wordpress/hooks';
13
13
  */
14
14
  import withFilters from '..';
15
15
 
16
+ jest.useFakeTimers();
17
+
16
18
  describe( 'withFilters', () => {
17
19
  const hookName = 'EnhancedComponent';
18
20
  const MyComponent = () => <div>My component</div>;
@@ -79,14 +81,13 @@ describe( 'withFilters', () => {
79
81
 
80
82
  const { container } = render( <EnhancedComponent /> );
81
83
 
82
- expect( container ).toMatchSnapshot();
83
-
84
- jest.runAllTimers();
84
+ act( () => jest.runAllTimers() );
85
85
 
86
86
  expect( SpiedComponent ).toHaveBeenCalledTimes( 1 );
87
+ expect( container ).toMatchSnapshot();
87
88
  } );
88
89
 
89
- it( 'should re-render component once when new filter added after component was mounted', async () => {
90
+ it( 'should re-render component once when new filter added after component was mounted', () => {
90
91
  const SpiedComponent = jest.fn( () => <div>Spied component</div> );
91
92
  const EnhancedComponent = withFilters( hookName )( SpiedComponent );
92
93
 
@@ -94,25 +95,24 @@ describe( 'withFilters', () => {
94
95
 
95
96
  SpiedComponent.mockClear();
96
97
 
97
- await act( () => {
98
- addFilter(
99
- hookName,
100
- 'test/enhanced-component-spy-1',
101
- ( FilteredComponent ) => () =>
102
- (
103
- <blockquote>
104
- <FilteredComponent />
105
- </blockquote>
106
- )
107
- );
108
- jest.runAllTimers();
109
- } );
98
+ addFilter(
99
+ hookName,
100
+ 'test/enhanced-component-spy-1',
101
+ ( FilteredComponent ) => () =>
102
+ (
103
+ <blockquote>
104
+ <FilteredComponent />
105
+ </blockquote>
106
+ )
107
+ );
108
+
109
+ act( () => jest.runAllTimers() );
110
110
 
111
111
  expect( SpiedComponent ).toHaveBeenCalledTimes( 1 );
112
112
  expect( container ).toMatchSnapshot();
113
113
  } );
114
114
 
115
- it( 'should re-render component once when two filters added in the same animation frame', async () => {
115
+ it( 'should re-render component once when two filters added in the same animation frame', () => {
116
116
  const SpiedComponent = jest.fn( () => <div>Spied component</div> );
117
117
  const EnhancedComponent = withFilters( hookName )( SpiedComponent );
118
118
 
@@ -120,65 +120,62 @@ describe( 'withFilters', () => {
120
120
 
121
121
  SpiedComponent.mockClear();
122
122
 
123
- await act( () => {
124
- addFilter(
125
- hookName,
126
- 'test/enhanced-component-spy-1',
127
- ( FilteredComponent ) => () =>
128
- (
129
- <blockquote>
130
- <FilteredComponent />
131
- </blockquote>
132
- )
133
- );
134
- addFilter(
135
- hookName,
136
- 'test/enhanced-component-spy-2',
137
- ( FilteredComponent ) => () =>
138
- (
139
- <section>
140
- <FilteredComponent />
141
- </section>
142
- )
143
- );
144
- jest.runAllTimers();
145
- } );
123
+ addFilter(
124
+ hookName,
125
+ 'test/enhanced-component-spy-1',
126
+ ( FilteredComponent ) => () =>
127
+ (
128
+ <blockquote>
129
+ <FilteredComponent />
130
+ </blockquote>
131
+ )
132
+ );
133
+ addFilter(
134
+ hookName,
135
+ 'test/enhanced-component-spy-2',
136
+ ( FilteredComponent ) => () =>
137
+ (
138
+ <section>
139
+ <FilteredComponent />
140
+ </section>
141
+ )
142
+ );
143
+
144
+ act( () => jest.runAllTimers() );
146
145
 
147
146
  expect( SpiedComponent ).toHaveBeenCalledTimes( 1 );
148
147
  expect( container ).toMatchSnapshot();
149
148
  } );
150
149
 
151
- it( 'should re-render component twice when new filter added and removed in two different animation frames', async () => {
150
+ it( 'should re-render component twice when new filter added and removed in two different animation frames', () => {
152
151
  const SpiedComponent = jest.fn( () => <div>Spied component</div> );
153
152
  const EnhancedComponent = withFilters( hookName )( SpiedComponent );
154
153
  const { container } = render( <EnhancedComponent /> );
155
154
 
156
155
  SpiedComponent.mockClear();
157
156
 
158
- await act( () => {
159
- addFilter(
160
- hookName,
161
- 'test/enhanced-component-spy',
162
- ( FilteredComponent ) => () =>
163
- (
164
- <div>
165
- <FilteredComponent />
166
- </div>
167
- )
168
- );
169
- jest.runAllTimers();
170
- } );
171
-
172
- await act( () => {
173
- removeFilter( hookName, 'test/enhanced-component-spy' );
174
- jest.runAllTimers();
175
- } );
157
+ addFilter(
158
+ hookName,
159
+ 'test/enhanced-component-spy',
160
+ ( FilteredComponent ) => () =>
161
+ (
162
+ <div>
163
+ <FilteredComponent />
164
+ </div>
165
+ )
166
+ );
167
+
168
+ act( () => jest.runAllTimers() );
169
+
170
+ removeFilter( hookName, 'test/enhanced-component-spy' );
171
+
172
+ act( () => jest.runAllTimers() );
176
173
 
177
174
  expect( SpiedComponent ).toHaveBeenCalledTimes( 2 );
178
175
  expect( container ).toMatchSnapshot();
179
176
  } );
180
177
 
181
- it( 'should re-render both components once each when one filter added', async () => {
178
+ it( 'should re-render both components once each when one filter added', () => {
182
179
  const SpiedComponent = jest.fn( () => <div>Spied component</div> );
183
180
  const EnhancedComponent = withFilters( hookName )( SpiedComponent );
184
181
 
@@ -192,19 +189,18 @@ describe( 'withFilters', () => {
192
189
 
193
190
  SpiedComponent.mockClear();
194
191
 
195
- await act( () => {
196
- addFilter(
197
- hookName,
198
- 'test/enhanced-component-spy-1',
199
- ( FilteredComponent ) => () =>
200
- (
201
- <blockquote>
202
- <FilteredComponent />
203
- </blockquote>
204
- )
205
- );
206
- jest.runAllTimers();
207
- } );
192
+ addFilter(
193
+ hookName,
194
+ 'test/enhanced-component-spy-1',
195
+ ( FilteredComponent ) => () =>
196
+ (
197
+ <blockquote>
198
+ <FilteredComponent />
199
+ </blockquote>
200
+ )
201
+ );
202
+
203
+ act( () => jest.runAllTimers() );
208
204
 
209
205
  expect( SpiedComponent ).toHaveBeenCalledTimes( 2 );
210
206
  expect( container ).toMatchSnapshot();
@@ -14,6 +14,8 @@ import { Component } from '@wordpress/element';
14
14
  */
15
15
  import withFocusOutside from '../';
16
16
 
17
+ jest.useFakeTimers();
18
+
17
19
  let onFocusOutside;
18
20
 
19
21
  describe( 'withFocusOutside', () => {
@@ -14,6 +14,8 @@ import { Component } from '@wordpress/element';
14
14
  */
15
15
  import withFocusReturn from '../';
16
16
 
17
+ jest.useFakeTimers();
18
+
17
19
  class Test extends Component {
18
20
  render() {
19
21
  const { className, focusHistory } = this.props;
@@ -101,6 +101,7 @@ describe( 'withNotices operations', () => {
101
101
  act( () => {
102
102
  handle.current.createErrorNotice( message );
103
103
  } );
104
+ // eslint-disable-next-line testing-library/no-node-access
104
105
  expect( getByText( message )?.closest( '.is-error' ) ).not.toBeNull();
105
106
  } );
106
107
 
@@ -0,0 +1,103 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import type { ComponentMeta, ComponentStory } from '@storybook/react';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { SVG, Path } from '@wordpress/primitives';
10
+ import { wordpress } from '@wordpress/icons';
11
+
12
+ /**
13
+ * Internal dependencies
14
+ */
15
+ import Icon from '..';
16
+ import { VStack } from '../../v-stack';
17
+
18
+ const meta: ComponentMeta< typeof Icon > = {
19
+ title: 'Components/Icon',
20
+ component: Icon,
21
+ parameters: {
22
+ controls: { expanded: true },
23
+ docs: { source: { state: 'open' } },
24
+ },
25
+ };
26
+ export default meta;
27
+
28
+ const Template: ComponentStory< typeof Icon > = ( args ) => (
29
+ <Icon { ...args } />
30
+ );
31
+
32
+ export const Default = Template.bind( {} );
33
+ Default.args = {
34
+ icon: wordpress,
35
+ };
36
+
37
+ export const FillColor: ComponentStory< typeof Icon > = ( args ) => {
38
+ return (
39
+ <div
40
+ style={ {
41
+ fill: 'blue',
42
+ } }
43
+ >
44
+ <Icon { ...args } />
45
+ </div>
46
+ );
47
+ };
48
+ FillColor.args = {
49
+ ...Default.args,
50
+ };
51
+
52
+ export const WithAFunction = Template.bind( {} );
53
+ WithAFunction.args = {
54
+ ...Default.args,
55
+ icon: () => (
56
+ <SVG>
57
+ <Path d="M5 4v3h5.5v12h3V7H19V4z" />
58
+ </SVG>
59
+ ),
60
+ };
61
+
62
+ const MyIconComponent = () => (
63
+ <SVG>
64
+ <Path d="M5 4v3h5.5v12h3V7H19V4z" />
65
+ </SVG>
66
+ );
67
+
68
+ export const WithAComponent = Template.bind( {} );
69
+ WithAComponent.args = {
70
+ ...Default.args,
71
+ icon: MyIconComponent,
72
+ };
73
+
74
+ export const WithAnSVG = Template.bind( {} );
75
+ WithAnSVG.args = {
76
+ ...Default.args,
77
+ icon: (
78
+ <SVG>
79
+ <Path d="M5 4v3h5.5v12h3V7H19V4z" />
80
+ </SVG>
81
+ ),
82
+ };
83
+
84
+ /**
85
+ * Although it's preferred to use icons from the `@wordpress/icons` package, Dashicons are still supported,
86
+ * as long as you are in a context where the Dashicons stylesheet is loaded. To simulate that here,
87
+ * use the Global CSS Injector in the Storybook toolbar at the top and select the "WordPress" preset.
88
+ */
89
+ export const WithADashicon: ComponentStory< typeof Icon > = ( args ) => {
90
+ return (
91
+ <VStack>
92
+ <Icon { ...args } />
93
+ <small>
94
+ This won’t show an icon if the Dashicons stylesheet isn’t
95
+ loaded.
96
+ </small>
97
+ </VStack>
98
+ );
99
+ };
100
+ WithADashicon.args = {
101
+ ...Default.args,
102
+ icon: 'wordpress',
103
+ };