-
Notifications
You must be signed in to change notification settings - Fork 1.3k
ActionMenu docs #2227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
ActionMenu docs #2227
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
91786c0
ActionMenu docs
ktabors 24f7b98
copy edits
ktabors 21950fe
docs usage import cleanup
ktabors a2d802a
adding shouldflip to the direction align story
ktabors 190314c
copy edit
ktabors 4229c35
fixing an example
ktabors 7f56bd5
Update Events section copy
ktabors ffde14d
example improvements
ktabors 343ab02
Merge branch 'main' into actionmenu_docs
ktabors 44d94a5
Update packages/@react-spectrum/menu/stories/ActionMenu.stories.tsx
ktabors f3bdc61
Merge branch 'main' into actionmenu_docs
ktabors deb8904
fixing a merge conflix mistake
ktabors 3f20a70
adding an isQuiet example to docs
ktabors b976159
simplifying quiet example and changing order
ktabors ed06179
removing the deploy after version
ktabors bd77fce
Merge branch 'main' into actionmenu_docs
snowystinger 2a76bc6
Merge branch 'main' into actionmenu_docs
snowystinger f6748c8
Merge branch 'main' into actionmenu_docs
snowystinger fe3f100
upgrading mdx comment style
ktabors c8c48b7
updating keys to match names
ktabors 043bd5a
Merge branch 'main' into actionmenu_docs
snowystinger 049ff65
adding open and disabled exampels to the docs
ktabors 81489c3
Merge branch 'actionmenu_docs' of github.com:adobe/react-spectrum int…
ktabors 9e83c40
Merge branch 'main' into actionmenu_docs
ktabors f85a269
Merge branch 'main' into actionmenu_docs
ktabors d3f5164
Merge branch 'main' into actionmenu_docs
snowystinger 7176660
Merge branch 'main' into actionmenu_docs
ktabors File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,313 @@ | ||
{/* Copyright 2022 Adobe. All rights reserved. | ||
This file is licensed to you under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. You may obtain a copy | ||
of the License at http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software distributed under | ||
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS | ||
OF ANY KIND, either express or implied. See the License for the specific language | ||
governing permissions and limitations under the License. */} | ||
|
||
import {Layout} from '@react-spectrum/docs'; | ||
export default Layout; | ||
|
||
import docs from 'docs:@react-spectrum/menu'; | ||
import {HeaderInfo, PropTable} from '@react-spectrum/docs'; | ||
import packageData from '@react-spectrum/menu/package.json'; | ||
|
||
```jsx import | ||
import {ActionMenu, Item, Section} from '@react-spectrum/menu'; | ||
import Copy from '@spectrum-icons/workflow/Copy'; | ||
import Cut from '@spectrum-icons/workflow/Cut'; | ||
import {Flex} from '@react-spectrum/layout'; | ||
import Paste from '@spectrum-icons/workflow/Paste'; | ||
``` | ||
|
||
--- | ||
category: Collections | ||
keywords: [action menu, dropdown] | ||
--- | ||
|
||
# ActionMenu | ||
|
||
<p>{docs.exports.ActionMenu.description}</p> | ||
|
||
<HeaderInfo | ||
packageData={packageData} | ||
componentNames={['ActionMenu']} | ||
sourceData={[ | ||
{type: 'Spectrum', url: 'https://spectrum.adobe.com/page/popover/'} | ||
]} /> | ||
|
||
## Example | ||
|
||
```tsx example | ||
<ActionMenu> | ||
<Item>Cut</Item> | ||
<Item>Copy</Item> | ||
<Item>Paste</Item> | ||
</ActionMenu> | ||
``` | ||
|
||
## Content | ||
|
||
ActionMenu follows the [Collection Components](../react-stately/collections.html) API, | ||
accepting both static and dynamic collections. See [Menu](Menu.html#content) for further explanation. | ||
|
||
```tsx example | ||
function Example() { | ||
let actionMenuItems = [ | ||
{name: 'Cut'}, | ||
{name: 'Copy'}, | ||
{name: 'Paste'}, | ||
{name: 'Select All'} | ||
]; | ||
|
||
return ( | ||
<ActionMenu items={actionMenuItems}> | ||
{item => <Item key={item.name}>{item.name}</Item>} | ||
</ActionMenu> | ||
); | ||
} | ||
``` | ||
|
||
### Trays | ||
On mobile, ActionMenus automatically display in a tray instead of a popover to improve usability. | ||
|
||
### Internationalization | ||
In order to internationalize an ActionMenu, the content provided to all child items should be localized. | ||
For languages that are read right-to-left (e.g. Hebrew and Arabic), the layout of the ActionMenu is flipped. | ||
|
||
## Events | ||
ActionMenu supports the `onAction` prop, which is called when the user presses a menu item. It receives the key of the item as an argument, which can be used to perform the relevant action. | ||
|
||
```tsx example | ||
function Example() { | ||
let [action, setAction] = React.useState(''); | ||
|
||
return ( | ||
<> | ||
<ActionMenu onAction={setAction}> | ||
<Item key="cut">Cut</Item> | ||
<Item key="copy">Copy</Item> | ||
<Item key="paste">Paste</Item> | ||
</ActionMenu> | ||
<p>Action: {action}</p> | ||
</> | ||
); | ||
} | ||
``` | ||
|
||
## Sections | ||
ActionMenu supports sections in order to group options. Sections can be used by wrapping groups of Items in a `Section` component. Each `Section` takes a `title` and `key` prop. | ||
|
||
### Static Items | ||
|
||
```tsx example | ||
<ActionMenu> | ||
<Section title="File"> | ||
<Item key="new">New</Item> | ||
<Item key="open">Open...</Item> | ||
</Section> | ||
<Section title="Save"> | ||
<Item key="save">Save</Item> | ||
<Item key="saveAs">Save As...</Item> | ||
<Item key="saveAll">Save All</Item> | ||
</Section> | ||
</ActionMenu> | ||
``` | ||
|
||
### Dynamic Items | ||
|
||
Sections used with dynamic items are populated from a hierarchical data structure. Similarly to the props on ActionMenu, `<Section>` takes an array of data using the `items` prop. | ||
|
||
```tsx example | ||
function Example() { | ||
let openWindows = [ | ||
{ | ||
name: 'Reversion', | ||
id: 'reversion', | ||
children: [ | ||
{id: 'undo', name: 'Undo'}, | ||
{id: 'redo', name: 'Redo'} | ||
] | ||
}, | ||
{ | ||
name: 'Clipboard', | ||
id: 'clipboard', | ||
children: [ | ||
{id: 'cut', name: 'Cut'}, | ||
{id: 'copy', name: 'Copy'}, | ||
{id: 'paste', name: 'Paste'} | ||
] | ||
} | ||
]; | ||
|
||
return ( | ||
<ActionMenu | ||
items={openWindows}> | ||
{item => ( | ||
<Section items={item.children} title={item.name}> | ||
{item => <Item>{item.name}</Item>} | ||
</Section> | ||
)} | ||
</ActionMenu> | ||
); | ||
} | ||
``` | ||
ktabors marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### Accessibility | ||
|
||
Sections without a `title` must provide an `aria-label` for accessibility. | ||
|
||
## Complex Menu Items | ||
|
||
Items within ActionMenu also allow for additional content used to better communicate options. Icons and descriptions can be added to the `children` of `Item` as shown in the example below. If a description is added, the prop `slot="description"` must be used to distinguish the different `<Text>` elements. | ||
|
||
```tsx example | ||
import {Keyboard, Text} from '@react-spectrum/text'; | ||
<ActionMenu> | ||
<Item key="cut" textValue="cut"> | ||
<Cut size="S"/> | ||
<Text>Cut</Text> | ||
<Keyboard>⌘X</Keyboard> | ||
</Item> | ||
<Item key="copy" textValue="copy"> | ||
<Copy size="S"/> | ||
<Text>Copy</Text> | ||
<Keyboard>⌘C</Keyboard> | ||
</Item> | ||
<Item key="paste" textValue="paste"> | ||
<Paste size="S"/> | ||
<Text>Paste</Text> | ||
<Keyboard>⌘V</Keyboard> | ||
</Item> | ||
</ActionMenu> | ||
``` | ||
|
||
## Props | ||
|
||
<PropTable component={docs.exports.ActionMenu} links={docs.links} /> | ||
|
||
## Visual options | ||
snowystinger marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### Quiet | ||
|
||
[View guidelines](https://spectrum.adobe.com/page/action-button/#Quiet) | ||
|
||
```tsx example | ||
<ActionMenu | ||
isQuiet | ||
items={[ | ||
{name: 'Cut', id: 'cut'}, | ||
{name: 'Copy', id: 'copy'}, | ||
{name: 'Paste', id: 'paste'} | ||
]}> | ||
{item => <Item>{item.name}</Item>} | ||
</ActionMenu> | ||
``` | ||
|
||
### Autofocus | ||
|
||
Applying `autoFocus` to the ActionMenu sets focus to the ActionMenu trigger. | ||
|
||
### Disabled | ||
|
||
```tsx example | ||
<ActionMenu | ||
items={[ | ||
{name: 'Undo', id: 'undo'}, | ||
{name: 'Redo', id: 'redo'}, | ||
{name: 'Cut', id: 'cut'}, | ||
{name: 'Copy', id: 'copy'}, | ||
{name: 'Paste', id: 'paste'} | ||
]} | ||
isDisabled> | ||
{item => <Item>{item.name}</Item>} | ||
</ActionMenu> | ||
``` | ||
|
||
### Disabled items | ||
snowystinger marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```tsx example | ||
<ActionMenu | ||
items={[ | ||
{name: 'Undo', id: 'undo'}, | ||
{name: 'Redo', id: 'redo'}, | ||
{name: 'Cut', id: 'cut'}, | ||
{name: 'Copy', id: 'copy'}, | ||
{name: 'Paste', id: 'paste'} | ||
]} | ||
disabledKeys={['redo', 'paste']}> | ||
{item => <Item>{item.name}</Item>} | ||
</ActionMenu> | ||
``` | ||
|
||
### Align and direction | ||
|
||
[View guidelines](https://spectrum.adobe.com/page/popover/#Placement) | ||
|
||
The `align` prop aligns the ActionMenu menu relative to the trigger and the `direction` prop controls the direction the ActionMenu will render. | ||
|
||
```tsx example | ||
<Flex gap="size-100"> | ||
<ActionMenu align="start"> | ||
<Item key="cut">Cut</Item> | ||
<Item key="copy">Copy</Item> | ||
<Item key="paste">Paste</Item> | ||
</ActionMenu> | ||
<ActionMenu align="end" direction="top" shouldFlip={false}> | ||
<Item key="cut">Cut</Item> | ||
<Item key="copy">Copy</Item> | ||
<Item key="paste">Paste</Item> | ||
</ActionMenu> | ||
<ActionMenu direction="start" align="start"> | ||
<Item key="cut">Cut</Item> | ||
<Item key="copy">Copy</Item> | ||
<Item key="paste">Paste</Item> | ||
</ActionMenu> | ||
<ActionMenu direction="end" align="end"> | ||
<Item key="cut">Cut</Item> | ||
<Item key="copy">Copy</Item> | ||
<Item key="paste">Paste</Item> | ||
</ActionMenu> | ||
</Flex> | ||
``` | ||
|
||
### Flipping | ||
By default, the ActionMenu menu flips direction automatically upon opening when space is limited. To change this, set the `shouldFlip` prop to `false`. Try scrolling the viewport close to the edge of the trigger in the example to see this in action. | ||
|
||
```tsx example | ||
<Flex gap="size-100"> | ||
<ActionMenu shouldFlip> | ||
<Item key="cut">Cut</Item> | ||
<Item key="copy">Copy</Item> | ||
<Item key="paste">Paste</Item> | ||
</ActionMenu> | ||
<ActionMenu shouldFlip={false}> | ||
<Item key="cut">Cut</Item> | ||
<Item key="copy">Copy</Item> | ||
<Item key="paste">Paste</Item> | ||
</ActionMenu> | ||
</Flex> | ||
``` | ||
|
||
### Open | ||
|
||
The `isOpen` and `defaultOpen` props on the ActionMenu control whether the menu is open by default. | ||
They apply controlled and uncontrolled behavior on the Menu respectively. | ||
|
||
```tsx example | ||
function Example() { | ||
let [open, setOpen] = React.useState(false); | ||
|
||
return ( | ||
<ActionMenu | ||
isOpen={open} | ||
onOpenChange={setOpen}> | ||
<Item key="cut">Cut</Item> | ||
<Item key="copy">Copy</Item> | ||
<Item key="paste">Paste</Item> | ||
</ActionMenu> | ||
); | ||
} | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -203,3 +203,4 @@ function Example() { | |
</MenuTrigger> | ||
); | ||
} | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Menu points to popover, I assumed that is applicable.