@wordpress/components 25.10.0 → 25.11.1-next.f8d8eceb.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 (74) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/build/autocomplete/index.js +104 -52
  3. package/build/autocomplete/index.js.map +1 -1
  4. package/build/dropdown-menu-v2-ariakit/index.js +217 -0
  5. package/build/dropdown-menu-v2-ariakit/index.js.map +1 -0
  6. package/build/dropdown-menu-v2-ariakit/styles.js +157 -0
  7. package/build/dropdown-menu-v2-ariakit/styles.js.map +1 -0
  8. package/build/dropdown-menu-v2-ariakit/types.js +6 -0
  9. package/build/dropdown-menu-v2-ariakit/types.js.map +1 -0
  10. package/build/input-control/styles/input-control-styles.js +23 -23
  11. package/build/input-control/styles/input-control-styles.js.map +1 -1
  12. package/build/mobile/global-styles-context/utils.native.js +1 -1
  13. package/build/mobile/global-styles-context/utils.native.js.map +1 -1
  14. package/build/private-apis.js +9 -1
  15. package/build/private-apis.js.map +1 -1
  16. package/build/select-control/styles/select-control-styles.js +8 -8
  17. package/build/select-control/styles/select-control-styles.js.map +1 -1
  18. package/build/tabs/index.js +2 -2
  19. package/build/tabs/index.js.map +1 -1
  20. package/build/tooltip/index.js +2 -2
  21. package/build/tooltip/index.js.map +1 -1
  22. package/build-module/autocomplete/index.js +104 -52
  23. package/build-module/autocomplete/index.js.map +1 -1
  24. package/build-module/dropdown-menu-v2-ariakit/index.js +199 -0
  25. package/build-module/dropdown-menu-v2-ariakit/index.js.map +1 -0
  26. package/build-module/dropdown-menu-v2-ariakit/styles.js +136 -0
  27. package/build-module/dropdown-menu-v2-ariakit/styles.js.map +1 -0
  28. package/build-module/dropdown-menu-v2-ariakit/types.js +2 -0
  29. package/build-module/dropdown-menu-v2-ariakit/types.js.map +1 -0
  30. package/build-module/input-control/styles/input-control-styles.js +23 -23
  31. package/build-module/input-control/styles/input-control-styles.js.map +1 -1
  32. package/build-module/mobile/global-styles-context/utils.native.js +2 -2
  33. package/build-module/mobile/global-styles-context/utils.native.js.map +1 -1
  34. package/build-module/private-apis.js +9 -1
  35. package/build-module/private-apis.js.map +1 -1
  36. package/build-module/select-control/styles/select-control-styles.js +8 -8
  37. package/build-module/select-control/styles/select-control-styles.js.map +1 -1
  38. package/build-module/tabs/index.js +3 -3
  39. package/build-module/tabs/index.js.map +1 -1
  40. package/build-module/tooltip/index.js +2 -2
  41. package/build-module/tooltip/index.js.map +1 -1
  42. package/build-style/style-rtl.css +1 -1
  43. package/build-style/style.css +1 -1
  44. package/build-types/autocomplete/index.d.ts.map +1 -1
  45. package/build-types/dropdown-menu-v2-ariakit/index.d.ts +11 -0
  46. package/build-types/dropdown-menu-v2-ariakit/index.d.ts.map +1 -0
  47. package/build-types/dropdown-menu-v2-ariakit/stories/index.story.d.ts +16 -0
  48. package/build-types/dropdown-menu-v2-ariakit/stories/index.story.d.ts.map +1 -0
  49. package/build-types/dropdown-menu-v2-ariakit/styles.d.ts +88 -0
  50. package/build-types/dropdown-menu-v2-ariakit/styles.d.ts.map +1 -0
  51. package/build-types/dropdown-menu-v2-ariakit/test/index.d.ts +2 -0
  52. package/build-types/dropdown-menu-v2-ariakit/test/index.d.ts.map +1 -0
  53. package/build-types/dropdown-menu-v2-ariakit/types.d.ts +174 -0
  54. package/build-types/dropdown-menu-v2-ariakit/types.d.ts.map +1 -0
  55. package/build-types/private-apis.d.ts.map +1 -1
  56. package/build-types/tooltip/index.d.ts.map +1 -1
  57. package/package.json +21 -20
  58. package/src/autocomplete/index.tsx +136 -77
  59. package/src/dimension-control/test/__snapshots__/index.test.js.snap +8 -8
  60. package/src/dropdown-menu-v2-ariakit/README.md +324 -0
  61. package/src/dropdown-menu-v2-ariakit/index.tsx +318 -0
  62. package/src/dropdown-menu-v2-ariakit/stories/index.story.tsx +506 -0
  63. package/src/dropdown-menu-v2-ariakit/styles.ts +297 -0
  64. package/src/dropdown-menu-v2-ariakit/test/index.tsx +1139 -0
  65. package/src/dropdown-menu-v2-ariakit/types.ts +186 -0
  66. package/src/input-control/styles/input-control-styles.tsx +2 -2
  67. package/src/mobile/global-styles-context/utils.native.js +2 -2
  68. package/src/private-apis.ts +16 -0
  69. package/src/select-control/styles/select-control-styles.ts +2 -2
  70. package/src/tabs/index.tsx +3 -3
  71. package/src/tabs/test/index.tsx +12 -3
  72. package/src/toggle-group-control/test/__snapshots__/index.tsx.snap +8 -0
  73. package/src/tooltip/index.tsx +2 -3
  74. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,186 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ // eslint-disable-next-line no-restricted-imports
5
+ import type * as Ariakit from '@ariakit/react';
6
+ import type { Placement } from '@floating-ui/react-dom';
7
+
8
+ export interface DropdownMenuContext {
9
+ /**
10
+ * The ariakit store shared across all DropdownMenu subcomponents.
11
+ */
12
+ store: Ariakit.MenuStore;
13
+ /**
14
+ * The variant used by the underlying menu popover.
15
+ */
16
+ variant?: 'toolbar';
17
+ }
18
+
19
+ export interface DropdownMenuProps {
20
+ /**
21
+ * The trigger button.
22
+ */
23
+ trigger: React.ReactElement;
24
+ /**
25
+ * The contents of the dropdown.
26
+ */
27
+ children?: React.ReactNode;
28
+ /**
29
+ * The open state of the dropdown menu when it is initially rendered. Use when
30
+ * not wanting to control its open state.
31
+ *
32
+ * @default false
33
+ */
34
+ defaultOpen?: boolean;
35
+ /**
36
+ * The controlled open state of the dropdown menu. Must be used in conjunction
37
+ * with `onOpenChange`.
38
+ */
39
+ open?: boolean;
40
+ /**
41
+ * Event handler called when the open state of the dropdown menu changes.
42
+ */
43
+ onOpenChange?: ( open: boolean ) => void;
44
+ /**
45
+ * The modality of the dropdown menu. When set to true, interaction with
46
+ * outside elements will be disabled and only menu content will be visible to
47
+ * screen readers.
48
+ *
49
+ * @default true
50
+ */
51
+ modal?: boolean;
52
+ /**
53
+ * The placement of the dropdown menu popover.
54
+ *
55
+ * @default 'bottom-start' for root-level menus, 'right-start' for nested menus
56
+ */
57
+ placement?: Placement;
58
+ /**
59
+ * The distance between the popover and the anchor element.
60
+ *
61
+ * @default 8 for root-level menus, 16 for nested menus
62
+ */
63
+ gutter?: number;
64
+ /**
65
+ * The skidding of the popover along the anchor element. Can be set to
66
+ * negative values to make the popover shift to the opposite side.
67
+ *
68
+ * @default 0 for root-level menus, -8 for nested menus
69
+ */
70
+ shift?: number;
71
+ /**
72
+ * Determines whether the menu popover will be hidden when the user presses
73
+ * the Escape key.
74
+ *
75
+ * @default true
76
+ */
77
+ hideOnEscape?:
78
+ | boolean
79
+ | ( (
80
+ event: KeyboardEvent | React.KeyboardEvent< Element >
81
+ ) => boolean );
82
+ }
83
+
84
+ export interface DropdownMenuGroupProps {
85
+ /**
86
+ * The contents of the dropdown menu group.
87
+ */
88
+ children: React.ReactNode;
89
+ }
90
+
91
+ export interface DropdownMenuGroupLabelProps {
92
+ /**
93
+ * The contents of the dropdown menu group label.
94
+ */
95
+ children: React.ReactNode;
96
+ }
97
+
98
+ export interface DropdownMenuItemProps {
99
+ /**
100
+ * The contents of the menu item.
101
+ */
102
+ children: React.ReactNode;
103
+ /**
104
+ * The contents of the menu item's prefix.
105
+ */
106
+ prefix?: React.ReactNode;
107
+ /**
108
+ * The contents of the menu item's suffix.
109
+ */
110
+ suffix?: React.ReactNode;
111
+ /**
112
+ * Whether to hide the parent menu when the item is clicked.
113
+ *
114
+ * @default true
115
+ */
116
+ hideOnClick?: boolean;
117
+ /**
118
+ * Determines if the element is disabled.
119
+ */
120
+ disabled?: boolean;
121
+ }
122
+
123
+ export interface DropdownMenuCheckboxItemProps
124
+ extends Omit< DropdownMenuItemProps, 'prefix' | 'hideOnClick' > {
125
+ /**
126
+ * Whether to hide the dropdown menu when the item is clicked.
127
+ *
128
+ * @default false
129
+ */
130
+ hideOnClick?: boolean;
131
+ /**
132
+ * The checkbox menu item's name.
133
+ */
134
+ name: string;
135
+ /**
136
+ * The checkbox item's value, useful when using multiple checkbox menu items
137
+ * associated to the same `name`.
138
+ */
139
+ value?: string;
140
+ /**
141
+ * The controlled checked state of the checkbox menu item.
142
+ */
143
+ checked?: boolean;
144
+ /**
145
+ * The checked state of the checkbox menu item when it is initially rendered.
146
+ * Use when not wanting to control its checked state.
147
+ */
148
+ defaultChecked?: boolean;
149
+ /**
150
+ * Event handler called when the checked state of the checkbox menu item changes.
151
+ */
152
+ onChange?: ( event: React.ChangeEvent< HTMLInputElement > ) => void;
153
+ }
154
+
155
+ export interface DropdownMenuRadioItemProps
156
+ extends Omit< DropdownMenuItemProps, 'prefix' | 'hideOnClick' > {
157
+ /**
158
+ * Whether to hide the dropdown menu when the item is clicked.
159
+ *
160
+ * @default false
161
+ */
162
+ hideOnClick?: boolean;
163
+ /**
164
+ * The radio item's name.
165
+ */
166
+ name: string;
167
+ /**
168
+ * The radio item's value.
169
+ */
170
+ value: string | number;
171
+ /**
172
+ * The controlled checked state of the radio menu item.
173
+ */
174
+ checked?: boolean;
175
+ /**
176
+ * The checked state of the radio menu item when it is initially rendered.
177
+ * Use when not wanting to control its checked state.
178
+ */
179
+ defaultChecked?: boolean;
180
+ /**
181
+ * Event handler called when the checked radio menu item changes.
182
+ */
183
+ onChange?: ( event: React.ChangeEvent< HTMLInputElement > ) => void;
184
+ }
185
+
186
+ export interface DropdownMenuSeparatorProps {}
@@ -149,9 +149,9 @@ export const getSizeConfig = ( {
149
149
 
150
150
  if ( ! __next40pxDefaultSize ) {
151
151
  sizes.default = {
152
- height: 30,
152
+ height: 32,
153
153
  lineHeight: 1,
154
- minHeight: 30,
154
+ minHeight: 32,
155
155
  paddingLeft: space( 2 ),
156
156
  paddingRight: space( 2 ),
157
157
  };
@@ -9,7 +9,7 @@ import { Dimensions } from 'react-native';
9
9
  */
10
10
  import {
11
11
  getPxFromCssUnit,
12
- useSetting,
12
+ useSettings,
13
13
  useMultipleOriginColorsAndGradients,
14
14
  } from '@wordpress/block-editor';
15
15
 
@@ -357,7 +357,7 @@ export function useMobileGlobalStylesColors( type = 'colors' ) {
357
357
  // Default editor colors/gradients if it's not a block-based theme.
358
358
  const colorPalette =
359
359
  type === 'colors' ? 'color.palette' : 'color.gradients';
360
- const editorDefaultPalette = useSetting( colorPalette );
360
+ const [ editorDefaultPalette ] = useSettings( colorPalette );
361
361
 
362
362
  return availableThemeColors.length >= 1
363
363
  ? availableThemeColors
@@ -29,6 +29,15 @@ import {
29
29
  DropdownSubMenu as DropdownSubMenuV2,
30
30
  DropdownSubMenuTrigger as DropdownSubMenuTriggerV2,
31
31
  } from './dropdown-menu-v2';
32
+ import {
33
+ DropdownMenu as DropdownMenuV2Ariakit,
34
+ DropdownMenuGroup as DropdownMenuGroupV2Ariakit,
35
+ DropdownMenuGroupLabel as DropdownMenuGroupLabelV2Ariakit,
36
+ DropdownMenuItem as DropdownMenuItemV2Ariakit,
37
+ DropdownMenuCheckboxItem as DropdownMenuCheckboxItemV2Ariakit,
38
+ DropdownMenuRadioItem as DropdownMenuRadioItemV2Ariakit,
39
+ DropdownMenuSeparator as DropdownMenuSeparatorV2Ariakit,
40
+ } from './dropdown-menu-v2-ariakit';
32
41
  import { ComponentsContext } from './context/context-system-provider';
33
42
  import Theme from './theme';
34
43
  import Tabs from './tabs';
@@ -63,4 +72,11 @@ lock( privateApis, {
63
72
  ProgressBar,
64
73
  Tabs,
65
74
  Theme,
75
+ DropdownMenuV2Ariakit,
76
+ DropdownMenuGroupV2Ariakit,
77
+ DropdownMenuGroupLabelV2Ariakit,
78
+ DropdownMenuItemV2Ariakit,
79
+ DropdownMenuCheckboxItemV2Ariakit,
80
+ DropdownMenuRadioItemV2Ariakit,
81
+ DropdownMenuSeparatorV2Ariakit,
66
82
  } );
@@ -85,8 +85,8 @@ const sizeStyles = ( {
85
85
 
86
86
  if ( ! __next40pxDefaultSize ) {
87
87
  sizes.default = {
88
- height: 30,
89
- minHeight: 30,
88
+ height: 32,
89
+ minHeight: 32,
90
90
  paddingTop: 0,
91
91
  paddingBottom: 0,
92
92
  };
@@ -8,7 +8,7 @@ import * as Ariakit from '@ariakit/react';
8
8
  * WordPress dependencies
9
9
  */
10
10
  import { useInstanceId } from '@wordpress/compose';
11
- import { useEffect, useLayoutEffect, useRef } from '@wordpress/element';
11
+ import { useLayoutEffect, useRef } from '@wordpress/element';
12
12
 
13
13
  /**
14
14
  * Internal dependencies
@@ -104,7 +104,7 @@ function Tabs( {
104
104
  ] );
105
105
 
106
106
  // Handle the currently selected tab becoming disabled.
107
- useEffect( () => {
107
+ useLayoutEffect( () => {
108
108
  if ( ! selectedTab?.dimmed ) {
109
109
  return;
110
110
  }
@@ -136,7 +136,7 @@ function Tabs( {
136
136
  ] );
137
137
 
138
138
  // Clear `selectedId` if the active tab is removed from the DOM in controlled mode.
139
- useEffect( () => {
139
+ useLayoutEffect( () => {
140
140
  if ( ! isControlled ) {
141
141
  return;
142
142
  }
@@ -471,10 +471,13 @@ describe( 'Tabs', () => {
471
471
 
472
472
  // Because all other tabs should have `tabindex=-1`, pressing Tab
473
473
  // should NOT move the focus to the next tab, which is Beta.
474
+ // Instead, focus should go to the currently selected tabpanel (alpha).
474
475
  await user.keyboard( '[Tab]' );
475
476
  expect(
476
- await screen.findByRole( 'tab', { name: 'Beta' } )
477
- ).not.toHaveFocus();
477
+ await screen.findByRole( 'tabpanel', {
478
+ name: 'Alpha',
479
+ } )
480
+ ).toHaveFocus();
478
481
  } );
479
482
 
480
483
  it( 'switches to manual tab activation when the `selectOnMove` prop is set to `false`', async () => {
@@ -497,6 +500,9 @@ describe( 'Tabs', () => {
497
500
  // Click on Alpha and make sure it is selected.
498
501
  // onSelect shouldn't fire since the selected tab didn't change.
499
502
  await user.click( screen.getByRole( 'tab', { name: 'Alpha' } ) );
503
+ expect(
504
+ await screen.findByRole( 'tab', { name: 'Alpha' } )
505
+ ).toHaveFocus();
500
506
  expect( mockOnSelect ).toHaveBeenCalledTimes( 1 );
501
507
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'alpha' );
502
508
 
@@ -505,10 +511,10 @@ describe( 'Tabs', () => {
505
511
  // or enter key. onSelect shouldn't fire since the selected tab
506
512
  // didn't change.
507
513
  await user.keyboard( '[ArrowRight]' );
508
- expect( mockOnSelect ).toHaveBeenCalledTimes( 1 );
509
514
  expect(
510
515
  await screen.findByRole( 'tab', { name: 'Beta' } )
511
516
  ).toHaveFocus();
517
+ expect( mockOnSelect ).toHaveBeenCalledTimes( 1 );
512
518
 
513
519
  await user.keyboard( '[Enter]' );
514
520
  expect( mockOnSelect ).toHaveBeenCalledTimes( 2 );
@@ -519,6 +525,9 @@ describe( 'Tabs', () => {
519
525
  // spacebar or enter key. onSelect shouldn't fire since the selected
520
526
  // tab didn't change.
521
527
  await user.keyboard( '[ArrowRight]' );
528
+ expect(
529
+ await screen.findByRole( 'tab', { name: 'Gamma' } )
530
+ ).toHaveFocus();
522
531
  expect( mockOnSelect ).toHaveBeenCalledTimes( 2 );
523
532
  expect(
524
533
  screen.getByRole( 'tab', { name: 'Gamma' } )
@@ -256,6 +256,7 @@ exports[`ToggleGroupControl controlled should render correctly with icons 1`] =
256
256
  id="toggle-group-control-as-radio-group-8-20"
257
257
  role="radio"
258
258
  type="button"
259
+ value="uppercase"
259
260
  >
260
261
  <div
261
262
  class="emotion-13 emotion-14"
@@ -294,6 +295,7 @@ exports[`ToggleGroupControl controlled should render correctly with icons 1`] =
294
295
  id="toggle-group-control-as-radio-group-8-21"
295
296
  role="radio"
296
297
  type="button"
298
+ value="lowercase"
297
299
  >
298
300
  <div
299
301
  class="emotion-13 emotion-14"
@@ -503,6 +505,7 @@ exports[`ToggleGroupControl controlled should render correctly with text options
503
505
  id="toggle-group-control-as-radio-group-7-18"
504
506
  role="radio"
505
507
  type="button"
508
+ value="rigas"
506
509
  >
507
510
  <div
508
511
  class="emotion-13 emotion-14"
@@ -525,6 +528,7 @@ exports[`ToggleGroupControl controlled should render correctly with text options
525
528
  id="toggle-group-control-as-radio-group-7-19"
526
529
  role="radio"
527
530
  type="button"
531
+ value="jack"
528
532
  >
529
533
  <div
530
534
  class="emotion-13 emotion-14"
@@ -801,6 +805,7 @@ exports[`ToggleGroupControl uncontrolled should render correctly with icons 1`]
801
805
  id="toggle-group-control-as-radio-group-1-2"
802
806
  role="radio"
803
807
  type="button"
808
+ value="uppercase"
804
809
  >
805
810
  <div
806
811
  class="emotion-13 emotion-14"
@@ -839,6 +844,7 @@ exports[`ToggleGroupControl uncontrolled should render correctly with icons 1`]
839
844
  id="toggle-group-control-as-radio-group-1-3"
840
845
  role="radio"
841
846
  type="button"
847
+ value="lowercase"
842
848
  >
843
849
  <div
844
850
  class="emotion-13 emotion-14"
@@ -1042,6 +1048,7 @@ exports[`ToggleGroupControl uncontrolled should render correctly with text optio
1042
1048
  id="toggle-group-control-as-radio-group-0-0"
1043
1049
  role="radio"
1044
1050
  type="button"
1051
+ value="rigas"
1045
1052
  >
1046
1053
  <div
1047
1054
  class="emotion-13 emotion-14"
@@ -1064,6 +1071,7 @@ exports[`ToggleGroupControl uncontrolled should render correctly with text optio
1064
1071
  id="toggle-group-control-as-radio-group-0-1"
1065
1072
  role="radio"
1066
1073
  type="button"
1074
+ value="jack"
1067
1075
  >
1068
1076
  <div
1069
1077
  class="emotion-13 emotion-14"
@@ -69,8 +69,6 @@ function Tooltip( props: TooltipProps ) {
69
69
  timeout: delay,
70
70
  } );
71
71
 
72
- const isTooltipOpen = tooltipStore.useState( 'open' );
73
-
74
72
  return (
75
73
  <>
76
74
  <Ariakit.TooltipAnchor
@@ -80,8 +78,9 @@ function Tooltip( props: TooltipProps ) {
80
78
  >
81
79
  { isOnlyChild ? undefined : children }
82
80
  </Ariakit.TooltipAnchor>
83
- { isOnlyChild && ( text || shortcut ) && isTooltipOpen && (
81
+ { isOnlyChild && ( text || shortcut ) && (
84
82
  <Ariakit.Tooltip
83
+ unmountOnHide
85
84
  className="components-tooltip"
86
85
  gutter={ 4 }
87
86
  id={ describedById }