@primer/components 33.0.0-rc.b495ba4a → 33.0.0-rc.cface7dc

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. package/.github/workflows/statuses.yml +32 -0
  2. package/.gitignore +1 -0
  3. package/CHANGELOG.md +6 -0
  4. package/contributor-docs/CONTRIBUTING.md +14 -58
  5. package/docs/content/{ActionList2.mdx → drafts/ActionList2.mdx} +5 -9
  6. package/docs/content/drafts/ActionMenu2.mdx +251 -0
  7. package/docs/src/@primer/gatsby-theme-doctocat/live-code-scope.js +9 -1
  8. package/docs/src/component-checklist.js +10 -2
  9. package/lib/ActionList2/Divider.d.ts +3 -2
  10. package/lib/ActionList2/Divider.js +10 -5
  11. package/lib/ActionList2/Item.js +21 -5
  12. package/lib/ActionList2/List.js +11 -1
  13. package/lib/ActionList2/MenuContext.d.ts +10 -0
  14. package/lib/ActionList2/MenuContext.js +15 -0
  15. package/lib/ActionList2/Selection.js +11 -0
  16. package/lib/ActionList2/index.d.ts +1 -2
  17. package/lib/ActionMenu2.d.ts +313 -0
  18. package/lib/ActionMenu2.js +91 -0
  19. package/lib/Autocomplete/Autocomplete.d.ts +2 -1
  20. package/lib/Autocomplete/AutocompleteInput.d.ts +2 -1
  21. package/lib/Button/Button.d.ts +2 -2
  22. package/lib/Button/ButtonClose.d.ts +2 -2
  23. package/lib/Button/ButtonDanger.d.ts +2 -2
  24. package/lib/Button/ButtonInvisible.d.ts +2 -2
  25. package/lib/Button/ButtonOutline.d.ts +2 -2
  26. package/lib/Button/ButtonPrimary.d.ts +2 -2
  27. package/lib/CircleOcticon.d.ts +35 -35
  28. package/lib/Dialog.d.ts +37 -37
  29. package/lib/Dropdown.d.ts +6 -6
  30. package/lib/DropdownMenu/DropdownButton.d.ts +6 -3
  31. package/lib/FilterList.d.ts +1 -1
  32. package/lib/Position.d.ts +4 -4
  33. package/lib/SelectMenu/SelectMenu.d.ts +11 -10
  34. package/lib/SelectMenu/SelectMenuItem.d.ts +1 -1
  35. package/lib/SelectMenu/SelectMenuModal.d.ts +1 -1
  36. package/lib/TextInputWithTokens.d.ts +2 -1
  37. package/lib/Token/AvatarToken.d.ts +1 -1
  38. package/lib/Token/IssueLabelToken.d.ts +1 -1
  39. package/lib/Token/Token.d.ts +1 -1
  40. package/lib/drafts.d.ts +1 -0
  41. package/lib/drafts.js +13 -0
  42. package/lib/stories/ActionMenu2.stories.js +433 -0
  43. package/lib-esm/ActionList2/Divider.d.ts +3 -2
  44. package/lib-esm/ActionList2/Divider.js +8 -5
  45. package/lib-esm/ActionList2/Item.js +19 -5
  46. package/lib-esm/ActionList2/List.js +9 -1
  47. package/lib-esm/ActionList2/MenuContext.d.ts +10 -0
  48. package/lib-esm/ActionList2/MenuContext.js +3 -0
  49. package/lib-esm/ActionList2/Selection.js +9 -0
  50. package/lib-esm/ActionList2/index.d.ts +1 -2
  51. package/lib-esm/ActionMenu2.d.ts +313 -0
  52. package/lib-esm/ActionMenu2.js +67 -0
  53. package/lib-esm/Autocomplete/Autocomplete.d.ts +2 -1
  54. package/lib-esm/Autocomplete/AutocompleteInput.d.ts +2 -1
  55. package/lib-esm/Button/Button.d.ts +2 -2
  56. package/lib-esm/Button/ButtonClose.d.ts +2 -2
  57. package/lib-esm/Button/ButtonDanger.d.ts +2 -2
  58. package/lib-esm/Button/ButtonInvisible.d.ts +2 -2
  59. package/lib-esm/Button/ButtonOutline.d.ts +2 -2
  60. package/lib-esm/Button/ButtonPrimary.d.ts +2 -2
  61. package/lib-esm/CircleOcticon.d.ts +35 -35
  62. package/lib-esm/Dialog.d.ts +37 -37
  63. package/lib-esm/Dropdown.d.ts +6 -6
  64. package/lib-esm/DropdownMenu/DropdownButton.d.ts +6 -3
  65. package/lib-esm/FilterList.d.ts +1 -1
  66. package/lib-esm/Position.d.ts +4 -4
  67. package/lib-esm/SelectMenu/SelectMenu.d.ts +11 -10
  68. package/lib-esm/SelectMenu/SelectMenuItem.d.ts +1 -1
  69. package/lib-esm/SelectMenu/SelectMenuModal.d.ts +1 -1
  70. package/lib-esm/TextInputWithTokens.d.ts +2 -1
  71. package/lib-esm/Token/AvatarToken.d.ts +1 -1
  72. package/lib-esm/Token/IssueLabelToken.d.ts +1 -1
  73. package/lib-esm/Token/Token.d.ts +1 -1
  74. package/lib-esm/drafts.d.ts +1 -0
  75. package/lib-esm/drafts.js +2 -1
  76. package/lib-esm/stories/ActionMenu2.stories.js +376 -0
  77. package/package-lock.json +303 -255
  78. package/package.json +4 -2
  79. package/script/component-status-project/build.ts +100 -0
  80. package/script/component-status-project/deploy.rb +142 -0
  81. package/src/ActionList2/Divider.tsx +13 -8
  82. package/src/ActionList2/Item.tsx +13 -3
  83. package/src/ActionList2/List.tsx +6 -2
  84. package/src/ActionList2/MenuContext.tsx +6 -0
  85. package/src/ActionList2/Selection.tsx +9 -0
  86. package/src/ActionMenu2.tsx +94 -0
  87. package/src/drafts.ts +1 -0
  88. package/src/stories/ActionMenu2.stories.tsx +551 -0
  89. package/stats.html +1 -1
  90. package/tsconfig.build.json +1 -1
  91. package/tsconfig.json +1 -1
@@ -0,0 +1,32 @@
1
+ name: Update status project
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ # Only run workflow on changes to component docs
8
+ paths:
9
+ - 'docs/content/**'
10
+
11
+ jobs:
12
+ build-and-deploy:
13
+ name: Update status project
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v2
17
+ - name: Setup Ruby
18
+ uses: actions/setup-ruby@v1
19
+ with:
20
+ ruby-version: 2.7.x
21
+ - name: Set up Node.js
22
+ uses: actions/setup-node@v2
23
+ with:
24
+ node-version: 14
25
+ - name: Install node deps
26
+ run: npm ci
27
+ - name: Install ruby deps
28
+ run: gem install graphql-client
29
+ - name: Build statuses
30
+ run: npx ts-node script/component-status-project/build.ts
31
+ - name: Deploy statuses to project
32
+ run: GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} script/component-status-project/deploy.rb
package/.gitignore CHANGED
@@ -8,3 +8,4 @@ lib/
8
8
  lib-esm/
9
9
  public/
10
10
  stats.html
11
+ .env
package/CHANGELOG.md CHANGED
@@ -12,12 +12,18 @@
12
12
 
13
13
  * [#1643](https://github.com/primer/react/pull/1643) [`3938550f`](https://github.com/primer/react/commit/3938550fb3ea3fbec542a0cadaf6aeb734fba938) Thanks [@jfuchs](https://github.com/jfuchs)! - Heading no longer accepts styled-system props. Please use the `sx` prop to extend Primer component styling instead. See also https://primer.style/react/overriding-styles for information about `sx` and https://primer.style/react/system-props for context on the removal.
14
14
 
15
+ ### Minor Changes
16
+
17
+ - [#1619](https://github.com/primer/react/pull/1619) [`a13efa45`](https://github.com/primer/react/commit/a13efa457ded69656fb390b5b9b666d00157fd21) Thanks [@siddharthkp](https://github.com/siddharthkp)! - Add composable `ActionMenu` to `@primer/components/drafts`
18
+
15
19
  ### Patch Changes
16
20
 
17
21
  - [#1668](https://github.com/primer/react/pull/1668) [`98dc6336`](https://github.com/primer/react/commit/98dc633674b793edfa4fbeb88fd239e6ca40544e) Thanks [@siddharthkp](https://github.com/siddharthkp)! - ActionList: Fix multiple selection svg by overriding global shape-rendering for github.com
18
22
 
19
23
  * [#1596](https://github.com/primer/react/pull/1596) [`5c6dc644`](https://github.com/primer/react/commit/5c6dc644c1e68b36d309deac653aca189f1fa624) Thanks [@dmarcey](https://github.com/dmarcey)! - Fix alignment of items in ActionList (single-select) if some of the items have wrapping text.
20
24
 
25
+ - [#1538](https://github.com/primer/react/pull/1538) [`dda6e5d7`](https://github.com/primer/react/commit/dda6e5d7204347c3c66183464dd0903e878a4f20) Thanks [@shiftkey](https://github.com/shiftkey)! - Update `typescript` package to correct generated type declarations.
26
+
21
27
  ## 32.1.0
22
28
 
23
29
  ### Minor Changes
@@ -77,65 +77,35 @@ Additionally, every component should support [the `sx` prop](https://primer.styl
77
77
 
78
78
  Here's an example of a basic component written in the style of Primer Components:
79
79
 
80
- ```jsx
81
- import {TYPOGRAPHY, COMMON} from './constants'
82
- import sx from './sx'
80
+ ```tsx
81
+ import sx, {SxProp} from './sx'
83
82
 
84
- const Component = styled.div`
83
+ const Component = styled.div<SxProp>`
85
84
  // additional styles here
86
85
 
87
- ${COMMON};
88
- ${TYPOGRAPHY};
89
86
  ${sx};
90
87
  `
91
88
 
92
89
  Component.defaultProps = {
93
90
  m: 0,
94
- fontSize: 5,
91
+ fontSize: 5
95
92
  }
96
93
 
97
94
  export default Component
98
95
  ```
99
96
 
100
- ### Adding system props
101
-
102
- Each component should have access to the appropriate system props. Every component has access to `COMMON`. For **most** components added, you'll only need to give the component to `COMMON`. If you are unsure, ping a DS team member on your PR.
103
-
104
- Categories of system props are exported from `src/constants.js`:
105
-
106
- - `COMMON` includes color and spacing (margin and padding) props
107
- - `TYPOGRAPHY` includes font family, font weight, and line-height props
108
- - `POSITION` includes positioning props
109
- - `FLEX` includes flexbox props
110
- - `BORDER` includes border and box-shadow props
111
- - `GRID` includes grid props
112
-
113
- To give the component access to a group of system props, import the system prop function from `./constants` and include the system prop function in your styled-component like so:
114
-
115
- ```jsx
116
- import {COMMON} from './constants'
117
-
118
- const Component = styled.div`
119
- // additional styles here
120
- ${COMMON};
121
- `
122
- ```
123
-
124
- Remember that the system prop function inside your style declaration needs to go _after_ any built-in styles you want to be overridable.
125
-
126
97
  ### Adding the `sx` prop
127
98
 
128
- Each component should provide access to a prop called `sx` that allows for setting theme-aware ad-hoc styles. See the [overriding styles](https://primer.style/components/overriding-styles) doc for more information on using the prop.
99
+ Each component should accept a prop called `sx` that allows for setting theme-aware ad-hoc styles. See the [overriding styles](https://primer.style/components/overriding-styles) doc for more information on using the prop.
129
100
 
130
- Adding the `sx` prop is similar to adding system props; import the default export from the `sx` module, add it to your style definition, and add the appropriate prop types. **The `sx` prop should go at the _very end_ of your style definition.**
101
+ To add the `sx` prop to your component: import the default export from the `sx` module, add it to your style definition, and add the appropriate prop types. **The `sx` prop should go at the _very end_ of your style definition.**
131
102
 
132
- ```jsx
133
- import {COMMON} from './constants'
134
- import sx from './sx'
103
+ ```tsx
104
+ import sx, {SxProp} from './sx'
135
105
 
136
- const Component = styled.div`
106
+ const Component = styled.div<SxProp>`
137
107
  // additional styles here
138
- ${COMMON};
108
+
139
109
  ${sx};
140
110
  `
141
111
  ```
@@ -175,15 +145,16 @@ See [`src/__tests__/example.js`](src/__tests__/example.js) for examples of ways
175
145
 
176
146
  ### TypeScript support
177
147
 
178
- Several of the projects that consume Primer Components are written in TypeScript. Though Primer Components is not currently written in TS, we do export type definitions in order to make Primer Components compatible with other TS projects.
148
+ Primer React is written in TypeScript. We include type definitions in our built artifacts. To check types, run the `typecheck` script:
179
149
 
180
- Whenever adding new components or modifying the props of an existing component, **please make sure to update the type definition** in `index.d.ts`! This is super important to make sure we don't break compatibility :)
150
+ ```
151
+ npm run typecheck
152
+ ```
181
153
 
182
154
  ### Additional resources
183
155
 
184
156
  - [Primer Components Philosophy](https://primer.style/components/philosophy)
185
157
  - [Primer Components Core Concepts](https://primer.style/components/core-concepts)
186
- - [Primer Components System Props](https://primer.style/components/system-props)
187
158
  - [Styled Components docs](https://styled-components.com/)
188
159
  - [Styled System docs](https://styled-system.com/)
189
160
 
@@ -206,7 +177,6 @@ After opening a pull request, a member of the design systems team will add the a
206
177
  - If it's a new component, does the component make sense to add to Primer Components? (Ideally this is discussed before the pull request stage, please reach out to a DS member if you aren't sure if a component should be added to Primer Components!)
207
178
  - Does the component follow our [Primer Components code style](#component-patterns)?
208
179
  - Does the component use theme values for most CSS values?
209
- - Does the component have the [correct system props implemented](#adding-system-props)?
210
180
  - Is the component API intuitive?
211
181
  - Does the component have the appropriate [type definitions in `index.d.ts`](#typescript-support)?
212
182
  - Is the component documented accurately?
@@ -251,20 +221,6 @@ Make sure to run `npm install` from inside the `docs/` subfolder _as well as_ th
251
221
 
252
222
  Ensure you are using the latest minor of Node.js for the major version specified in the `.nvmrc` file. For example, if `.nvmrc` contains `8`, make sure you're using the latest version of Node.js with the major version of 8.
253
223
 
254
- ## Glossary
255
-
256
- ### System props
257
-
258
- System props are style functions that provide one or more props, and can be passed directly the return value of [styled-components]'s `styled()` function:
259
-
260
- ```jsx
261
- import styled from 'styled-components'
262
- import {space} from 'styled-system'
263
- const SpaceDiv = styled.div`
264
- ${space}
265
- `
266
- ```
267
-
268
224
  [classnames]: https://www.npmjs.com/package/classnames
269
225
  [spread syntax]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
270
226
  [styled-system]: https://styled-system.com
@@ -6,16 +6,13 @@ storybook: '/react/storybook?path=/story/composite-components-actionlist2'
6
6
  description: An ActionList is a list of items that can be activated or selected. ActionList is the base component for many menu-type components, including DropdownMenu and ActionMenu.
7
7
  ---
8
8
 
9
- import {BorderBox, Avatar} from '@primer/components'
9
+ import {Box, Avatar} from '@primer/components'
10
10
  import {ActionList} from '@primer/components/drafts'
11
- import {ComponentChecklist} from '../src/component-checklist'
12
-
13
- import {ImageContainer} from '@primer/gatsby-theme-doctocat'
14
11
  import {LinkIcon, AlertIcon, ArrowRightIcon} from '@primer/octicons-react'
15
12
 
16
13
  <br />
17
14
 
18
- <BorderBox sx={{padding: 6}}>
15
+ <Box sx={{border: '1px solid', borderColor: 'border.default', borderRadius: 2, padding: 6}}>
19
16
  <ActionList sx={{width: 320}}>
20
17
  <ActionList.Item>
21
18
  <ActionList.LeadingVisual>
@@ -43,7 +40,7 @@ import {LinkIcon, AlertIcon, ArrowRightIcon} from '@primer/octicons-react'
43
40
  </ActionList.TrailingVisual>
44
41
  </ActionList.Item>
45
42
  </ActionList>
46
- </BorderBox>
43
+ </Box>
47
44
 
48
45
  <br />
49
46
 
@@ -351,11 +348,10 @@ render(<SelectFields />)
351
348
 
352
349
  - [Interface guidelines: Action List](https://primer.style/design/components/action-list)
353
350
 
354
- <br />
355
-
356
351
  ## Related components
357
352
 
358
- - [ActionMenu](/ActionMenu)
353
+ - [ActionMenu](/drafts/ActionMenu2)
354
+ - [DropdownMenu](/DropdownMenu)
359
355
  - [SelectPanel](/SelectPanel)
360
356
 
361
357
  ## Component status
@@ -0,0 +1,251 @@
1
+ ---
2
+ title: ActionMenu
3
+ status: Alpha
4
+ source: https://github.com/primer/react/tree/main/src/ActionMenu
5
+ storybook: '/react/storybook?path=/story/composite-components-actionmenu2'
6
+ description: An ActionMenu is an ActionList-based component for creating a menu of actions that expands through a trigger button.
7
+ ---
8
+
9
+ import {Box, Avatar} from '@primer/components'
10
+ import {ActionMenu, ActionList} from '@primer/components/drafts'
11
+ import {Props} from '../../src/props'
12
+
13
+ <br />
14
+
15
+ <Box sx={{border: '1px solid', borderColor: 'border.default', borderRadius: 2, padding: 6}}>
16
+ <ActionMenu>
17
+ <ActionMenu.Button>Menu</ActionMenu.Button>
18
+ <ActionList>
19
+ <ActionList.Item onSelect={() => onSelect('Copy link')}>
20
+ Copy link
21
+ <ActionList.TrailingVisual>⌘C</ActionList.TrailingVisual>
22
+ </ActionList.Item>
23
+ <ActionList.Item onSelect={() => onSelect('Quote reply')}>
24
+ Quote reply
25
+ <ActionList.TrailingVisual>⌘Q</ActionList.TrailingVisual>
26
+ </ActionList.Item>
27
+ <ActionList.Item onSelect={() => onSelect('Edit comment')}>
28
+ Edit comment
29
+ <ActionList.TrailingVisual>⌘E</ActionList.TrailingVisual>
30
+ </ActionList.Item>
31
+ <ActionList.Divider />
32
+ <ActionList.Item variant="danger" onSelect={() => onSelect('Delete file')}>
33
+ Delete file
34
+ <ActionList.TrailingVisual>⌘D</ActionList.TrailingVisual>
35
+ </ActionList.Item>
36
+ </ActionList>
37
+
38
+ </ActionMenu>
39
+ </Box>
40
+
41
+ <br />
42
+
43
+ ```js
44
+ import {ActionMenu} from '@primer/components/drafts'
45
+ ```
46
+
47
+ <br />
48
+
49
+ ## Examples
50
+
51
+ ### Minimal example
52
+
53
+ `ActionMenu` ships with `ActionMenu.Button` which is an accessible trigger for the overlay. It's recommended to compose `ActionList` with this component.
54
+
55
+ &nbsp;
56
+
57
+ ```javascript live noinline
58
+ // import {ActionMenu, ActionList} from '@primer/components/drafts'
59
+ const {ActionMenu, ActionList} = drafts // ignore docs silliness; import like that ↑
60
+
61
+ render(
62
+ <ActionMenu>
63
+ <ActionMenu.Button>Menu</ActionMenu.Button>
64
+
65
+ <ActionList>
66
+ <ActionList.Item onSelect={event => console.log('New file')}>New file</ActionList.Item>
67
+ <ActionList.Item>Copy link</ActionList.Item>
68
+ <ActionList.Item>Edit file</ActionList.Item>
69
+ <ActionList.Divider />
70
+ <ActionList.Item variant="danger">Delete file</ActionList.Item>
71
+ </ActionList>
72
+ </ActionMenu>
73
+ )
74
+ ```
75
+
76
+ ### With a custom anchor
77
+
78
+ You can choose to have a different _anchor_ for the Menu dependending on the application's context.
79
+
80
+ &nbsp;
81
+
82
+ ```javascript live noinline
83
+ // import {ActionMenu, ActionList} from '@primer/components/drafts'
84
+ const {ActionMenu, ActionList} = drafts // ignore docs silliness; import like that ↑
85
+
86
+ render(
87
+ <ActionMenu>
88
+ <ActionMenu.Anchor>
89
+ <ButtonInvisible aria-label="Open column options">
90
+ <KebabHorizontalIcon />
91
+ </ButtonInvisible>
92
+ </ActionMenu.Anchor>
93
+
94
+ <ActionList>
95
+ <ActionList.Item>
96
+ <ActionList.LeadingVisual>
97
+ <PencilIcon />
98
+ </ActionList.LeadingVisual>
99
+ Rename
100
+ </ActionList.Item>
101
+ <ActionList.Item>
102
+ <ActionList.LeadingVisual>
103
+ <ArchiveIcon />
104
+ </ActionList.LeadingVisual>
105
+ Archive all cards
106
+ </ActionList.Item>
107
+ <ActionList.Item variant="danger">
108
+ <ActionList.LeadingVisual>
109
+ <TrashIcon />
110
+ </ActionList.LeadingVisual>
111
+ Delete
112
+ </ActionList.Item>
113
+ </ActionList>
114
+ </ActionMenu>
115
+ )
116
+ ```
117
+
118
+ ### With Groups
119
+
120
+ ```javascript live noinline
121
+ // import {ActionMenu, ActionList} from '@primer/components/drafts'
122
+ const {ActionMenu, ActionList} = drafts // ignore docs silliness; import like that ↑
123
+
124
+ render(
125
+ <ActionMenu>
126
+ <ActionMenu.Button>Open column menu</ActionMenu.Button>
127
+
128
+ <ActionList showDividers>
129
+ <ActionList.Group title="Live query">
130
+ <ActionList.Item>
131
+ <ActionList.LeadingVisual>
132
+ <SearchIcon />
133
+ </ActionList.LeadingVisual>
134
+ repo:github/memex,github/github
135
+ </ActionList.Item>
136
+ </ActionList.Group>
137
+ <ActionList.Divider />
138
+ <ActionList.Group title="Layout" variant="subtle">
139
+ <ActionList.Item>
140
+ <ActionList.LeadingVisual>
141
+ <NoteIcon />
142
+ </ActionList.LeadingVisual>
143
+ Table
144
+ <ActionList.Description variant="block">
145
+ Information-dense table optimized for operations across teams
146
+ </ActionList.Description>
147
+ </ActionList.Item>
148
+ <ActionList.Item role="listitem">
149
+ <ActionList.LeadingVisual>
150
+ <ProjectIcon />
151
+ </ActionList.LeadingVisual>
152
+ Board
153
+ <ActionList.Description variant="block">Kanban-style board focused on visual states</ActionList.Description>
154
+ </ActionList.Item>
155
+ </ActionList.Group>
156
+ <ActionList.Divider />
157
+ <ActionList.Group>
158
+ <ActionList.Item>
159
+ <ActionList.LeadingVisual>
160
+ <FilterIcon />
161
+ </ActionList.LeadingVisual>
162
+ Save sort and filters to current view
163
+ </ActionList.Item>
164
+ <ActionList.Item>
165
+ <ActionList.LeadingVisual>
166
+ <FilterIcon />
167
+ </ActionList.LeadingVisual>
168
+ Save sort and filters to new view
169
+ </ActionList.Item>
170
+ </ActionList.Group>
171
+ <ActionList.Divider />
172
+ <ActionList.Group>
173
+ <ActionList.Item>
174
+ <ActionList.LeadingVisual>
175
+ <GearIcon />
176
+ </ActionList.LeadingVisual>
177
+ View settings
178
+ </ActionList.Item>
179
+ </ActionList.Group>
180
+ </ActionList>
181
+ </ActionMenu>
182
+ )
183
+ ```
184
+
185
+ ### With External Anchor
186
+
187
+ To create an anchor outside of the menu, you need to switch to controlled mode for the menu and pass it as `anchorRef` to `ActionMenu`:
188
+
189
+ ```javascript live noinline
190
+ // import {ActionMenu, ActionList} from '@primer/components/drafts'
191
+ const {ActionMenu, ActionList} = drafts // ignore docs silliness; import like that ↑
192
+
193
+ const Example = () => {
194
+ const [open, setOpen] = React.useState(false)
195
+ const anchorRef = React.createRef()
196
+
197
+ return (
198
+ <>
199
+ <Button ref={anchorRef} onClick={() => setOpen(!open)}>
200
+ {open ? 'Close Menu' : 'Open Menu'}
201
+ </Button>
202
+
203
+ <ActionMenu open={open} onOpenChange={setOpen} anchorRef={anchorRef}>
204
+ <ActionList>
205
+ <ActionList.Item>Copy link</ActionList.Item>
206
+ <ActionList.Item>Quote reply</ActionList.Item>
207
+ <ActionList.Item>Edit comment</ActionList.Item>
208
+ <ActionList.Divider />
209
+ <ActionList.Item variant="danger">Delete file</ActionList.Item>
210
+ </ActionList>
211
+ </ActionMenu>
212
+ </>
213
+ )
214
+ }
215
+
216
+ render(<Example />)
217
+ ```
218
+
219
+ ## Props / API reference
220
+
221
+ ### ActionMenu
222
+
223
+ | Name | Type | Default | Description |
224
+ | :----------- | :-------------------------------------------------- | :-----: | :----------------------------------------------------------------------------------------------------------------------- |
225
+ | children\* | `React.ReactElement[]` | - | Required. Recommended: `ActionMenu.Button` or `ActionMenu.Anchor` with [`ActionList`](/drafts/ActionList2) |
226
+ | open | `boolean` | - | Optional. If defined, will control the open/closed state of the overlay. Must be used in conjuction with `onOpenChange`. |
227
+ | onOpenChange | `(open: boolean) => void` | - | Optional. If defined, will control the open/closed state of the overlay. Must be used in conjuction with `open`. |
228
+ | anchorRef | `React.RefObject<HTMLElement>` | - | Optional. Useful for defining an external anchor |
229
+ | overlayProps | [`Partial<OverlayProps>`](/Overlay#component-props) | - | Optional. Props to be spread on the internal [`AnchoredOverlay`](/AnchoredOverlay) component. |
230
+
231
+ ### ActionMenu.Button
232
+
233
+ | Type | Default | Description |
234
+ | :-------------------------------------- | :-----: | :------------------------------------------------------------------------------------------------------------------- |
235
+ | [ButtonProps](/Buttons#component-props) | - | Optional. You can pass all of the props that you would pass to a [`Button`](/Buttons) component like `variant`, `sx` |
236
+
237
+ ### ActionMenu.Anchor
238
+
239
+ | Name | Type | Default | Description |
240
+ | :--------- | :------------------- | :-----: | :-------------------------------- |
241
+ | children\* | `React.ReactElement` | - | Required. Accepts a single child. |
242
+
243
+ ## Further reading
244
+
245
+ [Interface guidelines: Action List + Menu](https://primer.style/design/components/action-list)
246
+
247
+ ## Related components
248
+
249
+ - [ActionList](/drafts/ActionList2)
250
+ - [DropdownMenu](/DropdownMenu)
251
+ - [SelectPanel](/SelectPanel)
@@ -24,7 +24,11 @@ import {
24
24
  LawIcon,
25
25
  StarIcon,
26
26
  AlertIcon,
27
- ArrowRightIcon
27
+ ArrowRightIcon,
28
+ KebabHorizontalIcon,
29
+ PencilIcon,
30
+ ArchiveIcon,
31
+ TrashIcon
28
32
  } from '@primer/octicons-react'
29
33
  import State from '../../../components/State'
30
34
  import {Dialog as Dialog2} from '../../../../src/Dialog/Dialog'
@@ -65,6 +69,10 @@ export default {
65
69
  StarIcon,
66
70
  AlertIcon,
67
71
  ArrowRightIcon,
72
+ KebabHorizontalIcon,
73
+ PencilIcon,
74
+ ArchiveIcon,
75
+ TrashIcon,
68
76
  Dialog2,
69
77
  ConfirmationDialog,
70
78
  useConfirm,
@@ -9,7 +9,9 @@ export function ComponentChecklist({items}) {
9
9
  <>
10
10
  <H3>Alpha</H3>
11
11
  <Checklist aria-describedby="alpha">
12
- <Checklist.Item checked={items.propsDocumented}>Component props are documented.</Checklist.Item>
12
+ <Checklist.Item checked={items.propsDocumented}>
13
+ Component props are documented on <Link href="https://primer.style/react/">primer.style/react</Link>.
14
+ </Checklist.Item>
13
15
  <Checklist.Item checked={items.noUnnecessaryDeps}>
14
16
  Component does not have any unnecessary third-party dependencies.
15
17
  </Checklist.Item>
@@ -22,7 +24,13 @@ export function ComponentChecklist({items}) {
22
24
  <H3>Beta</H3>
23
25
  <Checklist aria-describedby="beta">
24
26
  <Checklist.Item checked={items.usedInProduction}>Component is used in a production application.</Checklist.Item>
25
- <Checklist.Item checked={items.usageExamplesDocumented}>Common usage examples are documented.</Checklist.Item>
27
+ <Checklist.Item checked={items.usageExamplesDocumented}>
28
+ Common usage examples are documented on <Link href="https://primer.style/react/">primer.style/react</Link>.
29
+ </Checklist.Item>
30
+ <Checklist.Item checked={items.hasStorybookStories}>
31
+ Common usage examples are documented in <Link href="https://primer.style/react/storybook">storybook</Link>{' '}
32
+ stories.
33
+ </Checklist.Item>
26
34
  <Checklist.Item checked={items.designReviewed}>
27
35
  Component has been reviewed by a systems designer and any resulting issues have been addressed.
28
36
  </Checklist.Item>
@@ -1,5 +1,6 @@
1
- /// <reference types="react" />
1
+ import React from 'react';
2
+ import { SxProp } from '../sx';
2
3
  /**
3
4
  * Visually separates `Item`s or `Group`s in an `ActionList`.
4
5
  */
5
- export declare function Divider(): JSX.Element;
6
+ export declare const Divider: React.FC<SxProp>;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.Divider = Divider;
6
+ exports.Divider = void 0;
7
7
 
8
8
  var _react = _interopRequireDefault(require("react"));
9
9
 
@@ -11,25 +11,30 @@ var _Box = _interopRequireDefault(require("../Box"));
11
11
 
12
12
  var _constants = require("../constants");
13
13
 
14
+ var _sx = require("../sx");
15
+
14
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
17
 
16
18
  /**
17
19
  * Visually separates `Item`s or `Group`s in an `ActionList`.
18
20
  */
19
- function Divider() {
21
+ const Divider = ({
22
+ sx = {}
23
+ }) => {
20
24
  return /*#__PURE__*/_react.default.createElement(_Box.default, {
21
25
  as: "li",
22
26
  role: "separator",
23
- sx: {
27
+ sx: (0, _sx.merge)({
24
28
  height: 1,
25
29
  backgroundColor: 'actionListItem.inlineDivider',
26
30
  marginTop: theme => `calc(${(0, _constants.get)('space.2')(theme)} - 1px)`,
27
31
  marginBottom: 2,
28
32
  listStyle: 'none' // hide the ::marker inserted by browser's stylesheet
29
33
 
30
- },
34
+ }, sx),
31
35
  "data-component": "ActionList.Divider"
32
36
  });
33
- }
37
+ };
34
38
 
39
+ exports.Divider = Divider;
35
40
  Divider.displayName = "Divider";
@@ -21,6 +21,8 @@ var _createSlots = _interopRequireDefault(require("../utils/create-slots"));
21
21
 
22
22
  var _List = require("./List");
23
23
 
24
+ var _MenuContext = require("./MenuContext");
25
+
24
26
  var _Selection = require("./Selection");
25
27
 
26
28
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
@@ -82,6 +84,7 @@ const Item = /*#__PURE__*/_react.default.forwardRef(({
82
84
  onSelect,
83
85
  sx: sxProp = {},
84
86
  id,
87
+ role,
85
88
  _PrivateItemWrapper,
86
89
  ...props
87
90
  }, forwardedRef) => {
@@ -90,6 +93,11 @@ const Item = /*#__PURE__*/_react.default.forwardRef(({
90
93
  showDividers
91
94
  } = _react.default.useContext(_List.ListContext);
92
95
 
96
+ const {
97
+ itemRole,
98
+ afterSelect
99
+ } = _react.default.useContext(_MenuContext.MenuContext);
100
+
93
101
  const {
94
102
  theme
95
103
  } = (0, _ThemeProvider.useTheme)();
@@ -165,17 +173,24 @@ const Item = /*#__PURE__*/_react.default.forwardRef(({
165
173
  const clickHandler = _react.default.useCallback(event => {
166
174
  if (typeof onSelect !== 'function') return;
167
175
  if (disabled) return;
168
- if (!event.defaultPrevented) onSelect(event);
169
- }, [onSelect, disabled]);
176
+
177
+ if (!event.defaultPrevented) {
178
+ onSelect(event); // if this Item is inside a Menu, close the Menu
179
+
180
+ if (typeof afterSelect === 'function') afterSelect();
181
+ }
182
+ }, [onSelect, disabled, afterSelect]);
170
183
 
171
184
  const keyPressHandler = _react.default.useCallback(event => {
172
185
  if (typeof onSelect !== 'function') return;
173
186
  if (disabled) return;
174
187
 
175
188
  if (!event.defaultPrevented && [' ', 'Enter'].includes(event.key)) {
176
- onSelect(event);
189
+ onSelect(event); // if this Item is inside a Menu, close the Menu
190
+
191
+ if (typeof afterSelect === 'function') afterSelect();
177
192
  }
178
- }, [onSelect, disabled]); // use props.id if provided, otherwise generate one.
193
+ }, [onSelect, disabled, afterSelect]); // use props.id if provided, otherwise generate one.
179
194
 
180
195
 
181
196
  const labelId = (0, _ssr.useSSRSafeId)(id);
@@ -198,7 +213,8 @@ const Item = /*#__PURE__*/_react.default.forwardRef(({
198
213
  "aria-disabled": disabled ? true : undefined,
199
214
  tabIndex: disabled || _PrivateItemWrapper ? undefined : 0,
200
215
  "aria-labelledby": `${labelId} ${slots.InlineDescription ? inlineDescriptionId : ''}`,
201
- "aria-describedby": slots.BlockDescription ? blockDescriptionId : undefined
216
+ "aria-describedby": slots.BlockDescription ? blockDescriptionId : undefined,
217
+ role: role || itemRole
202
218
  }, props), /*#__PURE__*/_react.default.createElement(ItemWrapper, null, /*#__PURE__*/_react.default.createElement(_Selection.Selection, {
203
219
  selected: selected
204
220
  }), slots.LeadingVisual, /*#__PURE__*/_react.default.createElement(_Box.default, {