@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,500 @@
1
+ # NavigationHeader
2
+
3
+ ## Source Code
4
+
5
+ The component's source code in the SDS codebase can be found [here](https://github.com/chanzuckerberg/sci-components/tree/main/packages/components/src/core/NavigationHeader).
6
+
7
+ ## Import
8
+
9
+ **React TypeScript**
10
+
11
+ ```tsx
12
+ import { NavigationHeader } from "@czi-sds/components";
13
+ ```
14
+
15
+ ## Code examples
16
+
17
+ > **Note:** Most headers below set `isSticky={false}` so they stay inside their example rather than pinning themselves to the top of this page. Because they are narrower than a real page, some collapse to the narrow layout with a hamburger; widen the window to see the wide layout. Overlays such as the narrow layout's drawer expect a real viewport, so they cover this page instead of their example unless the example holds them in, as the drawer-style one below does.
18
+
19
+ ### Default header
20
+
21
+ A dropdown-style header with a logo, title, tag, a text item and a dropdown item, one secondary item, and two buttons.
22
+
23
+ **Example: NavigationHeaderDefault**
24
+
25
+ ```tsx
26
+ // The default dropdown style: primary items on the left of the search field,
27
+ // secondary items and buttons on the right. Nav items are data, not children,
28
+ // so the header owns the markup for every row.
29
+
30
+ import {
31
+ Icon,
32
+ NavigationHeader,
33
+ getSemanticColors,
34
+ type CommonThemeProps,
35
+ type NavigationHeaderPrimaryNavItem,
36
+ type NavigationHeaderSecondaryNavItem,
37
+ } from "@czi-sds/components";
38
+ import styled from "@emotion/styled";
39
+ import { useState } from "react";
40
+
41
+ const Logo = styled.div<CommonThemeProps>`
42
+ ${(props) => {
43
+ const semanticColors = getSemanticColors(props);
44
+
45
+ return `
46
+ align-items: center;
47
+ border: 1px dashed ${semanticColors?.base?.borderPrimary};
48
+ color: ${semanticColors?.base?.textSecondary};
49
+ display: flex;
50
+ font-size: 10px;
51
+ height: 24px;
52
+ justify-content: center;
53
+ width: 50px;
54
+ `;
55
+ }}
56
+ `;
57
+
58
+ const primaryNavItems: NavigationHeaderPrimaryNavItem<string>[] = [
59
+ {
60
+ itemType: "text",
61
+ key: "datasets",
62
+ label: "Datasets",
63
+ onClick: () => console.log("Datasets clicked"),
64
+ },
65
+ {
66
+ itemType: "dropdown",
67
+ items: [
68
+ { label: "Cell types", onClick: () => console.log("Cell types clicked") },
69
+ { label: "Genes", onClick: () => console.log("Genes clicked") },
70
+ ],
71
+ key: "explore",
72
+ label: "Explore",
73
+ },
74
+ ];
75
+
76
+ const secondaryNavItems: NavigationHeaderSecondaryNavItem<string>[] = [
77
+ {
78
+ itemType: "text",
79
+ key: "docs",
80
+ label: "Docs",
81
+ onClick: () => console.log("Docs clicked"),
82
+ },
83
+ ];
84
+
85
+ function App() {
86
+ const [activePrimaryNavKey, setActivePrimaryNavKey] = useState("datasets");
87
+
88
+ return (
89
+ <div className="app">
90
+ <NavigationHeader
91
+ activePrimaryNavKey={activePrimaryNavKey}
92
+ setActivePrimaryNavKey={setActivePrimaryNavKey}
93
+ buttons={[
94
+ { children: "Sign in", sdsStyle: "outline", sdsType: "primary" },
95
+ {
96
+ children: <Icon sdsIcon="Person" sdsSize="s" />,
97
+ onClick: () => console.log("Profile clicked"),
98
+ sdsStyle: "minimal",
99
+ sdsType: "secondary",
100
+ },
101
+ ]}
102
+ isSticky={false}
103
+ logo={<Logo>Logo slot</Logo>}
104
+ logoUrl="https://chanzuckerberg.com"
105
+ menuProps={{ disablePortal: true, disableScrollLock: true }}
106
+ primaryNavItems={primaryNavItems}
107
+ secondaryNavItems={secondaryNavItems}
108
+ showSearch={false}
109
+ tag="Beta"
110
+ tagColor="beta"
111
+ title="Cell Atlas"
112
+ />
113
+ </div>
114
+ );
115
+ }
116
+
117
+ export default App;
118
+ ```
119
+
120
+ ### Grouped dropdown items
121
+
122
+ Giving items a section name groups them under headings with a divider between groups. Only the label and the section are used in this style, so there is no point giving these items icons or details.
123
+
124
+ **Example: NavigationHeaderSections**
125
+
126
+ ```tsx
127
+ // Dropdown items grouped into sections: each item names its section, and the
128
+ // menu draws a heading per group with a divider between them. This style uses
129
+ // only the label and the section; icons and details need drawer style.
130
+
131
+ import {
132
+ NavigationHeader,
133
+ type NavigationHeaderPrimaryNavItem,
134
+ } from "@czi-sds/components";
135
+ import { useState } from "react";
136
+
137
+ const primaryNavItems: NavigationHeaderPrimaryNavItem<string>[] = [
138
+ {
139
+ itemType: "dropdown",
140
+ items: [
141
+ { label: "Browse datasets", section: "Data" },
142
+ { label: "API reference", section: "Data" },
143
+ { label: "CZ CELLxGENE", section: "Repositories" },
144
+ { label: "CryoET", section: "Repositories" },
145
+ ],
146
+ key: "data",
147
+ label: "Data",
148
+ },
149
+ {
150
+ itemType: "text",
151
+ key: "about",
152
+ label: "About",
153
+ onClick: () => console.log("About clicked"),
154
+ },
155
+ ];
156
+
157
+ function App() {
158
+ const [activePrimaryNavKey, setActivePrimaryNavKey] = useState("data");
159
+
160
+ return (
161
+ <div className="app">
162
+ <NavigationHeader
163
+ activePrimaryNavKey={activePrimaryNavKey}
164
+ setActivePrimaryNavKey={setActivePrimaryNavKey}
165
+ isSticky={false}
166
+ menuProps={{ disablePortal: true, disableScrollLock: true }}
167
+ primaryNavItems={primaryNavItems}
168
+ showSearch={false}
169
+ title="Science Data"
170
+ />
171
+ </div>
172
+ );
173
+ }
174
+
175
+ export default App;
176
+ ```
177
+
178
+ ### Drawer style on a dark header
179
+
180
+ Hovering the nav item opens a panel instead of a menu, and this is the style that renders item icons and the section's actions. The panel is a MUI Drawer that fixes itself to the viewport, so this example adds a theme override and some CSS to keep it inside the frame; a page whose header spans the viewport needs neither.
181
+
182
+ **Example: NavigationHeaderDrawer**
183
+
184
+ ```tsx
185
+ // sdsStyle="drawer" opens a full-width panel on hover instead of a menu on
186
+ // click. It is the only style that draws item icons and the per-section
187
+ // actions, and backgroundAppearance="dark" inverts the whole header.
188
+ //
189
+ // The panel is a MUI Drawer: it goes to the end of the page and fixes itself to
190
+ // the viewport, which here would cover the docs rather than the example. The
191
+ // theme below sends it to the box instead, the CSS anchors it there, and the
192
+ // focus options stop it from scrolling itself into view. Rendering it in place
193
+ // with disablePortal would put it inside the header, where it paints over the
194
+ // bar as it slides in. A real page, where the header spans the viewport and the
195
+ // panel slides out from under it, needs none of this.
196
+
197
+ import {
198
+ NavigationHeader,
199
+ fontBodyS,
200
+ getSemanticColors,
201
+ type CommonThemeProps,
202
+ type NavigationHeaderPrimaryNavItem,
203
+ } from "@czi-sds/components";
204
+ import styled from "@emotion/styled";
205
+ import { ThemeProvider, createTheme, useTheme } from "@mui/material/styles";
206
+ import { useMemo, useRef, useState } from "react";
207
+
208
+ const Stage = styled.div`
209
+ min-height: 380px;
210
+ position: relative;
211
+
212
+ /* The panel starts above the box it belongs to and slides down into it, which
213
+ on a real page means starting off screen. Here it would cross the docs. */
214
+ overflow: hidden;
215
+
216
+ /* The panel, its backdrop, and the modal wrapper are all fixed to the
217
+ viewport by default; anchoring them to this box keeps them in the frame. */
218
+ .MuiModal-root,
219
+ .MuiBackdrop-root,
220
+ .MuiDrawer-paper {
221
+ position: absolute;
222
+ }
223
+ `;
224
+
225
+ const Hint = styled.p<CommonThemeProps>`
226
+ ${fontBodyS}
227
+
228
+ ${(props) => {
229
+ const semanticColors = getSemanticColors(props);
230
+
231
+ return `
232
+ color: ${semanticColors?.base?.textSecondary};
233
+ margin: 24px;
234
+ `;
235
+ }}
236
+ `;
237
+
238
+ const primaryNavItems: NavigationHeaderPrimaryNavItem<string>[] = [
239
+ {
240
+ itemType: "dropdown",
241
+ items: [
242
+ {
243
+ details: "Every public dataset",
244
+ icon: "Search",
245
+ label: "Browse datasets",
246
+ section: "Data",
247
+ },
248
+ {
249
+ details: "Pull data from the command line",
250
+ icon: "Code",
251
+ label: "API reference",
252
+ section: "Data",
253
+ },
254
+ {
255
+ details: "Single-cell multiomic data",
256
+ icon: "Grid",
257
+ label: "CZ CELLxGENE",
258
+ section: "Repositories",
259
+ },
260
+ {
261
+ details: "3D sub-cellular tomograms",
262
+ icon: "Flask",
263
+ label: "CryoET",
264
+ section: "Repositories",
265
+ },
266
+ ],
267
+ key: "data",
268
+ label: "Data",
269
+ sectionProps: {
270
+ Repositories: {
271
+ actions: [{ href: "/repositories", label: "Browse all" }],
272
+ },
273
+ },
274
+ },
275
+ {
276
+ itemType: "text",
277
+ key: "about",
278
+ label: "About",
279
+ onClick: () => console.log("About clicked"),
280
+ },
281
+ ];
282
+
283
+ function App() {
284
+ const [activePrimaryNavKey, setActivePrimaryNavKey] = useState("data");
285
+ const stageRef = useRef<HTMLDivElement>(null);
286
+ const theme = useTheme();
287
+
288
+ const containedTheme = useMemo(
289
+ () =>
290
+ createTheme(theme, {
291
+ components: {
292
+ MuiModal: {
293
+ defaultProps: {
294
+ container: () => stageRef.current,
295
+ disableAutoFocus: true,
296
+ disableEnforceFocus: true,
297
+ // The docs and the playground render overlays in place by
298
+ // default. This one needs its portal back, aimed at the stage.
299
+ disablePortal: false,
300
+ disableRestoreFocus: true,
301
+ },
302
+ },
303
+ },
304
+ }),
305
+ [theme]
306
+ );
307
+
308
+ return (
309
+ <div className="app">
310
+ <ThemeProvider theme={containedTheme}>
311
+ <Stage ref={stageRef}>
312
+ <NavigationHeader
313
+ activePrimaryNavKey={activePrimaryNavKey}
314
+ backgroundAppearance="dark"
315
+ primaryNavItems={primaryNavItems}
316
+ sdsStyle="drawer"
317
+ setActivePrimaryNavKey={setActivePrimaryNavKey}
318
+ showSearch={false}
319
+ title="Science Data"
320
+ />
321
+
322
+ <Hint>Hover “Data” to open the panel.</Hint>
323
+ </Stage>
324
+ </ThemeProvider>
325
+ </div>
326
+ );
327
+ }
328
+
329
+ export default App;
330
+ ```
331
+
332
+ ### Banner above the header
333
+
334
+ The header sits below whatever `topComponentSlot` holds and re-measures it when it changes, so dismissing this banner closes the gap.
335
+
336
+ **Example: NavigationHeaderTopSlot**
337
+
338
+ ```tsx
339
+ // Anything in topComponentSlot renders above the header. The header measures
340
+ // that slot and offsets its own sticky top by the slot's height, so dismissing
341
+ // the banner moves the header back up on its own.
342
+ //
343
+ // This one keeps the default sticky position: the offset is applied as a CSS
344
+ // top, which a relatively positioned header would read as a second gap below
345
+ // the slot.
346
+
347
+ import {
348
+ Banner,
349
+ NavigationHeader,
350
+ type NavigationHeaderPrimaryNavItem,
351
+ } from "@czi-sds/components";
352
+ import { useState } from "react";
353
+
354
+ const primaryNavItems: NavigationHeaderPrimaryNavItem<string>[] = [
355
+ {
356
+ itemType: "text",
357
+ key: "datasets",
358
+ label: "Datasets",
359
+ onClick: () => console.log("Datasets clicked"),
360
+ },
361
+ {
362
+ itemType: "text",
363
+ key: "about",
364
+ label: "About",
365
+ onClick: () => console.log("About clicked"),
366
+ },
367
+ ];
368
+
369
+ function App() {
370
+ const [bannerDismissed, setBannerDismissed] = useState(false);
371
+
372
+ return (
373
+ <div className="app">
374
+ <NavigationHeader
375
+ primaryNavItems={primaryNavItems}
376
+ showSearch={false}
377
+ title="Cell Atlas"
378
+ topComponentSlot={
379
+ <Banner
380
+ dismissed={bannerDismissed}
381
+ onClose={() => setBannerDismissed(true)}
382
+ sdsType="primary"
383
+ >
384
+ Scheduled maintenance this Saturday from 8am to noon PT.
385
+ </Banner>
386
+ }
387
+ />
388
+ </div>
389
+ );
390
+ }
391
+
392
+ export default App;
393
+ ```
394
+
395
+ ## Behavior notes
396
+
397
+ - Nav items are data, not children. Everything in the bar comes from `primaryNavItems`, `secondaryNavItems`, `buttons`, and the logo and title props; the header owns the markup.
398
+
399
+ - The header switches to its narrow layout on its own. It happens below 512px, and also whenever the bar's content is wider than the space it has, which a ResizeObserver watches for. A crowded header can therefore collapse well above 512px.
400
+
401
+ - There is no `hasInvertedStyle` prop. Use `backgroundAppearance`: `"dark"` puts the header on a dark surface and inverts its contents while the app is in light mode, and does nothing in dark mode, where the header is dark already.
402
+
403
+ - `position` is not a prop. The header computes it: drawer style is always sticky, and dropdown style follows `isSticky`, which is sticky by default and relative when `false`.
404
+
405
+ - `activePrimaryNavKey` works either way round. The header keeps its own copy of the active key, so the prop is optional; pass it and it wins, and `setActivePrimaryNavKey` is called alongside the internal update.
406
+
407
+ - The narrow drawer does not work that way. Passing `setDrawerOpen` replaces the internal state update rather than running beside it, so the hamburger will never open the drawer unless you also feed `drawerOpen` back in. Pass both or neither.
408
+
409
+ - `menuProps` replaces the default `{ disableScrollLock: true, disablePortal: true }` wholesale rather than merging into it. Note that dropdown menus force `disablePortal` on regardless of what you pass.
410
+
411
+ - The logo always renders inside a link element, because the link component defaults to an anchor whether or not `logoUrl` is set. Give it a URL so the anchor has a destination.
412
+
413
+ - Anything in `topComponentSlot` renders above the header, and the header offsets its sticky top by the slot's measured height, so a banner that is dismissed or resized takes the header with it. Keep the header sticky when you use the slot: the offset is applied as a CSS `top`, which a relatively positioned header reads as a second gap below the slot.
414
+
415
+ ## Dropdown style and drawer style
416
+
417
+ `sdsStyle` picks between two ways of opening a dropdown nav item, and it changes which parts of the item data are used.
418
+
419
+ | | `"dropdown"` (default) | `"drawer"` |
420
+ | ---------------------- | ----------------------------------- | ------------------------------------------------ |
421
+ | Opens | A menu, on click | A full-width panel, on hover |
422
+ | Item icons | Ignored | Shown, 24px with a details line and 16px without |
423
+ | Item details | Ignored | Shown as a caption under the label |
424
+ | `sectionProps` actions | Ignored | Shown under the section |
425
+ | Section headings | Shown, with dividers between groups | Shown, as panel columns |
426
+ | Position | Follows `isSticky` | Always sticky |
427
+
428
+ In the narrow layout both styles collapse to accordions inside the drawer, and the same split applies there: icons and section actions only appear when `sdsStyle` is `"drawer"`.
429
+
430
+ ## Props
431
+
432
+ Any custom SDS props and MUI props required for implementation are found on the table below. See the MUI documentation for additional optional props.
433
+
434
+ | Name | Type | Default | Description |
435
+ | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
436
+ | `activePrimaryNavKey` | `string` | - | The key of the active primary item. Optional, since the header tracks this itself; when given, it overrides the internal value. |
437
+ | `setActivePrimaryNavKey` | `(key: string) => void` | - | Called when a primary item becomes active. The header updates its internal key as well, so this is a notification rather than the only way the value changes. |
438
+ | `backgroundAppearance` | `"matchBackground"` \| `"dark"` | `"matchBackground"` | `"dark"` puts the header on a dark surface and inverts its contents. It only changes anything in light mode. |
439
+ | `buttons` | `Partial<ButtonProps>[]` \| `ReactNode[]` | - | Actions at the right end of the bar. Prop objects render as SDS Buttons; elements are cloned with the header's appearance applied. An icon-only button gets an `aria-label` from its child, and in the narrow layout every button goes full width and closes the drawer when clicked. |
440
+ | `sdsStyle` | `"dropdown"` \| `"drawer"` | `"dropdown"` | How dropdown nav items open, and which parts of their data are used. See the comparison above. |
441
+ | `drawerOpen` | `boolean` | - | Controls the narrow layout's drawer. Leave both this and `setDrawerOpen` out to let the hamburger manage it. |
442
+ | `setDrawerOpen` | `(open: boolean) => void` | - | Replaces the drawer's internal state update, so it has to be paired with `drawerOpen` or the drawer stops opening. |
443
+ | `isSticky` | `boolean` | `true` | Whether the header sticks to the top on scroll. Ignored when `sdsStyle` is `"drawer"`, which is always sticky, and best left alone alongside `topComponentSlot`. |
444
+ | `menuProps` | [`Partial<MenuProps>`](https://mui.com/material-ui/api/menu/) | `{ disableScrollLock: true, disablePortal: true }` | Props for the dropdown menus. Passing this replaces the default object rather than merging with it. |
445
+ | `topComponentSlot` | `ReactNode` | - | Content rendered above the header, such as a Banner. The header measures it and offsets its own sticky top to match. |
446
+ | `onDrawerStyleNavItemHover` | `function` | - | `(item: NavigationHeaderPrimaryNavItem<T> \| NavigationHeaderSecondaryNavItem) => void`. Called with the hovered primary or secondary item while `sdsStyle` is `"drawer"`. Useful for prefetching what the panel will show. |
447
+ | `logo` | `ReactNode` | - | The logo displayed in the header. Can be an image, icon, svg or any `ReactNode`. |
448
+ | `logoUrl` | `string` | - | URL for the logo link. If provided, clicking the logo navigates to this URL. |
449
+ | `logoLinkComponent` | `ElementType` | `"a"` | Specifies the component to use for the logo link. |
450
+ | `logoLinkProps` | [`LinkProps`](https://mui.com/material-ui/api/link/) | - | Props to pass to the logo link component. |
451
+ | `primaryNavItems` | `NavigationHeaderPrimaryNavItem<T>[]` | - | List of items for the primary navigation section. |
452
+ | `primaryNavPosition` | `"left" \|"right"` | `"left"` | Position of the `primaryNavItems` list. If set to `"left"`, the items appear to the left of the search bar. If set to `"right"`, they are positioned next to the `secondaryNavItems` on the right. |
453
+ | `showSearch` | `boolean` | `true` | Whether to display the search input in the header. |
454
+ | `searchProps` | `Partial<InputSearchProps>` | - | Props passed to the search input component. |
455
+ | `secondaryNavItems` | `NavigationHeaderSecondaryNavItem[]` | - | List of items for the secondary navigation section. |
456
+ | `scrollElevation` | `boolean` | `true` | Controls whether a shadow is shown under the Nav when scrolling. |
457
+ | `tag` | `string` | - | A small label displayed next to the title. |
458
+ | `tagColor` | `"info"` \| `"positive"` \| `"notice"` \| `"negative"` \| `"neutral"` \| `"beta"` \| `[string, string]` \| `[string, string, string]` | `"neutral"` | The color of the tag label. |
459
+ | `title` | `string` | - | The main title displayed in the header. |
460
+
461
+ NavigationHeader also extends MUI's [AppBar](https://mui.com/material-ui/api/app-bar/) minus its `position` prop, so the remaining AppBar and DOM props reach the underlying element.
462
+
463
+ ## Navigation Header Primary Nav Item and Navigation Header Secondary Nav Item
464
+
465
+ Primary and secondary items share the same shape. Both are a union keyed on `itemType`: a plain label, or a label that opens a menu.
466
+
467
+ | Name | Type | itemType | Description |
468
+ | ---------------------------- | ----------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
469
+ | `itemType` | `"text"` \| `"dropdown"` | both | Which variant this item is. An item without it is treated as text, but TypeScript requires it. |
470
+ | `key` | `string` | both | Identifies the item. It is what `activePrimaryNavKey` is compared against, so it has to be unique within the list. |
471
+ | `label` | `ReactNode` | both | What the item reads in the bar. |
472
+ | `onClick` | `(e: React.SyntheticEvent) => void` | both | Runs when the item is clicked. On a dropdown item this fires alongside opening the menu, not instead of it. |
473
+ | `tag`, `tagColor` | `string`, `SdsTagColorType` | `"text"` | A small Tag rendered after the label. |
474
+ | `items` | `DropdownItem[]` | `"dropdown"` | The contents of the menu. See the table below. |
475
+ | `sectionProps` | `Record<string, SectionProps>` | `"dropdown"` | Extra configuration per section name, applied only when `sdsStyle` is `"drawer"`. |
476
+ | `defaultUrl` | `string` | `"dropdown"` | Makes the item itself a link, for when the section has a landing page of its own. Pair it with `component`, `target`, and `rel` as needed. |
477
+ | `component`, `target`, `rel` | `ElementType`, `string`, `string` | `"dropdown"` | Link plumbing for `defaultUrl`. |
478
+
479
+ ## DropdownItem
480
+
481
+ | Name | Type | Default | Description |
482
+ | ----------- | ----------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
483
+ | `label` | `ReactNode` | - | The row's text. |
484
+ | `details` | `string` | - | A caption under the label, drawn only when `sdsStyle` is `"drawer"`. In dropdown style it lands on the element as an attribute and shows nothing. |
485
+ | `icon` | `keyof IconNameToSizes` \| `ReactElement` | - | An icon for the row, drawn only when `sdsStyle` is `"drawer"`. A named icon renders at 24px when the row has details and 16px when it does not, so the name has to offer that size. |
486
+ | `section` | `string` | - | Groups rows under a heading. Rows are grouped by this value in the order the sections first appear. |
487
+ | `onClick` | `(event: React.MouseEvent) => void` | - | Runs on click, then the menu closes. |
488
+ | `href` | `string` | - | Turns the row into a link to this URL. |
489
+ | `component` | `ElementType` | - | What the link renders as, for routing through something other than an anchor. |
490
+ | `target` | `string` | - | Where the link opens, for example `"_blank"`. |
491
+ | `rel` | `string` | - | The link's relationship to the target, for example `"noreferrer"`. |
492
+
493
+ ## SectionProps and ActionItem
494
+
495
+ Keyed by section name on a dropdown item's `sectionProps`, and used only in drawer style.
496
+
497
+ | Name | Type | Default | Description |
498
+ | --------- | -------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
499
+ | `actions` | `ActionItem[]` | - | Links rendered under the section, for example a "Browse all". Each takes `label` plus `href`, `onClick`, `component`, `target`, and `rel`. |
500
+ | `colSpan` | `number` | `1` | How many columns of the panel this section occupies. |