@wordpress/components 25.10.0 → 25.11.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 +16 -0
- package/build/autocomplete/index.js +104 -52
- package/build/autocomplete/index.js.map +1 -1
- package/build/dropdown-menu-v2-ariakit/index.js +217 -0
- package/build/dropdown-menu-v2-ariakit/index.js.map +1 -0
- package/build/dropdown-menu-v2-ariakit/styles.js +157 -0
- package/build/dropdown-menu-v2-ariakit/styles.js.map +1 -0
- package/build/dropdown-menu-v2-ariakit/types.js +6 -0
- package/build/dropdown-menu-v2-ariakit/types.js.map +1 -0
- package/build/input-control/styles/input-control-styles.js +23 -23
- package/build/input-control/styles/input-control-styles.js.map +1 -1
- package/build/mobile/global-styles-context/utils.native.js +1 -1
- package/build/mobile/global-styles-context/utils.native.js.map +1 -1
- package/build/private-apis.js +9 -1
- package/build/private-apis.js.map +1 -1
- package/build/select-control/styles/select-control-styles.js +8 -8
- package/build/select-control/styles/select-control-styles.js.map +1 -1
- package/build/slot-fill/bubbles-virtually/slot-fill-provider.js +1 -1
- package/build/slot-fill/bubbles-virtually/slot-fill-provider.js.map +1 -1
- package/build/tabs/index.js +2 -2
- package/build/tabs/index.js.map +1 -1
- package/build/tooltip/index.js +2 -2
- package/build/tooltip/index.js.map +1 -1
- package/build-module/autocomplete/index.js +104 -52
- package/build-module/autocomplete/index.js.map +1 -1
- package/build-module/dropdown-menu-v2-ariakit/index.js +199 -0
- package/build-module/dropdown-menu-v2-ariakit/index.js.map +1 -0
- package/build-module/dropdown-menu-v2-ariakit/styles.js +136 -0
- package/build-module/dropdown-menu-v2-ariakit/styles.js.map +1 -0
- package/build-module/dropdown-menu-v2-ariakit/types.js +2 -0
- package/build-module/dropdown-menu-v2-ariakit/types.js.map +1 -0
- package/build-module/input-control/styles/input-control-styles.js +23 -23
- package/build-module/input-control/styles/input-control-styles.js.map +1 -1
- package/build-module/mobile/global-styles-context/utils.native.js +2 -2
- package/build-module/mobile/global-styles-context/utils.native.js.map +1 -1
- package/build-module/private-apis.js +9 -1
- package/build-module/private-apis.js.map +1 -1
- package/build-module/select-control/styles/select-control-styles.js +8 -8
- package/build-module/select-control/styles/select-control-styles.js.map +1 -1
- package/build-module/slot-fill/bubbles-virtually/slot-fill-provider.js +1 -1
- package/build-module/slot-fill/bubbles-virtually/slot-fill-provider.js.map +1 -1
- package/build-module/tabs/index.js +3 -3
- package/build-module/tabs/index.js.map +1 -1
- package/build-module/tooltip/index.js +2 -2
- package/build-module/tooltip/index.js.map +1 -1
- package/build-style/style-rtl.css +1 -1
- package/build-style/style.css +1 -1
- package/build-types/autocomplete/index.d.ts.map +1 -1
- package/build-types/dropdown-menu-v2-ariakit/index.d.ts +11 -0
- package/build-types/dropdown-menu-v2-ariakit/index.d.ts.map +1 -0
- package/build-types/dropdown-menu-v2-ariakit/stories/index.story.d.ts +16 -0
- package/build-types/dropdown-menu-v2-ariakit/stories/index.story.d.ts.map +1 -0
- package/build-types/dropdown-menu-v2-ariakit/styles.d.ts +88 -0
- package/build-types/dropdown-menu-v2-ariakit/styles.d.ts.map +1 -0
- package/build-types/dropdown-menu-v2-ariakit/test/index.d.ts +2 -0
- package/build-types/dropdown-menu-v2-ariakit/test/index.d.ts.map +1 -0
- package/build-types/dropdown-menu-v2-ariakit/types.d.ts +174 -0
- package/build-types/dropdown-menu-v2-ariakit/types.d.ts.map +1 -0
- package/build-types/private-apis.d.ts.map +1 -1
- package/build-types/tooltip/index.d.ts.map +1 -1
- package/package.json +21 -20
- package/src/autocomplete/index.tsx +136 -77
- package/src/dimension-control/test/__snapshots__/index.test.js.snap +8 -8
- package/src/dropdown-menu-v2-ariakit/README.md +324 -0
- package/src/dropdown-menu-v2-ariakit/index.tsx +318 -0
- package/src/dropdown-menu-v2-ariakit/stories/index.story.tsx +506 -0
- package/src/dropdown-menu-v2-ariakit/styles.ts +297 -0
- package/src/dropdown-menu-v2-ariakit/test/index.tsx +1139 -0
- package/src/dropdown-menu-v2-ariakit/types.ts +186 -0
- package/src/input-control/styles/input-control-styles.tsx +2 -2
- package/src/mobile/global-styles-context/utils.native.js +2 -2
- package/src/private-apis.ts +16 -0
- package/src/select-control/styles/select-control-styles.ts +2 -2
- package/src/slot-fill/bubbles-virtually/slot-fill-provider.tsx +1 -1
- package/src/tabs/index.tsx +3 -3
- package/src/tabs/test/index.tsx +12 -3
- package/src/toggle-group-control/test/__snapshots__/index.tsx.snap +8 -0
- package/src/tooltip/index.tsx +2 -3
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type { Meta, StoryFn } from '@storybook/react';
|
|
5
|
+
import styled from '@emotion/styled';
|
|
6
|
+
import { css } from '@emotion/react';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* WordPress dependencies
|
|
10
|
+
*/
|
|
11
|
+
import { wordpress } from '@wordpress/icons';
|
|
12
|
+
import { useState, useMemo, useContext } from '@wordpress/element';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Internal dependencies
|
|
16
|
+
*/
|
|
17
|
+
import { COLORS, useCx } from '../../utils';
|
|
18
|
+
import {
|
|
19
|
+
DropdownMenu,
|
|
20
|
+
DropdownMenuItem,
|
|
21
|
+
DropdownMenuCheckboxItem,
|
|
22
|
+
DropdownMenuGroup,
|
|
23
|
+
DropdownMenuGroupLabel,
|
|
24
|
+
DropdownMenuSeparator,
|
|
25
|
+
DropdownMenuContext,
|
|
26
|
+
DropdownMenuRadioItem,
|
|
27
|
+
} from '..';
|
|
28
|
+
import Icon from '../../icon';
|
|
29
|
+
import Button from '../../button';
|
|
30
|
+
import Modal from '../../modal';
|
|
31
|
+
import { createSlotFill, Provider as SlotFillProvider } from '../../slot-fill';
|
|
32
|
+
import { ContextSystemProvider } from '../../context';
|
|
33
|
+
|
|
34
|
+
const meta: Meta< typeof DropdownMenu > = {
|
|
35
|
+
title: 'Components (Experimental)/DropdownMenu v2 ariakit',
|
|
36
|
+
component: DropdownMenu,
|
|
37
|
+
subcomponents: {
|
|
38
|
+
// @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170
|
|
39
|
+
DropdownMenuItem,
|
|
40
|
+
},
|
|
41
|
+
argTypes: {
|
|
42
|
+
children: { control: { type: null } },
|
|
43
|
+
},
|
|
44
|
+
parameters: {
|
|
45
|
+
actions: { argTypesRegex: '^on.*' },
|
|
46
|
+
controls: { expanded: true },
|
|
47
|
+
docs: {
|
|
48
|
+
canvas: { sourceState: 'shown' },
|
|
49
|
+
source: { excludeDecorators: true },
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
decorators: [
|
|
53
|
+
// Layout wrapper
|
|
54
|
+
( Story ) => (
|
|
55
|
+
<div
|
|
56
|
+
style={ {
|
|
57
|
+
minHeight: '300px',
|
|
58
|
+
} }
|
|
59
|
+
>
|
|
60
|
+
<Story />
|
|
61
|
+
</div>
|
|
62
|
+
),
|
|
63
|
+
],
|
|
64
|
+
};
|
|
65
|
+
export default meta;
|
|
66
|
+
|
|
67
|
+
const ItemHelpText = styled.span`
|
|
68
|
+
font-size: 12px;
|
|
69
|
+
color: ${ COLORS.gray[ '700' ] };
|
|
70
|
+
|
|
71
|
+
/* when the immediate parent item is hovered / focused */
|
|
72
|
+
[data-active-item] > * > &,
|
|
73
|
+
/* when the parent item is a submenu trigger and the submenu is open */
|
|
74
|
+
[aria-expanded='true'] > &,
|
|
75
|
+
/* when the parent item is disabled */
|
|
76
|
+
[aria-disabled='true'] > & {
|
|
77
|
+
color: inherit;
|
|
78
|
+
}
|
|
79
|
+
`;
|
|
80
|
+
|
|
81
|
+
export const Default: StoryFn< typeof DropdownMenu > = ( props ) => (
|
|
82
|
+
<DropdownMenu { ...props }>
|
|
83
|
+
<DropdownMenuItem>Default item</DropdownMenuItem>
|
|
84
|
+
<DropdownMenuItem hideOnClick={ false }>
|
|
85
|
+
<div
|
|
86
|
+
style={ {
|
|
87
|
+
display: 'inline-flex',
|
|
88
|
+
flexDirection: 'column',
|
|
89
|
+
} }
|
|
90
|
+
>
|
|
91
|
+
Other item
|
|
92
|
+
<ItemHelpText>
|
|
93
|
+
Won't close the menu when clicked
|
|
94
|
+
</ItemHelpText>
|
|
95
|
+
</div>
|
|
96
|
+
</DropdownMenuItem>
|
|
97
|
+
<DropdownMenuItem disabled>Disabled item</DropdownMenuItem>
|
|
98
|
+
<DropdownMenuSeparator />
|
|
99
|
+
<DropdownMenuGroup>
|
|
100
|
+
<DropdownMenuGroupLabel>Prefix and suffix</DropdownMenuGroupLabel>
|
|
101
|
+
<DropdownMenuItem
|
|
102
|
+
prefix={ <Icon icon={ wordpress } size={ 24 } /> }
|
|
103
|
+
>
|
|
104
|
+
With prefix
|
|
105
|
+
</DropdownMenuItem>
|
|
106
|
+
<DropdownMenuItem suffix={ <span>⌘S</span> }>
|
|
107
|
+
With suffix
|
|
108
|
+
</DropdownMenuItem>
|
|
109
|
+
<DropdownMenuItem
|
|
110
|
+
disabled
|
|
111
|
+
prefix={ <Icon icon={ wordpress } size={ 24 } /> }
|
|
112
|
+
suffix={ <span>⌥⌘T</span> }
|
|
113
|
+
>
|
|
114
|
+
Disabled with prefix and suffix
|
|
115
|
+
</DropdownMenuItem>
|
|
116
|
+
</DropdownMenuGroup>
|
|
117
|
+
</DropdownMenu>
|
|
118
|
+
);
|
|
119
|
+
Default.args = {
|
|
120
|
+
trigger: (
|
|
121
|
+
<Button __next40pxDefaultSize variant="secondary">
|
|
122
|
+
Open menu
|
|
123
|
+
</Button>
|
|
124
|
+
),
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
export const WithSubmenu: StoryFn< typeof DropdownMenu > = ( props ) => (
|
|
128
|
+
<DropdownMenu { ...props }>
|
|
129
|
+
<DropdownMenuItem>Level 1 item</DropdownMenuItem>
|
|
130
|
+
<DropdownMenu
|
|
131
|
+
trigger={ <DropdownMenuItem>Submenu trigger</DropdownMenuItem> }
|
|
132
|
+
>
|
|
133
|
+
<DropdownMenuItem>Level 2 item</DropdownMenuItem>
|
|
134
|
+
<DropdownMenuItem>Level 2 item</DropdownMenuItem>
|
|
135
|
+
<DropdownMenu
|
|
136
|
+
trigger={ <DropdownMenuItem>Submenu trigger</DropdownMenuItem> }
|
|
137
|
+
>
|
|
138
|
+
<DropdownMenuItem>Level 3 item</DropdownMenuItem>
|
|
139
|
+
<DropdownMenuItem>Level 3 item</DropdownMenuItem>
|
|
140
|
+
</DropdownMenu>
|
|
141
|
+
</DropdownMenu>
|
|
142
|
+
</DropdownMenu>
|
|
143
|
+
);
|
|
144
|
+
WithSubmenu.args = {
|
|
145
|
+
...Default.args,
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export const WithCheckboxes: StoryFn< typeof DropdownMenu > = ( props ) => {
|
|
149
|
+
const [ isAChecked, setAChecked ] = useState( false );
|
|
150
|
+
const [ isBChecked, setBChecked ] = useState( true );
|
|
151
|
+
const [ multipleCheckboxesValue, setMultipleCheckboxesValue ] = useState<
|
|
152
|
+
string[]
|
|
153
|
+
>( [ 'b' ] );
|
|
154
|
+
|
|
155
|
+
const onMultipleCheckboxesCheckedChange: React.ComponentProps<
|
|
156
|
+
typeof DropdownMenuCheckboxItem
|
|
157
|
+
>[ 'onChange' ] = ( e ) => {
|
|
158
|
+
setMultipleCheckboxesValue( ( prevValues ) => {
|
|
159
|
+
if ( prevValues.includes( e.target.value ) ) {
|
|
160
|
+
return prevValues.filter( ( val ) => val !== e.target.value );
|
|
161
|
+
}
|
|
162
|
+
return [ ...prevValues, e.target.value ];
|
|
163
|
+
} );
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
return (
|
|
167
|
+
<DropdownMenu { ...props }>
|
|
168
|
+
<DropdownMenuGroup>
|
|
169
|
+
<DropdownMenuGroupLabel>
|
|
170
|
+
Individual, uncontrolled checkboxes
|
|
171
|
+
</DropdownMenuGroupLabel>
|
|
172
|
+
<DropdownMenuCheckboxItem
|
|
173
|
+
name="checkbox-individual-uncontrolled-a"
|
|
174
|
+
value="a"
|
|
175
|
+
>
|
|
176
|
+
Checkbox item A (initially unchecked)
|
|
177
|
+
</DropdownMenuCheckboxItem>
|
|
178
|
+
<DropdownMenuCheckboxItem
|
|
179
|
+
name="checkbox-individual-uncontrolled-b"
|
|
180
|
+
value="b"
|
|
181
|
+
defaultChecked
|
|
182
|
+
>
|
|
183
|
+
Checkbox item B (initially checked)
|
|
184
|
+
</DropdownMenuCheckboxItem>
|
|
185
|
+
</DropdownMenuGroup>
|
|
186
|
+
<DropdownMenuSeparator />
|
|
187
|
+
<DropdownMenuGroup>
|
|
188
|
+
<DropdownMenuGroupLabel>
|
|
189
|
+
Individual, controlled checkboxes
|
|
190
|
+
</DropdownMenuGroupLabel>
|
|
191
|
+
<DropdownMenuCheckboxItem
|
|
192
|
+
name="checkbox-individual-controlled-a"
|
|
193
|
+
value="a"
|
|
194
|
+
checked={ isAChecked }
|
|
195
|
+
onChange={ ( e ) => setAChecked( e.target.checked ) }
|
|
196
|
+
>
|
|
197
|
+
Checkbox item A
|
|
198
|
+
</DropdownMenuCheckboxItem>
|
|
199
|
+
<DropdownMenuCheckboxItem
|
|
200
|
+
name="checkbox-individual-controlled-b"
|
|
201
|
+
value="b"
|
|
202
|
+
checked={ isBChecked }
|
|
203
|
+
onChange={ ( e ) => setBChecked( e.target.checked ) }
|
|
204
|
+
>
|
|
205
|
+
Checkbox item B (initially checked)
|
|
206
|
+
</DropdownMenuCheckboxItem>
|
|
207
|
+
</DropdownMenuGroup>
|
|
208
|
+
<DropdownMenuSeparator />
|
|
209
|
+
<DropdownMenuGroup>
|
|
210
|
+
<DropdownMenuGroupLabel>
|
|
211
|
+
Multiple, uncontrolled checkboxes
|
|
212
|
+
</DropdownMenuGroupLabel>
|
|
213
|
+
<DropdownMenuCheckboxItem
|
|
214
|
+
name="checkbox-multiple-uncontrolled"
|
|
215
|
+
value="a"
|
|
216
|
+
>
|
|
217
|
+
Checkbox item A (initially unchecked)
|
|
218
|
+
</DropdownMenuCheckboxItem>
|
|
219
|
+
<DropdownMenuCheckboxItem
|
|
220
|
+
name="checkbox-multiple-uncontrolled"
|
|
221
|
+
value="b"
|
|
222
|
+
defaultChecked
|
|
223
|
+
>
|
|
224
|
+
Checkbox item B (initially checked)
|
|
225
|
+
</DropdownMenuCheckboxItem>
|
|
226
|
+
</DropdownMenuGroup>
|
|
227
|
+
<DropdownMenuSeparator />
|
|
228
|
+
<DropdownMenuGroup>
|
|
229
|
+
<DropdownMenuGroupLabel>
|
|
230
|
+
Multiple, controlled checkboxes
|
|
231
|
+
</DropdownMenuGroupLabel>
|
|
232
|
+
<DropdownMenuCheckboxItem
|
|
233
|
+
name="checkbox-multiple-controlled"
|
|
234
|
+
value="a"
|
|
235
|
+
checked={ multipleCheckboxesValue.includes( 'a' ) }
|
|
236
|
+
onChange={ onMultipleCheckboxesCheckedChange }
|
|
237
|
+
>
|
|
238
|
+
Checkbox item A (initially unchecked)
|
|
239
|
+
</DropdownMenuCheckboxItem>
|
|
240
|
+
<DropdownMenuCheckboxItem
|
|
241
|
+
name="checkbox-multiple-controlled"
|
|
242
|
+
value="b"
|
|
243
|
+
checked={ multipleCheckboxesValue.includes( 'b' ) }
|
|
244
|
+
onChange={ onMultipleCheckboxesCheckedChange }
|
|
245
|
+
>
|
|
246
|
+
Checkbox item B (initially checked)
|
|
247
|
+
</DropdownMenuCheckboxItem>
|
|
248
|
+
</DropdownMenuGroup>
|
|
249
|
+
</DropdownMenu>
|
|
250
|
+
);
|
|
251
|
+
};
|
|
252
|
+
WithCheckboxes.args = {
|
|
253
|
+
...Default.args,
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
export const WithRadios: StoryFn< typeof DropdownMenu > = ( props ) => {
|
|
257
|
+
const [ radioValue, setRadioValue ] = useState( 'two' );
|
|
258
|
+
const onRadioChange: React.ComponentProps<
|
|
259
|
+
typeof DropdownMenuRadioItem
|
|
260
|
+
>[ 'onChange' ] = ( e ) => setRadioValue( e.target.value );
|
|
261
|
+
|
|
262
|
+
return (
|
|
263
|
+
<DropdownMenu { ...props }>
|
|
264
|
+
<DropdownMenuGroup>
|
|
265
|
+
<DropdownMenuGroupLabel>
|
|
266
|
+
Uncontrolled radios
|
|
267
|
+
</DropdownMenuGroupLabel>
|
|
268
|
+
<DropdownMenuRadioItem name="radio-uncontrolled" value="one">
|
|
269
|
+
Radio item 1
|
|
270
|
+
</DropdownMenuRadioItem>
|
|
271
|
+
<DropdownMenuRadioItem
|
|
272
|
+
name="radio-uncontrolled"
|
|
273
|
+
value="two"
|
|
274
|
+
defaultChecked
|
|
275
|
+
>
|
|
276
|
+
Radio item 2 (initially checked)
|
|
277
|
+
</DropdownMenuRadioItem>
|
|
278
|
+
</DropdownMenuGroup>
|
|
279
|
+
<DropdownMenuSeparator />
|
|
280
|
+
<DropdownMenuGroup>
|
|
281
|
+
<DropdownMenuGroupLabel>
|
|
282
|
+
Controlled radios
|
|
283
|
+
</DropdownMenuGroupLabel>
|
|
284
|
+
<DropdownMenuRadioItem
|
|
285
|
+
name="radio-controlled"
|
|
286
|
+
value="one"
|
|
287
|
+
checked={ radioValue === 'one' }
|
|
288
|
+
onChange={ onRadioChange }
|
|
289
|
+
>
|
|
290
|
+
Radio item 1
|
|
291
|
+
</DropdownMenuRadioItem>
|
|
292
|
+
<DropdownMenuRadioItem
|
|
293
|
+
name="radio-controlled"
|
|
294
|
+
value="two"
|
|
295
|
+
checked={ radioValue === 'two' }
|
|
296
|
+
onChange={ onRadioChange }
|
|
297
|
+
>
|
|
298
|
+
Radio item 2 (initially checked)
|
|
299
|
+
</DropdownMenuRadioItem>
|
|
300
|
+
</DropdownMenuGroup>
|
|
301
|
+
</DropdownMenu>
|
|
302
|
+
);
|
|
303
|
+
};
|
|
304
|
+
WithRadios.args = {
|
|
305
|
+
...Default.args,
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
const modalOnTopOfDropdown = css`
|
|
309
|
+
&& {
|
|
310
|
+
z-index: 1000000;
|
|
311
|
+
}
|
|
312
|
+
`;
|
|
313
|
+
|
|
314
|
+
// For more examples with `Modal`, check https://ariakit.org/examples/menu-wordpress-modal
|
|
315
|
+
export const WithModals: StoryFn< typeof DropdownMenu > = ( props ) => {
|
|
316
|
+
const [ isOuterModalOpen, setOuterModalOpen ] = useState( false );
|
|
317
|
+
const [ isInnerModalOpen, setInnerModalOpen ] = useState( false );
|
|
318
|
+
|
|
319
|
+
const cx = useCx();
|
|
320
|
+
const modalOverlayClassName = cx( modalOnTopOfDropdown );
|
|
321
|
+
|
|
322
|
+
return (
|
|
323
|
+
<>
|
|
324
|
+
<DropdownMenu { ...props }>
|
|
325
|
+
<DropdownMenuItem
|
|
326
|
+
onClick={ () => setOuterModalOpen( true ) }
|
|
327
|
+
hideOnClick={ false }
|
|
328
|
+
>
|
|
329
|
+
Open outer modal
|
|
330
|
+
</DropdownMenuItem>
|
|
331
|
+
<DropdownMenuItem
|
|
332
|
+
onClick={ () => setInnerModalOpen( true ) }
|
|
333
|
+
hideOnClick={ false }
|
|
334
|
+
>
|
|
335
|
+
Open inner modal
|
|
336
|
+
</DropdownMenuItem>
|
|
337
|
+
{ isInnerModalOpen && (
|
|
338
|
+
<Modal
|
|
339
|
+
onRequestClose={ () => setInnerModalOpen( false ) }
|
|
340
|
+
overlayClassName={ modalOverlayClassName }
|
|
341
|
+
>
|
|
342
|
+
Modal's contents
|
|
343
|
+
<button onClick={ () => setInnerModalOpen( false ) }>
|
|
344
|
+
Close
|
|
345
|
+
</button>
|
|
346
|
+
</Modal>
|
|
347
|
+
) }
|
|
348
|
+
</DropdownMenu>
|
|
349
|
+
{ isOuterModalOpen && (
|
|
350
|
+
<Modal
|
|
351
|
+
onRequestClose={ () => setOuterModalOpen( false ) }
|
|
352
|
+
overlayClassName={ modalOverlayClassName }
|
|
353
|
+
>
|
|
354
|
+
Modal's contents
|
|
355
|
+
<button onClick={ () => setOuterModalOpen( false ) }>
|
|
356
|
+
Close
|
|
357
|
+
</button>
|
|
358
|
+
</Modal>
|
|
359
|
+
) }
|
|
360
|
+
</>
|
|
361
|
+
);
|
|
362
|
+
};
|
|
363
|
+
WithModals.args = {
|
|
364
|
+
...Default.args,
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
const ExampleSlotFill = createSlotFill( 'Example' );
|
|
368
|
+
|
|
369
|
+
const Slot = () => {
|
|
370
|
+
const dropdownMenuContext = useContext( DropdownMenuContext );
|
|
371
|
+
|
|
372
|
+
// Forwarding the content of the slot so that it can be used by the fill
|
|
373
|
+
const fillProps = useMemo(
|
|
374
|
+
() => ( {
|
|
375
|
+
forwardedContext: [
|
|
376
|
+
[
|
|
377
|
+
DropdownMenuContext.Provider,
|
|
378
|
+
{ value: dropdownMenuContext },
|
|
379
|
+
],
|
|
380
|
+
],
|
|
381
|
+
} ),
|
|
382
|
+
[ dropdownMenuContext ]
|
|
383
|
+
);
|
|
384
|
+
|
|
385
|
+
return <ExampleSlotFill.Slot fillProps={ fillProps } bubblesVirtually />;
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
type ForwardedContextTuple< P = {} > = [
|
|
389
|
+
React.ComponentType< React.PropsWithChildren< P > >,
|
|
390
|
+
P,
|
|
391
|
+
];
|
|
392
|
+
|
|
393
|
+
const Fill = ( { children }: { children: React.ReactNode } ) => {
|
|
394
|
+
const innerMarkup = <>{ children }</>;
|
|
395
|
+
|
|
396
|
+
return (
|
|
397
|
+
<ExampleSlotFill.Fill>
|
|
398
|
+
{ ( fillProps: { forwardedContext?: ForwardedContextTuple[] } ) => {
|
|
399
|
+
const { forwardedContext = [] } = fillProps;
|
|
400
|
+
|
|
401
|
+
return forwardedContext.reduce(
|
|
402
|
+
( inner: JSX.Element, [ Provider, props ] ) => (
|
|
403
|
+
<Provider { ...props }>{ inner }</Provider>
|
|
404
|
+
),
|
|
405
|
+
innerMarkup
|
|
406
|
+
);
|
|
407
|
+
} }
|
|
408
|
+
</ExampleSlotFill.Fill>
|
|
409
|
+
);
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
export const WithSlotFill: StoryFn< typeof DropdownMenu > = ( props ) => {
|
|
413
|
+
return (
|
|
414
|
+
<SlotFillProvider>
|
|
415
|
+
<DropdownMenu { ...props }>
|
|
416
|
+
<DropdownMenuItem>Item</DropdownMenuItem>
|
|
417
|
+
<Slot />
|
|
418
|
+
</DropdownMenu>
|
|
419
|
+
|
|
420
|
+
<Fill>
|
|
421
|
+
<DropdownMenuItem>Item from fill</DropdownMenuItem>
|
|
422
|
+
<DropdownMenu
|
|
423
|
+
trigger={
|
|
424
|
+
<DropdownMenuItem>Submenu from fill</DropdownMenuItem>
|
|
425
|
+
}
|
|
426
|
+
>
|
|
427
|
+
<DropdownMenuItem>Submenu item from fill</DropdownMenuItem>
|
|
428
|
+
</DropdownMenu>
|
|
429
|
+
</Fill>
|
|
430
|
+
</SlotFillProvider>
|
|
431
|
+
);
|
|
432
|
+
};
|
|
433
|
+
WithSlotFill.args = {
|
|
434
|
+
...Default.args,
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
const toolbarVariantContextValue = {
|
|
438
|
+
DropdownMenu: {
|
|
439
|
+
variant: 'toolbar',
|
|
440
|
+
},
|
|
441
|
+
};
|
|
442
|
+
export const ToolbarVariant: StoryFn< typeof DropdownMenu > = ( props ) => (
|
|
443
|
+
<ContextSystemProvider value={ toolbarVariantContextValue }>
|
|
444
|
+
<DropdownMenu { ...props }>
|
|
445
|
+
<DropdownMenuItem>Level 1 item</DropdownMenuItem>
|
|
446
|
+
<DropdownMenuItem>Level 1 item</DropdownMenuItem>
|
|
447
|
+
<DropdownMenuSeparator />
|
|
448
|
+
<DropdownMenu
|
|
449
|
+
trigger={ <DropdownMenuItem>Submenu trigger</DropdownMenuItem> }
|
|
450
|
+
>
|
|
451
|
+
<DropdownMenuItem>Level 2 item</DropdownMenuItem>
|
|
452
|
+
</DropdownMenu>
|
|
453
|
+
</DropdownMenu>
|
|
454
|
+
</ContextSystemProvider>
|
|
455
|
+
);
|
|
456
|
+
ToolbarVariant.args = {
|
|
457
|
+
...Default.args,
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
export const InsideModal: StoryFn< typeof DropdownMenu > = ( props ) => {
|
|
461
|
+
const [ isModalOpen, setModalOpen ] = useState( false );
|
|
462
|
+
return (
|
|
463
|
+
<>
|
|
464
|
+
<Button
|
|
465
|
+
onClick={ () => setModalOpen( true ) }
|
|
466
|
+
__next40pxDefaultSize
|
|
467
|
+
variant="secondary"
|
|
468
|
+
>
|
|
469
|
+
Open modal
|
|
470
|
+
</Button>
|
|
471
|
+
{ isModalOpen && (
|
|
472
|
+
<Modal onRequestClose={ () => setModalOpen( false ) }>
|
|
473
|
+
<DropdownMenu { ...props }>
|
|
474
|
+
<DropdownMenuItem>Level 1 item</DropdownMenuItem>
|
|
475
|
+
<DropdownMenuItem>Level 1 item</DropdownMenuItem>
|
|
476
|
+
<DropdownMenuSeparator />
|
|
477
|
+
<DropdownMenu
|
|
478
|
+
trigger={
|
|
479
|
+
<DropdownMenuItem>
|
|
480
|
+
Submenu trigger
|
|
481
|
+
</DropdownMenuItem>
|
|
482
|
+
}
|
|
483
|
+
>
|
|
484
|
+
<DropdownMenuItem>Level 2 item</DropdownMenuItem>
|
|
485
|
+
</DropdownMenu>
|
|
486
|
+
</DropdownMenu>
|
|
487
|
+
<Button onClick={ () => setModalOpen( false ) }>
|
|
488
|
+
Close modal
|
|
489
|
+
</Button>
|
|
490
|
+
</Modal>
|
|
491
|
+
) }
|
|
492
|
+
</>
|
|
493
|
+
);
|
|
494
|
+
};
|
|
495
|
+
InsideModal.args = {
|
|
496
|
+
...Default.args,
|
|
497
|
+
hideOnEscape: ( e ) => {
|
|
498
|
+
e.stopPropagation();
|
|
499
|
+
return true;
|
|
500
|
+
},
|
|
501
|
+
};
|
|
502
|
+
InsideModal.parameters = {
|
|
503
|
+
docs: {
|
|
504
|
+
source: { type: 'code' },
|
|
505
|
+
},
|
|
506
|
+
};
|