@primer/components 32.1.1-rc.b4502a34 → 33.0.0-rc.9f3670b7
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +15 -1
- package/contributor-docs/CONTRIBUTING.md +14 -58
- package/dist/browser.esm.js +104 -108
- package/dist/browser.esm.js.map +1 -1
- package/dist/browser.umd.js +104 -108
- package/dist/browser.umd.js.map +1 -1
- package/docs/content/BranchName.md +6 -5
- package/docs/content/Details.md +4 -8
- package/docs/content/Heading.md +5 -10
- package/docs/content/Label.md +6 -7
- package/docs/content/ProgressBar.mdx +7 -6
- package/docs/content/Text.md +0 -6
- package/docs/content/{ActionList2.mdx → drafts/ActionList2.mdx} +5 -9
- package/docs/content/drafts/ActionMenu2.mdx +251 -0
- package/docs/content/status.mdx +1 -1
- package/docs/content/system-props.mdx +1 -1
- package/docs/src/@primer/gatsby-theme-doctocat/live-code-scope.js +9 -1
- package/docs/src/@primer/gatsby-theme-doctocat/nav.yml +1 -1
- package/lib/ActionList2/Divider.d.ts +3 -2
- package/lib/ActionList2/Divider.js +10 -5
- package/lib/ActionList2/Item.js +21 -5
- package/lib/ActionList2/List.js +11 -1
- package/lib/ActionList2/MenuContext.d.ts +10 -0
- package/lib/ActionList2/MenuContext.js +15 -0
- package/lib/ActionList2/Selection.js +11 -0
- package/lib/ActionList2/index.d.ts +1 -2
- package/lib/ActionMenu2.d.ts +310 -0
- package/lib/ActionMenu2.js +91 -0
- package/lib/Avatar.d.ts +1 -2
- package/lib/Avatar.js +1 -1
- package/lib/BranchName.d.ts +1 -2
- package/lib/BranchName.js +1 -1
- package/lib/Details.d.ts +1 -2
- package/lib/Details.js +1 -3
- package/lib/Dropdown.d.ts +2 -66
- package/lib/Heading.d.ts +1 -2
- package/lib/Heading.js +1 -6
- package/lib/ProgressBar.d.ts +16 -11
- package/lib/ProgressBar.js +6 -10
- package/lib/Spinner.d.ts +1 -2
- package/lib/Spinner.js +1 -3
- package/lib/__tests__/Avatar.test.js +4 -2
- package/lib/__tests__/Avatar.types.test.d.ts +3 -0
- package/lib/__tests__/Avatar.types.test.js +31 -0
- package/lib/__tests__/BranchName.types.test.d.ts +3 -0
- package/lib/__tests__/BranchName.types.test.js +28 -0
- package/lib/__tests__/Details.types.test.d.ts +3 -0
- package/lib/__tests__/Details.types.test.js +28 -0
- package/lib/__tests__/Heading.test.js +63 -30
- package/lib/__tests__/Heading.types.test.d.ts +3 -0
- package/lib/__tests__/Heading.types.test.js +28 -0
- package/lib/drafts.d.ts +1 -0
- package/lib/drafts.js +13 -0
- package/lib/stories/ActionMenu2.stories.js +433 -0
- package/lib-esm/ActionList2/Divider.d.ts +3 -2
- package/lib-esm/ActionList2/Divider.js +8 -5
- package/lib-esm/ActionList2/Item.js +19 -5
- package/lib-esm/ActionList2/List.js +9 -1
- package/lib-esm/ActionList2/MenuContext.d.ts +10 -0
- package/lib-esm/ActionList2/MenuContext.js +3 -0
- package/lib-esm/ActionList2/Selection.js +9 -0
- package/lib-esm/ActionList2/index.d.ts +1 -2
- package/lib-esm/ActionMenu2.d.ts +310 -0
- package/lib-esm/ActionMenu2.js +67 -0
- package/lib-esm/Avatar.d.ts +1 -2
- package/lib-esm/Avatar.js +2 -2
- package/lib-esm/BranchName.d.ts +1 -2
- package/lib-esm/BranchName.js +2 -2
- package/lib-esm/Details.d.ts +1 -2
- package/lib-esm/Details.js +1 -2
- package/lib-esm/Dropdown.d.ts +2 -66
- package/lib-esm/Heading.d.ts +1 -2
- package/lib-esm/Heading.js +2 -6
- package/lib-esm/ProgressBar.d.ts +16 -11
- package/lib-esm/ProgressBar.js +7 -11
- package/lib-esm/Spinner.d.ts +1 -2
- package/lib-esm/Spinner.js +1 -2
- package/lib-esm/__tests__/Avatar.test.js +4 -2
- package/lib-esm/__tests__/Avatar.types.test.d.ts +3 -0
- package/lib-esm/__tests__/Avatar.types.test.js +16 -0
- package/lib-esm/__tests__/BranchName.types.test.d.ts +3 -0
- package/lib-esm/__tests__/BranchName.types.test.js +13 -0
- package/lib-esm/__tests__/Details.types.test.d.ts +3 -0
- package/lib-esm/__tests__/Details.types.test.js +13 -0
- package/lib-esm/__tests__/Heading.test.js +62 -30
- package/lib-esm/__tests__/Heading.types.test.d.ts +3 -0
- package/lib-esm/__tests__/Heading.types.test.js +13 -0
- package/lib-esm/drafts.d.ts +1 -0
- package/lib-esm/drafts.js +2 -1
- package/lib-esm/stories/ActionMenu2.stories.js +376 -0
- package/package.json +1 -1
- package/src/ActionList2/Divider.tsx +13 -8
- package/src/ActionList2/Item.tsx +13 -3
- package/src/ActionList2/List.tsx +6 -2
- package/src/ActionList2/MenuContext.tsx +6 -0
- package/src/ActionList2/Selection.tsx +9 -0
- package/src/ActionMenu2.tsx +94 -0
- package/src/Avatar.tsx +2 -4
- package/src/BranchName.tsx +3 -3
- package/src/Details.tsx +1 -5
- package/src/Heading.tsx +2 -9
- package/src/ProgressBar.tsx +11 -10
- package/src/Spinner.tsx +1 -3
- package/src/__tests__/Avatar.test.tsx +1 -1
- package/src/__tests__/Avatar.types.test.tsx +11 -0
- package/src/__tests__/BranchName.types.test.tsx +11 -0
- package/src/__tests__/Details.types.test.tsx +11 -0
- package/src/__tests__/Heading.test.tsx +71 -25
- package/src/__tests__/Heading.types.test.tsx +11 -0
- package/src/drafts.ts +1 -0
- package/src/stories/ActionMenu2.stories.tsx +551 -0
- package/stats.html +1 -1
@@ -0,0 +1,376 @@
|
|
1
|
+
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
2
|
+
|
3
|
+
import React from 'react';
|
4
|
+
import { ThemeProvider } from '..';
|
5
|
+
import BaseStyles from '../BaseStyles';
|
6
|
+
import { ActionMenu } from '../ActionMenu2';
|
7
|
+
import { ActionList } from '../ActionList2';
|
8
|
+
import Button, { ButtonInvisible } from '../Button';
|
9
|
+
import Box from '../Box';
|
10
|
+
import Text from '../Text';
|
11
|
+
import TextInput from '../TextInput';
|
12
|
+
import StyledOcticon from '../StyledOcticon';
|
13
|
+
import FormGroup from '../FormGroup';
|
14
|
+
import { ServerIcon, PlusCircleIcon, TriangleDownIcon, KebabHorizontalIcon, PencilIcon, ArchiveIcon, TrashIcon, ProjectIcon, ListUnorderedIcon, ArrowDownIcon, SearchIcon, VersionsIcon, TableIcon } from '@primer/octicons-react';
|
15
|
+
const meta = {
|
16
|
+
title: 'Composite components/ActionMenu2',
|
17
|
+
component: ActionMenu,
|
18
|
+
decorators: [Story => /*#__PURE__*/React.createElement(ThemeProvider, null, /*#__PURE__*/React.createElement(BaseStyles, null, /*#__PURE__*/React.createElement(Story, null)))],
|
19
|
+
parameters: {
|
20
|
+
controls: {
|
21
|
+
disabled: true
|
22
|
+
}
|
23
|
+
}
|
24
|
+
};
|
25
|
+
export default meta;
|
26
|
+
export function SimpleListStory() {
|
27
|
+
const [actionFired, fireAction] = React.useState('');
|
28
|
+
|
29
|
+
const onSelect = name => fireAction(name);
|
30
|
+
|
31
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("h1", null, "Simple Menu"), /*#__PURE__*/React.createElement("h2", null, "Last option activated: ", actionFired), /*#__PURE__*/React.createElement(ActionMenu, null, /*#__PURE__*/React.createElement(ActionMenu.Button, null, "Menu"), /*#__PURE__*/React.createElement(ActionList, null, /*#__PURE__*/React.createElement(ActionList.Item, {
|
32
|
+
onSelect: () => onSelect('Copy link')
|
33
|
+
}, "Copy link", /*#__PURE__*/React.createElement(ActionList.TrailingVisual, null, "\u2318C")), /*#__PURE__*/React.createElement(ActionList.Item, {
|
34
|
+
onSelect: () => onSelect('Quote reply')
|
35
|
+
}, "Quote reply", /*#__PURE__*/React.createElement(ActionList.TrailingVisual, null, "\u2318Q")), /*#__PURE__*/React.createElement(ActionList.Item, {
|
36
|
+
onSelect: () => onSelect('Edit comment')
|
37
|
+
}, "Edit comment", /*#__PURE__*/React.createElement(ActionList.TrailingVisual, null, "\u2318E")), /*#__PURE__*/React.createElement(ActionList.Divider, null), /*#__PURE__*/React.createElement(ActionList.Item, {
|
38
|
+
variant: "danger",
|
39
|
+
onSelect: () => onSelect('Delete file')
|
40
|
+
}, "Delete file", /*#__PURE__*/React.createElement(ActionList.TrailingVisual, null, "\u2318D")))));
|
41
|
+
}
|
42
|
+
SimpleListStory.storyName = 'Simple Menu';
|
43
|
+
export function ActionsStory() {
|
44
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("h1", null, "Actions"), /*#__PURE__*/React.createElement(ActionMenu, {
|
45
|
+
overlayProps: {
|
46
|
+
width: 'medium'
|
47
|
+
}
|
48
|
+
}, /*#__PURE__*/React.createElement(ActionMenu.Button, {
|
49
|
+
"aria-label": "Open Actions Menu"
|
50
|
+
}, /*#__PURE__*/React.createElement(ServerIcon, null)), /*#__PURE__*/React.createElement(ActionList, null, /*#__PURE__*/React.createElement(ActionList.Item, null, /*#__PURE__*/React.createElement(ActionList.LeadingVisual, null, /*#__PURE__*/React.createElement(ServerIcon, null)), "Open current Codespace", /*#__PURE__*/React.createElement(ActionList.Description, {
|
51
|
+
variant: "block"
|
52
|
+
}, "Your existing Codespace will be opened to its previous state, and you'll be asked to manually switch to new-branch."), /*#__PURE__*/React.createElement(ActionList.TrailingVisual, null, "\u2318O")), /*#__PURE__*/React.createElement(ActionList.Item, null, /*#__PURE__*/React.createElement(ActionList.LeadingVisual, null, /*#__PURE__*/React.createElement(PlusCircleIcon, null)), "Create new Codespace", /*#__PURE__*/React.createElement(ActionList.Description, {
|
53
|
+
variant: "block"
|
54
|
+
}, "Create a brand new Codespace with a fresh image and checkout this branch."), /*#__PURE__*/React.createElement(ActionList.TrailingVisual, null, "\u2318C")))));
|
55
|
+
}
|
56
|
+
ActionsStory.storyName = 'Actions';
|
57
|
+
export function ExternalAnchor() {
|
58
|
+
const [actionFired, fireAction] = React.useState('');
|
59
|
+
|
60
|
+
const onSelect = name => fireAction(name);
|
61
|
+
|
62
|
+
const [open, setOpen] = React.useState(false);
|
63
|
+
const triggerRef = /*#__PURE__*/React.createRef();
|
64
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("h1", null, "External Anchor"), /*#__PURE__*/React.createElement("h2", null, "External Open State: ", open ? 'Open' : 'Closed'), /*#__PURE__*/React.createElement("h2", null, "Last option activated: ", actionFired), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Button, {
|
65
|
+
ref: triggerRef,
|
66
|
+
onClick: () => setOpen(!open)
|
67
|
+
}, open ? 'Close Menu' : 'Open Menu')), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(ActionMenu, {
|
68
|
+
open: open,
|
69
|
+
onOpenChange: setOpen,
|
70
|
+
anchorRef: triggerRef
|
71
|
+
}, /*#__PURE__*/React.createElement(ActionList, null, /*#__PURE__*/React.createElement(ActionList.Item, {
|
72
|
+
onSelect: () => onSelect('Copy link')
|
73
|
+
}, "Copy link", /*#__PURE__*/React.createElement(ActionList.TrailingVisual, null, "\u2318C")), /*#__PURE__*/React.createElement(ActionList.Item, {
|
74
|
+
onSelect: () => onSelect('Quote reply')
|
75
|
+
}, "Quote reply", /*#__PURE__*/React.createElement(ActionList.TrailingVisual, null, "\u2318Q")), /*#__PURE__*/React.createElement(ActionList.Item, {
|
76
|
+
onSelect: () => onSelect('Edit comment')
|
77
|
+
}, "Edit comment", /*#__PURE__*/React.createElement(ActionList.TrailingVisual, null, "\u2318E")), /*#__PURE__*/React.createElement(ActionList.Divider, null), /*#__PURE__*/React.createElement(ActionList.Item, {
|
78
|
+
variant: "danger",
|
79
|
+
onSelect: () => onSelect('Delete file')
|
80
|
+
}, "Delete file", /*#__PURE__*/React.createElement(ActionList.TrailingVisual, null, "\u2318D")))));
|
81
|
+
}
|
82
|
+
ExternalAnchor.storyName = 'External Anchor';
|
83
|
+
export function ControlledMenu() {
|
84
|
+
const [actionFired, fireAction] = React.useState('');
|
85
|
+
|
86
|
+
const onSelect = name => fireAction(name);
|
87
|
+
|
88
|
+
const [open, setOpen] = React.useState(false);
|
89
|
+
const triggerRef = /*#__PURE__*/React.createRef();
|
90
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("h1", null, "Controlled Menu"), /*#__PURE__*/React.createElement("h2", null, "External Open State: ", open ? 'Open' : 'Closed'), /*#__PURE__*/React.createElement("h2", null, "Last option activated: ", actionFired), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Button, {
|
91
|
+
ref: triggerRef,
|
92
|
+
onClick: () => setOpen(!open)
|
93
|
+
}, open ? 'Close Menu' : 'Open Menu')), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(ActionMenu, {
|
94
|
+
open: open,
|
95
|
+
onOpenChange: setOpen,
|
96
|
+
overlayProps: {
|
97
|
+
// Because the component is controlled from outside, but the anchor is still internal,
|
98
|
+
// clicking the external button should not be counted as "clicking outside"
|
99
|
+
ignoreClickRefs: [triggerRef]
|
100
|
+
}
|
101
|
+
}, /*#__PURE__*/React.createElement(ActionMenu.Button, null, "Anchor"), /*#__PURE__*/React.createElement(ActionList, null, /*#__PURE__*/React.createElement(ActionList.Item, {
|
102
|
+
onSelect: () => onSelect('Copy link')
|
103
|
+
}, "Copy link", /*#__PURE__*/React.createElement(ActionList.TrailingVisual, null, "\u2318C")), /*#__PURE__*/React.createElement(ActionList.Item, {
|
104
|
+
onSelect: () => onSelect('Quote reply')
|
105
|
+
}, "Quote reply", /*#__PURE__*/React.createElement(ActionList.TrailingVisual, null, "\u2318Q")), /*#__PURE__*/React.createElement(ActionList.Item, {
|
106
|
+
onSelect: () => onSelect('Edit comment')
|
107
|
+
}, "Edit comment", /*#__PURE__*/React.createElement(ActionList.TrailingVisual, null, "\u2318E")), /*#__PURE__*/React.createElement(ActionList.Divider, null), /*#__PURE__*/React.createElement(ActionList.Item, {
|
108
|
+
variant: "danger",
|
109
|
+
onSelect: () => onSelect('Delete file')
|
110
|
+
}, "Delete file", /*#__PURE__*/React.createElement(ActionList.TrailingVisual, null, "\u2318D")))));
|
111
|
+
}
|
112
|
+
ControlledMenu.storyName = 'Controlled Menu';
|
113
|
+
export function CustomAnchor() {
|
114
|
+
const [actionFired, fireAction] = React.useState('');
|
115
|
+
|
116
|
+
const onSelect = name => fireAction(name);
|
117
|
+
|
118
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("h1", null, "Custom Anchor"), /*#__PURE__*/React.createElement("h2", null, "Last option activated: ", actionFired), /*#__PURE__*/React.createElement(ActionMenu, null, /*#__PURE__*/React.createElement(ActionMenu.Anchor, null, /*#__PURE__*/React.createElement("summary", {
|
119
|
+
style: {
|
120
|
+
cursor: 'pointer'
|
121
|
+
},
|
122
|
+
"aria-label": "Open column options"
|
123
|
+
}, /*#__PURE__*/React.createElement(KebabHorizontalIcon, null))), /*#__PURE__*/React.createElement(ActionList, null, /*#__PURE__*/React.createElement(ActionList.Item, {
|
124
|
+
onSelect: () => onSelect('Rename')
|
125
|
+
}, /*#__PURE__*/React.createElement(ActionList.LeadingVisual, null, /*#__PURE__*/React.createElement(PencilIcon, null)), "Rename"), /*#__PURE__*/React.createElement(ActionList.Item, {
|
126
|
+
onSelect: () => onSelect('Archive')
|
127
|
+
}, /*#__PURE__*/React.createElement(ActionList.LeadingVisual, null, /*#__PURE__*/React.createElement(ArchiveIcon, null)), "Archive all cards"), /*#__PURE__*/React.createElement(ActionList.Item, {
|
128
|
+
variant: "danger",
|
129
|
+
onSelect: () => onSelect('Delete file')
|
130
|
+
}, /*#__PURE__*/React.createElement(ActionList.LeadingVisual, null, /*#__PURE__*/React.createElement(TrashIcon, null)), "Delete"))));
|
131
|
+
}
|
132
|
+
CustomAnchor.storyName = 'Custom Anchor';
|
133
|
+
export function MemexTableMenu() {
|
134
|
+
const [name, setName] = React.useState('Estimate');
|
135
|
+
const inputRef = /*#__PURE__*/React.createRef();
|
136
|
+
/** To add custom components to the Menu,
|
137
|
+
* you need to switch to a controlled menu
|
138
|
+
*/
|
139
|
+
|
140
|
+
const [open, setOpen] = React.useState(false);
|
141
|
+
|
142
|
+
const handleKeyPress = event => {
|
143
|
+
if (event.key === 'Enter') {
|
144
|
+
setName(event.currentTarget.value);
|
145
|
+
setOpen(false);
|
146
|
+
}
|
147
|
+
};
|
148
|
+
/** This requires inside knowledge. If you to do this with onBlur
|
149
|
+
* on the input, it doesn't work :(
|
150
|
+
*/
|
151
|
+
|
152
|
+
|
153
|
+
const handleClickOutside = () => {
|
154
|
+
if (inputRef.current) setName(inputRef.current.value);
|
155
|
+
setOpen(false);
|
156
|
+
};
|
157
|
+
|
158
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("h1", null, "Memex Table Menu"), /*#__PURE__*/React.createElement(Box, {
|
159
|
+
sx: {
|
160
|
+
width: 200,
|
161
|
+
display: 'flex',
|
162
|
+
justifyContent: 'space-between',
|
163
|
+
p: 2,
|
164
|
+
border: '1px solid',
|
165
|
+
borderColor: 'border.default'
|
166
|
+
}
|
167
|
+
}, /*#__PURE__*/React.createElement(Text, {
|
168
|
+
sx: {
|
169
|
+
fontSize: 0,
|
170
|
+
fontWeight: 'bold'
|
171
|
+
}
|
172
|
+
}, name), /*#__PURE__*/React.createElement(ActionMenu, {
|
173
|
+
open: open,
|
174
|
+
onOpenChange: setOpen,
|
175
|
+
overlayProps: {
|
176
|
+
onClickOutside: handleClickOutside
|
177
|
+
}
|
178
|
+
}, /*#__PURE__*/React.createElement(ActionMenu.Button, {
|
179
|
+
"aria-label": "Open Estimate column options menu",
|
180
|
+
sx: {
|
181
|
+
p: 0,
|
182
|
+
display: 'flex',
|
183
|
+
alignItems: 'center',
|
184
|
+
justifyContent: 'center'
|
185
|
+
}
|
186
|
+
}, /*#__PURE__*/React.createElement(TriangleDownIcon, null)), /*#__PURE__*/React.createElement(TextInput, {
|
187
|
+
ref: inputRef,
|
188
|
+
sx: {
|
189
|
+
m: 2
|
190
|
+
},
|
191
|
+
defaultValue: name,
|
192
|
+
onKeyPress: handleKeyPress
|
193
|
+
}), /*#__PURE__*/React.createElement(ActionMenu.Divider, {
|
194
|
+
sx: {
|
195
|
+
m: 0
|
196
|
+
}
|
197
|
+
}), /*#__PURE__*/React.createElement(ActionList, null, /*#__PURE__*/React.createElement(ActionList.Item, null, "Sort ascending (123...)"), /*#__PURE__*/React.createElement(ActionList.Item, null, "Sort descending (123...)"), /*#__PURE__*/React.createElement(ActionList.Divider, null), /*#__PURE__*/React.createElement(ActionList.Item, null, "Filter by values"), /*#__PURE__*/React.createElement(ActionList.Item, null, "Group by values"), /*#__PURE__*/React.createElement(ActionList.Divider, null), /*#__PURE__*/React.createElement(ActionList.Item, {
|
198
|
+
disabled: true
|
199
|
+
}, "Hide field"), /*#__PURE__*/React.createElement(ActionList.Item, {
|
200
|
+
variant: "danger"
|
201
|
+
}, "Delete file")))));
|
202
|
+
}
|
203
|
+
MemexTableMenu.storyName = 'Memex Table Menu';
|
204
|
+
/* copied from github/memex */
|
205
|
+
|
206
|
+
const LayoutToggleItem = ({
|
207
|
+
selected,
|
208
|
+
children,
|
209
|
+
Icon,
|
210
|
+
...props
|
211
|
+
}) => {
|
212
|
+
return /*#__PURE__*/React.createElement(FormGroup, {
|
213
|
+
sx: {
|
214
|
+
flex: 'auto',
|
215
|
+
borderRadius: 2,
|
216
|
+
border: '1px solid',
|
217
|
+
borderColor: selected ? 'accent.emphasis' : 'border.default',
|
218
|
+
textAlign: 'center',
|
219
|
+
cursor: 'pointer',
|
220
|
+
backgroundColor: selected ? 'accent.subtle' : '',
|
221
|
+
boxShadow: selected ? theme => `inset 0 0 0 1px ${theme.colors.accent.emphasis}` : '',
|
222
|
+
mb: 2,
|
223
|
+
mt: 1,
|
224
|
+
'&:hover': {
|
225
|
+
backgroundColor: !selected ? 'canvas.subtle' : ''
|
226
|
+
},
|
227
|
+
'&:first-of-type': {
|
228
|
+
borderTopRightRadius: '0px',
|
229
|
+
borderBottomRightRadius: '0px',
|
230
|
+
borderRight: selected ? undefined : '0'
|
231
|
+
},
|
232
|
+
'&:last-of-type': {
|
233
|
+
borderTopLeftRadius: '0px',
|
234
|
+
borderBottomLeftRadius: '0px',
|
235
|
+
borderLeft: selected ? undefined : '0'
|
236
|
+
}
|
237
|
+
}
|
238
|
+
}, /*#__PURE__*/React.createElement(FormGroup.Label, _extends({
|
239
|
+
htmlFor: "layout-selector",
|
240
|
+
sx: {
|
241
|
+
fontWeight: 'normal',
|
242
|
+
cursor: 'pointer',
|
243
|
+
px: 3,
|
244
|
+
py: 2,
|
245
|
+
mb: 0
|
246
|
+
}
|
247
|
+
}, props), /*#__PURE__*/React.createElement(Box, {
|
248
|
+
sx: {
|
249
|
+
textAlign: 'center',
|
250
|
+
flexDirection: 'column',
|
251
|
+
m: 'auto',
|
252
|
+
alignItems: 'center',
|
253
|
+
display: 'flex'
|
254
|
+
}
|
255
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
256
|
+
size: "medium"
|
257
|
+
}), /*#__PURE__*/React.createElement(Text, {
|
258
|
+
sx: {
|
259
|
+
color: selected ? 'fg.default' : 'fg.muted',
|
260
|
+
fontSize: 0
|
261
|
+
}
|
262
|
+
}, children))));
|
263
|
+
};
|
264
|
+
|
265
|
+
LayoutToggleItem.displayName = "LayoutToggleItem";
|
266
|
+
|
267
|
+
/* copied from github/memex */
|
268
|
+
const ViewChangeButtons = ({
|
269
|
+
setOpen
|
270
|
+
}) => /*#__PURE__*/React.createElement(Box, {
|
271
|
+
sx: {
|
272
|
+
display: 'flex'
|
273
|
+
}
|
274
|
+
}, /*#__PURE__*/React.createElement(ButtonInvisible, {
|
275
|
+
onClick: () => setOpen(false),
|
276
|
+
sx: {
|
277
|
+
flex: 'auto',
|
278
|
+
minWidth: '50%',
|
279
|
+
borderRight: '1px solid',
|
280
|
+
borderColor: 'border.default',
|
281
|
+
borderRadius: 0,
|
282
|
+
mt: -2,
|
283
|
+
mb: -2,
|
284
|
+
py: 3,
|
285
|
+
'&:hover': {
|
286
|
+
bg: 'canvas.inset'
|
287
|
+
}
|
288
|
+
}
|
289
|
+
}, "Save changes"), /*#__PURE__*/React.createElement(ButtonInvisible, {
|
290
|
+
onClick: () => setOpen(false),
|
291
|
+
sx: {
|
292
|
+
flex: 'auto',
|
293
|
+
color: 'fg.muted',
|
294
|
+
borderRadius: 0,
|
295
|
+
mt: -2,
|
296
|
+
mb: -2,
|
297
|
+
py: 3,
|
298
|
+
fontWeight: 'normal',
|
299
|
+
'&:hover': {
|
300
|
+
bg: 'canvas.inset'
|
301
|
+
}
|
302
|
+
}
|
303
|
+
}, "Discard changes"));
|
304
|
+
|
305
|
+
ViewChangeButtons.displayName = "ViewChangeButtons";
|
306
|
+
export function MemexViewOptionsMenu() {
|
307
|
+
const [open, setOpen] = React.useState(false);
|
308
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("h1", null, "Memex View Options Menu"), /*#__PURE__*/React.createElement(Box, {
|
309
|
+
sx: {
|
310
|
+
display: 'flex',
|
311
|
+
alignItems: 'center'
|
312
|
+
}
|
313
|
+
}, /*#__PURE__*/React.createElement(Text, {
|
314
|
+
sx: {
|
315
|
+
fontSize: 1,
|
316
|
+
mr: 3
|
317
|
+
}
|
318
|
+
}, /*#__PURE__*/React.createElement(StyledOcticon, {
|
319
|
+
icon: ProjectIcon,
|
320
|
+
sx: {
|
321
|
+
mr: 2
|
322
|
+
}
|
323
|
+
}), "React"), /*#__PURE__*/React.createElement(ActionMenu, {
|
324
|
+
open: open,
|
325
|
+
onOpenChange: setOpen,
|
326
|
+
overlayProps: {
|
327
|
+
width: 'medium'
|
328
|
+
}
|
329
|
+
}, /*#__PURE__*/React.createElement(ActionMenu.Button, {
|
330
|
+
"aria-label": "Open View options menu",
|
331
|
+
sx: {
|
332
|
+
p: 0,
|
333
|
+
width: 18,
|
334
|
+
height: 18,
|
335
|
+
display: 'flex',
|
336
|
+
alignItems: 'center',
|
337
|
+
justifyContent: 'center'
|
338
|
+
}
|
339
|
+
}, /*#__PURE__*/React.createElement(TriangleDownIcon, null)), /*#__PURE__*/React.createElement(ActionList, null, /*#__PURE__*/React.createElement(ActionList.Group, {
|
340
|
+
title: "Layout"
|
341
|
+
}, /*#__PURE__*/React.createElement("li", {
|
342
|
+
style: {
|
343
|
+
listStyle: 'none'
|
344
|
+
}
|
345
|
+
}, /*#__PURE__*/React.createElement(Box, {
|
346
|
+
sx: {
|
347
|
+
mx: 3,
|
348
|
+
display: 'flex'
|
349
|
+
}
|
350
|
+
}, /*#__PURE__*/React.createElement(LayoutToggleItem, {
|
351
|
+
selected: true,
|
352
|
+
Icon: TableIcon
|
353
|
+
}, "Table"), /*#__PURE__*/React.createElement(LayoutToggleItem, {
|
354
|
+
selected: false,
|
355
|
+
Icon: ProjectIcon
|
356
|
+
}, "Board")))), /*#__PURE__*/React.createElement(ActionList.Divider, null), /*#__PURE__*/React.createElement(ActionList.Group, {
|
357
|
+
title: "Configuration"
|
358
|
+
}, /*#__PURE__*/React.createElement(ActionList.Item, null, /*#__PURE__*/React.createElement(ActionList.LeadingVisual, null, /*#__PURE__*/React.createElement(ListUnorderedIcon, null)), "Title, Assignees, Status, Labels, Repositories"), /*#__PURE__*/React.createElement(ActionList.Item, null, /*#__PURE__*/React.createElement(ActionList.LeadingVisual, null, /*#__PURE__*/React.createElement(ListUnorderedIcon, null)), "group: none"), /*#__PURE__*/React.createElement(ActionList.Item, null, /*#__PURE__*/React.createElement(ActionList.LeadingVisual, null, /*#__PURE__*/React.createElement(ArrowDownIcon, null)), "sort: manual"), /*#__PURE__*/React.createElement(ActionList.Item, null, /*#__PURE__*/React.createElement(ActionList.LeadingVisual, null, /*#__PURE__*/React.createElement(SearchIcon, null)), "Search or filter this view")), /*#__PURE__*/React.createElement(ActionList.Divider, null), /*#__PURE__*/React.createElement(ActionList.Item, null, /*#__PURE__*/React.createElement(ActionList.LeadingVisual, null, /*#__PURE__*/React.createElement(PencilIcon, null)), "Rename view"), /*#__PURE__*/React.createElement(ActionList.Item, null, /*#__PURE__*/React.createElement(ActionList.LeadingVisual, null, /*#__PURE__*/React.createElement(VersionsIcon, null)), "Save changes to new view"), /*#__PURE__*/React.createElement(ActionList.Item, {
|
359
|
+
disabled: true
|
360
|
+
}, /*#__PURE__*/React.createElement(ActionList.LeadingVisual, null, /*#__PURE__*/React.createElement(TrashIcon, null)), "Delete view"), /*#__PURE__*/React.createElement(ActionList.Divider, null), /*#__PURE__*/React.createElement("li", {
|
361
|
+
style: {
|
362
|
+
listStyle: 'none'
|
363
|
+
}
|
364
|
+
}, /*#__PURE__*/React.createElement(ViewChangeButtons, {
|
365
|
+
setOpen: setOpen
|
366
|
+
}))))));
|
367
|
+
}
|
368
|
+
MemexViewOptionsMenu.storyName = 'Memex View Options Menu';
|
369
|
+
export function UnexpectedSelectionVariant() {
|
370
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("h1", null, "Expect error if selectionVariant is passed"), /*#__PURE__*/React.createElement(ActionMenu, null, /*#__PURE__*/React.createElement(ActionMenu.Button, null, "Menu"), /*#__PURE__*/React.createElement(ActionList, {
|
371
|
+
selectionVariant: "multiple"
|
372
|
+
}, /*#__PURE__*/React.createElement(ActionList.Item, null, "Copy link"), /*#__PURE__*/React.createElement(ActionList.Item, null, "Quote reply"), /*#__PURE__*/React.createElement(ActionList.Item, null, "Edit comment"), /*#__PURE__*/React.createElement(ActionList.Divider, null), /*#__PURE__*/React.createElement(ActionList.Item, {
|
373
|
+
variant: "danger"
|
374
|
+
}, "Delete file"))));
|
375
|
+
}
|
376
|
+
UnexpectedSelectionVariant.storyName = 'Unexpected selectionVariant';
|
package/package.json
CHANGED
@@ -2,22 +2,27 @@ import React from 'react'
|
|
2
2
|
import Box from '../Box'
|
3
3
|
import {get} from '../constants'
|
4
4
|
import {Theme} from '../ThemeProvider'
|
5
|
+
import {SxProp, merge} from '../sx'
|
5
6
|
|
6
7
|
/**
|
7
8
|
* Visually separates `Item`s or `Group`s in an `ActionList`.
|
8
9
|
*/
|
9
|
-
|
10
|
+
|
11
|
+
export const Divider: React.FC<SxProp> = ({sx = {}}) => {
|
10
12
|
return (
|
11
13
|
<Box
|
12
14
|
as="li"
|
13
15
|
role="separator"
|
14
|
-
sx={
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
sx={merge(
|
17
|
+
{
|
18
|
+
height: 1,
|
19
|
+
backgroundColor: 'actionListItem.inlineDivider',
|
20
|
+
marginTop: (theme: Theme) => `calc(${get('space.2')(theme)} - 1px)`,
|
21
|
+
marginBottom: 2,
|
22
|
+
listStyle: 'none' // hide the ::marker inserted by browser's stylesheet
|
23
|
+
},
|
24
|
+
sx as SxProp
|
25
|
+
)}
|
21
26
|
data-component="ActionList.Divider"
|
22
27
|
/>
|
23
28
|
)
|
package/src/ActionList2/Item.tsx
CHANGED
@@ -8,6 +8,7 @@ import sx, {SxProp, merge} from '../sx'
|
|
8
8
|
import createSlots from '../utils/create-slots'
|
9
9
|
import {AriaRole} from '../utils/types'
|
10
10
|
import {ListContext} from './List'
|
11
|
+
import {MenuContext} from './MenuContext'
|
11
12
|
import {Selection} from './Selection'
|
12
13
|
|
13
14
|
export const getVariantStyles = (variant: ItemProps['variant'], disabled: ItemProps['disabled']) => {
|
@@ -94,12 +95,14 @@ export const Item = React.forwardRef<HTMLLIElement, ItemProps>(
|
|
94
95
|
onSelect,
|
95
96
|
sx: sxProp = {},
|
96
97
|
id,
|
98
|
+
role,
|
97
99
|
_PrivateItemWrapper,
|
98
100
|
...props
|
99
101
|
},
|
100
102
|
forwardedRef
|
101
103
|
): JSX.Element => {
|
102
104
|
const {variant: listVariant, showDividers} = React.useContext(ListContext)
|
105
|
+
const {itemRole, afterSelect} = React.useContext(MenuContext)
|
103
106
|
|
104
107
|
const {theme} = useTheme()
|
105
108
|
|
@@ -170,9 +173,13 @@ export const Item = React.forwardRef<HTMLLIElement, ItemProps>(
|
|
170
173
|
event => {
|
171
174
|
if (typeof onSelect !== 'function') return
|
172
175
|
if (disabled) return
|
173
|
-
if (!event.defaultPrevented)
|
176
|
+
if (!event.defaultPrevented) {
|
177
|
+
onSelect(event)
|
178
|
+
// if this Item is inside a Menu, close the Menu
|
179
|
+
if (typeof afterSelect === 'function') afterSelect()
|
180
|
+
}
|
174
181
|
},
|
175
|
-
[onSelect, disabled]
|
182
|
+
[onSelect, disabled, afterSelect]
|
176
183
|
)
|
177
184
|
|
178
185
|
const keyPressHandler = React.useCallback(
|
@@ -181,9 +188,11 @@ export const Item = React.forwardRef<HTMLLIElement, ItemProps>(
|
|
181
188
|
if (disabled) return
|
182
189
|
if (!event.defaultPrevented && [' ', 'Enter'].includes(event.key)) {
|
183
190
|
onSelect(event)
|
191
|
+
// if this Item is inside a Menu, close the Menu
|
192
|
+
if (typeof afterSelect === 'function') afterSelect()
|
184
193
|
}
|
185
194
|
},
|
186
|
-
[onSelect, disabled]
|
195
|
+
[onSelect, disabled, afterSelect]
|
187
196
|
)
|
188
197
|
|
189
198
|
// use props.id if provided, otherwise generate one.
|
@@ -206,6 +215,7 @@ export const Item = React.forwardRef<HTMLLIElement, ItemProps>(
|
|
206
215
|
tabIndex={disabled || _PrivateItemWrapper ? undefined : 0}
|
207
216
|
aria-labelledby={`${labelId} ${slots.InlineDescription ? inlineDescriptionId : ''}`}
|
208
217
|
aria-describedby={slots.BlockDescription ? blockDescriptionId : undefined}
|
218
|
+
role={role || itemRole}
|
209
219
|
{...props}
|
210
220
|
>
|
211
221
|
<ItemWrapper>
|
package/src/ActionList2/List.tsx
CHANGED
@@ -3,6 +3,7 @@ import {ForwardRefComponent as PolymorphicForwardRefComponent} from '@radix-ui/r
|
|
3
3
|
import styled from 'styled-components'
|
4
4
|
import sx, {SxProp, merge} from '../sx'
|
5
5
|
import {AriaRole} from '../utils/types'
|
6
|
+
import {MenuContext} from './MenuContext'
|
6
7
|
|
7
8
|
export type ListProps = {
|
8
9
|
/**
|
@@ -30,7 +31,7 @@ const ListBox = styled.ul<SxProp>(sx)
|
|
30
31
|
|
31
32
|
export const List = React.forwardRef<HTMLUListElement, ListProps>(
|
32
33
|
(
|
33
|
-
{variant = 'inset', selectionVariant, showDividers = false, sx: sxProp = {}, ...props},
|
34
|
+
{variant = 'inset', selectionVariant, showDividers = false, role, sx: sxProp = {}, ...props},
|
34
35
|
forwardedRef
|
35
36
|
): JSX.Element => {
|
36
37
|
const styles = {
|
@@ -39,8 +40,11 @@ export const List = React.forwardRef<HTMLUListElement, ListProps>(
|
|
39
40
|
paddingY: variant === 'inset' ? 2 : 0
|
40
41
|
}
|
41
42
|
|
43
|
+
/** if list is inside a Menu, it will get a role from the Menu */
|
44
|
+
const {listRole} = React.useContext(MenuContext)
|
45
|
+
|
42
46
|
return (
|
43
|
-
<ListBox sx={merge(styles, sxProp as SxProp)} {...props} ref={forwardedRef}>
|
47
|
+
<ListBox sx={merge(styles, sxProp as SxProp)} role={role || listRole} {...props} ref={forwardedRef}>
|
44
48
|
<ListContext.Provider value={{variant, selectionVariant, showDividers}}>{props.children}</ListContext.Provider>
|
45
49
|
</ListBox>
|
46
50
|
)
|
@@ -0,0 +1,6 @@
|
|
1
|
+
/** This context can be used by components that compose ActionList inside a Menu */
|
2
|
+
|
3
|
+
import React from 'react'
|
4
|
+
|
5
|
+
type ContextProps = {parent?: string; listRole?: string; itemRole?: string; afterSelect?: () => void}
|
6
|
+
export const MenuContext = React.createContext<ContextProps>({})
|
@@ -2,6 +2,7 @@ import React from 'react'
|
|
2
2
|
import {CheckIcon} from '@primer/octicons-react'
|
3
3
|
import {ListContext} from './List'
|
4
4
|
import {GroupContext} from './Group'
|
5
|
+
import {MenuContext} from './MenuContext'
|
5
6
|
import {ItemProps} from './Item'
|
6
7
|
import {LeadingVisualContainer} from './Visuals'
|
7
8
|
|
@@ -9,6 +10,7 @@ type SelectionProps = Pick<ItemProps, 'selected'>
|
|
9
10
|
export const Selection: React.FC<SelectionProps> = ({selected}) => {
|
10
11
|
const {selectionVariant: listSelectionVariant} = React.useContext(ListContext)
|
11
12
|
const {selectionVariant: groupSelectionVariant} = React.useContext(GroupContext)
|
13
|
+
const {parent} = React.useContext(MenuContext)
|
12
14
|
|
13
15
|
/** selectionVariant in Group can override the selectionVariant in List root */
|
14
16
|
const selectionVariant = typeof groupSelectionVariant !== 'undefined' ? groupSelectionVariant : listSelectionVariant
|
@@ -23,6 +25,13 @@ export const Selection: React.FC<SelectionProps> = ({selected}) => {
|
|
23
25
|
return null
|
24
26
|
}
|
25
27
|
|
28
|
+
if (parent === 'ActionMenu') {
|
29
|
+
throw new Error(
|
30
|
+
'ActionList cannot have a selectionVariant inside ActionMenu, please use DropdownMenu or SelectPanel instead. More information: https://primer.style/design/components/action-list#application'
|
31
|
+
)
|
32
|
+
return null
|
33
|
+
}
|
34
|
+
|
26
35
|
if (selectionVariant === 'single') {
|
27
36
|
return <LeadingVisualContainer>{selected && <CheckIcon />}</LeadingVisualContainer>
|
28
37
|
}
|
@@ -0,0 +1,94 @@
|
|
1
|
+
import Button, {ButtonProps} from './Button'
|
2
|
+
import React from 'react'
|
3
|
+
import {AnchoredOverlay} from './AnchoredOverlay'
|
4
|
+
import {useProvidedStateOrCreate} from './hooks/useProvidedStateOrCreate'
|
5
|
+
import {OverlayProps} from './Overlay'
|
6
|
+
import {useProvidedRefOrCreate} from './hooks'
|
7
|
+
import {AnchoredOverlayWrapperAnchorProps} from './AnchoredOverlay/AnchoredOverlay'
|
8
|
+
import {Divider} from './ActionList2/Divider'
|
9
|
+
import {MenuContext as ActionListMenuContext} from './ActionList2/MenuContext'
|
10
|
+
|
11
|
+
type ActionMenuBaseProps = {
|
12
|
+
/**
|
13
|
+
* Recommended: `ActionMenu.Button` or `ActionMenu.Anchor` with ActionList`
|
14
|
+
*/
|
15
|
+
children: React.ReactElement[] | React.ReactElement
|
16
|
+
|
17
|
+
/**
|
18
|
+
* If defined, will control the open/closed state of the overlay. Must be used in conjuction with `onOpenChange`.
|
19
|
+
*/
|
20
|
+
open?: boolean
|
21
|
+
|
22
|
+
/**
|
23
|
+
* If defined, will control the open/closed state of the overlay. Must be used in conjuction with `open`.
|
24
|
+
*/
|
25
|
+
onOpenChange?: (s: boolean) => void
|
26
|
+
|
27
|
+
/**
|
28
|
+
* Props to be spread on the internal `Overlay` component.
|
29
|
+
*/
|
30
|
+
overlayProps?: Partial<OverlayProps>
|
31
|
+
}
|
32
|
+
|
33
|
+
export type ActionMenuProps = ActionMenuBaseProps & AnchoredOverlayWrapperAnchorProps
|
34
|
+
|
35
|
+
const ActionMenuBase: React.FC<ActionMenuProps> = ({
|
36
|
+
anchorRef: externalAnchorRef,
|
37
|
+
open,
|
38
|
+
onOpenChange,
|
39
|
+
overlayProps,
|
40
|
+
children
|
41
|
+
}: ActionMenuProps) => {
|
42
|
+
const [combinedOpenState, setCombinedOpenState] = useProvidedStateOrCreate(open, onOpenChange, false)
|
43
|
+
const anchorRef = useProvidedRefOrCreate(externalAnchorRef)
|
44
|
+
const onOpen = React.useCallback(() => setCombinedOpenState(true), [setCombinedOpenState])
|
45
|
+
const onClose = React.useCallback(() => setCombinedOpenState(false), [setCombinedOpenState])
|
46
|
+
|
47
|
+
let renderAnchor: AnchoredOverlayWrapperAnchorProps['renderAnchor'] = null
|
48
|
+
const contents: React.ReactElement[] = []
|
49
|
+
|
50
|
+
React.Children.map(children, child => {
|
51
|
+
if (child.type === MenuButton || child.type === Anchor) {
|
52
|
+
renderAnchor = anchorProps => React.cloneElement(child, anchorProps)
|
53
|
+
} else {
|
54
|
+
contents.push(child)
|
55
|
+
}
|
56
|
+
})
|
57
|
+
|
58
|
+
return (
|
59
|
+
<AnchoredOverlay
|
60
|
+
renderAnchor={renderAnchor}
|
61
|
+
anchorRef={anchorRef}
|
62
|
+
open={combinedOpenState}
|
63
|
+
onOpen={onOpen}
|
64
|
+
onClose={onClose}
|
65
|
+
overlayProps={overlayProps}
|
66
|
+
>
|
67
|
+
<ActionListMenuContext.Provider
|
68
|
+
value={{parent: 'ActionMenu', listRole: 'menu', itemRole: 'menuitem', afterSelect: onClose}}
|
69
|
+
>
|
70
|
+
{contents}
|
71
|
+
</ActionListMenuContext.Provider>
|
72
|
+
</AnchoredOverlay>
|
73
|
+
)
|
74
|
+
}
|
75
|
+
|
76
|
+
type AnchorRef = AnchoredOverlayWrapperAnchorProps['anchorRef']
|
77
|
+
|
78
|
+
export type MenuAnchorProps = {children: React.ReactElement}
|
79
|
+
const Anchor = React.forwardRef<AnchorRef, MenuAnchorProps>(({children, ...anchorProps}, anchorRef) => {
|
80
|
+
return React.cloneElement(children, {...anchorProps, ref: anchorRef})
|
81
|
+
})
|
82
|
+
|
83
|
+
/** this component is syntactical sugar 🍭 */
|
84
|
+
export type MenuButtonProps = ButtonProps
|
85
|
+
const MenuButton = React.forwardRef<AnchorRef, ButtonProps>((props, anchorRef) => {
|
86
|
+
return (
|
87
|
+
<Anchor ref={anchorRef}>
|
88
|
+
<Button {...props} />
|
89
|
+
</Anchor>
|
90
|
+
)
|
91
|
+
})
|
92
|
+
|
93
|
+
ActionMenuBase.displayName = 'ActionMenu'
|
94
|
+
export const ActionMenu = Object.assign(ActionMenuBase, {Button: MenuButton, Anchor, Divider})
|
package/src/Avatar.tsx
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import styled from 'styled-components'
|
2
|
-
import {
|
2
|
+
import {get} from './constants'
|
3
3
|
import sx, {SxProp} from './sx'
|
4
4
|
import {ComponentProps} from './utils/types'
|
5
5
|
|
@@ -12,8 +12,7 @@ type StyledAvatarProps = {
|
|
12
12
|
src: string
|
13
13
|
/** Provide alt text when the Avatar is used without the user's name next to it. */
|
14
14
|
alt?: string
|
15
|
-
} &
|
16
|
-
SxProp
|
15
|
+
} & SxProp
|
17
16
|
|
18
17
|
function getBorderRadius({size, square}: StyledAvatarProps) {
|
19
18
|
if (square) {
|
@@ -32,7 +31,6 @@ const Avatar = styled.img.attrs<StyledAvatarProps>(props => ({
|
|
32
31
|
line-height: ${get('lineHeights.condensedUltra')};
|
33
32
|
vertical-align: middle;
|
34
33
|
border-radius: ${props => getBorderRadius(props)};
|
35
|
-
${COMMON};
|
36
34
|
${sx}
|
37
35
|
`
|
38
36
|
|