Skip to content

Commit

Permalink
Menu primitive (#612)
Browse files Browse the repository at this point in the history
  • Loading branch information
reesscot authored Nov 9, 2021
1 parent f84e994 commit beb9b49
Show file tree
Hide file tree
Showing 37 changed files with 1,339 additions and 31 deletions.
30 changes: 30 additions & 0 deletions .changeset/three-rats-destroy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
"@aws-amplify/ui-react": patch
"@aws-amplify/ui": patch
---

Menu primitive

New primitive which enables customers to create aaccessible, interactive menu for selecting actions within an application.
Dropdown menu is collision-aware and will automatically change location based on available space.

```jsx
import { Divider, Menu, MenuItem } from '@aws-amplify/ui-react';

export const BasicExample = () => {
return (
<Menu>
<MenuItem onClick={() => alert('Download')}>Download</MenuItem>
<MenuItem onClick={() => alert('Create a Copy')}>Create a Copy</MenuItem>
<MenuItem onClick={() => alert('Mark as Draft')}>Mark as Draft</MenuItem>
<Divider />
<MenuItem isDisabled onClick={() => alert('Delete')}>
Delete
</MenuItem>
<MenuItem onClick={() => alert('Attend a workshop')}>
Attend a workshop
</MenuItem>
</Menu>
);
};
```
43 changes: 43 additions & 0 deletions docs/src/components/MenuPropControls.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import * as React from 'react';
import { MenuProps, SelectField, TextField } from '@aws-amplify/ui-react';
import { DemoBox } from './DemoBox';

export interface MenuPropControlsProps extends MenuProps {
setMenuAlign: (value: React.SetStateAction<MenuProps['menuAlign']>) => void;
setSize: (value: React.SetStateAction<MenuProps['size']>) => void;
}

interface MenuPropControlsInterface {
(props: MenuPropControlsProps): JSX.Element;
}

export const MenuPropControls: MenuPropControlsInterface = ({
setMenuAlign,
setSize,
}) => {
return (
<DemoBox primitiveName="Menu">
<SelectField
label="menuAlign"
name="menuAlign"
onChange={(event) =>
setMenuAlign(event.target.value as MenuProps['menuAlign'])
}
>
<option value="start">start</option>
<option value="center">center</option>
<option value="end">end</option>
</SelectField>

<SelectField
label="size"
name="size"
placeholder="default"
onChange={(event) => setSize(event.target.value as MenuProps['size'])}
>
<option value="small">small</option>
<option value="large">large</option>
</SelectField>
</DemoBox>
);
};
22 changes: 22 additions & 0 deletions docs/src/components/useMenuProps.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { MenuProps } from '@aws-amplify/ui-react';
import { useState } from 'react';
import { MenuPropControlsProps } from './MenuPropControls';

interface UseMenuProps {
(initialValues?: MenuProps): MenuPropControlsProps;
}

export const useMenuProps: UseMenuProps = (initialValues) => {
const [menuAlign, setMenuAlign] = useState<MenuProps['menuAlign']>(
initialValues.align
);
const [size, setSize] = useState<MenuProps['size']>(initialValues.size);

return {
...initialValues,
menuAlign,
size,
setMenuAlign,
setSize,
};
};
4 changes: 3 additions & 1 deletion docs/src/pages/ui/primitives/button/react.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,19 @@ Use the `size` prop to change the Button size. Available options are `small`, `l

### Variations

Use the `variation` prop to change the Button variation. Available options are `primary`, `link`, and none (default).
Use the `variation` prop to change the Button variation. Available options are `primary`, `link`, `menu` and none (default).

```jsx
<Button variation="primary">Primary</Button>
<Button variation="link">Link</Button>
<Button variation="menu">Menu</Button>
<Button>Default</Button>
```

<Example>
<Button variation="primary">Primary</Button>
<Button variation="link">Link</Button>
<Button variation="menu">Menu</Button>
<Button>Default</Button>
</Example>

Expand Down
37 changes: 37 additions & 0 deletions docs/src/pages/ui/primitives/menu/demo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import * as React from 'react';

import { Divider, Menu, MenuItem, View } from '@aws-amplify/ui-react';
import { MenuPropControls } from '@/components/MenuPropControls';
import { useMenuProps } from '@/components/useMenuProps';
import { Example } from '@/components/Example';

export const MenuDemo = () => {
const props = useMenuProps({
menuAlign: 'start',
size: null,
});

return (
<View>
<MenuPropControls {...props} />
<Example>
<Menu {...props}>
<MenuItem onClick={() => alert('Download')}>Download</MenuItem>
<MenuItem onClick={() => alert('Create a Copy')}>
Create a Copy
</MenuItem>
<MenuItem onClick={() => alert('Mark as Draft')}>
Mark as Draft
</MenuItem>
<Divider />
<MenuItem isDisabled onClick={() => alert('Delete')}>
Delete
</MenuItem>
<MenuItem onClick={() => alert('Attend a workshop')}>
Attend a workshop
</MenuItem>
</Menu>
</Example>
</View>
);
};
18 changes: 18 additions & 0 deletions docs/src/pages/ui/primitives/menu/examples/basicExample.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Divider, Menu, MenuItem } from '@aws-amplify/ui-react';

export const BasicExample = () => {
return (
<Menu>
<MenuItem onClick={() => alert('Download')}>Download</MenuItem>
<MenuItem onClick={() => alert('Create a Copy')}>Create a Copy</MenuItem>
<MenuItem onClick={() => alert('Mark as Draft')}>Mark as Draft</MenuItem>
<Divider />
<MenuItem isDisabled onClick={() => alert('Delete')}>
Delete
</MenuItem>
<MenuItem onClick={() => alert('Attend a workshop')}>
Attend a workshop
</MenuItem>
</Menu>
);
};
42 changes: 42 additions & 0 deletions docs/src/pages/ui/primitives/menu/examples/controlledExample.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import * as React from 'react';

import { Menu, MenuItem } from '@aws-amplify/ui-react';

export const ControlledExample = () => {
const [isOpen, setIsOpen] = React.useState(false);

const handleOpenChange = (open) => {
setIsOpen(open);
// Do something else
};
const closeMenu = () => setIsOpen(false);

return (
<Menu onOpenChange={handleOpenChange} isOpen={isOpen}>
<MenuItem
onClick={() => {
closeMenu();
alert('Download');
}}
>
Download
</MenuItem>
<MenuItem
onClick={() => {
closeMenu();
alert('Create a Copy');
}}
>
Create a Copy
</MenuItem>
<MenuItem
onClick={() => {
closeMenu();
alert('Mark as Draft');
}}
>
Mark as Draft
</MenuItem>
</Menu>
);
};
5 changes: 5 additions & 0 deletions docs/src/pages/ui/primitives/menu/examples/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export { BasicExample } from './basicExample';
export { ControlledExample } from './controlledExample';
export { MenuExample } from './menuExample';
export { SizeExample } from './sizeExample';
export { MenuAlignExample } from './menuAlignExample';
20 changes: 20 additions & 0 deletions docs/src/pages/ui/primitives/menu/examples/menuAlignExample.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Flex, Menu, MenuItem } from '@aws-amplify/ui-react';

export const MenuAlignExample = () => {
return (
<Flex direction="column" width="4rem">
<Menu>
<MenuItem>Download</MenuItem>
<MenuItem>Create a Copy</MenuItem>
</Menu>
<Menu menuAlign="center">
<MenuItem>Download</MenuItem>
<MenuItem>Create a Copy</MenuItem>
</Menu>
<Menu menuAlign="end">
<MenuItem>Download</MenuItem>
<MenuItem>Create a Copy</MenuItem>
</Menu>
</Flex>
);
};
18 changes: 18 additions & 0 deletions docs/src/pages/ui/primitives/menu/examples/menuExample.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Divider, Menu, MenuItem, MenuButton } from '@aws-amplify/ui-react';

export const MenuExample = () => (
<Menu
trigger={
<MenuButton variation="primary" size="large">
Menu
</MenuButton>
}
>
<MenuItem>Download</MenuItem>
<MenuItem>Create a Copy</MenuItem>
<MenuItem>Mark as Draft</MenuItem>
<Divider />
<MenuItem isDisabled>Delete</MenuItem>
<MenuItem>Attend a workshop</MenuItem>
</Menu>
);
20 changes: 20 additions & 0 deletions docs/src/pages/ui/primitives/menu/examples/sizeExample.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Menu, MenuItem, Flex } from '@aws-amplify/ui-react';

export const SizeExample = () => {
return (
<Flex direction="column" width="4rem">
<Menu size="small">
<MenuItem>Download</MenuItem>
<MenuItem>Create a Copy</MenuItem>
</Menu>
<Menu>
<MenuItem>Download</MenuItem>
<MenuItem>Create a Copy</MenuItem>
</Menu>
<Menu size="large">
<MenuItem>Download</MenuItem>
<MenuItem>Create a Copy</MenuItem>
</Menu>
</Flex>
);
};
7 changes: 7 additions & 0 deletions docs/src/pages/ui/primitives/menu/index.page.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
title: Menu
---

import { Fragment } from '@/components/Fragment';

<Fragment>{({ platform }) => import(`./${platform}.mdx`)}</Fragment>
Loading

0 comments on commit beb9b49

Please sign in to comment.