@wordpress/components 25.2.0 → 25.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 (208) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/build/button/index.js +13 -4
  3. package/build/button/index.js.map +1 -1
  4. package/build/button/index.native.js +9 -6
  5. package/build/button/index.native.js.map +1 -1
  6. package/build/confirm-dialog/component.js +9 -1
  7. package/build/confirm-dialog/component.js.map +1 -1
  8. package/build/font-size-picker/index.js +5 -3
  9. package/build/font-size-picker/index.js.map +1 -1
  10. package/build/font-size-picker/styles.js +19 -26
  11. package/build/font-size-picker/styles.js.map +1 -1
  12. package/build/form-token-field/styles.js +4 -2
  13. package/build/form-token-field/styles.js.map +1 -1
  14. package/build/guide/icons.js +2 -5
  15. package/build/guide/icons.js.map +1 -1
  16. package/build/guide/index.js +14 -11
  17. package/build/guide/index.js.map +1 -1
  18. package/build/guide/page-control.js +1 -3
  19. package/build/guide/page-control.js.map +1 -1
  20. package/build/item-group/item/hook.js +1 -1
  21. package/build/item-group/item/hook.js.map +1 -1
  22. package/build/item-group/styles.js +13 -10
  23. package/build/item-group/styles.js.map +1 -1
  24. package/build/mobile/bottom-sheet/cell.native.js +2 -1
  25. package/build/mobile/bottom-sheet/cell.native.js.map +1 -1
  26. package/build/mobile/image/index.native.js +4 -3
  27. package/build/mobile/image/index.native.js.map +1 -1
  28. package/build/navigator/navigator-provider/component.js +18 -10
  29. package/build/navigator/navigator-provider/component.js.map +1 -1
  30. package/build/number-control/index.js +8 -4
  31. package/build/number-control/index.js.map +1 -1
  32. package/build/number-control/styles/number-control-styles.js +9 -15
  33. package/build/number-control/styles/number-control-styles.js.map +1 -1
  34. package/build/query-controls/index.js +1 -0
  35. package/build/query-controls/index.js.map +1 -1
  36. package/build/query-controls/index.native.js +1 -0
  37. package/build/query-controls/index.native.js.map +1 -1
  38. package/build/range-control/index.js +7 -1
  39. package/build/range-control/index.js.map +1 -1
  40. package/build/range-control/input-range.js.map +1 -1
  41. package/build/range-control/styles/range-control-styles.js +35 -36
  42. package/build/range-control/styles/range-control-styles.js.map +1 -1
  43. package/build/select-control/index.js +2 -1
  44. package/build/select-control/index.js.map +1 -1
  45. package/build/text-control/index.js +2 -2
  46. package/build/text-control/index.js.map +1 -1
  47. package/build/toolbar/toolbar-group/toolbar-group-container.native.js +10 -7
  48. package/build/toolbar/toolbar-group/toolbar-group-container.native.js.map +1 -1
  49. package/build/unit-control/index.js +4 -2
  50. package/build/unit-control/index.js.map +1 -1
  51. package/build/z-stack/component.js +5 -3
  52. package/build/z-stack/component.js.map +1 -1
  53. package/build/z-stack/styles.js +23 -42
  54. package/build/z-stack/styles.js.map +1 -1
  55. package/build-module/button/index.js +13 -4
  56. package/build-module/button/index.js.map +1 -1
  57. package/build-module/button/index.native.js +8 -6
  58. package/build-module/button/index.native.js.map +1 -1
  59. package/build-module/confirm-dialog/component.js +10 -2
  60. package/build-module/confirm-dialog/component.js.map +1 -1
  61. package/build-module/font-size-picker/index.js +5 -4
  62. package/build-module/font-size-picker/index.js.map +1 -1
  63. package/build-module/font-size-picker/styles.js +17 -23
  64. package/build-module/font-size-picker/styles.js.map +1 -1
  65. package/build-module/form-token-field/styles.js +3 -2
  66. package/build-module/form-token-field/styles.js.map +1 -1
  67. package/build-module/guide/icons.js +2 -5
  68. package/build-module/guide/icons.js.map +1 -1
  69. package/build-module/guide/index.js +14 -10
  70. package/build-module/guide/index.js.map +1 -1
  71. package/build-module/guide/page-control.js +1 -3
  72. package/build-module/guide/page-control.js.map +1 -1
  73. package/build-module/item-group/item/hook.js +1 -1
  74. package/build-module/item-group/item/hook.js.map +1 -1
  75. package/build-module/item-group/styles.js +13 -11
  76. package/build-module/item-group/styles.js.map +1 -1
  77. package/build-module/mobile/bottom-sheet/cell.native.js +2 -1
  78. package/build-module/mobile/bottom-sheet/cell.native.js.map +1 -1
  79. package/build-module/mobile/image/index.native.js +4 -3
  80. package/build-module/mobile/image/index.native.js.map +1 -1
  81. package/build-module/navigator/navigator-provider/component.js +18 -10
  82. package/build-module/navigator/navigator-provider/component.js.map +1 -1
  83. package/build-module/number-control/index.js +8 -5
  84. package/build-module/number-control/index.js.map +1 -1
  85. package/build-module/number-control/styles/number-control-styles.js +7 -14
  86. package/build-module/number-control/styles/number-control-styles.js.map +1 -1
  87. package/build-module/query-controls/index.js +1 -0
  88. package/build-module/query-controls/index.js.map +1 -1
  89. package/build-module/query-controls/index.native.js +1 -0
  90. package/build-module/query-controls/index.native.js.map +1 -1
  91. package/build-module/range-control/index.js +6 -1
  92. package/build-module/range-control/index.js.map +1 -1
  93. package/build-module/range-control/input-range.js.map +1 -1
  94. package/build-module/range-control/styles/range-control-styles.js +35 -36
  95. package/build-module/range-control/styles/range-control-styles.js.map +1 -1
  96. package/build-module/select-control/index.js +2 -1
  97. package/build-module/select-control/index.js.map +1 -1
  98. package/build-module/text-control/index.js +2 -2
  99. package/build-module/text-control/index.js.map +1 -1
  100. package/build-module/toolbar/toolbar-group/toolbar-group-container.native.js +11 -7
  101. package/build-module/toolbar/toolbar-group/toolbar-group-container.native.js.map +1 -1
  102. package/build-module/unit-control/index.js +3 -2
  103. package/build-module/unit-control/index.js.map +1 -1
  104. package/build-module/z-stack/component.js +5 -3
  105. package/build-module/z-stack/component.js.map +1 -1
  106. package/build-module/z-stack/styles.js +22 -44
  107. package/build-module/z-stack/styles.js.map +1 -1
  108. package/build-style/style-rtl.css +22 -35
  109. package/build-style/style.css +22 -35
  110. package/build-types/button/deprecated.d.ts +6 -6
  111. package/build-types/button/index.d.ts.map +1 -1
  112. package/build-types/button/types.d.ts +16 -9
  113. package/build-types/button/types.d.ts.map +1 -1
  114. package/build-types/color-picker/styles.d.ts +2 -1
  115. package/build-types/color-picker/styles.d.ts.map +1 -1
  116. package/build-types/confirm-dialog/component.d.ts.map +1 -1
  117. package/build-types/font-size-picker/index.d.ts.map +1 -1
  118. package/build-types/font-size-picker/styles.d.ts +0 -6
  119. package/build-types/font-size-picker/styles.d.ts.map +1 -1
  120. package/build-types/form-token-field/styles.d.ts.map +1 -1
  121. package/build-types/guide/icons.d.ts +1 -3
  122. package/build-types/guide/icons.d.ts.map +1 -1
  123. package/build-types/guide/index.d.ts.map +1 -1
  124. package/build-types/guide/page-control.d.ts.map +1 -1
  125. package/build-types/item-group/item/hook.d.ts.map +1 -1
  126. package/build-types/item-group/stories/index.d.ts.map +1 -1
  127. package/build-types/item-group/styles.d.ts +1 -1
  128. package/build-types/item-group/styles.d.ts.map +1 -1
  129. package/build-types/navigator/navigator-back-button/component.d.ts +1 -1
  130. package/build-types/navigator/navigator-back-button/hook.d.ts +1 -1
  131. package/build-types/navigator/navigator-button/component.d.ts +1 -1
  132. package/build-types/navigator/navigator-button/hook.d.ts +1 -1
  133. package/build-types/navigator/navigator-provider/component.d.ts.map +1 -1
  134. package/build-types/navigator/navigator-to-parent-button/component.d.ts +1 -1
  135. package/build-types/navigator/types.d.ts +3 -1
  136. package/build-types/navigator/types.d.ts.map +1 -1
  137. package/build-types/number-control/index.d.ts.map +1 -1
  138. package/build-types/number-control/styles/number-control-styles.d.ts +5 -3
  139. package/build-types/number-control/styles/number-control-styles.d.ts.map +1 -1
  140. package/build-types/query-controls/index.d.ts.map +1 -1
  141. package/build-types/range-control/index.d.ts +15 -2
  142. package/build-types/range-control/index.d.ts.map +1 -1
  143. package/build-types/range-control/input-range.d.ts.map +1 -1
  144. package/build-types/range-control/styles/range-control-styles.d.ts +4 -2
  145. package/build-types/range-control/styles/range-control-styles.d.ts.map +1 -1
  146. package/build-types/range-control/types.d.ts +6 -0
  147. package/build-types/range-control/types.d.ts.map +1 -1
  148. package/build-types/select-control/index.d.ts.map +1 -1
  149. package/build-types/select-control/types.d.ts +6 -0
  150. package/build-types/select-control/types.d.ts.map +1 -1
  151. package/build-types/text-control/test/text-control.d.ts +2 -0
  152. package/build-types/text-control/test/text-control.d.ts.map +1 -0
  153. package/build-types/toolbar/toolbar-button/index.d.ts +6 -6
  154. package/build-types/unit-control/index.d.ts.map +1 -1
  155. package/build-types/z-stack/component.d.ts.map +1 -1
  156. package/build-types/z-stack/stories/index.d.ts.map +1 -1
  157. package/build-types/z-stack/styles.d.ts +5 -4
  158. package/build-types/z-stack/styles.d.ts.map +1 -1
  159. package/package.json +22 -22
  160. package/src/button/README.md +15 -0
  161. package/src/button/index.native.js +9 -3
  162. package/src/button/index.tsx +11 -4
  163. package/src/button/style.native.scss +9 -0
  164. package/src/button/style.scss +13 -12
  165. package/src/button/test/index.tsx +13 -0
  166. package/src/button/types.ts +17 -9
  167. package/src/confirm-dialog/component.tsx +12 -2
  168. package/src/confirm-dialog/stories/index.js +8 -15
  169. package/src/confirm-dialog/test/index.js +42 -0
  170. package/src/dropdown-menu/style.scss +9 -13
  171. package/src/font-size-picker/index.tsx +9 -5
  172. package/src/font-size-picker/styles.ts +0 -10
  173. package/src/form-token-field/styles.ts +2 -0
  174. package/src/guide/icons.tsx +2 -7
  175. package/src/guide/index.tsx +14 -13
  176. package/src/guide/page-control.tsx +1 -5
  177. package/src/guide/style.scss +8 -24
  178. package/src/item-group/item/hook.ts +2 -1
  179. package/src/item-group/stories/index.tsx +8 -3
  180. package/src/item-group/styles.ts +39 -28
  181. package/src/mobile/bottom-sheet/cell.native.js +1 -0
  182. package/src/mobile/image/index.native.js +8 -6
  183. package/src/mobile/image/style.native.scss +5 -1
  184. package/src/modal/style.scss +3 -2
  185. package/src/navigator/navigator-provider/component.tsx +30 -23
  186. package/src/navigator/types.ts +4 -1
  187. package/src/number-control/index.tsx +6 -4
  188. package/src/number-control/styles/number-control-styles.ts +8 -16
  189. package/src/placeholder/style.scss +5 -0
  190. package/src/query-controls/index.native.js +1 -0
  191. package/src/query-controls/index.tsx +1 -0
  192. package/src/range-control/index.tsx +14 -2
  193. package/src/range-control/input-range.tsx +0 -1
  194. package/src/range-control/styles/range-control-styles.ts +12 -3
  195. package/src/range-control/types.ts +6 -0
  196. package/src/select-control/index.tsx +1 -0
  197. package/src/select-control/types.ts +6 -0
  198. package/src/text-control/index.tsx +2 -2
  199. package/src/text-control/test/text-control.tsx +61 -0
  200. package/src/toolbar/toolbar-group/style.native.scss +2 -3
  201. package/src/toolbar/toolbar-group/toolbar-group-container.native.js +12 -17
  202. package/src/tooltip/README.md +1 -1
  203. package/src/unit-control/index.tsx +3 -2
  204. package/src/unit-control/test/index.tsx +5 -2
  205. package/src/z-stack/component.tsx +4 -2
  206. package/src/z-stack/stories/index.tsx +6 -13
  207. package/src/z-stack/styles.ts +23 -24
  208. package/tsconfig.tsbuildinfo +1 -1
@@ -24,6 +24,7 @@ import {
24
24
  */
25
25
  import Tooltip from '../tooltip';
26
26
  import Icon from '../icon';
27
+ import style from './style.scss';
27
28
 
28
29
  const isAndroid = Platform.OS === 'android';
29
30
  const marginBottom = isAndroid ? -0.5 : 0;
@@ -51,8 +52,6 @@ const styles = StyleSheet.create( {
51
52
  justifyContent: 'center',
52
53
  alignItems: 'center',
53
54
  borderRadius: 6,
54
- borderColor: '#2e4453',
55
- backgroundColor: '#2e4453',
56
55
  },
57
56
  subscriptInactive: {
58
57
  color: '#7b9ab1', // $toolbar-button.
@@ -95,6 +94,7 @@ export function Button( props ) {
95
94
  tooltipPosition,
96
95
  isActiveStyle,
97
96
  customContainerStyles,
97
+ hitSlop,
98
98
  } = props;
99
99
  const preferredColorScheme = usePreferredColorScheme();
100
100
 
@@ -105,10 +105,16 @@ export function Button( props ) {
105
105
  customContainerStyles && { ...customContainerStyles },
106
106
  ];
107
107
 
108
+ const buttonActiveColorStyles = usePreferredColorSchemeStyle(
109
+ style[ 'components-button-light--active' ],
110
+ style[ 'components-button-dark--active' ]
111
+ );
112
+
108
113
  const buttonViewStyle = {
109
114
  opacity: isDisabled ? 0.3 : 1,
110
115
  ...( fixedRatio && styles.fixedRatio ),
111
116
  ...( isPressed ? styles.buttonActive : styles.buttonInactive ),
117
+ ...( isPressed ? buttonActiveColorStyles : {} ),
112
118
  ...( isPressed &&
113
119
  isActiveStyle?.borderRadius && {
114
120
  borderRadius: isActiveStyle.borderRadius,
@@ -158,7 +164,6 @@ export function Button( props ) {
158
164
 
159
165
  const newIcon = icon
160
166
  ? cloneElement( <Icon icon={ icon } size={ iconSize } />, {
161
- colorScheme: preferredColorScheme,
162
167
  isPressed,
163
168
  } )
164
169
  : null;
@@ -184,6 +189,7 @@ export function Button( props ) {
184
189
  style={ containerStyle }
185
190
  disabled={ isDisabled }
186
191
  testID={ testID }
192
+ hitSlop={ hitSlop }
187
193
  >
188
194
  <LongPressGestureHandler
189
195
  minDurationMs={ 500 }
@@ -33,11 +33,18 @@ function useDeprecatedProps( {
33
33
  isSecondary,
34
34
  isTertiary,
35
35
  isLink,
36
+ isSmall,
37
+ size,
36
38
  variant,
37
39
  ...otherProps
38
40
  }: ButtonProps & DeprecatedButtonProps ): ButtonProps {
41
+ let computedSize = size;
39
42
  let computedVariant = variant;
40
43
 
44
+ if ( isSmall ) {
45
+ computedSize ??= 'small';
46
+ }
47
+
41
48
  if ( isPrimary ) {
42
49
  computedVariant ??= 'primary';
43
50
  }
@@ -66,6 +73,7 @@ function useDeprecatedProps( {
66
73
 
67
74
  return {
68
75
  ...otherProps,
76
+ size: computedSize,
69
77
  variant: computedVariant,
70
78
  };
71
79
  }
@@ -76,8 +84,6 @@ export function UnforwardedButton(
76
84
  ) {
77
85
  const {
78
86
  __next40pxDefaultSize,
79
- __next32pxSmallSize,
80
- isSmall,
81
87
  isPressed,
82
88
  isBusy,
83
89
  isDestructive,
@@ -91,6 +97,7 @@ export function UnforwardedButton(
91
97
  shortcut,
92
98
  label,
93
99
  children,
100
+ size = 'default',
94
101
  text,
95
102
  variant,
96
103
  __experimentalIsFocusable: isFocusable,
@@ -118,10 +125,10 @@ export function UnforwardedButton(
118
125
 
119
126
  const classes = classnames( 'components-button', className, {
120
127
  'is-next-40px-default-size': __next40pxDefaultSize,
121
- 'is-next-32px-small-size': __next32pxSmallSize,
122
128
  'is-secondary': variant === 'secondary',
123
129
  'is-primary': variant === 'primary',
124
- 'is-small': isSmall,
130
+ 'is-small': size === 'small',
131
+ 'is-compact': size === 'compact',
125
132
  'is-tertiary': variant === 'tertiary',
126
133
  'is-pressed': isPressed,
127
134
  'is-busy': isBusy,
@@ -0,0 +1,9 @@
1
+ .components-button-light--active {
2
+ border-color: $light-dim;
3
+ background-color: $light-dim;
4
+ }
5
+
6
+ .components-button-dark--active {
7
+ border-color: $dark-quaternary;
8
+ background-color: $dark-quaternary;
9
+ }
@@ -257,25 +257,26 @@
257
257
  /* stylelint-enable */
258
258
  }
259
259
 
260
+ &.is-compact {
261
+ height: $button-size-compact;
262
+
263
+ &.has-icon:not(.has-text) {
264
+ padding: 0;
265
+ width: $button-size-compact;
266
+ min-width: $button-size-compact;
267
+ }
268
+ }
269
+
260
270
  &.is-small {
261
- height: $button-size-small-next-default-32px;
271
+ height: $button-size-small;
262
272
  line-height: 22px;
263
273
  padding: 0 8px;
264
274
  font-size: 11px;
265
275
 
266
276
  &.has-icon:not(.has-text) {
267
277
  padding: 0;
268
- width: $button-size-small-next-default-32px;
269
- min-width: $button-size-small-next-default-32px;
270
- }
271
-
272
- &:not(.is-next-32px-small-size) {
273
- height: $button-size-small;
274
-
275
- &.has-icon:not(.has-text) {
276
- width: $button-size-small;
277
- min-width: $button-size-small;
278
- }
278
+ width: $button-size-small;
279
+ min-width: $button-size-small;
279
280
  }
280
281
  }
281
282
 
@@ -402,6 +402,19 @@ describe( 'Button', () => {
402
402
  );
403
403
  expect( console ).toHaveWarned();
404
404
  } );
405
+
406
+ it( 'should not break when the legacy isSmall prop is passed', () => {
407
+ render( <Button isSmall /> );
408
+ expect( screen.getByRole( 'button' ) ).toHaveClass( 'is-small' );
409
+ } );
410
+
411
+ it( 'should prioritize the `size` prop over `isSmall`', () => {
412
+ render( <Button size="compact" isSmall /> );
413
+ expect( screen.getByRole( 'button' ) ).not.toHaveClass(
414
+ 'is-small'
415
+ );
416
+ expect( screen.getByRole( 'button' ) ).toHaveClass( 'is-compact' );
417
+ } );
405
418
  } );
406
419
 
407
420
  describe( 'static typing', () => {
@@ -25,15 +25,6 @@ type BaseButtonProps = {
25
25
  * @default false
26
26
  */
27
27
  __next40pxDefaultSize?: boolean;
28
- /**
29
- * Start opting into the larger `isSmall` button size that will become the
30
- * default small size in a future version.
31
- *
32
- * Only takes effect when the `isSmall` prop is `true`.
33
- *
34
- * @default false
35
- */
36
- __next32pxSmallSize?: boolean;
37
28
  /**
38
29
  * The button's children.
39
30
  */
@@ -74,8 +65,13 @@ type BaseButtonProps = {
74
65
  * Renders a pressed button style.
75
66
  */
76
67
  isPressed?: boolean;
68
+ // TODO: Deprecate officially (add console warning and move to DeprecatedButtonProps).
77
69
  /**
78
70
  * Decreases the size of the button.
71
+ *
72
+ * Deprecated in favor of the `size` prop. If both props are defined, the `size` prop will take precedence.
73
+ *
74
+ * @deprecated Use the `'small'` value on the `size` prop instead.
79
75
  */
80
76
  isSmall?: boolean;
81
77
  /**
@@ -92,6 +88,18 @@ type BaseButtonProps = {
92
88
  * If provided, renders a Tooltip component for the button.
93
89
  */
94
90
  showTooltip?: boolean;
91
+ /**
92
+ * The size of the button.
93
+ *
94
+ * - `'default'`: For normal text-label buttons, unless it is a toggle button.
95
+ * - `'compact'`: For toggle buttons, icon buttons, and buttons when used in context of either.
96
+ * - `'small'`: For icon buttons associated with more advanced or auxiliary features.
97
+ *
98
+ * If the deprecated `isSmall` prop is also defined, this prop will take precedence.
99
+ *
100
+ * @default 'default'
101
+ */
102
+ size?: 'default' | 'compact' | 'small';
95
103
  /**
96
104
  * If provided, displays the given text inside the button. If the button contains children elements, the text is displayed before them.
97
105
  */
@@ -7,7 +7,7 @@ import type { ForwardedRef, KeyboardEvent } from 'react';
7
7
  * WordPress dependencies
8
8
  */
9
9
  import { __ } from '@wordpress/i18n';
10
- import { useCallback, useEffect, useState } from '@wordpress/element';
10
+ import { useCallback, useEffect, useRef, useState } from '@wordpress/element';
11
11
 
12
12
  /**
13
13
  * Internal dependencies
@@ -42,6 +42,8 @@ function ConfirmDialog(
42
42
 
43
43
  const cx = useCx();
44
44
  const wrapperClassName = cx( styles.wrapper );
45
+ const cancelButtonRef = useRef();
46
+ const confirmButtonRef = useRef();
45
47
 
46
48
  const [ isOpen, setIsOpen ] = useState< boolean >();
47
49
  const [ shouldSelfClose, setShouldSelfClose ] = useState< boolean >();
@@ -69,7 +71,13 @@ function ConfirmDialog(
69
71
 
70
72
  const handleEnter = useCallback(
71
73
  ( event: KeyboardEvent< HTMLDivElement > ) => {
72
- if ( event.key === 'Enter' ) {
74
+ // Avoid triggering the 'confirm' action when a button is focused,
75
+ // as this can cause a double submission.
76
+ const isConfirmOrCancelButton =
77
+ event.target === cancelButtonRef.current ||
78
+ event.target === confirmButtonRef.current;
79
+
80
+ if ( ! isConfirmOrCancelButton && event.key === 'Enter' ) {
73
81
  handleEvent( onConfirm )( event );
74
82
  }
75
83
  },
@@ -96,12 +104,14 @@ function ConfirmDialog(
96
104
  <Text>{ children }</Text>
97
105
  <Flex direction="row" justify="flex-end">
98
106
  <Button
107
+ ref={ cancelButtonRef }
99
108
  variant="tertiary"
100
109
  onClick={ handleEvent( onCancel ) }
101
110
  >
102
111
  { cancelLabel }
103
112
  </Button>
104
113
  <Button
114
+ ref={ confirmButtonRef }
105
115
  variant="primary"
106
116
  onClick={ handleEvent( onConfirm ) }
107
117
  >
@@ -7,7 +7,6 @@ import { useState } from '@wordpress/element';
7
7
  * Internal dependencies
8
8
  */
9
9
  import Button from '../../button';
10
- import { Heading } from '../../heading';
11
10
  import { ConfirmDialog } from '..';
12
11
 
13
12
  const meta = {
@@ -26,12 +25,8 @@ const meta = {
26
25
  isOpen: {
27
26
  control: { type: null },
28
27
  },
29
- onConfirm: {
30
- control: { type: null },
31
- },
32
- onCancel: {
33
- control: { type: null },
34
- },
28
+ onConfirm: { action: 'onConfirm' },
29
+ onCancel: { action: 'onCancel' },
35
30
  },
36
31
  args: {
37
32
  children: 'Would you like to privately publish the post now?',
@@ -43,19 +38,19 @@ const meta = {
43
38
 
44
39
  export default meta;
45
40
 
46
- const Template = ( args ) => {
41
+ const Template = ( { onConfirm, onCancel, ...args } ) => {
47
42
  const [ isOpen, setIsOpen ] = useState( false );
48
- const [ confirmVal, setConfirmVal ] = useState( '' );
49
43
 
50
- const handleConfirm = () => {
51
- setConfirmVal( 'Confirmed!' );
44
+ const handleConfirm = ( ...confirmArgs ) => {
45
+ onConfirm( ...confirmArgs );
52
46
  setIsOpen( false );
53
47
  };
54
48
 
55
- const handleCancel = () => {
56
- setConfirmVal( 'Cancelled' );
49
+ const handleCancel = ( ...cancelArgs ) => {
50
+ onCancel( ...cancelArgs );
57
51
  setIsOpen( false );
58
52
  };
53
+
59
54
  return (
60
55
  <>
61
56
  <Button variant="primary" onClick={ () => setIsOpen( true ) }>
@@ -70,8 +65,6 @@ const Template = ( args ) => {
70
65
  >
71
66
  { args.children }
72
67
  </ConfirmDialog>
73
-
74
- <Heading level={ 1 }>{ confirmVal }</Heading>
75
68
  </>
76
69
  );
77
70
  };
@@ -194,6 +194,48 @@ describe( 'Confirm', () => {
194
194
  expect( confirmDialog ).not.toBeInTheDocument();
195
195
  expect( onConfirm ).toHaveBeenCalled();
196
196
  } );
197
+
198
+ it( 'calls only the `onCancel` callback and not the `onConfirm` callback when the cancel button is submitted using the keyboard', async () => {
199
+ const user = userEvent.setup();
200
+
201
+ const onConfirm = jest.fn().mockName( 'onConfirm()' );
202
+ const onCancel = jest.fn().mockName( 'onCancel()' );
203
+
204
+ render(
205
+ <ConfirmDialog
206
+ onConfirm={ onConfirm }
207
+ onCancel={ onCancel }
208
+ >
209
+ Are you sure?
210
+ </ConfirmDialog>
211
+ );
212
+
213
+ await user.keyboard( '[Tab][Enter]' );
214
+
215
+ expect( onConfirm ).not.toHaveBeenCalled();
216
+ expect( onCancel ).toHaveBeenCalledTimes( 1 );
217
+ } );
218
+
219
+ it( 'calls only the `onConfirm` callback when the confirm button is submitted using the keyboard', async () => {
220
+ const user = userEvent.setup();
221
+
222
+ const onConfirm = jest.fn().mockName( 'onConfirm()' );
223
+ const onCancel = jest.fn().mockName( 'onCancel()' );
224
+
225
+ render(
226
+ <ConfirmDialog
227
+ onConfirm={ onConfirm }
228
+ onCancel={ onCancel }
229
+ >
230
+ Are you sure?
231
+ </ConfirmDialog>
232
+ );
233
+
234
+ await user.keyboard( '[Tab][Tab][Enter]' );
235
+
236
+ expect( onConfirm ).toHaveBeenCalledTimes( 1 );
237
+ expect( onCancel ).not.toHaveBeenCalled();
238
+ } );
197
239
  } );
198
240
  } );
199
241
 
@@ -30,19 +30,15 @@
30
30
  height: 1px;
31
31
  }
32
32
 
33
- &.is-active svg {
34
- // Block UI appearance.
35
- color: $white;
36
- background: $gray-900;
37
- box-shadow: 0 0 0 $border-width $gray-900;
38
- border-radius: $border-width;
39
- }
40
-
41
- // Formatting buttons
42
- > svg {
43
- border-radius: $radius-block-ui;
44
- width: $button-size-small;
45
- height: $button-size-small;
33
+ &.is-active {
34
+ svg,
35
+ .dashicon {
36
+ // Block UI appearance.
37
+ color: $white;
38
+ background: $gray-900;
39
+ box-shadow: 0 0 0 $border-width $gray-900;
40
+ border-radius: $border-width;
41
+ }
46
42
  }
47
43
 
48
44
  // If menu items are icon-only, make them stretch only to the icon size.
@@ -14,6 +14,7 @@ import { useState, useMemo, forwardRef } from '@wordpress/element';
14
14
  /**
15
15
  * Internal dependencies
16
16
  */
17
+ import { Button } from '../button';
17
18
  import RangeControl from '../range-control';
18
19
  import { Flex, FlexItem } from '../flex';
19
20
  import {
@@ -31,7 +32,6 @@ import {
31
32
  HeaderLabel,
32
33
  HeaderToggle,
33
34
  Controls,
34
- ResetButton,
35
35
  } from './styles';
36
36
  import { Spacer } from '../spacer';
37
37
  import FontSizePickerSelect from './font-size-picker-select';
@@ -268,17 +268,21 @@ const UnforwardedFontSizePicker = (
268
268
  ) }
269
269
  { withReset && (
270
270
  <FlexItem>
271
- <ResetButton
271
+ <Button
272
272
  disabled={ value === undefined }
273
273
  onClick={ () => {
274
274
  onChange?.( undefined );
275
275
  } }
276
- isSmall
277
276
  variant="secondary"
278
- size={ size }
277
+ __next40pxDefaultSize
278
+ size={
279
+ size !== '__unstable-large'
280
+ ? 'small'
281
+ : 'default'
282
+ }
279
283
  >
280
284
  { __( 'Reset' ) }
281
- </ResetButton>
285
+ </Button>
282
286
  </FlexItem>
283
287
  ) }
284
288
  </Flex>
@@ -11,7 +11,6 @@ import Button from '../button';
11
11
  import { HStack } from '../h-stack';
12
12
  import { space } from '../ui/utils/space';
13
13
  import { COLORS } from '../utils';
14
- import type { FontSizePickerProps } from './types';
15
14
 
16
15
  export const Container = styled.fieldset`
17
16
  border: 0;
@@ -44,12 +43,3 @@ export const Controls = styled.div< {
44
43
  ${ ( props ) =>
45
44
  ! props.__nextHasNoMarginBottom && `margin-bottom: ${ space( 6 ) };` }
46
45
  `;
47
-
48
- export const ResetButton = styled( Button )< {
49
- size: FontSizePickerProps[ 'size' ];
50
- } >`
51
- &&& {
52
- height: ${ ( props ) =>
53
- props.size === '__unstable-large' ? '40px' : '30px' };
54
- }
55
- `;
@@ -9,6 +9,7 @@ import { css } from '@emotion/react';
9
9
  */
10
10
  import { Flex } from '../flex';
11
11
  import { space } from '../ui/utils/space';
12
+ import { boxSizingReset } from '../utils';
12
13
 
13
14
  type TokensAndInputWrapperProps = {
14
15
  __next40pxDefaultSize: boolean;
@@ -27,6 +28,7 @@ const deprecatedPaddings = ( {
27
28
 
28
29
  export const TokensAndInputWrapperFlex = styled( Flex )`
29
30
  padding: 7px;
31
+ ${ boxSizingReset }
30
32
 
31
33
  ${ deprecatedPaddings }
32
34
  `;
@@ -3,13 +3,8 @@
3
3
  */
4
4
  import { SVG, Circle } from '@wordpress/primitives';
5
5
 
6
- export const PageControlIcon = ( { isSelected }: { isSelected: boolean } ) => (
6
+ export const PageControlIcon = () => (
7
7
  <SVG width="8" height="8" fill="none" xmlns="http://www.w3.org/2000/svg">
8
- <Circle
9
- cx="4"
10
- cy="4"
11
- r="4"
12
- fill={ isSelected ? '#419ECD' : '#E1E3E6' }
13
- />
8
+ <Circle cx="4" cy="4" r="4" />
14
9
  </SVG>
15
10
  );
@@ -9,7 +9,6 @@ import classnames from 'classnames';
9
9
  import { useState, useEffect, Children, useRef } from '@wordpress/element';
10
10
  import deprecated from '@wordpress/deprecated';
11
11
  import { __ } from '@wordpress/i18n';
12
- import { focus } from '@wordpress/dom';
13
12
 
14
13
  /**
15
14
  * Internal dependencies
@@ -59,9 +58,17 @@ function Guide( {
59
58
  onFinish,
60
59
  pages = [],
61
60
  }: GuideProps ) {
62
- const guideContainer = useRef< HTMLDivElement >( null );
61
+ const ref = useRef< HTMLDivElement >( null );
63
62
  const [ currentPage, setCurrentPage ] = useState( 0 );
64
63
 
64
+ useEffect( () => {
65
+ // Place focus at the top of the guide on mount and when the page changes.
66
+ const frame = ref.current?.querySelector( '.components-guide' );
67
+ if ( frame instanceof HTMLElement ) {
68
+ frame.focus();
69
+ }
70
+ }, [ currentPage ] );
71
+
65
72
  useEffect( () => {
66
73
  if ( Children.count( children ) ) {
67
74
  deprecated( 'Passing children to <Guide>', {
@@ -71,16 +78,6 @@ function Guide( {
71
78
  }
72
79
  }, [ children ] );
73
80
 
74
- useEffect( () => {
75
- // Each time we change the current page, start from the first element of the page.
76
- // This also solves any focus loss that can happen.
77
- if ( guideContainer.current ) {
78
- (
79
- focus.tabbable.find( guideContainer.current ) as HTMLElement[]
80
- )[ 0 ]?.focus();
81
- }
82
- }, [ currentPage ] );
83
-
84
81
  if ( Children.count( children ) ) {
85
82
  pages =
86
83
  Children.map( children, ( child ) => ( {
@@ -111,6 +108,7 @@ function Guide( {
111
108
  <Modal
112
109
  className={ classnames( 'components-guide', className ) }
113
110
  contentLabel={ contentLabel }
111
+ isDismissible={ pages.length > 1 }
114
112
  onRequestClose={ onFinish }
115
113
  onKeyDown={ ( event ) => {
116
114
  if ( event.code === 'ArrowLeft' ) {
@@ -123,7 +121,7 @@ function Guide( {
123
121
  event.preventDefault();
124
122
  }
125
123
  } }
126
- ref={ guideContainer }
124
+ ref={ ref }
127
125
  >
128
126
  <div className="components-guide__container">
129
127
  <div className="components-guide__page">
@@ -144,6 +142,7 @@ function Guide( {
144
142
  { canGoBack && (
145
143
  <Button
146
144
  className="components-guide__back-button"
145
+ variant="tertiary"
147
146
  onClick={ goBack }
148
147
  >
149
148
  { __( 'Previous' ) }
@@ -152,6 +151,7 @@ function Guide( {
152
151
  { canGoForward && (
153
152
  <Button
154
153
  className="components-guide__forward-button"
154
+ variant="primary"
155
155
  onClick={ goForward }
156
156
  >
157
157
  { __( 'Next' ) }
@@ -160,6 +160,7 @@ function Guide( {
160
160
  { ! canGoForward && (
161
161
  <Button
162
162
  className="components-guide__finish-button"
163
+ variant="primary"
163
164
  onClick={ onFinish }
164
165
  >
165
166
  { finishButtonText }
@@ -28,11 +28,7 @@ export default function PageControl( {
28
28
  >
29
29
  <Button
30
30
  key={ page }
31
- icon={
32
- <PageControlIcon
33
- isSelected={ page === currentPage }
34
- />
35
- }
31
+ icon={ <PageControlIcon /> }
36
32
  aria-label={ sprintf(
37
33
  /* translators: 1: current page number 2: total number of pages */
38
34
  __( 'Page %1$d of %2$d' ),
@@ -29,7 +29,7 @@
29
29
 
30
30
  &:hover {
31
31
  svg {
32
- fill: #fff;
32
+ fill: $white;
33
33
  }
34
34
  }
35
35
  }
@@ -57,7 +57,7 @@
57
57
  &__footer {
58
58
  align-content: center;
59
59
  display: flex;
60
- height: 30px;
60
+ height: $button-size;
61
61
  justify-content: center;
62
62
  margin: 0 0 $grid-unit-30 0;
63
63
  padding: 0 $grid-unit-40;
@@ -78,6 +78,11 @@
78
78
  height: 30px;
79
79
  min-width: 20px;
80
80
  margin: -6px 0;
81
+ color: $gray-200;
82
+ }
83
+
84
+ li[aria-current="step"] .components-button {
85
+ color: var(--wp-components-color-accent, var(--wp-admin-theme-color));
81
86
  }
82
87
  }
83
88
  }
@@ -85,7 +90,6 @@
85
90
  .components-modal__frame.components-guide {
86
91
  border: none;
87
92
  min-width: 312px;
88
- height: 80vh;
89
93
  max-height: 575px;
90
94
 
91
95
  @media ( max-width: $break-small ) {
@@ -98,34 +102,14 @@
98
102
  &.components-guide__back-button,
99
103
  &.components-guide__forward-button,
100
104
  &.components-guide__finish-button {
101
- height: 30px;
102
105
  position: absolute;
103
106
  }
104
107
 
105
- &.components-guide__back-button,
106
- &.components-guide__forward-button {
107
- font-size: $default-font-size;
108
- padding: 4px 2px;
109
-
110
- &.has-text svg {
111
- margin: 0;
112
- }
113
-
114
- &:hover {
115
- text-decoration: underline;
116
- }
117
- }
118
-
119
108
  &.components-guide__back-button {
120
109
  left: $grid-unit-40;
121
110
  }
122
111
 
123
- &.components-guide__forward-button {
124
- right: $grid-unit-40;
125
- color: #1386bf;
126
- font-weight: bold;
127
- }
128
-
112
+ &.components-guide__forward-button,
129
113
  &.components-guide__finish-button {
130
114
  right: $grid-unit-40;
131
115
  }
@@ -42,7 +42,8 @@ export function useItem( props: WordPressComponentProps< ItemProps, 'div' > ) {
42
42
  const classes = useMemo(
43
43
  () =>
44
44
  cx(
45
- as === 'button' && styles.unstyledButton,
45
+ ( as === 'button' || as === 'a' ) &&
46
+ styles.unstyledButton( as ),
46
47
  styles.itemSizes[ size ] || styles.itemSizes.medium,
47
48
  styles.item,
48
49
  spacedAround && styles.spacedAround,