@czi-sds/mcp 0.16.0 → 0.18.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 (167) hide show
  1. package/README.md +2 -1
  2. package/data/component-docs/Accordion.md +291 -0
  3. package/data/component-docs/Autocomplete.md +525 -0
  4. package/data/component-docs/Banner.md +231 -0
  5. package/data/component-docs/Button.md +224 -0
  6. package/data/component-docs/ButtonDropdown.md +256 -0
  7. package/data/component-docs/ButtonGroup.md +320 -0
  8. package/data/component-docs/ButtonToggle.md +397 -0
  9. package/data/component-docs/Callout.md +268 -0
  10. package/data/component-docs/CellBasic.md +122 -0
  11. package/data/component-docs/CellComponent.md +63 -0
  12. package/data/component-docs/CellHeader.md +128 -0
  13. package/data/component-docs/ComplexFilter.md +294 -0
  14. package/data/component-docs/ContentCard.md +406 -0
  15. package/data/component-docs/Dialog.md +651 -0
  16. package/data/component-docs/Dropdown.md +155 -0
  17. package/data/component-docs/DropdownMenu.md +949 -0
  18. package/data/component-docs/HeatmapChart.md +782 -0
  19. package/data/component-docs/Hero.md +363 -0
  20. package/data/component-docs/Icon.md +283 -0
  21. package/data/component-docs/InputCheckbox.md +205 -0
  22. package/data/component-docs/InputDropdown.md +482 -0
  23. package/data/component-docs/InputRadio.md +173 -0
  24. package/data/component-docs/InputSearch.md +81 -0
  25. package/data/component-docs/InputSlider.md +189 -0
  26. package/data/component-docs/InputText.md +110 -0
  27. package/data/component-docs/InputToggle.md +141 -0
  28. package/data/component-docs/IntentMessage.md +293 -0
  29. package/data/component-docs/Legend.md +442 -0
  30. package/data/component-docs/Link.md +23 -0
  31. package/data/component-docs/List.md +300 -0
  32. package/data/component-docs/LoadingIndicator.md +198 -0
  33. package/data/component-docs/Menu.md +298 -0
  34. package/data/component-docs/MenuItem.md +100 -0
  35. package/data/component-docs/NavigationFooter.md +165 -0
  36. package/data/component-docs/NavigationHeader.md +500 -0
  37. package/data/component-docs/NavigationJumpTo.md +414 -0
  38. package/data/component-docs/Notification.md +288 -0
  39. package/data/component-docs/Pagination.md +67 -0
  40. package/data/component-docs/Panel.md +636 -0
  41. package/data/component-docs/Popover.md +448 -0
  42. package/data/component-docs/PreComposedTable.md +2947 -0
  43. package/data/component-docs/ProteinStructureViewer.md +1044 -0
  44. package/data/component-docs/SegmentedControl.md +396 -0
  45. package/data/component-docs/StackedBarChart.md +475 -0
  46. package/data/component-docs/Table.md +2000 -0
  47. package/data/component-docs/TableHeader.md +53 -0
  48. package/data/component-docs/TableRow.md +74 -0
  49. package/data/component-docs/Tabs.md +455 -0
  50. package/data/component-docs/Tag.md +647 -0
  51. package/data/component-docs/TagFilter.md +131 -0
  52. package/data/component-docs/Tooltip.md +561 -0
  53. package/data/component-docs/TooltipCondensed.md +203 -0
  54. package/data/component-docs/TooltipTable.md +145 -0
  55. package/data/component-docs/index.json +267 -0
  56. package/data/component-list.json +2 -5
  57. package/data/component-props/Accordion.json +31 -11
  58. package/data/component-props/Alert.json +3 -3
  59. package/data/component-props/Autocomplete.json +150 -15
  60. package/data/component-props/Banner.json +31 -17
  61. package/data/component-props/Button.json +45 -20
  62. package/data/component-props/ButtonDropdown.json +36 -17
  63. package/data/component-props/ButtonDropdownLegacy.json +11 -11
  64. package/data/component-props/ButtonGroup.json +32 -11
  65. package/data/component-props/ButtonIcon.json +10 -10
  66. package/data/component-props/ButtonLegacy.json +19 -19
  67. package/data/component-props/ButtonToggle.json +32 -19
  68. package/data/component-props/ButtonToggleLegacy.json +11 -11
  69. package/data/component-props/Callout.json +58 -17
  70. package/data/component-props/CellBasic.json +94 -41
  71. package/data/component-props/CellComponent.json +23 -7
  72. package/data/component-props/CellHeader.json +62 -19
  73. package/data/component-props/ComplexFilter.json +52 -21
  74. package/data/component-props/ContentCard.json +70 -47
  75. package/data/component-props/Dialog.json +47 -14
  76. package/data/component-props/Dropdown.json +68 -31
  77. package/data/component-props/DropdownMenu.json +128 -23
  78. package/data/component-props/HeatmapChart.json +88 -12
  79. package/data/component-props/Hero.json +80 -39
  80. package/data/component-props/Icon.json +20 -9
  81. package/data/component-props/InputCheckbox.json +36 -14
  82. package/data/component-props/InputDropdown.json +75 -27
  83. package/data/component-props/InputRadio.json +31 -13
  84. package/data/component-props/InputSearch.json +41 -18
  85. package/data/component-props/InputSlider.json +46 -19
  86. package/data/component-props/InputText.json +26 -19
  87. package/data/component-props/InputToggle.json +26 -9
  88. package/data/component-props/IntentMessage.json +38 -9
  89. package/data/component-props/Link.json +13 -7
  90. package/data/component-props/LoadingIndicator.json +11 -3
  91. package/data/component-props/MenuItem.json +38 -19
  92. package/data/component-props/MenuSelect.json +8 -8
  93. package/data/component-props/NavigationFooter.json +49 -19
  94. package/data/component-props/NavigationHeader.json +150 -37
  95. package/data/component-props/NavigationJumpTo.json +33 -7
  96. package/data/component-props/Notification.json +39 -21
  97. package/data/component-props/Pagination.json +39 -11
  98. package/data/component-props/Panel.json +62 -9
  99. package/data/component-props/Popover.json +80 -7
  100. package/data/component-props/PreComposedTable.json +99 -27
  101. package/data/component-props/ProteinStructureViewer.json +117 -0
  102. package/data/component-props/SegmentedControl.json +42 -3
  103. package/data/component-props/StackedBarChart.json +116 -42
  104. package/data/component-props/TableRow.json +38 -19
  105. package/data/component-props/Tabs.json +66 -9
  106. package/data/component-props/Tag.json +34 -17
  107. package/data/component-props/TagFilter.json +10 -3
  108. package/data/component-props/Tooltip.json +49 -18
  109. package/data/component-props/TooltipCondensed.json +18 -9
  110. package/data/component-props/TooltipTable.json +17 -7
  111. package/data/resources/{zeroheight-rules.md → documentation-rules.md} +43 -30
  112. package/data/resources/figma-rules.md +2 -2
  113. package/data/tailwind.json +20 -14
  114. package/dist/stdio.js +112 -208
  115. package/package.json +9 -5
  116. package/data/component-props/ButtonDropdownV2.json +0 -34
  117. package/data/component-props/ButtonNew.json +0 -47
  118. package/data/component-props/ButtonToggleV2.json +0 -44
  119. package/data/component-props/ButtonV2.json +0 -43
  120. package/data/zeroheight-cache.json +0 -10259
  121. package/data/zeroheight-exports/Accordion.md +0 -774
  122. package/data/zeroheight-exports/Banner.md +0 -691
  123. package/data/zeroheight-exports/Borders.md +0 -117
  124. package/data/zeroheight-exports/Buttons.md +0 -1854
  125. package/data/zeroheight-exports/Callout.md +0 -931
  126. package/data/zeroheight-exports/Colors.md +0 -1755
  127. package/data/zeroheight-exports/Content-Card.md +0 -309
  128. package/data/zeroheight-exports/Contributing-to-SDS.md +0 -98
  129. package/data/zeroheight-exports/Control-Inputs.md +0 -2818
  130. package/data/zeroheight-exports/Corners.md +0 -104
  131. package/data/zeroheight-exports/Cover-page.md +0 -3
  132. package/data/zeroheight-exports/Dialog.md +0 -1367
  133. package/data/zeroheight-exports/Downloads.md +0 -236
  134. package/data/zeroheight-exports/Drop-Shadows.md +0 -79
  135. package/data/zeroheight-exports/Dropdown-Input.md +0 -1776
  136. package/data/zeroheight-exports/Dropdown-Menus.md +0 -913
  137. package/data/zeroheight-exports/Element-Status-Tracker.md +0 -267
  138. package/data/zeroheight-exports/Field-Inputs.md +0 -1405
  139. package/data/zeroheight-exports/Filters.md +0 -1111
  140. package/data/zeroheight-exports/Getting-Started.md +0 -1157
  141. package/data/zeroheight-exports/Hero.md +0 -414
  142. package/data/zeroheight-exports/Icons.md +0 -2067
  143. package/data/zeroheight-exports/Intent.md +0 -86
  144. package/data/zeroheight-exports/Introduction-to-Bases.md +0 -35
  145. package/data/zeroheight-exports/Introduction-to-Cells.md +0 -35
  146. package/data/zeroheight-exports/Introduction-to-DNA.md +0 -35
  147. package/data/zeroheight-exports/Introduction-to-Genes.md +0 -35
  148. package/data/zeroheight-exports/Introduction.md +0 -115
  149. package/data/zeroheight-exports/Link.md +0 -432
  150. package/data/zeroheight-exports/Lists.md +0 -986
  151. package/data/zeroheight-exports/Loading-Indicator.md +0 -41
  152. package/data/zeroheight-exports/Navigation.md +0 -1190
  153. package/data/zeroheight-exports/Notification.md +0 -1038
  154. package/data/zeroheight-exports/Panel.md +0 -1030
  155. package/data/zeroheight-exports/README.md +0 -122
  156. package/data/zeroheight-exports/Responsive-Design.md +0 -330
  157. package/data/zeroheight-exports/Search-Input.md +0 -91
  158. package/data/zeroheight-exports/Search.md +0 -822
  159. package/data/zeroheight-exports/Segmented-Control.md +0 -609
  160. package/data/zeroheight-exports/Spacing.md +0 -297
  161. package/data/zeroheight-exports/Table.md +0 -5345
  162. package/data/zeroheight-exports/Tabs.md +0 -1324
  163. package/data/zeroheight-exports/Tags.md +0 -1545
  164. package/data/zeroheight-exports/Text-Link.md +0 -268
  165. package/data/zeroheight-exports/Theming.md +0 -362
  166. package/data/zeroheight-exports/Tooltips.md +0 -2015
  167. package/data/zeroheight-exports/Typography.md +0 -800
@@ -0,0 +1,363 @@
1
+ # Hero
2
+
3
+ ## Source Code
4
+
5
+ The Hero component's source code in the SDS codebase can be found [here](https://github.com/chanzuckerberg/sci-components/blob/main/packages/components/src/core/Hero/index.tsx).
6
+
7
+ ## Import
8
+
9
+ **React TypeScript**
10
+
11
+ ```tsx
12
+ import { Hero } from "@czi-sds/components";
13
+ ```
14
+
15
+ ## Code examples
16
+
17
+ ### Default Hero
18
+
19
+ A headline, a caption, and a background color. With no `heroHeight` the section is as tall as its content plus the 40px of top and bottom padding.
20
+
21
+ **Example: DefaultHero**
22
+
23
+ ```tsx
24
+ // headerText and captionText are the only content props. Without heroHeight the
25
+ // section is as tall as its content plus the responsive padding.
26
+ //
27
+ // The fill comes from the theme rather than being written in as a hex, because
28
+ // the header and caption take their color from the theme too: a fixed light
29
+ // background keeps its own color in dark mode while the text over it turns
30
+ // light, and the two disappear into each other.
31
+
32
+ import { Hero, getSemanticColors } from "@czi-sds/components";
33
+ import { useTheme } from "@mui/material/styles";
34
+
35
+ function App() {
36
+ const theme = useTheme();
37
+ const semanticColors = getSemanticColors({ theme });
38
+
39
+ return (
40
+ <div className="app">
41
+ <Hero
42
+ headerText="Explore the Cell Atlas"
43
+ captionText="Browse millions of annotated cells across tissues, species, and disease states."
44
+ backgroundFill={semanticColors?.accent?.surfaceSecondary}
45
+ />
46
+ </div>
47
+ );
48
+ }
49
+
50
+ export default App;
51
+ ```
52
+
53
+ ### Header Sizes
54
+
55
+ `headerFontSize` picks the type scale for the headline. The caption is fixed and does not change with it.
56
+
57
+ **Example: HeroHeaderSizes**
58
+
59
+ ```tsx
60
+ // headerFontSize maps to the SDS header type scale: s, m (the default), and l.
61
+
62
+ import { Hero, getSemanticColors } from "@czi-sds/components";
63
+ import { useTheme } from "@mui/material/styles";
64
+
65
+ const SIZES = ["s", "m", "l"] as const;
66
+
67
+ function App() {
68
+ const theme = useTheme();
69
+ const semanticColors = getSemanticColors({ theme });
70
+
71
+ return (
72
+ <div
73
+ className="app"
74
+ style={{ display: "flex", flexDirection: "column", gap: "16px" }}
75
+ >
76
+ {SIZES.map((size) => (
77
+ <Hero
78
+ key={size}
79
+ headerFontSize={size}
80
+ headerText={`headerFontSize "${size}"`}
81
+ captionText="The caption always uses the same type style."
82
+ backgroundFill={semanticColors?.accent?.surfaceSecondary}
83
+ />
84
+ ))}
85
+ </div>
86
+ );
87
+ }
88
+
89
+ export default App;
90
+ ```
91
+
92
+ ### Hero with a Background Image
93
+
94
+ Passing a node to `backgroundFill` renders it full-bleed behind the content. The darkening mask keeps the text readable, and it needs both `darkeningMask` and a `darkeningMaskOpacity` above zero.
95
+
96
+ **Example: HeroWithBackgroundImage**
97
+
98
+ ```tsx
99
+ // backgroundFill also takes a node, which is stretched to cover the section.
100
+ // The darkening mask needs both darkeningMask and a darkeningMaskOpacity above
101
+ // zero, and hasInvertTextColor flips the title and caption to the light color.
102
+
103
+ import { Hero } from "@czi-sds/components";
104
+
105
+ // Inline placeholder so the example does not depend on a remote image
106
+ const BACKGROUND =
107
+ "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='1200' height='600'><defs><linearGradient id='g' x1='0' y1='0' x2='1' y2='1'><stop offset='0%' stop-color='rgb(58,74,148)'/><stop offset='100%' stop-color='rgb(126,86,194)'/></linearGradient></defs><rect width='1200' height='600' fill='url(%23g)'/></svg>";
108
+
109
+ function App() {
110
+ return (
111
+ <div className="app">
112
+ <Hero
113
+ heroHeight="320px"
114
+ backgroundFill={<img src={BACKGROUND} alt="" />}
115
+ darkeningMask
116
+ darkeningMaskOpacity={0.4}
117
+ hasInvertTextColor
118
+ headerText="Single-cell data, ready to explore"
119
+ captionText="The mask sits between the background and the content, so the text stays legible over busy imagery."
120
+ />
121
+ </div>
122
+ );
123
+ }
124
+
125
+ export default App;
126
+ ```
127
+
128
+ ### Content Position and Alignment
129
+
130
+ `overlayContentPosition` moves the whole content block within the section, while `textAlignment` aligns the text inside that block. Both need room to be visible, which comes from `heroHeight` and `overlayContentWidth`.
131
+
132
+ **Example: HeroContentPosition**
133
+
134
+ ```tsx
135
+ // overlayContentPosition places the content block inside the section, while
136
+ // textAlignment aligns the text within that block. overlayContentWidth keeps
137
+ // the block from spanning the full width.
138
+
139
+ import { Hero, getSemanticColors } from "@czi-sds/components";
140
+ import { useTheme } from "@mui/material/styles";
141
+
142
+ const POSITIONS = [
143
+ { position: "top-left", textAlignment: "left" },
144
+ { position: "center", textAlignment: "center" },
145
+ { position: "bottom-right", textAlignment: "right" },
146
+ ] as const;
147
+
148
+ function App() {
149
+ const theme = useTheme();
150
+ const semanticColors = getSemanticColors({ theme });
151
+
152
+ return (
153
+ <div
154
+ className="app"
155
+ style={{ display: "flex", flexDirection: "column", gap: "16px" }}
156
+ >
157
+ {POSITIONS.map(({ position, textAlignment }) => (
158
+ <Hero
159
+ key={position}
160
+ heroHeight="280px"
161
+ backgroundFill={semanticColors?.accent?.surfaceSecondary}
162
+ overlayContentPosition={position}
163
+ overlayContentWidth="60%"
164
+ textAlignment={textAlignment}
165
+ headerText={position}
166
+ captionText={`overlayContentPosition "${position}" with textAlignment "${textAlignment}".`}
167
+ />
168
+ ))}
169
+ </div>
170
+ );
171
+ }
172
+
173
+ export default App;
174
+ ```
175
+
176
+ ### Hero with a Call to Action
177
+
178
+ Children render in a slot below the caption. That slot keeps its own colors, so `hasInvertTextColor` does not reach the buttons.
179
+
180
+ **Example: HeroWithCallToAction**
181
+
182
+ ```tsx
183
+ // Children render in a content slot below the caption. Anything can go there;
184
+ // buttons and links are the common case. The slot does not inherit
185
+ // hasInvertTextColor, so style its contents yourself.
186
+
187
+ import { Button, Hero, getSemanticColors } from "@czi-sds/components";
188
+ import { useTheme } from "@mui/material/styles";
189
+
190
+ function App() {
191
+ const theme = useTheme();
192
+ const semanticColors = getSemanticColors({ theme });
193
+
194
+ return (
195
+ <div className="app">
196
+ <Hero
197
+ heroHeight="320px"
198
+ backgroundFill={semanticColors?.accent?.surfaceSecondary}
199
+ overlayContentWidth="60%"
200
+ headerText="Start a new analysis"
201
+ captionText="Upload your samples and get results in minutes."
202
+ >
203
+ <div style={{ display: "flex", gap: "8px" }}>
204
+ <Button sdsStyle="solid" sdsType="primary">
205
+ Upload samples
206
+ </Button>
207
+ <Button sdsStyle="outline" sdsType="primary">
208
+ View the docs
209
+ </Button>
210
+ </div>
211
+ </Hero>
212
+ </div>
213
+ );
214
+ }
215
+
216
+ export default App;
217
+ ```
218
+
219
+ ### Hero with Overlay Media
220
+
221
+ Overlay media is positioned independently of the text, so narrow the content block with `overlayContentWidth` to keep the two from overlapping.
222
+
223
+ **Example: HeroWithOverlayMedia**
224
+
225
+ ```tsx
226
+ // overlayMedia is a second layer of content, positioned independently of the
227
+ // text. Despite their names, overlayMediaMaxWidth and overlayMediaMaxHeight set
228
+ // the width and the height of that layer outright.
229
+
230
+ import { Hero, getSemanticColors } from "@czi-sds/components";
231
+ import { useTheme } from "@mui/material/styles";
232
+
233
+ // Inline placeholder so the example does not depend on a remote image
234
+ const MEDIA =
235
+ "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='400' height='200'><rect width='400' height='200' rx='8' fill='rgb(126,86,194)'/><circle cx='300' cy='60' r='40' fill='rgb(207,212,220)'/></svg>";
236
+
237
+ function App() {
238
+ const theme = useTheme();
239
+ const semanticColors = getSemanticColors({ theme });
240
+
241
+ return (
242
+ <div className="app">
243
+ <Hero
244
+ heroHeight="320px"
245
+ backgroundFill={semanticColors?.accent?.surfaceSecondary}
246
+ overlayContentWidth="50%"
247
+ overlayContentPosition="left"
248
+ headerText="Media alongside the copy"
249
+ captionText="The text block is held to half the width so the two layers do not collide."
250
+ overlayMedia={<img src={MEDIA} alt="" />}
251
+ overlayMediaPosition="right"
252
+ overlayMediaMaxWidth="240px"
253
+ overlayMediaMaxHeight="120px"
254
+ overlayMediaMargin="0 24px 0 0"
255
+ />
256
+ </div>
257
+ );
258
+ }
259
+
260
+ export default App;
261
+ ```
262
+
263
+ ### Hero with a Vignette
264
+
265
+ The vignette is a 40px gradient along the top edge, meant to sit behind a transparent header navigation.
266
+
267
+ **Example: HeroWithVignette**
268
+
269
+ ```tsx
270
+ // darkeningVignette draws a 40px gradient across the top edge. It exists so a
271
+ // transparent header navigation stays legible where it meets the Hero.
272
+
273
+ import { Hero } from "@czi-sds/components";
274
+
275
+ // Inline placeholder so the example does not depend on a remote image
276
+ const BACKGROUND =
277
+ "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='1200' height='600'><rect width='1200' height='600' fill='rgb(108,166,255)'/><circle cx='200' cy='120' r='160' fill='rgb(178,150,242)'/></svg>";
278
+
279
+ function App() {
280
+ return (
281
+ <div className="app">
282
+ <Hero
283
+ heroHeight="280px"
284
+ backgroundFill={<img src={BACKGROUND} alt="" />}
285
+ darkeningVignette
286
+ hasInvertTextColor
287
+ headerText="Blending into the navigation"
288
+ captionText="The gradient only covers the top 40px of the section."
289
+ />
290
+ </div>
291
+ );
292
+ }
293
+
294
+ export default App;
295
+ ```
296
+
297
+ ## Anatomy
298
+
299
+ Hero is not built on a MUI component. It renders a single `<section>` with the layers stacked inside it, so there is no MUI API underneath and no subcomponents to import:
300
+
301
+ - The background, from `backgroundFill`. A string is applied as a background color; a node is rendered into a full-bleed container where any img or video is stretched to cover the section.
302
+
303
+ - The darkening mask, from `darkeningMask`, which sits above the background and below everything else.
304
+
305
+ - The overlay media layer, from `overlayMedia`, positioned on its own so it does not follow the text.
306
+
307
+ - The content block, made of the `headerText` heading, the `captionText` paragraph, and a slot holding `children`.
308
+
309
+ - The vignette, from `darkeningVignette`, drawn on top of everything along the top edge.
310
+
311
+ `headerText` renders as an `h1`, so use one Hero per page and keep the rest of the page's headings below it.
312
+
313
+ ## Layout notes
314
+
315
+ - The side padding is driven by the viewport, not by the width of the Hero: 24px below 512px, 40px from 512px, and 120px from 1024px, which are the SDS sm, md, and lg breakpoints. The top and bottom padding is always 40px. In these previews the Hero is narrower than the viewport, so you are seeing the large breakpoint padding inside a small box.
316
+
317
+ - There is no built-in maximum width on the content area. Use `overlayContentWidth` when the text should not span the full section.
318
+
319
+ - `heroHeight` is ignored below 512px, where the section always falls back to `fit-content`.
320
+
321
+ - `darkeningMask` on its own changes nothing, because `darkeningMaskOpacity` defaults to `0`. Set both.
322
+
323
+ - `hasInvertTextColor` only applies to the header and the caption. Content passed as children keeps its own colors.
324
+
325
+ ## Props
326
+
327
+ Hero owns all of these props. Anything else, such as `className` or event handlers, is spread onto the section element.
328
+
329
+ ### Content
330
+
331
+ | Name | Type | Default | Description |
332
+ | -------------------- | ----------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
333
+ | `headerText` | `string` | - | The headline. Rendered as an `h1` and omitted entirely when not provided. |
334
+ | `headerFontSize` | `"s"` \| `"m"` \| `"l"` | `"m"` | The type scale of the headline. |
335
+ | `captionText` | `string` | - | Supporting copy rendered below the headline. |
336
+ | `children` | `ReactNode` | - | Rendered in a full-width slot below the caption. Use it for buttons, links, or a search field. |
337
+ | `hasInvertTextColor` | `boolean` | `false` | Sets the headline and caption in the light text color, for a hero over a dark backdrop: imagery, or a darkening mask over it. The color is the same in both themes, because the backdrop it is read against is. |
338
+
339
+ ### Layout
340
+
341
+ | Name | Type | Default | Description |
342
+ | --------------------------- | -------------------------------------------------------------------------------------------------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
343
+ | `className` | `string` | - | Declared so it type-checks, but nothing in the component reads it: it travels with the rest of the props onto the section element. |
344
+ | `heroHeight` | `string` | `"fit-content"` | Any CSS height. Below a 512px viewport it is ignored and the section falls back to `fit-content`. |
345
+ | `overlayContentPosition` | `"top-left" \| "top" \| "top-right" \| "left" \| "center" \| "right" \| "bottom-left" \| "bottom" \| "bottom-right"` | `"center"` | Where the content block sits inside the section. Only visible when the section is taller or wider than the content. |
346
+ | `overlayContentWidth` | `string` | `"100%"` | Any CSS width for the content block, for example `"60%"` or `"640px"`. |
347
+ | `textAlignment` | `"left" \| "center" \| "right"` | - | Aligns the text within the content block, which starts at the leading edge when the prop is unset. This is separate from `overlayContentPosition`, which moves the block itself. |
348
+ | `overlayContainerMinMargin` | `{ small: number; medium: number; large: number }` | `24px` / `40px` / `120px` | Overrides the side padding at each breakpoint. The value is written straight into CSS, so it needs a unit. The `number` type in the signature is wrong: a plain number produces an invalid declaration and the side padding drops to zero. |
349
+
350
+ ### Background and media
351
+
352
+ | Name | Type | Default | Description |
353
+ | ----------------------- | -------------------------------------------------------------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
354
+ | `backgroundFill` | `string \| ReactNode` | - | A string becomes the background color, so any CSS color or gradient works. A node is rendered full-bleed behind the content, and an img or video inside it is scaled to cover the section. |
355
+ | `darkeningMask` | `boolean` | `false` | Adds a solid layer over the background. Pair it with `darkeningMaskOpacity`, which is `0` by default. |
356
+ | `darkeningMaskColor` | `string` | `"#000000"` | The color of that layer. |
357
+ | `darkeningMaskOpacity` | `number` | `0` | The opacity of that layer, from 0 to 1. |
358
+ | `darkeningVignette` | `boolean` | `false` | Draws a 40px gradient along the top edge, above the content, so a transparent header navigation stays legible. |
359
+ | `overlayMedia` | `ReactNode` | - | A media layer above the background and independent of the text block. An img or video inside it is scaled to cover the layer. |
360
+ | `overlayMediaPosition` | `"top-left" \| "top" \| "top-right" \| "left" \| "center" \| "right" \| "bottom-left" \| "bottom" \| "bottom-right"` | `"center"` | Where that layer sits inside the section. |
361
+ | `overlayMediaMaxWidth` | `string` | - | Sets the width of the media layer outright rather than a maximum, despite the name. Without it the layer has no width. |
362
+ | `overlayMediaMaxHeight` | `string` | - | Sets the height of the media layer, with the same caveat. |
363
+ | `overlayMediaMargin` | `string \| { small: string; medium: string; large: string }` | `"0"` | A margin shorthand for the media layer. Pass the object form to vary it by breakpoint: `small` below md, `medium` below lg, `large` above. |
@@ -0,0 +1,283 @@
1
+ # Icon
2
+
3
+ > **Deprecated:** SDS icons come from [Phosphor](https://phosphoricons.com) now, and this component will be removed in a future major version. Import the icon you need from `@phosphor-icons/react`, or from `@czi-sds/icons` for the icons SDS draws itself. Both take the same props, so the only difference between them is where you import from. Migrating from Icon maps each prop on this page to its replacement.
4
+
5
+ The rest of this page documents the component as it still behaves, so existing usages can be read and migrated.
6
+
7
+ ## Source Code
8
+
9
+ The Icon component's source code in the SDS codebase can be found [here](https://github.com/chanzuckerberg/sci-components/blob/main/packages/components/src/core/Icon/index.tsx). The list of icon names and the sizes each one supports lives in [map.ts](https://github.com/chanzuckerberg/sci-components/blob/main/packages/components/src/core/Icon/map.ts).
10
+
11
+ ## Import
12
+
13
+ **React TypeScript**
14
+
15
+ ```tsx
16
+ import { Icon } from "@czi-sds/components";
17
+ ```
18
+
19
+ ## Code examples
20
+
21
+ ### Default Icon
22
+
23
+ `sdsIcon` and `sdsSize` are the only required props. With no `color` set, the icon renders in indigo.
24
+
25
+ **Example: DefaultIcon**
26
+
27
+ ```tsx
28
+ import { Icon } from "@czi-sds/components";
29
+
30
+ function App() {
31
+ return (
32
+ <div className="app">
33
+ <Icon sdsIcon="InfoCircle" sdsSize="l" />
34
+ </div>
35
+ );
36
+ }
37
+
38
+ export default App;
39
+ ```
40
+
41
+ ### Icon Sizes
42
+
43
+ The five sizes, shown with an icon that supports all of them. Below `"s"` the 16px artwork is scaled down, and at `"l"` and `"xl"` a separate, more detailed drawing is used.
44
+
45
+ **Example: IconSizes**
46
+
47
+ ```tsx
48
+ // Search is one of the icons that ships both drawings, so it covers all five
49
+ // sizes: 10, 12, 16, 24, and 32px.
50
+
51
+ import { Icon } from "@czi-sds/components";
52
+
53
+ const SIZES = ["xxs", "xs", "s", "l", "xl"] as const;
54
+
55
+ function App() {
56
+ return (
57
+ <div
58
+ className="app"
59
+ style={{ alignItems: "flex-end", display: "flex", gap: "24px" }}
60
+ >
61
+ {SIZES.map((size) => (
62
+ <div
63
+ key={size}
64
+ style={{
65
+ alignItems: "center",
66
+ display: "flex",
67
+ flexDirection: "column",
68
+ gap: "8px",
69
+ }}
70
+ >
71
+ <Icon sdsIcon="Search" sdsSize={size} />
72
+ <span style={{ fontSize: "12px" }}>{size}</span>
73
+ </div>
74
+ ))}
75
+ </div>
76
+ );
77
+ }
78
+
79
+ export default App;
80
+ ```
81
+
82
+ ### Sizes Are Per Icon
83
+
84
+ Some icons ship only the small artwork and some only the large. Asking for a size an icon does not have fails to compile, and renders nothing at runtime.
85
+
86
+ **Example: IconAvailableSizes**
87
+
88
+ ```tsx
89
+ // Gear only ships the small artwork, so xxs, xs, and s are its only sizes.
90
+ // Rocket only ships the large artwork, so it starts at l. Passing Gear an "l"
91
+ // would be a TypeScript error and would render nothing.
92
+
93
+ import { Icon } from "@czi-sds/components";
94
+
95
+ function App() {
96
+ return (
97
+ <div
98
+ className="app"
99
+ style={{ display: "flex", flexDirection: "column", gap: "16px" }}
100
+ >
101
+ <div style={{ alignItems: "center", display: "flex", gap: "16px" }}>
102
+ <Icon sdsIcon="Gear" sdsSize="xxs" />
103
+ <Icon sdsIcon="Gear" sdsSize="xs" />
104
+ <Icon sdsIcon="Gear" sdsSize="s" />
105
+ <span style={{ fontSize: "12px" }}>Gear: xxs, xs, s</span>
106
+ </div>
107
+
108
+ <div style={{ alignItems: "center", display: "flex", gap: "16px" }}>
109
+ <Icon sdsIcon="Rocket" sdsSize="l" />
110
+ <Icon sdsIcon="Rocket" sdsSize="xl" />
111
+ <span style={{ fontSize: "12px" }}>Rocket: l, xl</span>
112
+ </div>
113
+ </div>
114
+ );
115
+ }
116
+
117
+ export default App;
118
+ ```
119
+
120
+ ### Icon Colors
121
+
122
+ `color` picks the hue and `shade` picks the step within it. Both come from the SDS palette rather than from the surrounding text color.
123
+
124
+ **Example: IconColors**
125
+
126
+ ```tsx
127
+ // color chooses the hue and shade the step within it. Both are SDS palette
128
+ // values, so a CSS color is not accepted here.
129
+
130
+ import { Icon } from "@czi-sds/components";
131
+
132
+ const COLORS = [
133
+ "blue",
134
+ "gray",
135
+ "green",
136
+ "purple",
137
+ "indigo",
138
+ "red",
139
+ "yellow",
140
+ ] as const;
141
+
142
+ const SHADES = [300, 400, 500, 600, 700] as const;
143
+
144
+ function App() {
145
+ return (
146
+ <div
147
+ className="app"
148
+ style={{ display: "flex", flexDirection: "column", gap: "24px" }}
149
+ >
150
+ <div style={{ display: "flex", gap: "16px" }}>
151
+ {COLORS.map((color) => (
152
+ <Icon key={color} sdsIcon="CheckCircle" sdsSize="l" color={color} />
153
+ ))}
154
+ </div>
155
+
156
+ <div style={{ display: "flex", gap: "16px" }}>
157
+ {SHADES.map((shade) => (
158
+ <Icon
159
+ key={shade}
160
+ sdsIcon="CheckCircle"
161
+ sdsSize="l"
162
+ color="green"
163
+ shade={shade}
164
+ />
165
+ ))}
166
+ </div>
167
+ </div>
168
+ );
169
+ }
170
+
171
+ export default App;
172
+ ```
173
+
174
+ ### Icons in Components
175
+
176
+ When an icon is passed to another SDS component, that component controls the size and the color, so leave `color` off and let it inherit the component's states.
177
+
178
+ **Example: IconsInComponents**
179
+
180
+ ```tsx
181
+ // Components that take an icon set the size themselves and color it from their
182
+ // own states, so pass a bare Icon without a color.
183
+
184
+ import { Button, Callout, Icon, Tag } from "@czi-sds/components";
185
+
186
+ function App() {
187
+ return (
188
+ <div
189
+ className="app"
190
+ style={{ display: "flex", flexDirection: "column", gap: "16px" }}
191
+ >
192
+ <div style={{ display: "flex", gap: "8px" }}>
193
+ <Button
194
+ sdsStyle="solid"
195
+ sdsType="primary"
196
+ startIcon={<Icon sdsIcon="Download" sdsSize="s" />}
197
+ >
198
+ Download
199
+ </Button>
200
+ <Button
201
+ sdsStyle="outline"
202
+ sdsType="primary"
203
+ startIcon={<Icon sdsIcon="Search" sdsSize="s" />}
204
+ >
205
+ Search
206
+ </Button>
207
+ </div>
208
+
209
+ <div style={{ display: "flex" }}>
210
+ <Tag
211
+ label="Filtered"
212
+ color="info"
213
+ icon={<Icon sdsIcon="Filter" sdsSize="xs" />}
214
+ />
215
+ </div>
216
+
217
+ <Callout
218
+ intent="info"
219
+ icon={<Icon sdsIcon="LightBulb" sdsSize="s" />}
220
+ title="Swapping the icon"
221
+ body="Callout picks an icon from its intent, and the icon prop replaces it."
222
+ />
223
+ </div>
224
+ );
225
+ }
226
+
227
+ export default App;
228
+ ```
229
+
230
+ ### Accessible Icon-only Controls
231
+
232
+ The SVG carries no accessible name, so an icon on its own needs a label on the control around it. Next to visible text the icon is decorative and needs nothing.
233
+
234
+ **Example: AccessibleIcons**
235
+
236
+ ```tsx
237
+ // An icon-only control needs an accessible name on the control itself. Beside
238
+ // visible text the icon is decorative and adds nothing for a screen reader.
239
+
240
+ import { Button, Icon } from "@czi-sds/components";
241
+
242
+ function App() {
243
+ return (
244
+ <div className="app" style={{ display: "flex", gap: "16px" }}>
245
+ <Button sdsStyle="minimal" sdsType="secondary" aria-label="Delete file">
246
+ <Icon sdsIcon="TrashCan" sdsSize="l" />
247
+ </Button>
248
+
249
+ <Button
250
+ sdsStyle="outline"
251
+ sdsType="primary"
252
+ startIcon={<Icon sdsIcon="TrashCan" sdsSize="s" />}
253
+ >
254
+ Delete file
255
+ </Button>
256
+ </div>
257
+ );
258
+ }
259
+
260
+ export default App;
261
+ ```
262
+
263
+ ## How it works
264
+
265
+ Icon renders an SVG through MUI's SvgIcon, picking one of two drawings based on the size you ask for: `"xxs"`, `"xs"`, and `"s"` use the 16px artwork, while `"l"` and `"xl"` use the 24px artwork. Both are then scaled to the exact dimensions of the size. This is why the sizes are not interchangeable across icons; an icon that only ships the large artwork cannot be rendered at `"s"`.
266
+
267
+ - The types tie the two props together. Passing a size an icon does not support is a TypeScript error, and at runtime it logs an error to the console and renders nothing at all rather than falling back to another size.
268
+
269
+ - The icon is wrapped in a div with `display: contents`, so it does not add a box to the layout and the SVG behaves as a direct child of whatever contains it.
270
+
271
+ - The color comes from the SDS palette, not from the surrounding text color, and it defaults to indigo. Pair Icon with a component like Button or MenuItem when the icon should follow that component's state colors.
272
+
273
+ - The SVG has no title or label of its own. When an icon carries meaning on its own, put the label on the interactive element around it, for example an `aria-label` on an icon-only Button.
274
+
275
+ ## Props
276
+
277
+ | Name | Type | Default | Description |
278
+ | ----------- | -------------------------------------------------------------------------------- | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
279
+ | `sdsIcon` | `keyof IconNameToSizes` | - | Required. The name of the icon, as listed in the Icon Bank. Names are case-sensitive, for example `"XMark"` and `"LightBulb"`. |
280
+ | `sdsSize` | `"xxs"` (10px) \| `"xs"` (12px) \| `"s"` (16px) \| `"l"` (24px) \| `"xl"` (32px) | - | Required. Which sizes are accepted depends on the icon named in `sdsIcon`. |
281
+ | `color` | `"blue" \| "gray" \| "green" \| "purple" \| "indigo" \| "red" \| "yellow"` | `"indigo"` | A hue from the SDS palette. Note that this is the SDS `color` prop, not the MUI one, and it does not accept a CSS color. |
282
+ | `shade` | `100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800` | `500` in light mode, `600` in dark mode | The step within the chosen hue. |
283
+ | `className` | `string` | - | Applied to the SVG. Useful for overriding the fill from a parent component. |