Skip to content

Commit 08d6dee

Browse files
authored
feat(dropdowns.next): add refactored menu component (#1623)
1 parent 7b6a9d8 commit 08d6dee

31 files changed

+1849
-237
lines changed

packages/dropdowns.next/.size-snapshot.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
{
22
"index.cjs.js": {
3-
"bundled": 56744,
4-
"minified": 40969,
5-
"gzipped": 9399
3+
"bundled": 72908,
4+
"minified": 51748,
5+
"gzipped": 11329
66
},
77
"index.esm.js": {
8-
"bundled": 52071,
9-
"minified": 36540,
10-
"gzipped": 8815,
8+
"bundled": 66868,
9+
"minified": 45956,
10+
"gzipped": 10695,
1111
"treeshaked": {
1212
"rollup": {
13-
"code": 28825,
14-
"import_statements": 1064
13+
"code": 36151,
14+
"import_statements": 1174
1515
},
1616
"webpack": {
17-
"code": 31754
17+
"code": 39814
1818
}
1919
}
2020
}

packages/dropdowns.next/demo/menu.stories

Lines changed: 0 additions & 22 deletions
This file was deleted.
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { Meta, ArgsTable, Canvas, Story, Markdown } from '@storybook/addon-docs';
2+
import { useArgs } from '@storybook/client-api';
3+
import { Menu, Item, ItemGroup, Separator } from '@zendeskgarden/react-dropdowns.next';
4+
import { MenuStory } from './stories/MenuStory';
5+
import README from '../README.md';
6+
import { ITEMS } from './stories/data';
7+
8+
<Meta
9+
title="Packages/Dropdowns.Next/Menu"
10+
component={Menu}
11+
subcomponents={{ Item, 'Item.Meta': Item.Meta, Separator, ItemGroup }}
12+
argTypes={{
13+
appendToNode: { control: false }
14+
}}
15+
args={{
16+
button: 'Menu',
17+
items: ITEMS,
18+
placement: Menu.defaultProps.placement,
19+
maxHeight: Menu.defaultProps.maxHeight,
20+
zIndex: Menu.defaultProps.zIndex
21+
}}
22+
/>
23+
24+
# API
25+
26+
<ArgsTable />
27+
28+
# Uncontrolled
29+
30+
<Canvas>
31+
<Story
32+
name="Uncontrolled"
33+
argTypes={{
34+
isExpanded: { control: false },
35+
focusedValue: { control: false },
36+
selectedItems: { control: false }
37+
}}
38+
>
39+
{args => <MenuStory {...args} />}
40+
</Story>
41+
</Canvas>
42+
43+
# Controlled
44+
45+
<Canvas>
46+
<Story
47+
name="Controlled"
48+
argTypes={{
49+
defaultExpanded: { control: false },
50+
defaultFocusedValue: { control: false },
51+
focusedValue: { control: { type: 'text' } }
52+
}}
53+
args={{
54+
isExpanded: false,
55+
focusedValue: null,
56+
selectedItems: [{ value: 'aster', type: 'checkbox' }]
57+
}}
58+
>
59+
{args => {
60+
const updateArgs = useArgs()[1];
61+
const handleChange = changes => {
62+
const { type, ...rest } = changes;
63+
updateArgs(rest);
64+
};
65+
return <MenuStory {...args} onChange={handleChange} />;
66+
}}
67+
</Story>
68+
</Canvas>
69+
70+
<Markdown>{README}</Markdown>

packages/dropdowns.next/demo/stories/MenuStory

Lines changed: 0 additions & 38 deletions
This file was deleted.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* Copyright Zendesk, Inc.
3+
*
4+
* Use of this source code is governed under the Apache License, Version 2.0
5+
* found at http://www.apache.org/licenses/LICENSE-2.0.
6+
*/
7+
8+
import React from 'react';
9+
import { StoryFn } from '@storybook/react';
10+
import LeafIcon from '@zendeskgarden/svg-icons/src/16/leaf-stroke.svg';
11+
import CartIcon from '@zendeskgarden/svg-icons/src/16/shopping-cart-stroke.svg';
12+
import { Col, Grid, Row } from '@zendeskgarden/react-grid';
13+
import { IMenuProps, Item, ItemGroup, Separator, Menu } from '@zendeskgarden/react-dropdowns.next';
14+
import { IItem, Items } from './types';
15+
16+
const MenuItem = ({ icon, meta, ...item }: IItem) => {
17+
return (
18+
<Item {...item} icon={icon ? <LeafIcon /> : undefined}>
19+
{item.label}
20+
{meta && <Item.Meta>{meta}</Item.Meta>}
21+
</Item>
22+
);
23+
};
24+
25+
interface IArgs extends IMenuProps {
26+
items: Items;
27+
}
28+
29+
export const MenuStory: StoryFn<IArgs> = ({ items, ...args }) => {
30+
return (
31+
<Grid>
32+
<Row justifyContent="center" style={{ height: 800 }}>
33+
<Col alignSelf="center" textAlign="center">
34+
<div style={{ display: 'inline-block', position: 'relative', width: 200 }}>
35+
<Menu {...args}>
36+
{items.map(item => {
37+
if ('items' in item) {
38+
return (
39+
<ItemGroup
40+
legend={item.legend}
41+
aria-label={item['aria-label']}
42+
key={item.legend || item['aria-label']}
43+
type={item.type}
44+
icon={item.icon ? <CartIcon /> : undefined}
45+
>
46+
{item.items.map(groupItem => (
47+
<MenuItem key={groupItem.value} {...groupItem} />
48+
))}
49+
</ItemGroup>
50+
);
51+
}
52+
53+
if ('isSeparator' in item) {
54+
return <Separator key={item.value} />;
55+
}
56+
57+
return <MenuItem key={item.value} {...item} />;
58+
})}
59+
</Menu>
60+
</div>
61+
</Col>
62+
</Row>
63+
</Grid>
64+
);
65+
};

packages/dropdowns.next/demo/stories/data.ts

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,71 @@
55
* found at http://www.apache.org/licenses/LICENSE-2.0.
66
*/
77

8-
import { Options } from './types';
8+
import { Items, Options } from './types';
9+
10+
export const ITEMS: Items = [
11+
{
12+
value: 'item',
13+
label: 'Item'
14+
},
15+
{
16+
value: 'item-icon',
17+
label: 'Item with icon',
18+
icon: true
19+
},
20+
{
21+
value: 'separator',
22+
isSeparator: true
23+
},
24+
{
25+
value: 'item-meta',
26+
label: 'Item',
27+
meta: 'With meta'
28+
},
29+
{
30+
legend: 'Choose flowers',
31+
type: 'checkbox',
32+
icon: true,
33+
items: [
34+
{
35+
value: 'aster',
36+
label: 'Aster',
37+
isSelected: true
38+
},
39+
{
40+
value: 'daisy',
41+
label: 'Daisy',
42+
isDisabled: true
43+
},
44+
{
45+
value: 'ivy',
46+
label: 'Ivy'
47+
}
48+
]
49+
},
50+
{
51+
'aria-label': 'Select a fruit',
52+
type: 'radio',
53+
icon: true,
54+
items: [
55+
{
56+
value: 'apple',
57+
label: 'Apple',
58+
name: 'fruits'
59+
},
60+
{
61+
value: 'cherry',
62+
label: 'Cherry',
63+
name: 'fruits'
64+
},
65+
{
66+
value: 'clementine',
67+
label: 'Clementine',
68+
name: 'fruits'
69+
}
70+
]
71+
}
72+
];
973

1074
export const OPTIONS: Options = [
1175
{

packages/dropdowns.next/demo/stories/types.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55
* found at http://www.apache.org/licenses/LICENSE-2.0.
66
*/
77

8-
import { IOptGroupProps, IOptionProps } from '@zendeskgarden/react-dropdowns.next';
8+
import {
9+
IItemProps,
10+
IItemGroupProps,
11+
IOptGroupProps,
12+
IOptionProps
13+
} from '@zendeskgarden/react-dropdowns.next';
914

1015
export interface IOption extends Omit<IOptionProps, 'icon'> {
1116
icon?: boolean;
@@ -17,4 +22,17 @@ export interface IOptGroup extends Omit<IOptGroupProps, 'icon'> {
1722
options: IOption[];
1823
}
1924

25+
export interface IItem extends Omit<IItemProps, 'icon'> {
26+
icon?: boolean;
27+
meta?: string;
28+
isSeparator?: boolean;
29+
}
30+
31+
export interface IItemGroup extends Omit<IItemGroupProps, 'icon'> {
32+
icon?: boolean;
33+
items: IItem[];
34+
}
35+
2036
export type Options = (IOption | IOptGroup)[];
37+
38+
export type Items = (IItem | IItemGroup)[];

0 commit comments

Comments
 (0)