@czi-sds/mcp 0.2.1 → 0.3.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.
Files changed (50) hide show
  1. package/data/zeroheight-cache.json +5195 -0
  2. package/data/zeroheight-exports/Accordion.md +675 -0
  3. package/data/zeroheight-exports/Banner.md +576 -0
  4. package/data/zeroheight-exports/Borders.md +118 -0
  5. package/data/zeroheight-exports/Buttons.md +2260 -0
  6. package/data/zeroheight-exports/Callout.md +756 -0
  7. package/data/zeroheight-exports/Colors.md +633 -0
  8. package/data/zeroheight-exports/Content-Card.md +162 -0
  9. package/data/zeroheight-exports/Contributing-to-SDS.md +99 -0
  10. package/data/zeroheight-exports/Control-Inputs.md +2066 -0
  11. package/data/zeroheight-exports/Corners.md +112 -0
  12. package/data/zeroheight-exports/Cover-page.md +4 -0
  13. package/data/zeroheight-exports/Dialog.md +1133 -0
  14. package/data/zeroheight-exports/Downloads.md +121 -0
  15. package/data/zeroheight-exports/Drop-Shadows.md +80 -0
  16. package/data/zeroheight-exports/Dropdown-Input.md +1149 -0
  17. package/data/zeroheight-exports/Dropdown-Menu.md +3787 -0
  18. package/data/zeroheight-exports/Element-Status-Tracker.md +268 -0
  19. package/data/zeroheight-exports/Field-Inputs.md +965 -0
  20. package/data/zeroheight-exports/Filters.md +868 -0
  21. package/data/zeroheight-exports/Getting-Started.md +1296 -0
  22. package/data/zeroheight-exports/Hero.md +256 -0
  23. package/data/zeroheight-exports/Icons.md +432 -0
  24. package/data/zeroheight-exports/Intent.md +47 -0
  25. package/data/zeroheight-exports/Introduction-to-Bases.md +36 -0
  26. package/data/zeroheight-exports/Introduction-to-Cells.md +36 -0
  27. package/data/zeroheight-exports/Introduction-to-DNA.md +36 -0
  28. package/data/zeroheight-exports/Introduction-to-Genes.md +36 -0
  29. package/data/zeroheight-exports/Introduction.md +116 -0
  30. package/data/zeroheight-exports/Link.md +373 -0
  31. package/data/zeroheight-exports/Lists.md +617 -0
  32. package/data/zeroheight-exports/Loading-Indicator.md +38 -0
  33. package/data/zeroheight-exports/Navigation.md +853 -0
  34. package/data/zeroheight-exports/Notification.md +858 -0
  35. package/data/zeroheight-exports/Panel.md +862 -0
  36. package/data/zeroheight-exports/README.md +124 -0
  37. package/data/zeroheight-exports/Responsive-Design.md +275 -0
  38. package/data/zeroheight-exports/Search-Input.md +54 -0
  39. package/data/zeroheight-exports/Search.md +609 -0
  40. package/data/zeroheight-exports/Segmented-Control.md +561 -0
  41. package/data/zeroheight-exports/Spacing.md +298 -0
  42. package/data/zeroheight-exports/Table.md +4832 -0
  43. package/data/zeroheight-exports/Tabs.md +773 -0
  44. package/data/zeroheight-exports/Tags.md +1025 -0
  45. package/data/zeroheight-exports/Text-Link.md +185 -0
  46. package/data/zeroheight-exports/Theming.md +313 -0
  47. package/data/zeroheight-exports/Tooltips.md +1564 -0
  48. package/data/zeroheight-exports/Typography.md +769 -0
  49. package/dist/stdio.js +515 -12
  50. package/package.json +4 -3
@@ -0,0 +1,773 @@
1
+ # Tabs
2
+
3
+ Tabs allow users to switch between different sets of information or content that is related to one overarching category or group while staying on the same page.
4
+
5
+ ## Overview
6
+
7
+ ## Tab Variants
8
+
9
+ | There are two sizes of Tabs available for use determined by their location in the UI. Individual tabs within each size can optionally include an alert to draw user's attention to something specific on that tab, such as to communicate the content on the tab is newly added or updated. They can also be paired with an underline that spans the width of the entire div the tab group is placed within to provide visual separation between the Tabs and the content beneath them. Follow the usage criteria accompanying each variant as a guide for selecting the correct Tab size for any given use case. | | **Jump to variant:** Large Small |
10
+ | --- | --- | --- |
11
+
12
+ ---
13
+
14
+ ## Tabs
15
+
16
+ | | In Figma | | | Meets Accessibility | | | In napari hub + .org Codebases |
17
+ | --- | --- | --- | --- | --- | --- | --- | --- |
18
+
19
+ ### Large Tabs
20
+
21
+ Default Tabs size to be used throughout the UI. Specifically used in napari hub at the top of plugin detail pages allowing users to change between the plugin's description and additional information such as usage activity and related analytics or citation information.
22
+
23
+ An optional alert can be added on a per Tab basis to communicate additional details about the Tab or the content on it, for example, indicating that the Tab is new or has been recently updated.
24
+
25
+ Tabs can also optionally be paired with an underline beneath them that spans the width of the entire div the Tab group is placed within.
26
+
27
+ | **Default** | **Hover** | **Active** | **Disabled** |
28
+ | --- | --- | --- | --- |
29
+
30
+ | **Default + Alert** | **Hover** | **Active** | **Disabled** |
31
+ | --- | --- | --- | --- |
32
+
33
+ | **Default + Underline** | **Hover** | **Active** | **Disabled** |
34
+ | --- | --- | --- | --- |
35
+
36
+ | **Default + Alert + Underline** | **Hover** | **Active** | **Disabled** |
37
+ | --- | --- | --- | --- |
38
+
39
+ ### Small Tabs
40
+
41
+ Alternative Tab size to be used in napari hub on plugin detail pages for plugins whose authors are using official formatting for their plugin citations.
42
+
43
+ | **Default** | **Hover** | **Active** | **Disabled** |
44
+ | --- | --- | --- | --- |
45
+
46
+ | **Default + Alert** | **Hover** | **Active** | **Disabled** |
47
+ | --- | --- | --- | --- |
48
+
49
+ | **Default + Underline** | **Hover** | **Active** | **Disabled** |
50
+ | --- | --- | --- | --- |
51
+
52
+ | **Default + Alert + Underline** | **Hover** | **Active** | **Disabled** |
53
+ | --- | --- | --- | --- |
54
+
55
+ ---
56
+
57
+ ### Tabs Spacing
58
+
59
+ These rules establish how much margin should exist between and around elements.
60
+
61
+  
62
+
63
+ ## Code
64
+
65
+ ## Tabs Component
66
+
67
+ | Below you will find an interactive Storybook iframe for Tabs. Tabs within each iframe provide a different set of tools: The Controls tab allows you to see and adjust all available props. The Actions tab shows you data displayed by event handler arguments. | | **Jump to component:** Tabs |
68
+ | --- | --- | --- |
69
+
70
+ ---
71
+
72
+ >This component appears as it is in the default SDS codebase. Once imported into the napari hub or napari.org codebases, use a theme file to enable the napari visual appearance customization.
73
+
74
+ ### Tabs 
75
+
76
+ Storybook
77
+
78
+ ---
79
+
80
+ Tabs allow users to switch between different sets of information or content that is related to one overarching category or group while staying on the same page.
81
+
82
+ ## Overview
83
+
84
+ ## Tab Variants
85
+
86
+ | There are two sizes of Tabs available for use determined by their location in the UI. Each size can include a counter to indicate the number of items on that tab’s screen such as search or filter results. They can also be paired with an underline that spans the width of the entire div the tab group is placed within to provide visual separation between the Tabs and the content beneath them. Follow the usage criteria accompanying each variant as a guide for selecting the correct Tab size for any given use case. | | **Jump to variant:** Large Small |
87
+ | --- | --- | --- |
88
+
89
+ ---
90
+
91
+ ## Tabs
92
+
93
+ | | In Figma | | | Meets Accessibility | | | In CZ GEN EPI Codebase |
94
+ | --- | --- | --- | --- | --- | --- | --- | --- |
95
+
96
+ ### Large Tabs
97
+
98
+ Default Tabs size to be used throughout the CZ GEN EPI UI.
99
+
100
+ In CZ GEN EPI, Large Tabs holding quantifiable data sets (like a sample table) should include a Count to allow users to be aware of data that isn't currently visible. On the group page for members and group details, Large Tabs without a count are used to separate between sections.
101
+
102
+ Overall, include a counter when necessary to indicate the number of items on that Tab's screen, whether visible or not visible, such as when displaying search or filter results.
103
+
104
+ | **Default** | **Hover** | **Active** | **Disabled** |
105
+ | --- | --- | --- | --- |
106
+
107
+ | **Default + Count** | **Hover** | **Active** | **Disabled** |
108
+ | --- | --- | --- | --- |
109
+
110
+ | **Default + Underline** | **Hover** | **Active** | **Disabled** |
111
+ | --- | --- | --- | --- |
112
+
113
+  
114
+
115
+ | **Default + Count + Underline** | **Hover** | **Active** | **Disabled** |
116
+ | --- | --- | --- | --- |
117
+
118
+ ### Small Tabs
119
+
120
+ Alternative Tab size to be used only in conjunction with Large Tabs when a secondary layer of tabbing is needed.
121
+
122
+ Include a counter when necessary to indicate the number of items on that Tab's screen, such as in the Members section of CZ GEN EPI, to help delineate between active members and outstanding invitations to the group.
123
+
124
+ | **Default** | **Hover** | **Active** | **Disabled** |
125
+ | --- | --- | --- | --- |
126
+
127
+ | **Default + Count** | **Hover** | **Active** | **Disabled** |
128
+ | --- | --- | --- | --- |
129
+
130
+ | **Default + Underline** | **Hover** | **Active** | **Disabled** |
131
+ | --- | --- | --- | --- |
132
+
133
+ | **Default + Count + Underline** | **Hover** | **Active** | **Disabled** |
134
+ | --- | --- | --- | --- |
135
+
136
+ ---
137
+
138
+ ### Tabs Spacing
139
+
140
+ These rules establish how much margin should exist between and around elements.
141
+
142
+  
143
+
144
+ ## Code
145
+
146
+ ## Tabs Component
147
+
148
+ | Below you will find an interactive Storybook iframe for Tabs. Tabs within each iframe provide a different set of tools: The Controls tab allows you to see and adjust all available props. The Actions tab shows you data displayed by event handler arguments. | | **Jump to component:** Tabs |
149
+ | --- | --- | --- |
150
+
151
+ ---
152
+
153
+ >This component appears as it is in the default SDS codebase. Once imported into the CZ GEN EPI codebase, use a theme file to enable the CZ GEN EPI visual appearance customization.
154
+
155
+ ### Tabs 
156
+
157
+ Storybook
158
+
159
+  
160
+
161
+ ---
162
+
163
+ Tabs allow users to switch between different sets of information or content that is related to one overarching category or group while staying on the same page.
164
+
165
+ ## Overview
166
+
167
+ ## Tab Variants
168
+
169
+ | There are two sizes of Tabs available for use determined by their location in the UI. Each size can include a counter to indicate the number of items on that tab’s screen such as search or filter results. They can also be paired with an underline that spans the width of the entire div the tab group is placed within to provide visual separation between the Tabs and the content beneath them. Follow the usage criteria accompanying each variant as a guide for selecting the correct Tab size for any given use case. | | **Jump to variant:** Large Small |
170
+ | --- | --- | --- |
171
+
172
+ ---
173
+
174
+ ## Tabs
175
+
176
+ | | In Figma | | | Meets Accessibility | | | In CZ ID Codebase |
177
+ | --- | --- | --- | --- | --- | --- | --- | --- |
178
+
179
+ ### Large Tabs
180
+
181
+ Default Tabs size to be used throughout the CZ ID UI.
182
+
183
+ In CZ ID, Large Tabs should include a Count when used in conjunction with header-level searches to allow users to tab between search results.
184
+
185
+ Include a counter when necessary to indicate the number of items on that Tab's screen such as when displaying search or filter results.
186
+
187
+ | **Default** | **Hover** | **Active** | **Disabled** |
188
+ | --- | --- | --- | --- |
189
+
190
+ | **Default + Count** | **Hover** | **Active** | **Disabled** |
191
+ | --- | --- | --- | --- |
192
+
193
+ | **Default + Underline** | **Hover** | **Active** | **Disabled** |
194
+ | --- | --- | --- | --- |
195
+
196
+ | **Default + Count + Underline** | **Hover** | **Active** | **Disabled** |
197
+ | --- | --- | --- | --- |
198
+
199
+  
200
+
201
+ ### Small Tabs
202
+
203
+ Alternative Tab size to be used only in conjunction with Large Tabs when a secondary layer of tabbing is needed.
204
+
205
+ Include a counter when necessary to indicate the number of items on that Tab's screen such as when displaying search or filter results.
206
+
207
+ | **Default** | **Hover** | **Active** | **Disabled** |
208
+ | --- | --- | --- | --- |
209
+
210
+ | **Default + Count** | **Hover** | **Active** | **Disabled** |
211
+ | --- | --- | --- | --- |
212
+
213
+ | **Default + Underline** | **Hover** | **Active** | **Disabled** |
214
+ | --- | --- | --- | --- |
215
+
216
+ | **Default + Count + Underline** | **Hover** | **Active** | **Disabled** |
217
+ | --- | --- | --- | --- |
218
+
219
+ ---
220
+
221
+ ### Tabs Spacing
222
+
223
+ These rules establish how much margin should exist between and around elements.
224
+
225
+ ## Code
226
+
227
+ ## Tabs Component
228
+
229
+ | Below you will find an interactive Storybook iframe for Tabs. Tabs within each iframe provide a different set of tools: The Controls tab allows you to see and adjust all available props. The Actions tab shows you data displayed by event handler arguments. | | **Jump to component:** Tabs |
230
+ | --- | --- | --- |
231
+
232
+ ---
233
+
234
+ ### Tabs 
235
+
236
+ Storybook
237
+
238
+ ---
239
+
240
+ Tabs allow users to switch between different sets of information or content that is related to one overarching category while staying on the same page.
241
+
242
+ ## Guidelines
243
+
244
+ ## Overview
245
+
246
+ | | In Figma | | | Meets Accessibility | | | In Code |
247
+ | --- | --- | --- | --- | --- | --- | --- | --- |
248
+
249
+ ### Tabs Sizes
250
+
251
+ There are two sizes of Tabs available for use which is determined by their location in the UI, the key difference being the size of the text on each Tab. Each size can include a counter to indicate the number of items on that Tab’s screen such as when used as part of Filter results. They can also be paired with an underline that spans the width of the entire div the tab group is placed within to provide visual separation between the Tabs and the content beneath them.
252
+
253
+ ---
254
+
255
+ ### Live Instance
256
+
257
+ Interact with the live instance below and adjust the available props to better conceptualize how it will appear in product:
258
+
259
+ Default
260
+
261
+ ---
262
+
263
+ ### Tabs – Large
264
+
265
+ Tabs – Large is used at a top level within the UI. If a secondary layer of tabbing is needed, use Tabs – Small.
266
+
267
+ Include a counter when necessary to indicate the number of viewable items available when navigating to that Tab's screen.
268
+
269
+ | Default | Hover | Active | Disabled |
270
+ | --- | --- | --- | --- |
271
+
272
+ ---
273
+
274
+ ### Tabs – Small
275
+
276
+ Tabs – Small is an alternative size to be used only in conjunction with Tabs – Large when a secondary layer of tabbing is needed.
277
+
278
+ Include a counter when necessary to indicate the number of viewable items available when navigating to that Tab's screen.
279
+
280
+ | Default | Hover | Active | Disabled |
281
+ | --- | --- | --- | --- |
282
+
283
+ ---
284
+
285
+ ### Tabs Spacing
286
+
287
+ These rules establish how much margin should exist between and around elements.
288
+
289
+ ## Code
290
+
291
+ >**Note:** The code examples below must install dependencies before displaying and may take extra time to load
292
+
293
+ ## Tabs
294
+
295
+ ### SDS Source Code
296
+
297
+ The component's source code in the SDS codebase can be found here.
298
+
299
+ ### SDS vs MUI
300
+
301
+ The SDS `Tabs` component is built on the MUI `Tabs` component, but the SDS version has a few additional props to provide stylistic options that fit within the SDS designs:
302
+
303
+ * **`sdsSize`****:** Takes `large` (default) or `small` as values, and sizes the Tabs component and its label text accordingly
304
+ * **`underlined`****:** This boolean prop extends a light gray underline beneath the whole of the `Tabs` component when true; without this prop, only the selected tab has an underline of the primary color
305
+ * **count, metadata, and / or component:** Each individual tab within the `Tabs` component can be assigned a count, via a prop associated to that tab's position, such as `tabOneCount` for the first tab. These props take a number value to represent a count, but they can also take text or even another component, for example:
306
+
307
+ `count={123}`
308
+
309
+ `count={"Hello!"}`
310
+
311
+ `tabThreeCount={<Tag />}`  
312
+
313
+ This example demonstrates passing a ReactNode as the count prop to a `Tabs` component.
314
+
315
+ ### MUI Documentation
316
+
317
+ Documentation for the underlying MUI component can be found here.
318
+
319
+ ### Props
320
+
321
+ Any custom SDS props and MUI props required for implementation are found on the table below. See the MUI documentation for additional optional props.
322
+
323
+ | Name | Type | Default | Description |
324
+ | --- | --- | --- | --- |
325
+ | `sdsSize` | `"small"` `| "large"` | `"large"` | Specifies the size of the Tab element. |
326
+ | `underlined` | `boolean` | `false` | when set to `true`, adds a gray bottom border to the tab group, providing a distinctive visual effect. |
327
+
328
+ ### Code examples
329
+
330
+ #### Tabs – Large
331
+
332
+ This example demonstrates a `Tabs` group with a larger visual style.
333
+
334
+ **/styles.css**
335
+
336
+ ```css
337
+ body {
338
+ font-size: 13px;
339
+ font-weight: 400;
340
+ letter-spacing: 0.08px;
341
+ line-height: 20px;
342
+ text-transform: none;
343
+ font-family: "Inter", sans-serif;
344
+ }
345
+
346
+ h1 {
347
+ font-size: 1.5rem;
348
+ }
349
+
350
+ .app {
351
+ padding: 20px;
352
+ }
353
+ ```
354
+
355
+ **tsconfig.json**
356
+
357
+ ```json
358
+ {
359
+ "include": [
360
+ "./**/*"
361
+ ],
362
+ "compilerOptions": {
363
+ "strict": true,
364
+ "esModuleInterop": true,
365
+ "lib": [ "dom", "es2015" ],
366
+ "jsx": "react-jsx"
367
+ }
368
+ }
369
+ ```
370
+
371
+ **/App.tsx**
372
+
373
+ ```tsx
374
+ import { useState, SyntheticEvent } from "react";
375
+ import { Tabs, Tab } from "@czi-sds/components";
376
+ import "./styles.css";
377
+
378
+ function App() {
379
+ const [value, setValue] = useState(0);
380
+
381
+ const handleTabsChange = (_: SyntheticEvent, tabsValue: unknown) => {
382
+ setValue(tabsValue as number);
383
+ };
384
+
385
+ return (
386
+ <div className="app">
387
+ <Tabs value={value} sdsSize="large" onChange={handleTabsChange}>
388
+ <Tab label="First Tab"/>
389
+ <Tab label="Second Tab"/>
390
+ </Tabs>
391
+ </div>
392
+ );
393
+ }
394
+
395
+ export default App;
396
+ ```
397
+
398
+ **/index.tsx**
399
+
400
+ ```tsx
401
+ import React from "react";
402
+ import { createRoot } from "react-dom/client";
403
+ import { ThemeProvider as EmotionThemeProvider } from "@emotion/react";
404
+ import { StyledEngineProvider, ThemeProvider } from "@mui/material/styles";
405
+ import { Theme } from "@czi-sds/components";
406
+ import CssBaseline from "@mui/material/CssBaseline";
407
+ import useMediaQuery from "@mui/material/useMediaQuery";
408
+
409
+ import App from "./App";
410
+
411
+ const container = document.getElementById("root");
412
+ const root = createRoot(container!);
413
+
414
+ const RootApp = () => {
415
+ const prefersDarkMode = useMediaQuery("(prefers-color-scheme: dark)");
416
+ const theme = prefersDarkMode ? Theme("dark") : Theme("light");
417
+
418
+ return (
419
+ <StyledEngineProvider injectFirst>
420
+ <ThemeProvider theme={theme}>
421
+ <EmotionThemeProvider theme={theme}>
422
+ <CssBaseline />
423
+ <App />
424
+ </EmotionThemeProvider>
425
+ </ThemeProvider>
426
+ </StyledEngineProvider>
427
+ );
428
+ };
429
+
430
+ root.render(
431
+ <React.StrictMode>
432
+ <RootApp />
433
+ </React.StrictMode>
434
+ );
435
+
436
+ ```
437
+
438
+ **/public/index.html**
439
+
440
+ ```html
441
+ <!DOCTYPE html>
442
+ <html lang="en">
443
+ <head>
444
+ <meta charset="UTF-8" />
445
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
446
+ <title>Tabs</title>
447
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
448
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
449
+ <link
450
+ href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap"
451
+ rel="stylesheet"
452
+ />
453
+ <link
454
+ href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600&display=swap"
455
+ rel="stylesheet"
456
+ />
457
+ </head>
458
+ <body>
459
+ <div id="root"></div>
460
+ </body>
461
+ </html>
462
+
463
+ ```
464
+
465
+ **/package.json**
466
+
467
+ ```json
468
+ {"dependencies":{"react":"^18.0.0","react-dom":"^18.0.0","react-scripts":"^4.0.0"},"devDependencies":{"@types/react":"^18.0.0","@types/react-dom":"^18.0.0","typescript":"^4.0.0"},"main":"/index.tsx"}
469
+ ```
470
+
471
+ ---
472
+
473
+ #### Tabs – Small
474
+
475
+ This example showcases a `Tabs` group with a smaller visual style.
476
+
477
+ **/styles.css**
478
+
479
+ ```css
480
+ body {
481
+ font-size: 13px;
482
+ font-weight: 400;
483
+ letter-spacing: 0.08px;
484
+ line-height: 20px;
485
+ text-transform: none;
486
+ font-family: "Inter", sans-serif;
487
+ }
488
+
489
+ h1 {
490
+ font-size: 1.5rem;
491
+ }
492
+
493
+ .app {
494
+ padding: 20px;
495
+ }
496
+ ```
497
+
498
+ **tsconfig.json**
499
+
500
+ ```json
501
+ {
502
+ "include": [
503
+ "./**/*"
504
+ ],
505
+ "compilerOptions": {
506
+ "strict": true,
507
+ "esModuleInterop": true,
508
+ "lib": [ "dom", "es2015" ],
509
+ "jsx": "react-jsx"
510
+ }
511
+ }
512
+ ```
513
+
514
+ **/App.tsx**
515
+
516
+ ```tsx
517
+ import { useState, SyntheticEvent } from "react";
518
+ import { Tabs, Tab } from "@czi-sds/components";
519
+ import "./styles.css";
520
+
521
+ function App() {
522
+ const [value, setValue] = useState(0);
523
+
524
+ const handleTabsChange = (_: SyntheticEvent, tabsValue: unknown) => {
525
+ setValue(tabsValue as number);
526
+ };
527
+
528
+ return (
529
+ <div className="app">
530
+ <Tabs value={value} sdsSize="small" onChange={handleTabsChange}>
531
+ <Tab label="First Tab"/>
532
+ <Tab label="Second Tab"/>
533
+ </Tabs>
534
+ </div>
535
+ );
536
+ }
537
+
538
+ export default App;
539
+ ```
540
+
541
+ **/index.tsx**
542
+
543
+ ```tsx
544
+ import React from "react";
545
+ import { createRoot } from "react-dom/client";
546
+ import { ThemeProvider as EmotionThemeProvider } from "@emotion/react";
547
+ import { StyledEngineProvider, ThemeProvider } from "@mui/material/styles";
548
+ import { Theme } from "@czi-sds/components";
549
+ import CssBaseline from "@mui/material/CssBaseline";
550
+ import useMediaQuery from "@mui/material/useMediaQuery";
551
+
552
+ import App from "./App";
553
+
554
+ const container = document.getElementById("root");
555
+ const root = createRoot(container!);
556
+
557
+ const RootApp = () => {
558
+ const prefersDarkMode = useMediaQuery("(prefers-color-scheme: dark)");
559
+ const theme = prefersDarkMode ? Theme("dark") : Theme("light");
560
+
561
+ return (
562
+ <StyledEngineProvider injectFirst>
563
+ <ThemeProvider theme={theme}>
564
+ <EmotionThemeProvider theme={theme}>
565
+ <CssBaseline />
566
+ <App />
567
+ </EmotionThemeProvider>
568
+ </ThemeProvider>
569
+ </StyledEngineProvider>
570
+ );
571
+ };
572
+
573
+ root.render(
574
+ <React.StrictMode>
575
+ <RootApp />
576
+ </React.StrictMode>
577
+ );
578
+
579
+ ```
580
+
581
+ **/public/index.html**
582
+
583
+ ```html
584
+ <!DOCTYPE html>
585
+ <html lang="en">
586
+ <head>
587
+ <meta charset="UTF-8" />
588
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
589
+ <title>Tabs</title>
590
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
591
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
592
+ <link
593
+ href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap"
594
+ rel="stylesheet"
595
+ />
596
+ <link
597
+ href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600&display=swap"
598
+ rel="stylesheet"
599
+ />
600
+ </head>
601
+ <body>
602
+ <div id="root"></div>
603
+ </body>
604
+ </html>
605
+
606
+ ```
607
+
608
+ **/package.json**
609
+
610
+ ```json
611
+ {"dependencies":{"react":"^18.0.0","react-dom":"^18.0.0","react-scripts":"^4.0.0"},"devDependencies":{"@types/react":"^18.0.0","@types/react-dom":"^18.0.0","typescript":"^4.0.0"},"main":"/index.tsx"}
612
+ ```
613
+
614
+ ---
615
+
616
+ #### Tabs with count, text, and component
617
+
618
+ This example shows an underlined `Tabs` group where the last tab includes a custom `Tag` component alongside the count.
619
+
620
+ **/styles.css**
621
+
622
+ ```css
623
+ body {
624
+ font-size: 13px;
625
+ font-weight: 400;
626
+ letter-spacing: 0.08px;
627
+ line-height: 20px;
628
+ text-transform: none;
629
+ font-family: "Inter", sans-serif;
630
+ }
631
+
632
+ h1 {
633
+ font-size: 1.5rem;
634
+ }
635
+
636
+ .app {
637
+ padding: 20px;
638
+ }
639
+ ```
640
+
641
+ **tsconfig.json**
642
+
643
+ ```json
644
+ {
645
+ "include": [
646
+ "./**/*"
647
+ ],
648
+ "compilerOptions": {
649
+ "strict": true,
650
+ "esModuleInterop": true,
651
+ "lib": [ "dom", "es2015" ],
652
+ "jsx": "react-jsx"
653
+ }
654
+ }
655
+ ```
656
+
657
+ **/App.tsx**
658
+
659
+ ```tsx
660
+ import { useState, SyntheticEvent } from "react";
661
+ import { Tabs, Tab, Tag } from "@czi-sds/components";
662
+ import { styled } from "@mui/material";
663
+ import "./styles.css";
664
+
665
+ function App() {
666
+ const [value, setValue] = useState(0);
667
+
668
+ const handleTabsChange = (_: SyntheticEvent, tabsValue: unknown) => {
669
+ setValue(tabsValue as number);
670
+ };
671
+
672
+ const CountWrapper = styled("span")`
673
+ margin-right: 5px;
674
+ `;
675
+
676
+ function BetaTagWithCount() {
677
+ return (
678
+ <>
679
+ <CountWrapper>14</CountWrapper>
680
+ <Tag label="BETA" color="beta" sdsStyle="rounded" sdsType="secondary" />
681
+ </>
682
+ );
683
+ }
684
+
685
+ return (
686
+ <div className="app">
687
+ <Tabs value={value} sdsSize="large" onChange={handleTabsChange} underlined>
688
+ <Tab label="First Tab" count="4" />
689
+ <Tab label="Second Tab" count="20" />
690
+ <Tab label="Third Tab" count={<BetaTagWithCount />} />
691
+ </Tabs>
692
+ </div>
693
+ );
694
+ }
695
+
696
+ export default App;
697
+ ```
698
+
699
+ **/index.tsx**
700
+
701
+ ```tsx
702
+ import React from "react";
703
+ import { createRoot } from "react-dom/client";
704
+ import { ThemeProvider as EmotionThemeProvider } from "@emotion/react";
705
+ import { StyledEngineProvider, ThemeProvider } from "@mui/material/styles";
706
+ import { Theme } from "@czi-sds/components";
707
+ import CssBaseline from "@mui/material/CssBaseline";
708
+ import useMediaQuery from "@mui/material/useMediaQuery";
709
+
710
+ import App from "./App";
711
+
712
+ const container = document.getElementById("root");
713
+ const root = createRoot(container!);
714
+
715
+ const RootApp = () => {
716
+ const prefersDarkMode = useMediaQuery("(prefers-color-scheme: dark)");
717
+ const theme = prefersDarkMode ? Theme("dark") : Theme("light");
718
+
719
+ return (
720
+ <StyledEngineProvider injectFirst>
721
+ <ThemeProvider theme={theme}>
722
+ <EmotionThemeProvider theme={theme}>
723
+ <CssBaseline />
724
+ <App />
725
+ </EmotionThemeProvider>
726
+ </ThemeProvider>
727
+ </StyledEngineProvider>
728
+ );
729
+ };
730
+
731
+ root.render(
732
+ <React.StrictMode>
733
+ <RootApp />
734
+ </React.StrictMode>
735
+ );
736
+
737
+ ```
738
+
739
+ **/public/index.html**
740
+
741
+ ```html
742
+ <!DOCTYPE html>
743
+ <html lang="en">
744
+ <head>
745
+ <meta charset="UTF-8" />
746
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
747
+ <title>Tabs</title>
748
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
749
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
750
+ <link
751
+ href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap"
752
+ rel="stylesheet"
753
+ />
754
+ <link
755
+ href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600&display=swap"
756
+ rel="stylesheet"
757
+ />
758
+ </head>
759
+ <body>
760
+ <div id="root"></div>
761
+ </body>
762
+ </html>
763
+
764
+ ```
765
+
766
+ **/package.json**
767
+
768
+ ```json
769
+ {"dependencies":{"react":"^18.0.0","react-dom":"^18.0.0","react-scripts":"^4.0.0"},"devDependencies":{"@types/react":"^18.0.0","@types/react-dom":"^18.0.0","typescript":"^4.0.0"},"main":"/index.tsx"}
770
+ ```
771
+
772
+ ---
773
+