@primer/components 33.0.0-rc.b495ba4a → 33.1.0-rc.6856bcf5

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