@primer/components 32.1.1-rc.b4502a34 → 33.0.0-rc.9f3670b7

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.
Files changed (112) hide show
  1. package/CHANGELOG.md +15 -1
  2. package/contributor-docs/CONTRIBUTING.md +14 -58
  3. package/dist/browser.esm.js +104 -108
  4. package/dist/browser.esm.js.map +1 -1
  5. package/dist/browser.umd.js +104 -108
  6. package/dist/browser.umd.js.map +1 -1
  7. package/docs/content/BranchName.md +6 -5
  8. package/docs/content/Details.md +4 -8
  9. package/docs/content/Heading.md +5 -10
  10. package/docs/content/Label.md +6 -7
  11. package/docs/content/ProgressBar.mdx +7 -6
  12. package/docs/content/Text.md +0 -6
  13. package/docs/content/{ActionList2.mdx → drafts/ActionList2.mdx} +5 -9
  14. package/docs/content/drafts/ActionMenu2.mdx +251 -0
  15. package/docs/content/status.mdx +1 -1
  16. package/docs/content/system-props.mdx +1 -1
  17. package/docs/src/@primer/gatsby-theme-doctocat/live-code-scope.js +9 -1
  18. package/docs/src/@primer/gatsby-theme-doctocat/nav.yml +1 -1
  19. package/lib/ActionList2/Divider.d.ts +3 -2
  20. package/lib/ActionList2/Divider.js +10 -5
  21. package/lib/ActionList2/Item.js +21 -5
  22. package/lib/ActionList2/List.js +11 -1
  23. package/lib/ActionList2/MenuContext.d.ts +10 -0
  24. package/lib/ActionList2/MenuContext.js +15 -0
  25. package/lib/ActionList2/Selection.js +11 -0
  26. package/lib/ActionList2/index.d.ts +1 -2
  27. package/lib/ActionMenu2.d.ts +310 -0
  28. package/lib/ActionMenu2.js +91 -0
  29. package/lib/Avatar.d.ts +1 -2
  30. package/lib/Avatar.js +1 -1
  31. package/lib/BranchName.d.ts +1 -2
  32. package/lib/BranchName.js +1 -1
  33. package/lib/Details.d.ts +1 -2
  34. package/lib/Details.js +1 -3
  35. package/lib/Dropdown.d.ts +2 -66
  36. package/lib/Heading.d.ts +1 -2
  37. package/lib/Heading.js +1 -6
  38. package/lib/ProgressBar.d.ts +16 -11
  39. package/lib/ProgressBar.js +6 -10
  40. package/lib/Spinner.d.ts +1 -2
  41. package/lib/Spinner.js +1 -3
  42. package/lib/__tests__/Avatar.test.js +4 -2
  43. package/lib/__tests__/Avatar.types.test.d.ts +3 -0
  44. package/lib/__tests__/Avatar.types.test.js +31 -0
  45. package/lib/__tests__/BranchName.types.test.d.ts +3 -0
  46. package/lib/__tests__/BranchName.types.test.js +28 -0
  47. package/lib/__tests__/Details.types.test.d.ts +3 -0
  48. package/lib/__tests__/Details.types.test.js +28 -0
  49. package/lib/__tests__/Heading.test.js +63 -30
  50. package/lib/__tests__/Heading.types.test.d.ts +3 -0
  51. package/lib/__tests__/Heading.types.test.js +28 -0
  52. package/lib/drafts.d.ts +1 -0
  53. package/lib/drafts.js +13 -0
  54. package/lib/stories/ActionMenu2.stories.js +433 -0
  55. package/lib-esm/ActionList2/Divider.d.ts +3 -2
  56. package/lib-esm/ActionList2/Divider.js +8 -5
  57. package/lib-esm/ActionList2/Item.js +19 -5
  58. package/lib-esm/ActionList2/List.js +9 -1
  59. package/lib-esm/ActionList2/MenuContext.d.ts +10 -0
  60. package/lib-esm/ActionList2/MenuContext.js +3 -0
  61. package/lib-esm/ActionList2/Selection.js +9 -0
  62. package/lib-esm/ActionList2/index.d.ts +1 -2
  63. package/lib-esm/ActionMenu2.d.ts +310 -0
  64. package/lib-esm/ActionMenu2.js +67 -0
  65. package/lib-esm/Avatar.d.ts +1 -2
  66. package/lib-esm/Avatar.js +2 -2
  67. package/lib-esm/BranchName.d.ts +1 -2
  68. package/lib-esm/BranchName.js +2 -2
  69. package/lib-esm/Details.d.ts +1 -2
  70. package/lib-esm/Details.js +1 -2
  71. package/lib-esm/Dropdown.d.ts +2 -66
  72. package/lib-esm/Heading.d.ts +1 -2
  73. package/lib-esm/Heading.js +2 -6
  74. package/lib-esm/ProgressBar.d.ts +16 -11
  75. package/lib-esm/ProgressBar.js +7 -11
  76. package/lib-esm/Spinner.d.ts +1 -2
  77. package/lib-esm/Spinner.js +1 -2
  78. package/lib-esm/__tests__/Avatar.test.js +4 -2
  79. package/lib-esm/__tests__/Avatar.types.test.d.ts +3 -0
  80. package/lib-esm/__tests__/Avatar.types.test.js +16 -0
  81. package/lib-esm/__tests__/BranchName.types.test.d.ts +3 -0
  82. package/lib-esm/__tests__/BranchName.types.test.js +13 -0
  83. package/lib-esm/__tests__/Details.types.test.d.ts +3 -0
  84. package/lib-esm/__tests__/Details.types.test.js +13 -0
  85. package/lib-esm/__tests__/Heading.test.js +62 -30
  86. package/lib-esm/__tests__/Heading.types.test.d.ts +3 -0
  87. package/lib-esm/__tests__/Heading.types.test.js +13 -0
  88. package/lib-esm/drafts.d.ts +1 -0
  89. package/lib-esm/drafts.js +2 -1
  90. package/lib-esm/stories/ActionMenu2.stories.js +376 -0
  91. package/package.json +1 -1
  92. package/src/ActionList2/Divider.tsx +13 -8
  93. package/src/ActionList2/Item.tsx +13 -3
  94. package/src/ActionList2/List.tsx +6 -2
  95. package/src/ActionList2/MenuContext.tsx +6 -0
  96. package/src/ActionList2/Selection.tsx +9 -0
  97. package/src/ActionMenu2.tsx +94 -0
  98. package/src/Avatar.tsx +2 -4
  99. package/src/BranchName.tsx +3 -3
  100. package/src/Details.tsx +1 -5
  101. package/src/Heading.tsx +2 -9
  102. package/src/ProgressBar.tsx +11 -10
  103. package/src/Spinner.tsx +1 -3
  104. package/src/__tests__/Avatar.test.tsx +1 -1
  105. package/src/__tests__/Avatar.types.test.tsx +11 -0
  106. package/src/__tests__/BranchName.types.test.tsx +11 -0
  107. package/src/__tests__/Details.types.test.tsx +11 -0
  108. package/src/__tests__/Heading.test.tsx +71 -25
  109. package/src/__tests__/Heading.types.test.tsx +11 -0
  110. package/src/drafts.ts +1 -0
  111. package/src/stories/ActionMenu2.stories.tsx +551 -0
  112. package/stats.html +1 -1
@@ -0,0 +1,551 @@
1
+ import React from 'react'
2
+ import {Meta} from '@storybook/react'
3
+ import {ThemeProvider} from '..'
4
+ import BaseStyles from '../BaseStyles'
5
+ import {ActionMenu} from '../ActionMenu2'
6
+ import {ActionList} from '../ActionList2'
7
+ import Button, {ButtonInvisible} from '../Button'
8
+ import Box from '../Box'
9
+ import Text from '../Text'
10
+ import TextInput from '../TextInput'
11
+ import StyledOcticon from '../StyledOcticon'
12
+ import FormGroup from '../FormGroup'
13
+ import {
14
+ ServerIcon,
15
+ PlusCircleIcon,
16
+ TriangleDownIcon,
17
+ KebabHorizontalIcon,
18
+ PencilIcon,
19
+ ArchiveIcon,
20
+ TrashIcon,
21
+ ProjectIcon,
22
+ ListUnorderedIcon,
23
+ ArrowDownIcon,
24
+ SearchIcon,
25
+ VersionsIcon,
26
+ TableIcon,
27
+ IconProps
28
+ } from '@primer/octicons-react'
29
+
30
+ const meta: Meta = {
31
+ title: 'Composite components/ActionMenu2',
32
+ component: ActionMenu,
33
+ decorators: [
34
+ (Story: React.ComponentType): JSX.Element => (
35
+ <ThemeProvider>
36
+ <BaseStyles>
37
+ <Story />
38
+ </BaseStyles>
39
+ </ThemeProvider>
40
+ )
41
+ ],
42
+ parameters: {
43
+ controls: {
44
+ disabled: true
45
+ }
46
+ }
47
+ }
48
+ export default meta
49
+
50
+ export function SimpleListStory(): JSX.Element {
51
+ const [actionFired, fireAction] = React.useState('')
52
+ const onSelect = (name: string) => fireAction(name)
53
+
54
+ return (
55
+ <>
56
+ <h1>Simple Menu</h1>
57
+ <h2>Last option activated: {actionFired}</h2>
58
+ <ActionMenu>
59
+ <ActionMenu.Button>Menu</ActionMenu.Button>
60
+
61
+ <ActionList>
62
+ <ActionList.Item onSelect={() => onSelect('Copy link')}>
63
+ Copy link
64
+ <ActionList.TrailingVisual>⌘C</ActionList.TrailingVisual>
65
+ </ActionList.Item>
66
+ <ActionList.Item onSelect={() => onSelect('Quote reply')}>
67
+ Quote reply
68
+ <ActionList.TrailingVisual>⌘Q</ActionList.TrailingVisual>
69
+ </ActionList.Item>
70
+ <ActionList.Item onSelect={() => onSelect('Edit comment')}>
71
+ Edit comment
72
+ <ActionList.TrailingVisual>⌘E</ActionList.TrailingVisual>
73
+ </ActionList.Item>
74
+ <ActionList.Divider />
75
+ <ActionList.Item variant="danger" onSelect={() => onSelect('Delete file')}>
76
+ Delete file
77
+ <ActionList.TrailingVisual>⌘D</ActionList.TrailingVisual>
78
+ </ActionList.Item>
79
+ </ActionList>
80
+ </ActionMenu>
81
+ </>
82
+ )
83
+ }
84
+ SimpleListStory.storyName = 'Simple Menu'
85
+
86
+ export function ActionsStory(): JSX.Element {
87
+ return (
88
+ <>
89
+ <h1>Actions</h1>
90
+
91
+ <ActionMenu overlayProps={{width: 'medium'}}>
92
+ <ActionMenu.Button aria-label="Open Actions Menu">
93
+ <ServerIcon />
94
+ </ActionMenu.Button>
95
+ <ActionList>
96
+ <ActionList.Item>
97
+ <ActionList.LeadingVisual>
98
+ <ServerIcon />
99
+ </ActionList.LeadingVisual>
100
+ Open current Codespace
101
+ <ActionList.Description variant="block">
102
+ Your existing Codespace will be opened to its previous state, and you&apos;ll be asked to manually switch
103
+ to new-branch.
104
+ </ActionList.Description>
105
+ <ActionList.TrailingVisual>⌘O</ActionList.TrailingVisual>
106
+ </ActionList.Item>
107
+ <ActionList.Item>
108
+ <ActionList.LeadingVisual>
109
+ <PlusCircleIcon />
110
+ </ActionList.LeadingVisual>
111
+ Create new Codespace
112
+ <ActionList.Description variant="block">
113
+ Create a brand new Codespace with a fresh image and checkout this branch.
114
+ </ActionList.Description>
115
+ <ActionList.TrailingVisual>⌘C</ActionList.TrailingVisual>
116
+ </ActionList.Item>
117
+ </ActionList>
118
+ </ActionMenu>
119
+ </>
120
+ )
121
+ }
122
+ ActionsStory.storyName = 'Actions'
123
+
124
+ export function ExternalAnchor(): JSX.Element {
125
+ const [actionFired, fireAction] = React.useState('')
126
+ const onSelect = (name: string) => fireAction(name)
127
+
128
+ const [open, setOpen] = React.useState(false)
129
+ const triggerRef = React.createRef<HTMLButtonElement>()
130
+
131
+ return (
132
+ <>
133
+ <h1>External Anchor</h1>
134
+ <h2>External Open State: {open ? 'Open' : 'Closed'}</h2>
135
+ <h2>Last option activated: {actionFired}</h2>
136
+ <div>
137
+ <Button ref={triggerRef} onClick={() => setOpen(!open)}>
138
+ {open ? 'Close Menu' : 'Open Menu'}
139
+ </Button>
140
+ </div>
141
+ <br />
142
+
143
+ <ActionMenu open={open} onOpenChange={setOpen} anchorRef={triggerRef}>
144
+ <ActionList>
145
+ <ActionList.Item onSelect={() => onSelect('Copy link')}>
146
+ Copy link
147
+ <ActionList.TrailingVisual>⌘C</ActionList.TrailingVisual>
148
+ </ActionList.Item>
149
+ <ActionList.Item onSelect={() => onSelect('Quote reply')}>
150
+ Quote reply
151
+ <ActionList.TrailingVisual>⌘Q</ActionList.TrailingVisual>
152
+ </ActionList.Item>
153
+ <ActionList.Item onSelect={() => onSelect('Edit comment')}>
154
+ Edit comment
155
+ <ActionList.TrailingVisual>⌘E</ActionList.TrailingVisual>
156
+ </ActionList.Item>
157
+ <ActionList.Divider />
158
+ <ActionList.Item variant="danger" onSelect={() => onSelect('Delete file')}>
159
+ Delete file
160
+ <ActionList.TrailingVisual>⌘D</ActionList.TrailingVisual>
161
+ </ActionList.Item>
162
+ </ActionList>
163
+ </ActionMenu>
164
+ </>
165
+ )
166
+ }
167
+ ExternalAnchor.storyName = 'External Anchor'
168
+
169
+ export function ControlledMenu(): JSX.Element {
170
+ const [actionFired, fireAction] = React.useState('')
171
+ const onSelect = (name: string) => fireAction(name)
172
+
173
+ const [open, setOpen] = React.useState(false)
174
+ const triggerRef = React.createRef<HTMLButtonElement>()
175
+
176
+ return (
177
+ <>
178
+ <h1>Controlled Menu</h1>
179
+ <h2>External Open State: {open ? 'Open' : 'Closed'}</h2>
180
+ <h2>Last option activated: {actionFired}</h2>
181
+ <div>
182
+ <Button ref={triggerRef} onClick={() => setOpen(!open)}>
183
+ {open ? 'Close Menu' : 'Open Menu'}
184
+ </Button>
185
+ </div>
186
+ <br />
187
+
188
+ <ActionMenu
189
+ open={open}
190
+ onOpenChange={setOpen}
191
+ overlayProps={{
192
+ // Because the component is controlled from outside, but the anchor is still internal,
193
+ // clicking the external button should not be counted as "clicking outside"
194
+ ignoreClickRefs: [triggerRef]
195
+ }}
196
+ >
197
+ {/**
198
+ * Even though the state is controlled externally,
199
+ * we can pass an Anchor for the menu to "anchor to"
200
+ */}
201
+ <ActionMenu.Button>Anchor</ActionMenu.Button>
202
+ <ActionList>
203
+ <ActionList.Item onSelect={() => onSelect('Copy link')}>
204
+ Copy link
205
+ <ActionList.TrailingVisual>⌘C</ActionList.TrailingVisual>
206
+ </ActionList.Item>
207
+ <ActionList.Item onSelect={() => onSelect('Quote reply')}>
208
+ Quote reply
209
+ <ActionList.TrailingVisual>⌘Q</ActionList.TrailingVisual>
210
+ </ActionList.Item>
211
+ <ActionList.Item onSelect={() => onSelect('Edit comment')}>
212
+ Edit comment
213
+ <ActionList.TrailingVisual>⌘E</ActionList.TrailingVisual>
214
+ </ActionList.Item>
215
+ <ActionList.Divider />
216
+ <ActionList.Item variant="danger" onSelect={() => onSelect('Delete file')}>
217
+ Delete file
218
+ <ActionList.TrailingVisual>⌘D</ActionList.TrailingVisual>
219
+ </ActionList.Item>
220
+ </ActionList>
221
+ </ActionMenu>
222
+ </>
223
+ )
224
+ }
225
+ ControlledMenu.storyName = 'Controlled Menu'
226
+
227
+ export function CustomAnchor(): JSX.Element {
228
+ const [actionFired, fireAction] = React.useState('')
229
+ const onSelect = (name: string) => fireAction(name)
230
+
231
+ return (
232
+ <>
233
+ <h1>Custom Anchor</h1>
234
+ <h2>Last option activated: {actionFired}</h2>
235
+ <ActionMenu>
236
+ <ActionMenu.Anchor>
237
+ <summary style={{cursor: 'pointer'}} aria-label="Open column options">
238
+ <KebabHorizontalIcon />
239
+ </summary>
240
+ </ActionMenu.Anchor>
241
+
242
+ <ActionList>
243
+ <ActionList.Item onSelect={() => onSelect('Rename')}>
244
+ <ActionList.LeadingVisual>
245
+ <PencilIcon />
246
+ </ActionList.LeadingVisual>
247
+ Rename
248
+ </ActionList.Item>
249
+ <ActionList.Item onSelect={() => onSelect('Archive')}>
250
+ <ActionList.LeadingVisual>
251
+ <ArchiveIcon />
252
+ </ActionList.LeadingVisual>
253
+ Archive all cards
254
+ </ActionList.Item>
255
+ <ActionList.Item variant="danger" onSelect={() => onSelect('Delete file')}>
256
+ <ActionList.LeadingVisual>
257
+ <TrashIcon />
258
+ </ActionList.LeadingVisual>
259
+ Delete
260
+ </ActionList.Item>
261
+ </ActionList>
262
+ </ActionMenu>
263
+ </>
264
+ )
265
+ }
266
+ CustomAnchor.storyName = 'Custom Anchor'
267
+
268
+ export function MemexTableMenu(): JSX.Element {
269
+ const [name, setName] = React.useState('Estimate')
270
+ const inputRef = React.createRef<HTMLInputElement>()
271
+
272
+ /** To add custom components to the Menu,
273
+ * you need to switch to a controlled menu
274
+ */
275
+ const [open, setOpen] = React.useState(false)
276
+ const handleKeyPress = (event: React.KeyboardEvent<HTMLInputElement>) => {
277
+ if (event.key === 'Enter') {
278
+ setName(event.currentTarget.value)
279
+ setOpen(false)
280
+ }
281
+ }
282
+
283
+ /** This requires inside knowledge. If you to do this with onBlur
284
+ * on the input, it doesn't work :(
285
+ */
286
+ const handleClickOutside = () => {
287
+ if (inputRef.current) setName(inputRef.current.value)
288
+ setOpen(false)
289
+ }
290
+
291
+ return (
292
+ <>
293
+ <h1>Memex Table Menu</h1>
294
+ <Box
295
+ sx={{
296
+ width: 200,
297
+ display: 'flex',
298
+ justifyContent: 'space-between',
299
+ p: 2,
300
+ border: '1px solid',
301
+ borderColor: 'border.default'
302
+ }}
303
+ >
304
+ <Text sx={{fontSize: 0, fontWeight: 'bold'}}>{name}</Text>
305
+ <ActionMenu open={open} onOpenChange={setOpen} overlayProps={{onClickOutside: handleClickOutside}}>
306
+ <ActionMenu.Button
307
+ aria-label="Open Estimate column options menu"
308
+ sx={{
309
+ p: 0,
310
+ display: 'flex',
311
+ alignItems: 'center',
312
+ justifyContent: 'center'
313
+ }}
314
+ >
315
+ <TriangleDownIcon />
316
+ </ActionMenu.Button>
317
+
318
+ <TextInput ref={inputRef} sx={{m: 2}} defaultValue={name} onKeyPress={handleKeyPress} />
319
+ <ActionMenu.Divider sx={{m: 0}} />
320
+
321
+ <ActionList>
322
+ <ActionList.Item>Sort ascending (123...)</ActionList.Item>
323
+ <ActionList.Item>Sort descending (123...)</ActionList.Item>
324
+ <ActionList.Divider />
325
+ <ActionList.Item>Filter by values</ActionList.Item>
326
+ <ActionList.Item>Group by values</ActionList.Item>
327
+ <ActionList.Divider />
328
+ <ActionList.Item disabled>Hide field</ActionList.Item>
329
+ <ActionList.Item variant="danger">Delete file</ActionList.Item>
330
+ </ActionList>
331
+ </ActionMenu>
332
+ </Box>
333
+ </>
334
+ )
335
+ }
336
+ MemexTableMenu.storyName = 'Memex Table Menu'
337
+
338
+ /* copied from github/memex */
339
+ const LayoutToggleItem = ({
340
+ selected,
341
+ children,
342
+ Icon,
343
+ ...props
344
+ }: {
345
+ selected: boolean
346
+ children: React.ReactNode
347
+ Icon: React.ComponentType<IconProps>
348
+ }) => {
349
+ return (
350
+ <FormGroup
351
+ sx={{
352
+ flex: 'auto',
353
+ borderRadius: 2,
354
+ border: '1px solid',
355
+ borderColor: selected ? 'accent.emphasis' : 'border.default',
356
+ textAlign: 'center',
357
+ cursor: 'pointer',
358
+ backgroundColor: selected ? 'accent.subtle' : '',
359
+ boxShadow: selected ? theme => `inset 0 0 0 1px ${theme.colors.accent.emphasis}` : '',
360
+ mb: 2,
361
+ mt: 1,
362
+ '&:hover': {
363
+ backgroundColor: !selected ? 'canvas.subtle' : ''
364
+ },
365
+ '&:first-of-type': {
366
+ borderTopRightRadius: '0px',
367
+ borderBottomRightRadius: '0px',
368
+ borderRight: selected ? undefined : '0'
369
+ },
370
+ '&:last-of-type': {
371
+ borderTopLeftRadius: '0px',
372
+ borderBottomLeftRadius: '0px',
373
+ borderLeft: selected ? undefined : '0'
374
+ }
375
+ }}
376
+ >
377
+ <FormGroup.Label
378
+ htmlFor="layout-selector"
379
+ sx={{fontWeight: 'normal', cursor: 'pointer', px: 3, py: 2, mb: 0}}
380
+ {...props}
381
+ >
382
+ <Box sx={{textAlign: 'center', flexDirection: 'column', m: 'auto', alignItems: 'center', display: 'flex'}}>
383
+ <Icon size="medium" />
384
+ <Text sx={{color: selected ? 'fg.default' : 'fg.muted', fontSize: 0}}>{children}</Text>
385
+ </Box>
386
+ </FormGroup.Label>
387
+ </FormGroup>
388
+ )
389
+ }
390
+
391
+ /* copied from github/memex */
392
+ const ViewChangeButtons = ({setOpen}: {setOpen: (open: boolean) => void}) => (
393
+ <Box sx={{display: 'flex'}}>
394
+ <ButtonInvisible
395
+ onClick={() => setOpen(false)}
396
+ sx={{
397
+ flex: 'auto',
398
+ minWidth: '50%',
399
+ borderRight: '1px solid',
400
+ borderColor: 'border.default',
401
+ borderRadius: 0,
402
+ mt: -2,
403
+ mb: -2,
404
+ py: 3,
405
+ '&:hover': {
406
+ bg: 'canvas.inset'
407
+ }
408
+ }}
409
+ >
410
+ Save changes
411
+ </ButtonInvisible>
412
+
413
+ <ButtonInvisible
414
+ onClick={() => setOpen(false)}
415
+ sx={{
416
+ flex: 'auto',
417
+ color: 'fg.muted',
418
+ borderRadius: 0,
419
+ mt: -2,
420
+ mb: -2,
421
+ py: 3,
422
+ fontWeight: 'normal',
423
+ '&:hover': {
424
+ bg: 'canvas.inset'
425
+ }
426
+ }}
427
+ >
428
+ Discard changes
429
+ </ButtonInvisible>
430
+ </Box>
431
+ )
432
+
433
+ export function MemexViewOptionsMenu(): JSX.Element {
434
+ const [open, setOpen] = React.useState(false)
435
+
436
+ return (
437
+ <>
438
+ <h1>Memex View Options Menu</h1>
439
+ <Box sx={{display: 'flex', alignItems: 'center'}}>
440
+ <Text sx={{fontSize: 1, mr: 3}}>
441
+ <StyledOcticon icon={ProjectIcon} sx={{mr: 2}} />
442
+ React
443
+ </Text>
444
+ <ActionMenu open={open} onOpenChange={setOpen} overlayProps={{width: 'medium'}}>
445
+ <ActionMenu.Button
446
+ aria-label="Open View options menu"
447
+ sx={{
448
+ p: 0,
449
+ width: 18,
450
+ height: 18,
451
+ display: 'flex',
452
+ alignItems: 'center',
453
+ justifyContent: 'center'
454
+ }}
455
+ >
456
+ <TriangleDownIcon />
457
+ </ActionMenu.Button>
458
+
459
+ <ActionList>
460
+ <ActionList.Group title="Layout">
461
+ <li style={{listStyle: 'none'}}>
462
+ <Box sx={{mx: 3, display: 'flex'}}>
463
+ <LayoutToggleItem selected Icon={TableIcon}>
464
+ Table
465
+ </LayoutToggleItem>
466
+ <LayoutToggleItem selected={false} Icon={ProjectIcon}>
467
+ Board
468
+ </LayoutToggleItem>
469
+ </Box>
470
+ </li>
471
+ </ActionList.Group>
472
+ <ActionList.Divider />
473
+
474
+ <ActionList.Group title="Configuration">
475
+ <ActionList.Item>
476
+ <ActionList.LeadingVisual>
477
+ <ListUnorderedIcon />
478
+ </ActionList.LeadingVisual>
479
+ Title, Assignees, Status, Labels, Repositories
480
+ </ActionList.Item>
481
+ <ActionList.Item>
482
+ <ActionList.LeadingVisual>
483
+ <ListUnorderedIcon />
484
+ </ActionList.LeadingVisual>
485
+ group: none
486
+ </ActionList.Item>
487
+ <ActionList.Item>
488
+ <ActionList.LeadingVisual>
489
+ <ArrowDownIcon />
490
+ </ActionList.LeadingVisual>
491
+ sort: manual
492
+ </ActionList.Item>
493
+ <ActionList.Item>
494
+ <ActionList.LeadingVisual>
495
+ <SearchIcon />
496
+ </ActionList.LeadingVisual>
497
+ Search or filter this view
498
+ </ActionList.Item>
499
+ </ActionList.Group>
500
+ <ActionList.Divider />
501
+ <ActionList.Item>
502
+ <ActionList.LeadingVisual>
503
+ <PencilIcon />
504
+ </ActionList.LeadingVisual>
505
+ Rename view
506
+ </ActionList.Item>
507
+ <ActionList.Item>
508
+ <ActionList.LeadingVisual>
509
+ <VersionsIcon />
510
+ </ActionList.LeadingVisual>
511
+ Save changes to new view
512
+ </ActionList.Item>
513
+ <ActionList.Item disabled>
514
+ <ActionList.LeadingVisual>
515
+ <TrashIcon />
516
+ </ActionList.LeadingVisual>
517
+ Delete view
518
+ </ActionList.Item>
519
+ <ActionList.Divider />
520
+
521
+ <li style={{listStyle: 'none'}}>
522
+ <ViewChangeButtons setOpen={setOpen} />
523
+ </li>
524
+ </ActionList>
525
+ </ActionMenu>
526
+ </Box>
527
+ </>
528
+ )
529
+ }
530
+ MemexViewOptionsMenu.storyName = 'Memex View Options Menu'
531
+
532
+ export function UnexpectedSelectionVariant(): JSX.Element {
533
+ return (
534
+ <>
535
+ <h1>Expect error if selectionVariant is passed</h1>
536
+
537
+ <ActionMenu>
538
+ <ActionMenu.Button>Menu</ActionMenu.Button>
539
+
540
+ <ActionList selectionVariant="multiple">
541
+ <ActionList.Item>Copy link</ActionList.Item>
542
+ <ActionList.Item>Quote reply</ActionList.Item>
543
+ <ActionList.Item>Edit comment</ActionList.Item>
544
+ <ActionList.Divider />
545
+ <ActionList.Item variant="danger">Delete file</ActionList.Item>
546
+ </ActionList>
547
+ </ActionMenu>
548
+ </>
549
+ )
550
+ }
551
+ UnexpectedSelectionVariant.storyName = 'Unexpected selectionVariant'