@czi-sds/mcp 0.20.1 → 0.21.0
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.
- package/data/component-docs/Autocomplete.md +2 -14
- package/data/component-docs/Chip.md +160 -0
- package/data/component-docs/NavigationFooter.md +13 -13
- package/data/component-docs/NavigationHeader.md +26 -26
- package/data/component-docs/PreComposedTable.md +9 -27
- package/data/component-docs/ProteinStructureViewer.md +771 -37
- package/data/component-docs/Table.md +9 -31
- package/data/component-docs/Tabs.md +1 -6
- package/data/component-docs/Tag.md +357 -200
- package/data/component-docs/index.json +5 -5
- package/data/component-list.json +1 -0
- package/data/component-props/Button.json +6 -6
- package/data/component-props/Chip.json +30 -0
- package/data/component-props/Dropdown.json +6 -6
- package/data/component-props/InputSlider.json +5 -5
- package/data/component-props/LoadingIndicator.json +6 -6
- package/data/component-props/Menu.json +74 -0
- package/data/component-props/NavigationFooter.json +2 -2
- package/data/component-props/NavigationHeader.json +2 -2
- package/data/component-props/Notification.json +5 -5
- package/data/component-props/PreComposedTable.json +9 -9
- package/data/component-props/ProteinStructureViewer.json +74 -98
- package/data/component-props/Tag.json +41 -20
- package/data/component-props/TagFilter.json +0 -2
- package/data/component-props/TagLegacy.json +40 -0
- package/data/component-props/Tooltip.json +5 -5
- package/data/component-props/TooltipTable.json +5 -5
- package/package.json +2 -2
- package/data/component-docs/TagFilter.md +0 -131
|
@@ -12,21 +12,47 @@ The component's source code in the SDS codebase can be found [here](https://gith
|
|
|
12
12
|
import { Tag } from "@czi-sds/components";
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
+
> **Coming from the Tag before SDS 25?** Its API changed: `sdsStyle` is now `"solid"` or `"outline"`, sizes are `"small"` and `"medium"`, and `sdsType` and `hover` are gone. The previous component still ships as TagLegacy, and the table under "Migrating from TagLegacy" maps each old prop to its new one.
|
|
16
|
+
|
|
15
17
|
## Code examples
|
|
16
18
|
|
|
17
19
|
### **Default Tag**
|
|
18
20
|
|
|
19
|
-
A tag with nothing but a label,
|
|
21
|
+
A tag with nothing but a label: neutral, solid and medium.
|
|
20
22
|
|
|
21
23
|
**Example: DefaultTag**
|
|
22
24
|
|
|
23
25
|
```tsx
|
|
24
|
-
// A label is all a Tag needs. Everything else has a default: the neutral
|
|
25
|
-
//
|
|
26
|
+
// A label is all a Tag needs. Everything else has a default: the neutral intent,
|
|
27
|
+
// the solid style and the medium size. A tag is pill-shaped; only an icon-only
|
|
28
|
+
// tag is square.
|
|
29
|
+
|
|
30
|
+
import { Tag } from "@czi-sds/components";
|
|
31
|
+
|
|
32
|
+
function App() {
|
|
33
|
+
return (
|
|
34
|
+
<div className="app">
|
|
35
|
+
<Tag label="Science Design System" />
|
|
36
|
+
</div>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export default App;
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Styles and intents
|
|
44
|
+
|
|
45
|
+
The seven intents, drawn solid and then outlined. A tag left without a color is neutral.
|
|
46
|
+
|
|
47
|
+
**Example: TagStylesAndIntents**
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
// color carries the tag's intent. Seven are available, and neutral is what a tag
|
|
51
|
+
// falls back to when the prop is left out.
|
|
26
52
|
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
53
|
+
// sdsStyle picks how that intent is drawn: solid fills the tag with the intent
|
|
54
|
+
// color and sets the label white, outline tints the fill and draws the label,
|
|
55
|
+
// the icons and a 1px border in the intent color.
|
|
30
56
|
|
|
31
57
|
import {
|
|
32
58
|
Tag,
|
|
@@ -34,9 +60,23 @@ import {
|
|
|
34
60
|
getSemanticColors,
|
|
35
61
|
getSpaces,
|
|
36
62
|
type CommonThemeProps,
|
|
63
|
+
type SdsTagIntent,
|
|
64
|
+
type SdsTagStyle,
|
|
37
65
|
} from "@czi-sds/components";
|
|
38
66
|
import styled from "@emotion/styled";
|
|
39
67
|
|
|
68
|
+
const INTENTS: SdsTagIntent[] = [
|
|
69
|
+
"accent",
|
|
70
|
+
"beta",
|
|
71
|
+
"info",
|
|
72
|
+
"negative",
|
|
73
|
+
"neutral",
|
|
74
|
+
"notice",
|
|
75
|
+
"positive",
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
const STYLES: SdsTagStyle[] = ["solid", "outline"];
|
|
79
|
+
|
|
40
80
|
const Stack = styled.div<CommonThemeProps>`
|
|
41
81
|
${(props) => {
|
|
42
82
|
const spaces = getSpaces(props);
|
|
@@ -49,14 +89,14 @@ const Stack = styled.div<CommonThemeProps>`
|
|
|
49
89
|
}}
|
|
50
90
|
`;
|
|
51
91
|
|
|
52
|
-
const
|
|
92
|
+
const Row = styled.div<CommonThemeProps>`
|
|
53
93
|
${(props) => {
|
|
54
94
|
const spaces = getSpaces(props);
|
|
55
95
|
|
|
56
96
|
return `
|
|
57
|
-
align-items: center;
|
|
58
97
|
display: flex;
|
|
59
|
-
|
|
98
|
+
flex-wrap: wrap;
|
|
99
|
+
gap: ${spaces?.s}px;
|
|
60
100
|
`;
|
|
61
101
|
}}
|
|
62
102
|
`;
|
|
@@ -66,11 +106,11 @@ const Caption = styled.p<CommonThemeProps>`
|
|
|
66
106
|
|
|
67
107
|
${(props) => {
|
|
68
108
|
const semanticColors = getSemanticColors(props);
|
|
109
|
+
const spaces = getSpaces(props);
|
|
69
110
|
|
|
70
111
|
return `
|
|
71
112
|
color: ${semanticColors?.base?.textSecondary};
|
|
72
|
-
margin: 0;
|
|
73
|
-
min-width: 110px;
|
|
113
|
+
margin: 0 0 ${spaces?.xxs}px;
|
|
74
114
|
`;
|
|
75
115
|
}}
|
|
76
116
|
`;
|
|
@@ -79,15 +119,21 @@ function App() {
|
|
|
79
119
|
return (
|
|
80
120
|
<div className="app">
|
|
81
121
|
<Stack>
|
|
82
|
-
|
|
83
|
-
<
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
122
|
+
{STYLES.map((sdsStyle) => (
|
|
123
|
+
<div key={sdsStyle}>
|
|
124
|
+
<Caption>{sdsStyle}</Caption>
|
|
125
|
+
<Row>
|
|
126
|
+
{INTENTS.map((intent) => (
|
|
127
|
+
<Tag
|
|
128
|
+
color={intent}
|
|
129
|
+
key={intent}
|
|
130
|
+
label={intent}
|
|
131
|
+
sdsStyle={sdsStyle}
|
|
132
|
+
/>
|
|
133
|
+
))}
|
|
134
|
+
</Row>
|
|
135
|
+
</div>
|
|
136
|
+
))}
|
|
91
137
|
</Stack>
|
|
92
138
|
</div>
|
|
93
139
|
);
|
|
@@ -96,19 +142,16 @@ function App() {
|
|
|
96
142
|
export default App;
|
|
97
143
|
```
|
|
98
144
|
|
|
99
|
-
###
|
|
145
|
+
### Sizes
|
|
100
146
|
|
|
101
|
-
The
|
|
147
|
+
The medium and small sizes, each with a label, a label and an icon, and the icon alone.
|
|
102
148
|
|
|
103
|
-
**Example:
|
|
149
|
+
**Example: TagSizes**
|
|
104
150
|
|
|
105
151
|
```tsx
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
//
|
|
109
|
-
// sdsType picks how that intent is drawn: primary fills the tag with the intent
|
|
110
|
-
// color and sets the label white, secondary tints the fill and keeps the label in
|
|
111
|
-
// the intent color behind a matching border.
|
|
152
|
+
// size is medium unless it is set to small. A medium tag is 24px tall with a 13px
|
|
153
|
+
// label and 12px icons; a small one is 20px tall with a 10px label and 10px
|
|
154
|
+
// icons. Small suits a dense row, like a navigation bar or a tab's label.
|
|
112
155
|
|
|
113
156
|
import {
|
|
114
157
|
Tag,
|
|
@@ -116,18 +159,9 @@ import {
|
|
|
116
159
|
getSemanticColors,
|
|
117
160
|
getSpaces,
|
|
118
161
|
type CommonThemeProps,
|
|
119
|
-
type SdsTagColorType,
|
|
120
162
|
} from "@czi-sds/components";
|
|
121
163
|
import styled from "@emotion/styled";
|
|
122
|
-
|
|
123
|
-
const INTENTS: Extract<SdsTagColorType, string>[] = [
|
|
124
|
-
"info",
|
|
125
|
-
"positive",
|
|
126
|
-
"notice",
|
|
127
|
-
"negative",
|
|
128
|
-
"neutral",
|
|
129
|
-
"beta",
|
|
130
|
-
];
|
|
164
|
+
import { StackIcon } from "@phosphor-icons/react";
|
|
131
165
|
|
|
132
166
|
const Stack = styled.div<CommonThemeProps>`
|
|
133
167
|
${(props) => {
|
|
@@ -141,14 +175,14 @@ const Stack = styled.div<CommonThemeProps>`
|
|
|
141
175
|
}}
|
|
142
176
|
`;
|
|
143
177
|
|
|
144
|
-
const
|
|
178
|
+
const Group = styled.div<CommonThemeProps>`
|
|
145
179
|
${(props) => {
|
|
146
180
|
const spaces = getSpaces(props);
|
|
147
181
|
|
|
148
182
|
return `
|
|
183
|
+
align-items: center;
|
|
149
184
|
display: flex;
|
|
150
|
-
|
|
151
|
-
gap: ${spaces?.s}px;
|
|
185
|
+
gap: ${spaces?.m}px;
|
|
152
186
|
`;
|
|
153
187
|
}}
|
|
154
188
|
`;
|
|
@@ -158,11 +192,11 @@ const Caption = styled.p<CommonThemeProps>`
|
|
|
158
192
|
|
|
159
193
|
${(props) => {
|
|
160
194
|
const semanticColors = getSemanticColors(props);
|
|
161
|
-
const spaces = getSpaces(props);
|
|
162
195
|
|
|
163
196
|
return `
|
|
164
197
|
color: ${semanticColors?.base?.textSecondary};
|
|
165
|
-
margin: 0
|
|
198
|
+
margin: 0;
|
|
199
|
+
min-width: 80px;
|
|
166
200
|
`;
|
|
167
201
|
}}
|
|
168
202
|
`;
|
|
@@ -171,34 +205,74 @@ function App() {
|
|
|
171
205
|
return (
|
|
172
206
|
<div className="app">
|
|
173
207
|
<Stack>
|
|
174
|
-
<
|
|
175
|
-
<Caption>
|
|
176
|
-
<
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
208
|
+
<Group>
|
|
209
|
+
<Caption>medium</Caption>
|
|
210
|
+
<Tag color="accent" label="Annotated" />
|
|
211
|
+
<Tag
|
|
212
|
+
color="accent"
|
|
213
|
+
icon={<StackIcon weight="fill" />}
|
|
214
|
+
label="Annotated"
|
|
215
|
+
/>
|
|
216
|
+
<Tag
|
|
217
|
+
color="accent"
|
|
218
|
+
icon={<StackIcon weight="fill" />}
|
|
219
|
+
iconOnly
|
|
220
|
+
label="Annotated"
|
|
221
|
+
/>
|
|
222
|
+
<Tag color="accent" label="Annotated" sdsStyle="outline" />
|
|
223
|
+
<Tag
|
|
224
|
+
color="accent"
|
|
225
|
+
icon={<StackIcon weight="fill" />}
|
|
226
|
+
label="Annotated"
|
|
227
|
+
sdsStyle="outline"
|
|
228
|
+
/>
|
|
229
|
+
<Tag
|
|
230
|
+
color="accent"
|
|
231
|
+
icon={<StackIcon weight="fill" />}
|
|
232
|
+
iconOnly
|
|
233
|
+
label="Annotated"
|
|
234
|
+
sdsStyle="outline"
|
|
235
|
+
/>
|
|
236
|
+
</Group>
|
|
187
237
|
|
|
188
|
-
<
|
|
189
|
-
<Caption>
|
|
190
|
-
<
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
238
|
+
<Group>
|
|
239
|
+
<Caption>small</Caption>
|
|
240
|
+
<Tag color="accent" label="Annotated" size="small" />
|
|
241
|
+
<Tag
|
|
242
|
+
color="accent"
|
|
243
|
+
icon={<StackIcon weight="fill" />}
|
|
244
|
+
label="Annotated"
|
|
245
|
+
size="small"
|
|
246
|
+
/>
|
|
247
|
+
<Tag
|
|
248
|
+
color="accent"
|
|
249
|
+
icon={<StackIcon weight="fill" />}
|
|
250
|
+
iconOnly
|
|
251
|
+
label="Annotated"
|
|
252
|
+
size="small"
|
|
253
|
+
/>
|
|
254
|
+
<Tag
|
|
255
|
+
color="accent"
|
|
256
|
+
label="Annotated"
|
|
257
|
+
size="small"
|
|
258
|
+
sdsStyle="outline"
|
|
259
|
+
/>
|
|
260
|
+
<Tag
|
|
261
|
+
color="accent"
|
|
262
|
+
icon={<StackIcon weight="fill" />}
|
|
263
|
+
label="Annotated"
|
|
264
|
+
size="small"
|
|
265
|
+
sdsStyle="outline"
|
|
266
|
+
/>
|
|
267
|
+
<Tag
|
|
268
|
+
color="accent"
|
|
269
|
+
icon={<StackIcon weight="fill" />}
|
|
270
|
+
iconOnly
|
|
271
|
+
label="Annotated"
|
|
272
|
+
size="small"
|
|
273
|
+
sdsStyle="outline"
|
|
274
|
+
/>
|
|
275
|
+
</Group>
|
|
202
276
|
</Stack>
|
|
203
277
|
</div>
|
|
204
278
|
);
|
|
@@ -209,28 +283,29 @@ export default App;
|
|
|
209
283
|
|
|
210
284
|
### Tag + Icon
|
|
211
285
|
|
|
212
|
-
A
|
|
286
|
+
A leading icon from Phosphor or from `@czi-sds/icons`, and an icon-only tag inside the Tooltip that shows its label.
|
|
213
287
|
|
|
214
|
-
**Example:
|
|
288
|
+
**Example: TagIcons**
|
|
215
289
|
|
|
216
290
|
```tsx
|
|
217
|
-
// An icon goes on the leading edge of a tag
|
|
218
|
-
//
|
|
291
|
+
// An icon goes on the leading edge of a tag. The tag draws it at its own size,
|
|
292
|
+
// 12px in a medium tag and 10px in a small one, and in its own color, so pass a
|
|
293
|
+
// bare icon: one from Phosphor, or one from @czi-sds/icons for the icons SDS
|
|
294
|
+
// draws itself.
|
|
219
295
|
//
|
|
220
|
-
//
|
|
221
|
-
//
|
|
222
|
-
//
|
|
223
|
-
// Not every icon exists at both sizes: Virus below is large-only, so asking for it
|
|
224
|
-
// at a small size renders nothing and logs an error.
|
|
296
|
+
// iconOnly hides the label and squares the tag off. The label still names the
|
|
297
|
+
// tag for screen readers, but sighted users only see the icon, so an icon-only
|
|
298
|
+
// tag belongs in a Tooltip that shows the label.
|
|
225
299
|
|
|
226
|
-
import { Icon, Tag } from "@czi-sds/components";
|
|
227
|
-
import styled from "@emotion/styled";
|
|
228
300
|
import {
|
|
229
|
-
|
|
230
|
-
|
|
301
|
+
Tag,
|
|
302
|
+
Tooltip,
|
|
231
303
|
getSpaces,
|
|
232
304
|
type CommonThemeProps,
|
|
233
305
|
} from "@czi-sds/components";
|
|
306
|
+
import { StackIcon } from "@phosphor-icons/react";
|
|
307
|
+
import { CheckCircleIcon } from "@phosphor-icons/react";
|
|
308
|
+
import styled from "@emotion/styled";
|
|
234
309
|
|
|
235
310
|
const Row = styled.div<CommonThemeProps>`
|
|
236
311
|
${(props) => {
|
|
@@ -245,16 +320,67 @@ const Row = styled.div<CommonThemeProps>`
|
|
|
245
320
|
}}
|
|
246
321
|
`;
|
|
247
322
|
|
|
248
|
-
|
|
249
|
-
|
|
323
|
+
function App() {
|
|
324
|
+
return (
|
|
325
|
+
<div className="app">
|
|
326
|
+
<Row>
|
|
327
|
+
<Tag
|
|
328
|
+
color="accent"
|
|
329
|
+
icon={<StackIcon weight="fill" />}
|
|
330
|
+
label="Generated"
|
|
331
|
+
/>
|
|
332
|
+
|
|
333
|
+
<Tag
|
|
334
|
+
color="positive"
|
|
335
|
+
icon={<CheckCircleIcon />}
|
|
336
|
+
label="Verified"
|
|
337
|
+
sdsStyle="outline"
|
|
338
|
+
/>
|
|
339
|
+
|
|
340
|
+
<Tooltip placement="top" title="Generated">
|
|
341
|
+
<Tag
|
|
342
|
+
color="accent"
|
|
343
|
+
icon={<StackIcon weight="fill" />}
|
|
344
|
+
iconOnly
|
|
345
|
+
label="Generated"
|
|
346
|
+
/>
|
|
347
|
+
</Tooltip>
|
|
348
|
+
</Row>
|
|
349
|
+
</div>
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
export default App;
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Tag as a link
|
|
250
357
|
|
|
358
|
+
A tag with an `href` is a link. The arrow that says so is optional.
|
|
359
|
+
|
|
360
|
+
**Example: TagAsLink**
|
|
361
|
+
|
|
362
|
+
```tsx
|
|
363
|
+
// href turns a tag into a link: it renders as an <a>, takes a tab stop, and
|
|
364
|
+
// follows its href on click and on Enter. showLinkIcon adds an arrow after the
|
|
365
|
+
// label to say the tag leads somewhere. The arrow is optional; a tag with an
|
|
366
|
+
// href is a link either way.
|
|
367
|
+
//
|
|
368
|
+
// target="_blank" also sets rel="noopener noreferrer". For client-side routing,
|
|
369
|
+
// pass your router's link component as component and the tag renders that
|
|
370
|
+
// instead of a plain anchor.
|
|
371
|
+
|
|
372
|
+
import { Tag, getSpaces, type CommonThemeProps } from "@czi-sds/components";
|
|
373
|
+
import styled from "@emotion/styled";
|
|
374
|
+
|
|
375
|
+
const Row = styled.div<CommonThemeProps>`
|
|
251
376
|
${(props) => {
|
|
252
|
-
const semanticColors = getSemanticColors(props);
|
|
253
377
|
const spaces = getSpaces(props);
|
|
254
378
|
|
|
255
379
|
return `
|
|
256
|
-
|
|
257
|
-
|
|
380
|
+
align-items: center;
|
|
381
|
+
display: flex;
|
|
382
|
+
flex-wrap: wrap;
|
|
383
|
+
gap: ${spaces?.m}px;
|
|
258
384
|
`;
|
|
259
385
|
}}
|
|
260
386
|
`;
|
|
@@ -262,23 +388,29 @@ const Caption = styled.p<CommonThemeProps>`
|
|
|
262
388
|
function App() {
|
|
263
389
|
return (
|
|
264
390
|
<div className="app">
|
|
265
|
-
<Caption>
|
|
266
|
-
A large tag with a large icon, and a small tag with a small one
|
|
267
|
-
</Caption>
|
|
268
391
|
<Row>
|
|
269
392
|
<Tag
|
|
270
|
-
color="
|
|
271
|
-
|
|
272
|
-
label="
|
|
273
|
-
|
|
274
|
-
|
|
393
|
+
color="info"
|
|
394
|
+
href="https://sds.czi.design"
|
|
395
|
+
label="SDS website"
|
|
396
|
+
showLinkIcon
|
|
397
|
+
target="_blank"
|
|
398
|
+
/>
|
|
399
|
+
|
|
400
|
+
<Tag
|
|
401
|
+
color="info"
|
|
402
|
+
href="https://sds.czi.design"
|
|
403
|
+
label="SDS website"
|
|
404
|
+
sdsStyle="outline"
|
|
405
|
+
showLinkIcon
|
|
406
|
+
target="_blank"
|
|
275
407
|
/>
|
|
276
408
|
|
|
277
409
|
<Tag
|
|
278
|
-
color="
|
|
279
|
-
|
|
280
|
-
label="
|
|
281
|
-
|
|
410
|
+
color="info"
|
|
411
|
+
href="https://sds.czi.design"
|
|
412
|
+
label="Without the arrow"
|
|
413
|
+
target="_blank"
|
|
282
414
|
/>
|
|
283
415
|
</Row>
|
|
284
416
|
</div>
|
|
@@ -288,29 +420,29 @@ function App() {
|
|
|
288
420
|
export default App;
|
|
289
421
|
```
|
|
290
422
|
|
|
291
|
-
###
|
|
423
|
+
### Clickable, static and disabled tags
|
|
292
424
|
|
|
293
|
-
|
|
425
|
+
A tag with an `onClick` behaves as a button for both the pointer and the keyboard. A tag without one stays a static label, and `disabled` turns a clickable tag off.
|
|
294
426
|
|
|
295
|
-
**Example:
|
|
427
|
+
**Example: InteractiveTag**
|
|
296
428
|
|
|
297
429
|
```tsx
|
|
298
|
-
//
|
|
299
|
-
//
|
|
430
|
+
// A tag with an onClick becomes a button: it takes a tab stop, answers Enter and
|
|
431
|
+
// Space, reports its label as its name, and darkens under the pointer. A tag with
|
|
432
|
+
// neither an onClick nor an href is static: no role, no tab stop and no hover
|
|
433
|
+
// state, so it reads as a label rather than a control.
|
|
300
434
|
//
|
|
301
|
-
//
|
|
302
|
-
// a light background (the first tag below). A tag with an icon wants the
|
|
303
|
-
// three-value form, and the contrast of whatever colors you pick is on you, since
|
|
304
|
-
// SDS only guarantees it for its own intents.
|
|
435
|
+
// disabled greys a clickable tag out and takes it out of the tab order.
|
|
305
436
|
|
|
306
|
-
import { Icon, Tag } from "@czi-sds/components";
|
|
307
|
-
import styled from "@emotion/styled";
|
|
308
437
|
import {
|
|
438
|
+
Tag,
|
|
309
439
|
fontBodyXs,
|
|
310
440
|
getSemanticColors,
|
|
311
441
|
getSpaces,
|
|
312
442
|
type CommonThemeProps,
|
|
313
443
|
} from "@czi-sds/components";
|
|
444
|
+
import styled from "@emotion/styled";
|
|
445
|
+
import { useState } from "react";
|
|
314
446
|
|
|
315
447
|
const Stack = styled.div<CommonThemeProps>`
|
|
316
448
|
${(props) => {
|
|
@@ -345,45 +477,58 @@ const Caption = styled.p<CommonThemeProps>`
|
|
|
345
477
|
return `
|
|
346
478
|
color: ${semanticColors?.base?.textSecondary};
|
|
347
479
|
margin: 0;
|
|
348
|
-
min-width:
|
|
480
|
+
min-width: 150px;
|
|
481
|
+
`;
|
|
482
|
+
}}
|
|
483
|
+
`;
|
|
484
|
+
|
|
485
|
+
const Readout = styled.p<CommonThemeProps>`
|
|
486
|
+
${fontBodyXs}
|
|
487
|
+
|
|
488
|
+
${(props) => {
|
|
489
|
+
const semanticColors = getSemanticColors(props);
|
|
490
|
+
|
|
491
|
+
return `
|
|
492
|
+
color: ${semanticColors?.base?.textSecondary};
|
|
493
|
+
margin: 0;
|
|
349
494
|
`;
|
|
350
495
|
}}
|
|
351
496
|
`;
|
|
352
497
|
|
|
353
498
|
function App() {
|
|
499
|
+
const [clicks, setClicks] = useState(0);
|
|
500
|
+
|
|
354
501
|
return (
|
|
355
502
|
<div className="app">
|
|
356
503
|
<Stack>
|
|
357
504
|
<Group>
|
|
358
|
-
<Caption>
|
|
505
|
+
<Caption>Clickable</Caption>
|
|
359
506
|
<Tag
|
|
360
|
-
color=
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
sdsSize="l"
|
|
364
|
-
sdsStyle="rounded"
|
|
507
|
+
color="info"
|
|
508
|
+
label="Filter by species"
|
|
509
|
+
onClick={() => setClicks((count) => count + 1)}
|
|
365
510
|
/>
|
|
366
511
|
</Group>
|
|
367
512
|
|
|
368
513
|
<Group>
|
|
369
|
-
<Caption>
|
|
370
|
-
<Tag
|
|
371
|
-
color={["#3b2f00", "#ffe6a0", "#b26f00"]}
|
|
372
|
-
icon={<Icon sdsIcon="Star" sdsSize="l" />}
|
|
373
|
-
label="Icon colored too"
|
|
374
|
-
sdsSize="l"
|
|
375
|
-
sdsStyle="rounded"
|
|
376
|
-
/>
|
|
514
|
+
<Caption>Static</Caption>
|
|
515
|
+
<Tag label="Read-only label" />
|
|
377
516
|
</Group>
|
|
378
517
|
|
|
379
518
|
<Group>
|
|
380
|
-
<Caption>
|
|
519
|
+
<Caption>Disabled</Caption>
|
|
381
520
|
<Tag
|
|
382
|
-
color=
|
|
383
|
-
|
|
384
|
-
|
|
521
|
+
color="info"
|
|
522
|
+
disabled
|
|
523
|
+
label="Filter by tissue"
|
|
524
|
+
onClick={() => setClicks((count) => count + 1)}
|
|
385
525
|
/>
|
|
386
526
|
</Group>
|
|
527
|
+
|
|
528
|
+
<Readout>
|
|
529
|
+
The clickable tag has been activated {clicks}{" "}
|
|
530
|
+
{clicks === 1 ? "time" : "times"}, by pointer or by keyboard.
|
|
531
|
+
</Readout>
|
|
387
532
|
</Stack>
|
|
388
533
|
</div>
|
|
389
534
|
);
|
|
@@ -392,21 +537,20 @@ function App() {
|
|
|
392
537
|
export default App;
|
|
393
538
|
```
|
|
394
539
|
|
|
395
|
-
###
|
|
540
|
+
### Tag with custom colors
|
|
396
541
|
|
|
397
|
-
|
|
542
|
+
Colors given as a tuple, for a tag the intents do not cover.
|
|
398
543
|
|
|
399
|
-
**Example:
|
|
544
|
+
**Example: TagWithCustomColors**
|
|
400
545
|
|
|
401
546
|
```tsx
|
|
402
|
-
//
|
|
403
|
-
//
|
|
404
|
-
//
|
|
547
|
+
// color also takes a tuple of CSS colors for a tag the intents do not cover:
|
|
548
|
+
// [label, background] or [label, background, icon]. The icon takes the label
|
|
549
|
+
// color when the third value is left out, and an outline tag draws its border
|
|
550
|
+
// from the label color too.
|
|
405
551
|
//
|
|
406
|
-
//
|
|
407
|
-
//
|
|
408
|
-
// pointer events, so a static tag stops looking clickable, but it also stops
|
|
409
|
-
// answering the mouse and stops triggering a Tooltip wrapped around it.
|
|
552
|
+
// The contrast of whatever colors you pick is on you, since SDS only guarantees
|
|
553
|
+
// it for its own intents.
|
|
410
554
|
|
|
411
555
|
import {
|
|
412
556
|
Tag,
|
|
@@ -416,7 +560,7 @@ import {
|
|
|
416
560
|
type CommonThemeProps,
|
|
417
561
|
} from "@czi-sds/components";
|
|
418
562
|
import styled from "@emotion/styled";
|
|
419
|
-
import {
|
|
563
|
+
import { StarIcon } from "@phosphor-icons/react";
|
|
420
564
|
|
|
421
565
|
const Stack = styled.div<CommonThemeProps>`
|
|
422
566
|
${(props) => {
|
|
@@ -451,49 +595,41 @@ const Caption = styled.p<CommonThemeProps>`
|
|
|
451
595
|
return `
|
|
452
596
|
color: ${semanticColors?.base?.textSecondary};
|
|
453
597
|
margin: 0;
|
|
454
|
-
min-width:
|
|
455
|
-
`;
|
|
456
|
-
}}
|
|
457
|
-
`;
|
|
458
|
-
|
|
459
|
-
const Readout = styled.p<CommonThemeProps>`
|
|
460
|
-
${fontBodyXs}
|
|
461
|
-
|
|
462
|
-
${(props) => {
|
|
463
|
-
const semanticColors = getSemanticColors(props);
|
|
464
|
-
|
|
465
|
-
return `
|
|
466
|
-
color: ${semanticColors?.base?.textSecondary};
|
|
467
|
-
margin: 0;
|
|
598
|
+
min-width: 180px;
|
|
468
599
|
`;
|
|
469
600
|
}}
|
|
470
601
|
`;
|
|
471
602
|
|
|
472
603
|
function App() {
|
|
473
|
-
const [clicks, setClicks] = useState(0);
|
|
474
|
-
|
|
475
604
|
return (
|
|
476
605
|
<div className="app">
|
|
477
606
|
<Stack>
|
|
478
607
|
<Group>
|
|
479
|
-
<Caption>
|
|
608
|
+
<Caption>[label, background]</Caption>
|
|
480
609
|
<Tag
|
|
481
|
-
color="
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
sdsStyle="rounded"
|
|
610
|
+
color={["#3b2f00", "#ffe6a0"]}
|
|
611
|
+
icon={<StarIcon />}
|
|
612
|
+
label="Icon takes the label color"
|
|
485
613
|
/>
|
|
486
614
|
</Group>
|
|
487
615
|
|
|
488
616
|
<Group>
|
|
489
|
-
<Caption>
|
|
490
|
-
<Tag
|
|
617
|
+
<Caption>[label, background, icon]</Caption>
|
|
618
|
+
<Tag
|
|
619
|
+
color={["#3b2f00", "#ffe6a0", "#b26f00"]}
|
|
620
|
+
icon={<StarIcon />}
|
|
621
|
+
label="Icon colored on its own"
|
|
622
|
+
/>
|
|
491
623
|
</Group>
|
|
492
624
|
|
|
493
|
-
<
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
625
|
+
<Group>
|
|
626
|
+
<Caption>Outline</Caption>
|
|
627
|
+
<Tag
|
|
628
|
+
color={["#3b2f00", "#fff8e0"]}
|
|
629
|
+
label="Border from the label"
|
|
630
|
+
sdsStyle="outline"
|
|
631
|
+
/>
|
|
632
|
+
</Group>
|
|
497
633
|
</Stack>
|
|
498
634
|
</div>
|
|
499
635
|
);
|
|
@@ -509,13 +645,10 @@ What a long label does in a narrow container, and the Tooltip that keeps the tru
|
|
|
509
645
|
**Example: TagWithLongLabel**
|
|
510
646
|
|
|
511
647
|
```tsx
|
|
512
|
-
// A tag never wraps: it stretches to its label and then, in a container too
|
|
513
|
-
// for it, cuts the label off with an ellipsis. The text that is cut is not
|
|
648
|
+
// A tag never wraps: it stretches to its label and then, in a container too
|
|
649
|
+
// narrow for it, cuts the label off with an ellipsis. The text that is cut is not
|
|
514
650
|
// available anywhere else, so a tag that can hold a long value belongs in a
|
|
515
651
|
// Tooltip that carries the whole thing.
|
|
516
|
-
//
|
|
517
|
-
// The tooltip only works because the tag still receives pointer events. Adding
|
|
518
|
-
// hover={false} to quiet the hover styling would silence the tooltip with it.
|
|
519
652
|
|
|
520
653
|
import {
|
|
521
654
|
Tag,
|
|
@@ -544,10 +677,11 @@ const Stack = styled.div<CommonThemeProps>`
|
|
|
544
677
|
const NarrowColumn = styled.div<CommonThemeProps>`
|
|
545
678
|
${(props) => {
|
|
546
679
|
const semanticColors = getSemanticColors(props);
|
|
680
|
+
const spaces = getSpaces(props);
|
|
547
681
|
|
|
548
682
|
return `
|
|
549
683
|
border: 1px dashed ${semanticColors?.base?.divider};
|
|
550
|
-
padding:
|
|
684
|
+
padding: ${spaces?.xxs}px;
|
|
551
685
|
width: 160px;
|
|
552
686
|
`;
|
|
553
687
|
}}
|
|
@@ -573,7 +707,7 @@ function App() {
|
|
|
573
707
|
<Stack>
|
|
574
708
|
<div>
|
|
575
709
|
<Caption>Room for the whole label</Caption>
|
|
576
|
-
<Tag label={LABEL}
|
|
710
|
+
<Tag label={LABEL} />
|
|
577
711
|
</div>
|
|
578
712
|
|
|
579
713
|
<div>
|
|
@@ -582,7 +716,7 @@ function App() {
|
|
|
582
716
|
</Caption>
|
|
583
717
|
<NarrowColumn>
|
|
584
718
|
<Tooltip placement="top" title={LABEL}>
|
|
585
|
-
<Tag label={LABEL}
|
|
719
|
+
<Tag label={LABEL} />
|
|
586
720
|
</Tooltip>
|
|
587
721
|
</NarrowColumn>
|
|
588
722
|
</div>
|
|
@@ -596,21 +730,21 @@ export default App;
|
|
|
596
730
|
|
|
597
731
|
## SDS vs MUI
|
|
598
732
|
|
|
599
|
-
SDS Tag wraps MUI's Chip and replaces its palette, sizing and shape with SDS ones. SDS also splits the Chip's two jobs in two: Tag labels something, and
|
|
733
|
+
SDS Tag wraps MUI's Chip and replaces its palette, sizing and shape with SDS ones. SDS also splits the Chip's two jobs in two: Tag labels something, and Chip is the one that can be removed. The differences from MUI are these:
|
|
600
734
|
|
|
601
|
-
- `sdsStyle`: `"
|
|
735
|
+
- `sdsStyle`: `"solid"` (default) fills the tag with the intent color and sets the label white; `"outline"` tints the fill and draws the label, the icons and a 1px border in the intent color. It replaces MUI's `variant`, which Tag does not take.
|
|
602
736
|
|
|
603
|
-
- `
|
|
737
|
+
- `size`: MUI's own prop, but with SDS measurements. `"medium"` (default) is 24px tall with a 13px label and 12px icons, `"small"` is 20px tall with a 10px label and 10px icons.
|
|
604
738
|
|
|
605
|
-
- `
|
|
739
|
+
- `color`: an SDS intent rather than one of MUI's palette names. Seven intents are available, `"accent"` among them, and a tag without the prop is neutral. It also takes a tuple of CSS colors for cases the intents do not cover.
|
|
606
740
|
|
|
607
|
-
-
|
|
741
|
+
- **The shape follows the content:** a tag with a label is pill-shaped, and an icon-only tag (`iconOnly`) is square with 4px corners. There is no prop for it.
|
|
608
742
|
|
|
609
|
-
- `
|
|
743
|
+
- **Links:** `href` renders the tag as an `<a>`, which MUI's Chip only does when it is also handed `component="a"` and `clickable`. Passing `component` still works, so a router's link component can take the anchor's place. `showLinkIcon` adds Phosphor's ArrowUpRight after the label.
|
|
610
744
|
|
|
611
|
-
- **
|
|
745
|
+
- **Interactive styling follows behavior:** the hover and pressed states, the pointer cursor and the focus ring appear only on a tag with an `onClick` or an `href`, or one set `clickable`. A tag that only labels something has none of them.
|
|
612
746
|
|
|
613
|
-
- **onDelete works, but
|
|
747
|
+
- **onDelete works, but Chip is the removable tag:** a Tag given `onDelete` becomes deletable and draws MUI's Cancel icon at the tag's icon size. Reach for Chip when a tag needs to come off.
|
|
614
748
|
|
|
615
749
|
## MUI Documentation
|
|
616
750
|
|
|
@@ -618,30 +752,53 @@ Documentation for the underlying MUI component can be found [here](https://mui.c
|
|
|
618
752
|
|
|
619
753
|
## Behavior and accessibility
|
|
620
754
|
|
|
621
|
-
- A plain tag is a div holding its label, with no role and no tab stop, and is read as the text it shows. Giving it an `onClick` turns it into a button: it takes a tab stop, answers Enter and Space, and takes its accessible name from the label.
|
|
755
|
+
- A plain tag is a div holding its label, with no role and no tab stop, and is read as the text it shows. Giving it an `onClick` turns it into a button: it takes a tab stop, answers Enter and Space, and takes its accessible name from the label. Giving it an `href` turns it into a link instead.
|
|
622
756
|
|
|
623
|
-
-
|
|
757
|
+
- `disabled` greys a tag out. On a clickable tag or a link it also sets `aria-disabled` and takes the tag out of the tab order; on a static tag it changes nothing but the colors, so say in the label why the thing it describes is unavailable.
|
|
624
758
|
|
|
625
759
|
- Nothing about the intent reaches assistive technology: `color` is color only, so a negative tag needs a label that says what is wrong rather than relying on red.
|
|
626
760
|
|
|
761
|
+
- An icon-only tag keeps its label as its accessible name, hidden from view but read by screen readers. Sighted users see only the icon, so wrap the tag in a Tooltip that shows the label.
|
|
762
|
+
|
|
763
|
+
- The link arrow is decorative and hidden from screen readers. A link that opens in a new tab with `target="_blank"` should say so in its label or in text beside it.
|
|
764
|
+
|
|
627
765
|
- A tag never wraps. It stretches to fit its label and then, in a container too narrow, cuts the label off with an ellipsis, leaving the rest of the text nowhere else to be read. A tag that can hold a long value belongs in a Tooltip carrying the whole string.
|
|
628
766
|
|
|
629
|
-
- Icons are drawn at
|
|
767
|
+
- Icons are drawn at the tag's icon size (12px in a medium tag, 10px in a small one) and in its icon color, whatever the icon itself asks for, so pass a bare Phosphor or `@czi-sds/icons` icon. The deprecated SDS Icon still works, as long as the icon exists at a small size.
|
|
768
|
+
|
|
769
|
+
- Contrast is yours to check when you pass custom colors. SDS only guarantees it for its own intents.
|
|
770
|
+
|
|
771
|
+
## Migrating from TagLegacy
|
|
772
|
+
|
|
773
|
+
The Tag before SDS 25 is still exported as `TagLegacy`, so an app can switch its imports first and migrate each usage later. Its props map to the new Tag like this:
|
|
630
774
|
|
|
631
|
-
|
|
775
|
+
| Old prop | Replace with |
|
|
776
|
+
| ---------------------------------- | --------------------------------------------------------------------------------- |
|
|
777
|
+
| `sdsType="primary"` | `sdsStyle="solid"`, the default |
|
|
778
|
+
| `sdsType="secondary"` | `sdsStyle="outline"` |
|
|
779
|
+
| `sdsStyle="rounded"` or `"square"` | Nothing: a tag with a label is always pill-shaped, and an icon-only tag is square |
|
|
780
|
+
| `sdsSize="s"` | `size="small"` |
|
|
781
|
+
| `sdsSize="l"` | `size="medium"`, the default, which no longer needs an icon |
|
|
782
|
+
| `hover={false}` | Nothing: a tag without an `onClick` or an `href` is static |
|
|
783
|
+
| `tagColor` | `color` |
|
|
784
|
+
| `color={[label, background]}` | Unchanged, though the icon now takes the label color rather than staying white |
|
|
632
785
|
|
|
633
786
|
## Props
|
|
634
787
|
|
|
635
788
|
Any custom SDS props and MUI props required for implementation are found on the table below. See the MUI documentation for additional optional props.
|
|
636
789
|
|
|
637
|
-
| Name
|
|
638
|
-
|
|
|
639
|
-
| `label`
|
|
640
|
-
| `
|
|
641
|
-
| `
|
|
642
|
-
| `
|
|
643
|
-
| `
|
|
644
|
-
| `
|
|
645
|
-
| `
|
|
646
|
-
| `
|
|
647
|
-
| `
|
|
790
|
+
| Name | Type | Default | Description |
|
|
791
|
+
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
792
|
+
| `label` | `string` | - (required) | The tag's text, and its accessible name. It is cut off with an ellipsis rather than wrapped, so keep it to a word or two. An icon-only tag still needs it: the text is hidden from view but read by screen readers. |
|
|
793
|
+
| `sdsStyle` | `"solid"` \| `"outline"` | `"solid"` | `solid` fills the tag with the intent color. `outline` tints the fill and draws the label, the icons and a 1px border in the intent color. |
|
|
794
|
+
| `size` | `"small"` \| `"medium"` | `"medium"` | `medium` is 24px tall with a 13px label and 12px icons, `small` is 20px tall with a 10px label and 10px icons. |
|
|
795
|
+
| `color` | `"accent"` \| `"beta"` \| `"info"` \| `"negative"` \| `"neutral"` \| `"notice"` \| `"positive"` \| `[string, string]` \| `[string, string, string]` | `"neutral"` | One of the seven intents, or CSS colors for a tag the intents do not cover: `[label, background]` or `[label, background, icon]`. The icon takes the label color when the third value is left out. |
|
|
796
|
+
| `icon` | `ReactElement` | - | An icon on the leading edge, usually a Phosphor or `@czi-sds/icons` icon. The tag draws it at its own icon size and color. |
|
|
797
|
+
| `iconOnly` | `boolean` | `false` | Draws only the icon, in a square tag. The label is hidden from view but stays the tag's accessible name. Has no effect without an icon. |
|
|
798
|
+
| `showLinkIcon` | `boolean` | `false` | Adds an arrow after the label to say the tag leads somewhere. Usually paired with `href`, though a tag can be a link without it. |
|
|
799
|
+
| `href` | `string` | - | Turns the tag into a link. It renders as an `<a>` unless `component` says otherwise, as with a router's link component. |
|
|
800
|
+
| `target` | `string` | - | Where the link opens. `_blank` also sets `rel="noopener noreferrer"`. |
|
|
801
|
+
| `rel` | `string` | - | The link's relationship to the current page. |
|
|
802
|
+
| `disabled` | `boolean` | `false` | Greys the tag out. On a clickable tag or a link it also takes the tag out of the tab order. |
|
|
803
|
+
| `onClick` | `(event) => void` | - | MUI's prop. Makes the tag a button: a tab stop that answers Enter and Space, with hover and pressed states. |
|
|
804
|
+
| `onDelete` | `(event) => void` | - | MUI's prop. Adds a delete control, drawn with MUI's Cancel icon. Use Chip for a removable tag instead. |
|