@wordpress/components 24.0.0 → 25.0.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.
- package/CHANGELOG.md +26 -0
- package/CONTRIBUTING.md +10 -0
- package/build/color-picker/styles.js +8 -8
- package/build/color-picker/styles.js.map +1 -1
- package/build/date-time/date-time/index.js +3 -84
- package/build/date-time/date-time/index.js.map +1 -1
- package/build/date-time/date-time/styles.js +4 -19
- package/build/date-time/date-time/styles.js.map +1 -1
- package/build/dropdown-menu/index.js +87 -11
- package/build/dropdown-menu/index.js.map +1 -1
- package/build/dropdown-menu/types.js +6 -0
- package/build/dropdown-menu/types.js.map +1 -0
- package/build/dropdown-menu-v2/index.js +195 -0
- package/build/dropdown-menu-v2/index.js.map +1 -0
- package/build/dropdown-menu-v2/styles.js +176 -0
- package/build/dropdown-menu-v2/styles.js.map +1 -0
- package/build/dropdown-menu-v2/types.js +6 -0
- package/build/dropdown-menu-v2/types.js.map +1 -0
- package/build/index.native.js +0 -9
- package/build/index.native.js.map +1 -1
- package/build/input-control/styles/input-control-styles.js +30 -23
- package/build/input-control/styles/input-control-styles.js.map +1 -1
- package/build/mobile/bottom-sheet/cell.native.js +16 -8
- package/build/mobile/bottom-sheet/cell.native.js.map +1 -1
- package/build/mobile/bottom-sheet/range-cell.native.js +3 -2
- package/build/mobile/bottom-sheet/range-cell.native.js.map +1 -1
- package/build/mobile/bottom-sheet/stepper-cell/index.native.js +4 -2
- package/build/mobile/bottom-sheet/stepper-cell/index.native.js.map +1 -1
- package/build/mobile/bottom-sheet/switch-cell.native.js +8 -2
- package/build/mobile/bottom-sheet/switch-cell.native.js.map +1 -1
- package/build/mobile/bottom-sheet-select-control/index.native.js +4 -2
- package/build/mobile/bottom-sheet-select-control/index.native.js.map +1 -1
- package/build/mobile/bottom-sheet-text-control/index.native.js +4 -2
- package/build/mobile/bottom-sheet-text-control/index.native.js.map +1 -1
- package/build/modal/index.js +1 -2
- package/build/modal/index.js.map +1 -1
- package/build/private-apis.js +13 -1
- package/build/private-apis.js.map +1 -1
- package/build/range-control/index.native.js +5 -2
- package/build/range-control/index.native.js.map +1 -1
- package/build/snackbar/list.js +0 -2
- package/build/snackbar/list.js.map +1 -1
- package/build/toggle-group-control/toggle-group-control/styles.js +7 -7
- package/build/toggle-group-control/toggle-group-control/styles.js.map +1 -1
- package/build-module/color-picker/styles.js +8 -8
- package/build-module/color-picker/styles.js.map +1 -1
- package/build-module/date-time/date-time/index.js +6 -81
- package/build-module/date-time/date-time/index.js.map +1 -1
- package/build-module/date-time/date-time/styles.js +3 -17
- package/build-module/date-time/date-time/styles.js.map +1 -1
- package/build-module/dropdown-menu/index.js +87 -10
- package/build-module/dropdown-menu/index.js.map +1 -1
- package/build-module/dropdown-menu/types.js +2 -0
- package/build-module/dropdown-menu/types.js.map +1 -0
- package/build-module/dropdown-menu-v2/index.js +149 -0
- package/build-module/dropdown-menu-v2/index.js.map +1 -0
- package/build-module/dropdown-menu-v2/styles.js +153 -0
- package/build-module/dropdown-menu-v2/styles.js.map +1 -0
- package/build-module/dropdown-menu-v2/types.js +2 -0
- package/build-module/dropdown-menu-v2/types.js.map +1 -0
- package/build-module/index.native.js +0 -1
- package/build-module/index.native.js.map +1 -1
- package/build-module/input-control/styles/input-control-styles.js +30 -23
- package/build-module/input-control/styles/input-control-styles.js.map +1 -1
- package/build-module/mobile/bottom-sheet/cell.native.js +16 -8
- package/build-module/mobile/bottom-sheet/cell.native.js.map +1 -1
- package/build-module/mobile/bottom-sheet/range-cell.native.js +3 -2
- package/build-module/mobile/bottom-sheet/range-cell.native.js.map +1 -1
- package/build-module/mobile/bottom-sheet/stepper-cell/index.native.js +4 -2
- package/build-module/mobile/bottom-sheet/stepper-cell/index.native.js.map +1 -1
- package/build-module/mobile/bottom-sheet/switch-cell.native.js +7 -2
- package/build-module/mobile/bottom-sheet/switch-cell.native.js.map +1 -1
- package/build-module/mobile/bottom-sheet-select-control/index.native.js +4 -2
- package/build-module/mobile/bottom-sheet-select-control/index.native.js.map +1 -1
- package/build-module/mobile/bottom-sheet-text-control/index.native.js +4 -2
- package/build-module/mobile/bottom-sheet-text-control/index.native.js.map +1 -1
- package/build-module/modal/index.js +1 -2
- package/build-module/modal/index.js.map +1 -1
- package/build-module/private-apis.js +12 -1
- package/build-module/private-apis.js.map +1 -1
- package/build-module/range-control/index.native.js +5 -2
- package/build-module/range-control/index.native.js.map +1 -1
- package/build-module/snackbar/list.js +0 -2
- package/build-module/snackbar/list.js.map +1 -1
- package/build-module/toggle-group-control/toggle-group-control/styles.js +7 -7
- package/build-module/toggle-group-control/toggle-group-control/styles.js.map +1 -1
- package/build-style/style-rtl.css +11 -14
- package/build-style/style.css +11 -14
- package/build-types/color-picker/styles.d.ts.map +1 -1
- package/build-types/date-time/date-time/index.d.ts +3 -4
- package/build-types/date-time/date-time/index.d.ts.map +1 -1
- package/build-types/date-time/date-time/styles.d.ts +0 -4
- package/build-types/date-time/date-time/styles.d.ts.map +1 -1
- package/build-types/date-time/stories/date-time.d.ts.map +1 -1
- package/build-types/date-time/types.d.ts +0 -14
- package/build-types/date-time/types.d.ts.map +1 -1
- package/build-types/dropdown-menu/index.d.ts +83 -1
- package/build-types/dropdown-menu/index.d.ts.map +1 -1
- package/build-types/dropdown-menu/stories/index.d.ts +13 -0
- package/build-types/dropdown-menu/stories/index.d.ts.map +1 -0
- package/build-types/dropdown-menu/test/index.d.ts +2 -0
- package/build-types/dropdown-menu/test/index.d.ts.map +1 -0
- package/build-types/dropdown-menu/types.d.ts +134 -0
- package/build-types/dropdown-menu/types.d.ts.map +1 -0
- package/build-types/dropdown-menu-v2/index.d.ts +17 -0
- package/build-types/dropdown-menu-v2/index.d.ts.map +1 -0
- package/build-types/dropdown-menu-v2/stories/index.d.ts +13 -0
- package/build-types/dropdown-menu-v2/stories/index.d.ts.map +1 -0
- package/build-types/dropdown-menu-v2/styles.d.ts +41 -0
- package/build-types/dropdown-menu-v2/styles.d.ts.map +1 -0
- package/build-types/dropdown-menu-v2/test/index.d.ts +2 -0
- package/build-types/dropdown-menu-v2/test/index.d.ts.map +1 -0
- package/build-types/dropdown-menu-v2/types.d.ts +242 -0
- package/build-types/dropdown-menu-v2/types.d.ts.map +1 -0
- package/build-types/input-control/styles/input-control-styles.d.ts.map +1 -1
- package/build-types/modal/index.d.ts.map +1 -1
- package/build-types/private-apis.d.ts.map +1 -1
- package/build-types/snackbar/list.d.ts.map +1 -1
- package/build-types/toggle-group-control/toggle-group-control/styles.d.ts.map +1 -1
- package/build-types/toolbar/stories/index.d.ts.map +1 -1
- package/build-types/ui/context/get-styled-class-name-from-key.d.ts +1 -10
- package/build-types/ui/context/get-styled-class-name-from-key.d.ts.map +1 -1
- package/package.json +21 -20
- package/src/button/style.scss +5 -12
- package/src/color-picker/styles.ts +7 -2
- package/src/date-time/README.md +0 -16
- package/src/date-time/date-time/index.tsx +17 -155
- package/src/date-time/date-time/styles.ts +0 -4
- package/src/date-time/stories/date-time.tsx +0 -4
- package/src/date-time/types.ts +0 -16
- package/src/dropdown-menu/README.md +12 -22
- package/src/dropdown-menu/{index.js → index.tsx} +111 -25
- package/src/dropdown-menu/stories/{index.js → index.tsx} +14 -22
- package/src/dropdown-menu/test/{index.js → index.tsx} +6 -5
- package/src/dropdown-menu/types.ts +143 -0
- package/src/dropdown-menu-v2/README.md +392 -0
- package/src/dropdown-menu-v2/index.tsx +241 -0
- package/src/dropdown-menu-v2/stories/index.tsx +193 -0
- package/src/dropdown-menu-v2/styles.ts +263 -0
- package/src/dropdown-menu-v2/test/index.tsx +816 -0
- package/src/dropdown-menu-v2/types.ts +250 -0
- package/src/index.native.js +0 -1
- package/src/input-control/styles/input-control-styles.tsx +7 -0
- package/src/mobile/bottom-sheet/cell.native.js +26 -5
- package/src/mobile/bottom-sheet/range-cell.native.js +2 -1
- package/src/mobile/bottom-sheet/stepper-cell/index.native.js +2 -0
- package/src/mobile/bottom-sheet/styles.native.scss +13 -1
- package/src/mobile/bottom-sheet/switch-cell.native.js +10 -2
- package/src/mobile/bottom-sheet-select-control/index.native.js +2 -0
- package/src/mobile/bottom-sheet-text-control/index.native.js +2 -0
- package/src/modal/index.tsx +1 -6
- package/src/private-apis.ts +22 -0
- package/src/range-control/index.native.js +3 -0
- package/src/search-control/style.scss +2 -0
- package/src/snackbar/list.tsx +0 -1
- package/src/toggle-group-control/test/__snapshots__/index.tsx.snap +6 -2
- package/src/toggle-group-control/toggle-group-control/styles.ts +6 -1
- package/src/toolbar/stories/index.tsx +25 -28
- package/src/tooltip/style.scss +2 -2
- package/tsconfig.tsbuildinfo +1 -1
- package/build/mobile/readable-content-view/index.native.js +0 -97
- package/build/mobile/readable-content-view/index.native.js.map +0 -1
- package/build-module/mobile/readable-content-view/index.native.js +0 -81
- package/build-module/mobile/readable-content-view/index.native.js.map +0 -1
- package/src/mobile/readable-content-view/index.native.js +0 -85
- package/src/mobile/readable-content-view/style.native.scss +0 -30
|
@@ -52,10 +52,6 @@ const Template: ComponentStory< typeof DateTimePicker > = ( {
|
|
|
52
52
|
export const Default: ComponentStory< typeof DateTimePicker > = Template.bind(
|
|
53
53
|
{}
|
|
54
54
|
);
|
|
55
|
-
Default.args = {
|
|
56
|
-
__nextRemoveHelpButton: true,
|
|
57
|
-
__nextRemoveResetButton: true,
|
|
58
|
-
};
|
|
59
55
|
|
|
60
56
|
export const WithEvents: ComponentStory< typeof DateTimePicker > =
|
|
61
57
|
Template.bind( {} );
|
package/src/date-time/types.ts
CHANGED
|
@@ -73,20 +73,4 @@ export type DateTimePickerProps = Omit< DatePickerProps, 'onChange' > &
|
|
|
73
73
|
* passed the date and time as an argument.
|
|
74
74
|
*/
|
|
75
75
|
onChange?: ( date: string | null ) => void;
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Start opting in to not displaying a Help button which will become the
|
|
79
|
-
* default in a future version.
|
|
80
|
-
*
|
|
81
|
-
* @default false
|
|
82
|
-
*/
|
|
83
|
-
__nextRemoveHelpButton?: boolean;
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Start opting in to not displaying a Reset button which will become
|
|
87
|
-
* the default in a future version.
|
|
88
|
-
*
|
|
89
|
-
* @default false
|
|
90
|
-
*/
|
|
91
|
-
__nextRemoveResetButton?: boolean;
|
|
92
76
|
};
|
|
@@ -131,80 +131,70 @@ const MyDropdownMenu = () => (
|
|
|
131
131
|
|
|
132
132
|
The component accepts the following props:
|
|
133
133
|
|
|
134
|
-
#### icon
|
|
134
|
+
#### `icon`: `string | null`
|
|
135
135
|
|
|
136
136
|
The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug to be shown in the collapsed menu button.
|
|
137
137
|
|
|
138
|
-
- Type: `String|null`
|
|
139
138
|
- Required: No
|
|
140
139
|
- Default: `"menu"`
|
|
141
140
|
|
|
142
141
|
See also: [https://developer.wordpress.org/resource/dashicons/](https://developer.wordpress.org/resource/dashicons/)
|
|
143
142
|
|
|
144
|
-
#### label
|
|
143
|
+
#### `label`: `string`
|
|
145
144
|
|
|
146
145
|
A human-readable label to present as accessibility text on the focused collapsed menu button.
|
|
147
146
|
|
|
148
|
-
- Type: `String`
|
|
149
147
|
- Required: Yes
|
|
150
148
|
|
|
151
|
-
#### controls
|
|
149
|
+
#### `controls:` `DropdownOption[] | DropdownOption[][]`
|
|
152
150
|
|
|
153
|
-
An array of objects describing the options to be shown in the expanded menu.
|
|
151
|
+
An array or nested array of objects describing the options to be shown in the expanded menu.
|
|
154
152
|
|
|
155
153
|
Each object should include an `icon` [Dashicon](https://developer.wordpress.org/resource/dashicons/) slug string, a human-readable `title` string, `isDisabled` boolean flag and an `onClick` function callback to invoke when the option is selected.
|
|
156
154
|
|
|
157
|
-
A valid DropdownMenu must specify
|
|
158
|
-
|
|
159
|
-
- Type: `Array`
|
|
155
|
+
A valid DropdownMenu must specify a `controls` or `children` prop, or both.
|
|
160
156
|
- Required: No
|
|
161
157
|
|
|
162
|
-
#### children
|
|
158
|
+
#### `children`: `( callbackProps: DropdownCallbackProps ) => ReactNode`
|
|
163
159
|
|
|
164
160
|
A [function render prop](https://reactjs.org/docs/render-props.html#using-props-other-than-render) which should return an element or elements valid for use in a DropdownMenu: `MenuItem`, `MenuItemsChoice`, or `MenuGroup`. Its first argument is a props object including the same values as given to a [`Dropdown`'s `renderContent`](/packages/components/src/dropdown#rendercontent) (`isOpen`, `onToggle`, `onClose`).
|
|
165
161
|
|
|
166
|
-
A valid DropdownMenu must specify
|
|
162
|
+
A valid DropdownMenu must specify a `controls` or `children` prop, or both.
|
|
167
163
|
|
|
168
|
-
- Type: `Function`
|
|
169
164
|
- Required: No
|
|
170
165
|
|
|
171
166
|
See also: [https://developer.wordpress.org/resource/dashicons/](https://developer.wordpress.org/resource/dashicons/)
|
|
172
167
|
|
|
173
|
-
#### className
|
|
168
|
+
#### `className`: `string`
|
|
174
169
|
|
|
175
170
|
A class name to apply to the dropdown menu's toggle element wrapper.
|
|
176
171
|
|
|
177
|
-
- Type: `String`
|
|
178
172
|
- Required: No
|
|
179
173
|
|
|
180
|
-
#### popoverProps
|
|
174
|
+
#### `popoverProps`: `DropdownProps[ 'popoverProps' ]`
|
|
181
175
|
|
|
182
176
|
Properties of `popoverProps` object will be passed as props to the nested `Popover` component.
|
|
183
177
|
Use this object to modify props available for the `Popover` component that are not already exposed in the `DropdownMenu` component, e.g.: the direction in which the popover should open relative to its parent node set with `position` prop.
|
|
184
178
|
|
|
185
|
-
- Type: `Object`
|
|
186
179
|
- Required: No
|
|
187
180
|
|
|
188
|
-
#### toggleProps
|
|
181
|
+
#### `toggleProps`: `ToggleProps`
|
|
189
182
|
|
|
190
183
|
Properties of `toggleProps` object will be passed as props to the nested `Button` component in the `renderToggle` implementation of the `Dropdown` component used internally.
|
|
191
184
|
Use this object to modify props available for the `Button` component that are not already exposed in the `DropdownMenu` component, e.g.: the tooltip text displayed on hover set with `tooltip` prop.
|
|
192
185
|
|
|
193
|
-
- Type: `Object`
|
|
194
186
|
- Required: No
|
|
195
187
|
|
|
196
|
-
#### menuProps
|
|
188
|
+
#### `menuProps`: `NavigableContainerProps`
|
|
197
189
|
|
|
198
190
|
Properties of `menuProps` object will be passed as props to the nested `NavigableMenu` component in the `renderContent` implementation of the `Dropdown` component used internally.
|
|
199
191
|
Use this object to modify props available for the `NavigableMenu` component that are not already exposed in the `DropdownMenu` component, e.g.: the orientation of the menu set with `orientation` prop.
|
|
200
192
|
|
|
201
|
-
- Type: `Object`
|
|
202
193
|
- Required: No
|
|
203
194
|
|
|
204
|
-
#### disableOpenOnArrowDown
|
|
195
|
+
#### `disableOpenOnArrowDown`: `boolean`
|
|
205
196
|
|
|
206
197
|
In some contexts, the arrow down key used to open the dropdown menu might need to be disabled—for example when that key is used to perform another action.
|
|
207
198
|
|
|
208
|
-
- Type: `boolean`
|
|
209
199
|
- Required: No
|
|
210
200
|
- Default: `false`
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
1
|
/**
|
|
3
2
|
* External dependencies
|
|
4
3
|
*/
|
|
@@ -15,9 +14,12 @@ import { menu } from '@wordpress/icons';
|
|
|
15
14
|
import Button from '../button';
|
|
16
15
|
import Dropdown from '../dropdown';
|
|
17
16
|
import { NavigableMenu } from '../navigable-container';
|
|
17
|
+
import type { DropdownMenuProps, DropdownOption } from './types';
|
|
18
18
|
|
|
19
|
-
function mergeProps
|
|
20
|
-
|
|
19
|
+
function mergeProps<
|
|
20
|
+
T extends { className?: string; [ key: string ]: unknown }
|
|
21
|
+
>( defaultProps: Partial< T > = {}, props: T = {} as T ) {
|
|
22
|
+
const mergedProps: T = {
|
|
21
23
|
...defaultProps,
|
|
22
24
|
...props,
|
|
23
25
|
};
|
|
@@ -32,17 +34,92 @@ function mergeProps( defaultProps = {}, props = {} ) {
|
|
|
32
34
|
return mergedProps;
|
|
33
35
|
}
|
|
34
36
|
|
|
37
|
+
function isFunction( maybeFunc: unknown ): maybeFunc is () => void {
|
|
38
|
+
return typeof maybeFunc === 'function';
|
|
39
|
+
}
|
|
40
|
+
|
|
35
41
|
/**
|
|
36
|
-
* Whether the argument is a function.
|
|
37
42
|
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
43
|
+
* The DropdownMenu displays a list of actions (each contained in a MenuItem,
|
|
44
|
+
* MenuItemsChoice, or MenuGroup) in a compact way. It appears in a Popover
|
|
45
|
+
* after the user has interacted with an element (a button or icon) or when
|
|
46
|
+
* they perform a specific action.
|
|
47
|
+
*
|
|
48
|
+
* Render a Dropdown Menu with a set of controls:
|
|
49
|
+
*
|
|
50
|
+
* ```jsx
|
|
51
|
+
* import { DropdownMenu } from '@wordpress/components';
|
|
52
|
+
* import {
|
|
53
|
+
* more,
|
|
54
|
+
* arrowLeft,
|
|
55
|
+
* arrowRight,
|
|
56
|
+
* arrowUp,
|
|
57
|
+
* arrowDown,
|
|
58
|
+
* } from '@wordpress/icons';
|
|
59
|
+
*
|
|
60
|
+
* const MyDropdownMenu = () => (
|
|
61
|
+
* <DropdownMenu
|
|
62
|
+
* icon={ more }
|
|
63
|
+
* label="Select a direction"
|
|
64
|
+
* controls={ [
|
|
65
|
+
* {
|
|
66
|
+
* title: 'Up',
|
|
67
|
+
* icon: arrowUp,
|
|
68
|
+
* onClick: () => console.log( 'up' ),
|
|
69
|
+
* },
|
|
70
|
+
* {
|
|
71
|
+
* title: 'Right',
|
|
72
|
+
* icon: arrowRight,
|
|
73
|
+
* onClick: () => console.log( 'right' ),
|
|
74
|
+
* },
|
|
75
|
+
* {
|
|
76
|
+
* title: 'Down',
|
|
77
|
+
* icon: arrowDown,
|
|
78
|
+
* onClick: () => console.log( 'down' ),
|
|
79
|
+
* },
|
|
80
|
+
* {
|
|
81
|
+
* title: 'Left',
|
|
82
|
+
* icon: arrowLeft,
|
|
83
|
+
* onClick: () => console.log( 'left' ),
|
|
84
|
+
* },
|
|
85
|
+
* ] }
|
|
86
|
+
* />
|
|
87
|
+
* );
|
|
88
|
+
* ```
|
|
89
|
+
*
|
|
90
|
+
* Alternatively, specify a `children` function which returns elements valid for
|
|
91
|
+
* use in a DropdownMenu: `MenuItem`, `MenuItemsChoice`, or `MenuGroup`.
|
|
92
|
+
*
|
|
93
|
+
* ```jsx
|
|
94
|
+
* import { DropdownMenu, MenuGroup, MenuItem } from '@wordpress/components';
|
|
95
|
+
* import { more, arrowUp, arrowDown, trash } from '@wordpress/icons';
|
|
96
|
+
*
|
|
97
|
+
* const MyDropdownMenu = () => (
|
|
98
|
+
* <DropdownMenu icon={ more } label="Select a direction">
|
|
99
|
+
* { ( { onClose } ) => (
|
|
100
|
+
* <>
|
|
101
|
+
* <MenuGroup>
|
|
102
|
+
* <MenuItem icon={ arrowUp } onClick={ onClose }>
|
|
103
|
+
* Move Up
|
|
104
|
+
* </MenuItem>
|
|
105
|
+
* <MenuItem icon={ arrowDown } onClick={ onClose }>
|
|
106
|
+
* Move Down
|
|
107
|
+
* </MenuItem>
|
|
108
|
+
* </MenuGroup>
|
|
109
|
+
* <MenuGroup>
|
|
110
|
+
* <MenuItem icon={ trash } onClick={ onClose }>
|
|
111
|
+
* Remove
|
|
112
|
+
* </MenuItem>
|
|
113
|
+
* </MenuGroup>
|
|
114
|
+
* </>
|
|
115
|
+
* ) }
|
|
116
|
+
* </DropdownMenu>
|
|
117
|
+
* );
|
|
118
|
+
* ```
|
|
119
|
+
*
|
|
40
120
|
*/
|
|
41
|
-
function isFunction( maybeFunc ) {
|
|
42
|
-
return typeof maybeFunc === 'function';
|
|
43
|
-
}
|
|
44
121
|
|
|
45
|
-
function DropdownMenu( dropdownMenuProps ) {
|
|
122
|
+
function DropdownMenu( dropdownMenuProps: DropdownMenuProps ) {
|
|
46
123
|
const {
|
|
47
124
|
children,
|
|
48
125
|
className,
|
|
@@ -62,13 +139,18 @@ function DropdownMenu( dropdownMenuProps ) {
|
|
|
62
139
|
}
|
|
63
140
|
|
|
64
141
|
// Normalize controls to nested array of objects (sets of controls)
|
|
65
|
-
let controlSets;
|
|
142
|
+
let controlSets: DropdownOption[][];
|
|
66
143
|
if ( controls?.length ) {
|
|
144
|
+
// @ts-expect-error The check below is needed because `DropdownMenus`
|
|
145
|
+
// rendered by `ToolBarGroup` receive controls as a nested array.
|
|
67
146
|
controlSets = controls;
|
|
68
147
|
if ( ! Array.isArray( controlSets[ 0 ] ) ) {
|
|
69
|
-
|
|
148
|
+
// This is not ideal, but at this point we know that `controls` is
|
|
149
|
+
// not a nested array, even if TypeScript doesn't.
|
|
150
|
+
controlSets = [ controls as DropdownOption[] ];
|
|
70
151
|
}
|
|
71
152
|
}
|
|
153
|
+
|
|
72
154
|
const mergedPopoverProps = mergeProps(
|
|
73
155
|
{
|
|
74
156
|
className: 'components-dropdown-menu__popover',
|
|
@@ -81,7 +163,7 @@ function DropdownMenu( dropdownMenuProps ) {
|
|
|
81
163
|
className={ classnames( 'components-dropdown-menu', className ) }
|
|
82
164
|
popoverProps={ mergedPopoverProps }
|
|
83
165
|
renderToggle={ ( { isOpen, onToggle } ) => {
|
|
84
|
-
const openOnArrowDown = ( event ) => {
|
|
166
|
+
const openOnArrowDown = ( event: React.KeyboardEvent ) => {
|
|
85
167
|
if ( disableOpenOnArrowDown ) {
|
|
86
168
|
return;
|
|
87
169
|
}
|
|
@@ -110,18 +192,22 @@ function DropdownMenu( dropdownMenuProps ) {
|
|
|
110
192
|
<Toggle
|
|
111
193
|
{ ...mergedToggleProps }
|
|
112
194
|
icon={ icon }
|
|
113
|
-
onClick={
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
mergedToggleProps.onClick
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
195
|
+
onClick={
|
|
196
|
+
( ( event ) => {
|
|
197
|
+
onToggle();
|
|
198
|
+
if ( mergedToggleProps.onClick ) {
|
|
199
|
+
mergedToggleProps.onClick( event );
|
|
200
|
+
}
|
|
201
|
+
} ) as React.MouseEventHandler< HTMLButtonElement >
|
|
202
|
+
}
|
|
203
|
+
onKeyDown={
|
|
204
|
+
( ( event ) => {
|
|
205
|
+
openOnArrowDown( event );
|
|
206
|
+
if ( mergedToggleProps.onKeyDown ) {
|
|
207
|
+
mergedToggleProps.onKeyDown( event );
|
|
208
|
+
}
|
|
209
|
+
} ) as React.KeyboardEventHandler< HTMLButtonElement >
|
|
210
|
+
}
|
|
125
211
|
aria-haspopup="true"
|
|
126
212
|
aria-expanded={ isOpen }
|
|
127
213
|
label={ label }
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type { ComponentMeta, ComponentStory } from '@storybook/react';
|
|
1
5
|
/**
|
|
2
6
|
* Internal dependencies
|
|
3
7
|
*/
|
|
4
|
-
import DropdownMenu from '
|
|
5
|
-
import
|
|
8
|
+
import DropdownMenu from '..';
|
|
9
|
+
import MenuItem from '../../menu-item';
|
|
10
|
+
import MenuGroup from '../../menu-group';
|
|
6
11
|
|
|
7
12
|
/**
|
|
8
13
|
* WordPress dependencies
|
|
@@ -16,37 +21,24 @@ import {
|
|
|
16
21
|
trash,
|
|
17
22
|
} from '@wordpress/icons';
|
|
18
23
|
|
|
19
|
-
|
|
24
|
+
const meta: ComponentMeta< typeof DropdownMenu > = {
|
|
20
25
|
title: 'Components/DropdownMenu',
|
|
21
26
|
component: DropdownMenu,
|
|
27
|
+
parameters: {
|
|
28
|
+
controls: { expanded: true },
|
|
29
|
+
docs: { source: { state: 'open' } },
|
|
30
|
+
},
|
|
22
31
|
argTypes: {
|
|
23
|
-
className: { control: { type: 'text' } },
|
|
24
|
-
children: { control: { type: null } },
|
|
25
|
-
disableOpenOnArrowDown: { control: { type: 'boolean' } },
|
|
26
32
|
icon: {
|
|
27
33
|
options: [ 'menu', 'chevronDown', 'more' ],
|
|
28
34
|
mapping: { menu, chevronDown, more },
|
|
29
35
|
control: { type: 'select' },
|
|
30
36
|
},
|
|
31
|
-
menuProps: {
|
|
32
|
-
control: { type: 'object' },
|
|
33
|
-
},
|
|
34
|
-
noIcons: { control: { type: 'boolean' } },
|
|
35
|
-
popoverProps: {
|
|
36
|
-
control: { type: 'object' },
|
|
37
|
-
},
|
|
38
|
-
text: { control: { type: 'text' } },
|
|
39
|
-
toggleProps: {
|
|
40
|
-
control: { type: 'object' },
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
parameters: {
|
|
44
|
-
controls: { expanded: true },
|
|
45
|
-
docs: { source: { state: 'open' } },
|
|
46
37
|
},
|
|
47
38
|
};
|
|
39
|
+
export default meta;
|
|
48
40
|
|
|
49
|
-
const Template = ( props ) => (
|
|
41
|
+
const Template: ComponentStory< typeof DropdownMenu > = ( props ) => (
|
|
50
42
|
<div style={ { height: 150 } }>
|
|
51
43
|
<DropdownMenu { ...props } />
|
|
52
44
|
</div>
|
|
@@ -12,19 +12,19 @@ import { arrowLeft, arrowRight, arrowUp, arrowDown } from '@wordpress/icons';
|
|
|
12
12
|
/**
|
|
13
13
|
* Internal dependencies
|
|
14
14
|
*/
|
|
15
|
-
import DropdownMenu from '
|
|
16
|
-
import
|
|
15
|
+
import DropdownMenu from '..';
|
|
16
|
+
import MenuItem from '../../menu-item';
|
|
17
17
|
|
|
18
18
|
describe( 'DropdownMenu', () => {
|
|
19
19
|
it( 'should not render when neither controls nor children are assigned', () => {
|
|
20
|
-
render( <DropdownMenu /> );
|
|
20
|
+
render( <DropdownMenu label="Open dropdown" /> );
|
|
21
21
|
|
|
22
22
|
// The button toggle should not even be rendered
|
|
23
23
|
expect( screen.queryByRole( 'button' ) ).not.toBeInTheDocument();
|
|
24
24
|
} );
|
|
25
25
|
|
|
26
26
|
it( 'should not render when controls are empty and children is not specified', () => {
|
|
27
|
-
render( <DropdownMenu controls={ [] } /> );
|
|
27
|
+
render( <DropdownMenu label="Open dropdown" controls={ [] } /> );
|
|
28
28
|
|
|
29
29
|
// The button toggle should not even be rendered
|
|
30
30
|
expect( screen.queryByRole( 'button' ) ).not.toBeInTheDocument();
|
|
@@ -56,7 +56,7 @@ describe( 'DropdownMenu', () => {
|
|
|
56
56
|
},
|
|
57
57
|
];
|
|
58
58
|
|
|
59
|
-
render( <DropdownMenu controls={ controls } /> );
|
|
59
|
+
render( <DropdownMenu label="Open dropdown" controls={ controls } /> );
|
|
60
60
|
|
|
61
61
|
// Move focus on the toggle button
|
|
62
62
|
await user.tab();
|
|
@@ -78,6 +78,7 @@ describe( 'DropdownMenu', () => {
|
|
|
78
78
|
|
|
79
79
|
render(
|
|
80
80
|
<DropdownMenu
|
|
81
|
+
label="Open dropdown"
|
|
81
82
|
children={ ( { onClose } ) => <MenuItem onClick={ onClose } /> }
|
|
82
83
|
/>
|
|
83
84
|
);
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type { ReactNode } from 'react';
|
|
5
|
+
/**
|
|
6
|
+
* Internal dependencies
|
|
7
|
+
*/
|
|
8
|
+
import type { ButtonAsButtonProps } from '../button/types';
|
|
9
|
+
import type { WordPressComponentProps } from '../ui/context';
|
|
10
|
+
import type { DropdownProps } from '../dropdown/types';
|
|
11
|
+
import type { Props as IconProps } from '../icon';
|
|
12
|
+
import type { NavigableMenuProps } from '../navigable-container/types';
|
|
13
|
+
|
|
14
|
+
export type DropdownOption = {
|
|
15
|
+
/**
|
|
16
|
+
* The Dashicon icon slug to be shown for the option.
|
|
17
|
+
*/
|
|
18
|
+
icon?: IconProps[ 'icon' ];
|
|
19
|
+
/**
|
|
20
|
+
* A human-readable title to display for the option.
|
|
21
|
+
*/
|
|
22
|
+
title: string;
|
|
23
|
+
/**
|
|
24
|
+
* Whether or not the option is disabled.
|
|
25
|
+
*
|
|
26
|
+
* @default false
|
|
27
|
+
*/
|
|
28
|
+
isDisabled?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* A callback function to invoke when the option is selected.
|
|
31
|
+
*/
|
|
32
|
+
onClick?: () => void;
|
|
33
|
+
/**
|
|
34
|
+
* Whether or not the control is currently active.
|
|
35
|
+
*/
|
|
36
|
+
isActive?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Text to use for the internal `Button` component's tooltip.
|
|
39
|
+
*/
|
|
40
|
+
label?: string;
|
|
41
|
+
/**
|
|
42
|
+
* The role to apply to the option's HTML element
|
|
43
|
+
*/
|
|
44
|
+
role?: HTMLElement[ 'role' ];
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
type DropdownCallbackProps = {
|
|
48
|
+
isOpen: boolean;
|
|
49
|
+
onToggle: () => void;
|
|
50
|
+
onClose: () => void;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// Manually including `as` prop because `WordPressComponentProps` polymorhpism
|
|
54
|
+
// creates a union that is too large for TypeScript to handle.
|
|
55
|
+
type ToggleProps = Partial<
|
|
56
|
+
Omit<
|
|
57
|
+
WordPressComponentProps< ButtonAsButtonProps, 'button', false >,
|
|
58
|
+
'label' | 'text'
|
|
59
|
+
>
|
|
60
|
+
> & {
|
|
61
|
+
as?: React.ElementType | keyof JSX.IntrinsicElements;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export type DropdownMenuProps = {
|
|
65
|
+
/**
|
|
66
|
+
* The Dashicon icon slug to be shown in the collapsed menu button.
|
|
67
|
+
*
|
|
68
|
+
* @default "menu"
|
|
69
|
+
*/
|
|
70
|
+
icon?: IconProps[ 'icon' ] | null;
|
|
71
|
+
/**
|
|
72
|
+
* A human-readable label to present as accessibility text on the focused
|
|
73
|
+
* collapsed menu button.
|
|
74
|
+
*/
|
|
75
|
+
label: string;
|
|
76
|
+
/**
|
|
77
|
+
* A class name to apply to the dropdown menu's toggle element wrapper.
|
|
78
|
+
*/
|
|
79
|
+
className?: string;
|
|
80
|
+
/**
|
|
81
|
+
* Properties of `popoverProps` object will be passed as props to the nested
|
|
82
|
+
* `Popover` component.
|
|
83
|
+
* Use this object to modify props available for the `Popover` component that
|
|
84
|
+
* are not already exposed in the `DropdownMenu` component, e.g.: the
|
|
85
|
+
* direction in which the popover should open relative to its parent node
|
|
86
|
+
* set with `position` prop.
|
|
87
|
+
*/
|
|
88
|
+
popoverProps?: DropdownProps[ 'popoverProps' ];
|
|
89
|
+
/**
|
|
90
|
+
* Properties of `toggleProps` object will be passed as props to the nested
|
|
91
|
+
* `Button` component in the `renderToggle` implementation of the `Dropdown`
|
|
92
|
+
* component used internally.
|
|
93
|
+
* Use this object to modify props available for the `Button` component that
|
|
94
|
+
* are not already exposed in the `DropdownMenu` component, e.g.: the tooltip
|
|
95
|
+
* text displayed on hover set with `tooltip` prop.
|
|
96
|
+
*/
|
|
97
|
+
toggleProps?: ToggleProps;
|
|
98
|
+
/**
|
|
99
|
+
* Properties of `menuProps` object will be passed as props to the nested
|
|
100
|
+
* `NavigableMenu` component in the `renderContent` implementation of the
|
|
101
|
+
* `Dropdown` component used internally.
|
|
102
|
+
* Use this object to modify props available for the `NavigableMenu`
|
|
103
|
+
* component that are not already exposed in the `DropdownMenu` component,
|
|
104
|
+
* e.g.: the orientation of the menu set with `orientation` prop.
|
|
105
|
+
*/
|
|
106
|
+
menuProps?: Omit< Partial< NavigableMenuProps >, 'children' >;
|
|
107
|
+
/**
|
|
108
|
+
* In some contexts, the arrow down key used to open the dropdown menu might
|
|
109
|
+
* need to be disabled—for example when that key is used to perform another
|
|
110
|
+
* action.
|
|
111
|
+
*
|
|
112
|
+
* @default false
|
|
113
|
+
*/
|
|
114
|
+
disableOpenOnArrowDown?: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Text to display on the nested `Button` component in the `renderToggle`
|
|
117
|
+
* implementation of the `Dropdown` component used internally.
|
|
118
|
+
*/
|
|
119
|
+
text?: string;
|
|
120
|
+
/**
|
|
121
|
+
* Whether or not `no-icons` should be added to the menu's `className`.
|
|
122
|
+
*/
|
|
123
|
+
noIcons?: boolean;
|
|
124
|
+
/**
|
|
125
|
+
* A [function render prop](https://reactjs.org/docs/render-props.html#using-props-other-than-render)
|
|
126
|
+
* which should return an element or elements valid for use in a DropdownMenu:
|
|
127
|
+
* `MenuItem`, `MenuItemsChoice`, or `MenuGroup`. Its first argument is a
|
|
128
|
+
* props object including the same values as given to a `Dropdown`'s
|
|
129
|
+
* `renderContent` (`isOpen`, `onToggle`, `onClose`).
|
|
130
|
+
*
|
|
131
|
+
* A valid DropdownMenu must specify a `controls` or `children` prop, or both.
|
|
132
|
+
*/
|
|
133
|
+
children?: ( callbackProps: DropdownCallbackProps ) => ReactNode;
|
|
134
|
+
/**
|
|
135
|
+
* An array or nested array of objects describing the options to be shown in
|
|
136
|
+
* the expanded menu. Each object should include an `icon` Dashicon slug
|
|
137
|
+
* string, a human-readable `title` string, `isDisabled` boolean flag, and
|
|
138
|
+
* an `onClick` function callback to invoke when the option is selected.
|
|
139
|
+
*
|
|
140
|
+
* A valid DropdownMenu must specify a `controls` or `children` prop, or both.
|
|
141
|
+
*/
|
|
142
|
+
controls?: DropdownOption[] | DropdownOption[][];
|
|
143
|
+
};
|