@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,482 @@
1
+ # InputDropdown
2
+
3
+ > **InputDropdown is the trigger, not the menu.** It draws the field a dropdown opens from and reports the selection back, and it opens nothing by itself. Most applications want Dropdown, which is this component already paired with a menu; reach for this one to anchor a DropdownMenu you are driving yourself. It is filed under Inputs, but it belongs to the family the Dropdowns overview describes.
4
+
5
+ ## Source Code
6
+
7
+ The component's source code in the SDS codebase can be found [here](https://github.com/chanzuckerberg/sci-components/blob/main/packages/components/src/core/InputDropdown/index.tsx).
8
+
9
+ ## Import
10
+
11
+ **React TypeScript**
12
+
13
+ ```tsx
14
+ import { InputDropdown } from "@czi-sds/components";
15
+ ```
16
+
17
+ ## Code examples
18
+
19
+ ### Default
20
+
21
+ This example has the minimum props needed for the InputDropdown component.
22
+
23
+ **Example: Default**
24
+
25
+ ```tsx
26
+ // Most minimal InputDropdown (just has the basic requirements)
27
+
28
+ import { InputDropdown } from "@czi-sds/components";
29
+
30
+ function App() {
31
+ return (
32
+ <div className="app">
33
+ <InputDropdown label="Label" onClick={() => {}} />
34
+ </div>
35
+ );
36
+ }
37
+
38
+ export default App;
39
+ ```
40
+
41
+ ### Controlling the width
42
+
43
+ Left alone, the input is as wide as the text inside it, which means a row of them comes out ragged and the width jumps around as the selection changes. `width` fixes that. A bare number is read as pixels, and any other value is used as the CSS width, so `"100%"` fills the container and `"20rem"` works as written.
44
+
45
+ **Example: ControllingTheWidth**
46
+
47
+ ```tsx
48
+ // The InputDropdown is as wide as its own content until `width` says otherwise.
49
+ // A bare number is read as pixels; anything else is used as the CSS width, so a
50
+ // percentage sizes the input against whatever contains it. The dashed box below
51
+ // is the container the percentages are measured against.
52
+
53
+ import { InputDropdown } from "@czi-sds/components";
54
+
55
+ function App() {
56
+ return (
57
+ <div className="app">
58
+ <div
59
+ style={{
60
+ // Without this the column would stretch every input to its full width,
61
+ // which is the one thing this example is trying to show a difference in.
62
+ alignItems: "flex-start",
63
+ border: "1px dashed #a9a9a9",
64
+ display: "flex",
65
+ flexDirection: "column",
66
+ gap: "16px",
67
+ padding: "16px",
68
+ width: "400px",
69
+ }}
70
+ >
71
+ <InputDropdown label="Auto" onClick={() => {}} />
72
+ <InputDropdown label="240px" onClick={() => {}} width="240" />
73
+ <InputDropdown label="50%" onClick={() => {}} width="50%" />
74
+ <InputDropdown label="100%" onClick={() => {}} width="100%" />
75
+ </div>
76
+ </div>
77
+ );
78
+ }
79
+
80
+ export default App;
81
+ ```
82
+
83
+ > **MUI Tip:** MUI's `fullWidth` prop works here too and does the same thing as `width="100%"`. Pass both and `width` is the one that counts. Either way the input keeps a minimum width of 90px, so a smaller value leaves it at 90px rather than shrinking it.
84
+
85
+ ### Anchoring a menu
86
+
87
+ A DropdownMenu is a popper: it is positioned against an element rather than rendered inside one, so it needs the input's DOM node as its `anchorEl`. InputDropdown forwards its `ref` to the button it renders, and a callback ref keeps that node in state so the menu re-renders once the anchor exists. Reach for this when the Dropdown component below is more than you need, or when the menu has to be driven from state you already own.
88
+
89
+ **Example: AnchoringAMenu**
90
+
91
+ ```tsx
92
+ // A DropdownMenu is positioned against an element rather than nested inside
93
+ // one, so it needs the input's DOM node. InputDropdown forwards its ref to the
94
+ // button it renders, and a callback ref stores that node in state, which is
95
+ // what makes the menu re-render once the anchor exists.
96
+
97
+ import {
98
+ DropdownMenu,
99
+ InputDropdown,
100
+ type DefaultAutocompleteOption,
101
+ } from "@czi-sds/components";
102
+ import { useState, type SyntheticEvent } from "react";
103
+
104
+ const OPTIONS: DefaultAutocompleteOption[] = [
105
+ { name: "Chromosome 1" },
106
+ { name: "Chromosome 2" },
107
+ { name: "Chromosome 3" },
108
+ ];
109
+
110
+ function App() {
111
+ const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
112
+ const [open, setOpen] = useState(false);
113
+ const [value, setValue] = useState<DefaultAutocompleteOption | null>(null);
114
+
115
+ return (
116
+ <div className="app">
117
+ <InputDropdown
118
+ label="Chromosome"
119
+ onClick={() => setOpen((wasOpen) => !wasOpen)}
120
+ ref={setAnchorEl}
121
+ sdsStyle="square"
122
+ sdsType="value"
123
+ state={open ? "open" : "default"}
124
+ value={value?.name}
125
+ />
126
+
127
+ <DropdownMenu<DefaultAutocompleteOption, false, false, false>
128
+ anchorEl={anchorEl}
129
+ onChange={(
130
+ _event: SyntheticEvent,
131
+ newValue: DefaultAutocompleteOption | null
132
+ ) => {
133
+ setValue(newValue);
134
+ setOpen(false);
135
+ }}
136
+ onClickAway={() => setOpen(false)}
137
+ open={open}
138
+ options={OPTIONS}
139
+ search={false}
140
+ value={value}
141
+ />
142
+ </div>
143
+ );
144
+ }
145
+
146
+ export default App;
147
+ ```
148
+
149
+ ### Square with multi-select
150
+
151
+ Below is an example demonstrating the combined utilization of the InputDropdown component and a multi-select Dropdown component. The Dropdown allows multiple selections, while the InputDropdown features a square variant.
152
+
153
+ **Example: SquareWithMultiSelect**
154
+
155
+ ```tsx
156
+ import { MouseEvent, SyntheticEvent, useState } from "react";
157
+ import {
158
+ InputDropdown,
159
+ DropdownMenu,
160
+ DefaultAutocompleteOption,
161
+ } from "@czi-sds/components";
162
+
163
+ const options = [
164
+ {
165
+ details: "Details",
166
+ name: "Menu Item 1",
167
+ },
168
+ {
169
+ details: "A very long Details for the second Menu Item",
170
+ name: "Menu Item 2",
171
+ },
172
+ {
173
+ name: "Menu Item 3",
174
+ },
175
+ ];
176
+
177
+ function App() {
178
+ const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
179
+ const [open, setOpen] = useState(false);
180
+ const [counter, setCounter] = useState<string>();
181
+ const [value, setValue] = useState<DefaultAutocompleteOption[]>([]);
182
+
183
+ return (
184
+ <div className="app">
185
+ <InputDropdown
186
+ label="Label"
187
+ onClick={handleClick}
188
+ sdsStyle="square"
189
+ multiple
190
+ counter={counter}
191
+ />
192
+ <DropdownMenu<DefaultAutocompleteOption, true, false, false>
193
+ open={open}
194
+ anchorEl={anchorEl}
195
+ onClose={() => {}}
196
+ onChange={handleChange}
197
+ search={false}
198
+ multiple
199
+ disableCloseOnSelect
200
+ options={options}
201
+ value={value}
202
+ onClickAway={handleClickAway}
203
+ />
204
+ </div>
205
+ );
206
+
207
+ function handleClick(event: MouseEvent<HTMLElement>) {
208
+ if (open) {
209
+ setOpen(false);
210
+
211
+ if (anchorEl) {
212
+ anchorEl.focus();
213
+ }
214
+
215
+ setAnchorEl(null);
216
+ } else {
217
+ setAnchorEl(event.currentTarget);
218
+ setOpen(true);
219
+ }
220
+ }
221
+
222
+ function handleChange(
223
+ _: SyntheticEvent<Element, Event>,
224
+ newValue: DefaultAutocompleteOption[]
225
+ ) {
226
+ setValue(newValue);
227
+ setCounter(newValue.length.toString());
228
+ }
229
+
230
+ function handleClickAway() {
231
+ if (open) {
232
+ setOpen(false);
233
+ }
234
+ }
235
+ }
236
+
237
+ export default App;
238
+ ```
239
+
240
+ ### Rounded with single-select
241
+
242
+ Below is an example demonstrating the combined utilization of the default label variant InputDropdown component and a single-select Dropdown component.
243
+
244
+ **Example: RoundedWithSingleSelect**
245
+
246
+ ```tsx
247
+ import { MouseEvent, SyntheticEvent, useState } from "react";
248
+ import {
249
+ InputDropdown,
250
+ DropdownMenu,
251
+ DefaultAutocompleteOption,
252
+ } from "@czi-sds/components";
253
+
254
+ const options = [
255
+ {
256
+ details: "Details",
257
+ name: "Menu Item 1",
258
+ },
259
+ {
260
+ details: "A very long Details for the second Menu Item",
261
+ name: "Menu Item 2",
262
+ },
263
+ {
264
+ name: "Menu Item 3",
265
+ },
266
+ ];
267
+
268
+ function App() {
269
+ const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
270
+ const [open, setOpen] = useState(false);
271
+ const [inputDropdownValue, setInputDropdownValue] = useState<string>();
272
+ const [value, setValue] = useState<DefaultAutocompleteOption | null>(null);
273
+
274
+ return (
275
+ <div className="app">
276
+ <InputDropdown
277
+ label="Label"
278
+ onClick={handleClick}
279
+ sdsStyle="rounded"
280
+ multiple={false}
281
+ value={inputDropdownValue}
282
+ />
283
+ <DropdownMenu<DefaultAutocompleteOption, false, false, false>
284
+ open={open}
285
+ anchorEl={anchorEl}
286
+ onClose={() => {}}
287
+ onChange={handleChange}
288
+ search={false}
289
+ multiple={false}
290
+ disableCloseOnSelect
291
+ options={options}
292
+ value={value}
293
+ onClickAway={handleClickAway}
294
+ />
295
+ </div>
296
+ );
297
+
298
+ function handleClick(event: MouseEvent<HTMLElement>) {
299
+ if (open) {
300
+ setOpen(false);
301
+
302
+ if (anchorEl) {
303
+ anchorEl.focus();
304
+ }
305
+
306
+ setAnchorEl(null);
307
+ } else {
308
+ setAnchorEl(event.currentTarget);
309
+ setOpen(true);
310
+ }
311
+ }
312
+
313
+ function handleChange(
314
+ _: SyntheticEvent<Element, Event>,
315
+ newValue: DefaultAutocompleteOption | null
316
+ ) {
317
+ setOpen(false);
318
+ setValue(newValue);
319
+ setInputDropdownValue(newValue?.name);
320
+ }
321
+
322
+ function handleClickAway() {
323
+ if (open) {
324
+ setOpen(false);
325
+ }
326
+ }
327
+ }
328
+
329
+ export default App;
330
+ ```
331
+
332
+ ### Minimal with single-select
333
+
334
+ An example of the combined use of the value variation InputDropdown component and a single-select Dropdown component is shown below.
335
+
336
+ > **Warning:** The value variant can not be used in conjunction with the multi-select Dropdowns. If you set `sdsType="value"` and `multiple="true"`, the component will default to showing a label and a counter instead.
337
+
338
+ **Example: MinimalWithSingleSelect**
339
+
340
+ ```tsx
341
+ import { MouseEvent, SyntheticEvent, useState } from "react";
342
+ import {
343
+ InputDropdown,
344
+ DropdownMenu,
345
+ DefaultAutocompleteOption,
346
+ } from "@czi-sds/components";
347
+
348
+ const options = [
349
+ {
350
+ details: "Details",
351
+ name: "Menu Item 1",
352
+ },
353
+ {
354
+ details: "A very long Details for the second Menu Item",
355
+ name: "Menu Item 2",
356
+ },
357
+ {
358
+ name: "Menu Item 3",
359
+ },
360
+ ];
361
+
362
+ function App() {
363
+ const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
364
+ const [open, setOpen] = useState(false);
365
+ const [details, setDetails] = useState<string>();
366
+ const [inputDropdownValue, setInputDropdownValue] = useState<string>();
367
+ const [value, setValue] = useState<DefaultAutocompleteOption | null>(null);
368
+
369
+ return (
370
+ <div className="app">
371
+ <InputDropdown
372
+ label="Label"
373
+ onClick={handleClick}
374
+ sdsType="value"
375
+ sdsStyle="minimal"
376
+ multiple={false}
377
+ details={details}
378
+ value={inputDropdownValue}
379
+ style={{ maxWidth: 250 }}
380
+ />
381
+ <DropdownMenu<DefaultAutocompleteOption, false, false, false>
382
+ open={open}
383
+ anchorEl={anchorEl}
384
+ onClose={() => {}}
385
+ onChange={handleChange}
386
+ search={false}
387
+ multiple={false}
388
+ disableCloseOnSelect
389
+ options={options}
390
+ value={value}
391
+ onClickAway={handleClickAway}
392
+ />
393
+ </div>
394
+ );
395
+
396
+ function handleClick(event: MouseEvent<HTMLElement>) {
397
+ if (open) {
398
+ setOpen(false);
399
+
400
+ if (anchorEl) {
401
+ anchorEl.focus();
402
+ }
403
+
404
+ setAnchorEl(null);
405
+ } else {
406
+ setAnchorEl(event.currentTarget);
407
+ setOpen(true);
408
+ }
409
+ }
410
+
411
+ function handleChange(
412
+ _: SyntheticEvent<Element, Event>,
413
+ newValue: DefaultAutocompleteOption | null
414
+ ) {
415
+ setOpen(false);
416
+ setValue(newValue);
417
+
418
+ if (newValue) {
419
+ setInputDropdownValue(newValue.name);
420
+
421
+ if (newValue?.details) setDetails(newValue?.details);
422
+ else setDetails(undefined);
423
+ } else {
424
+ setDetails(undefined);
425
+ setInputDropdownValue(undefined);
426
+ }
427
+ }
428
+
429
+ function handleClickAway() {
430
+ if (open) {
431
+ setOpen(false);
432
+ }
433
+ }
434
+ }
435
+
436
+ export default App;
437
+ ```
438
+
439
+ ## SDS vs MUI
440
+
441
+ The SDS's InputDropdown component utilizes MUI's Button component as its foundation but introduces some SDS-specific enhancements. Below, the key distinctions between the SDS's InputDropdown and MUI's Button are outlined:
442
+
443
+ - **Variation**: MUI's Button offers a `variant` prop to define different visual styles for buttons. SDS's InputDropdown, however, uses the `sdsStyle` prop instead, providing the ability to select between three variants: `"square"`, `"rounded"`, or `"minimal"`.
444
+
445
+ - **Color**: In MUI's Button, the button's color can be modified using the `color` prop. SDS's InputDropdown deviates from this and introduces the `intent` prop. This prop provides the ability to choose between default, warning, and error colors, depending on the state of the InputDropdown.
446
+
447
+ - **Size**: While MUI's Button provides a `size` prop for adjusting the button's size, SDS's InputDropdown does not offer this capability. The size of the InputDropdown component remains fixed and cannot be altered through props.
448
+
449
+ - **Icon**: Unlike MUI's Button, which supports custom icons, SDS's InputDropdown does not accept external icon components. Instead, SDS's InputDropdown incorporates a built-in Chevron icon, which is an integral part of the component and cannot be replaced.
450
+
451
+ - **Ref**: Like MUI's Button, InputDropdown forwards a `ref` to the button it renders. That is how it becomes the `anchorEl` a DropdownMenu is positioned against, as in "Anchoring a menu" above.
452
+
453
+ ## MUI Documentation
454
+
455
+ Documentation for the underlying MUI component can be found [here](https://mui.com/material-ui/react-button/).
456
+
457
+ ## Props
458
+
459
+ Any custom SDS props and MUI props required for implementation are found on the table below. See the MUI documentation for additional optional props.
460
+
461
+ | Name | Type | Default | Description |
462
+ | ------------------------------ | --------------------------------------------------------- | ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
463
+ | `classes` | `object` | - | A class name for each part of the input, for styling one of them without reaching through the DOM: `root`, `label`, `labelDetailsWrapper`, `contentWrapper`, `details`, `counter`, `iconWrapper`, `chevronIcon` and `minimalDetails`. |
464
+ | `className` | `string` | - | Added to the input's root element, alongside anything `classes.root` puts there. |
465
+ | `counter` | `ReactNode` | - | If `multiple` set to `true`, this number shows the number of selected menu items. |
466
+ | `details` | `ReactNode` | - | A text showing details for the selected menu item. |
467
+ | `disabled` | `boolean` | `false` | If `true`, the component is disabled. |
468
+ | `intent` | `"default"` \| `"negative"` \| `"notice"` \| `"positive"` | `"default"` | The color of the component. |
469
+ | `label` | `ReactNode` | - | The label of the Input Button. |
470
+ | `multiple` | `boolean` | `false` | Allows users to select multiple menu items.`multiple=true` cannot be used with the minimum variant. |
471
+ | `onClick` | `function` | `(event: React.MouseEvent<HTMLElement>) => void` | Sets what happens when a user clicks on the component. |
472
+ | `sdsStyle` | `"minimal"` \| `"square"` \| `"rounded"` | `"square"` | The visual appearance of the component. |
473
+ | `sdsType` | `"label"` \| `"value"` | `"label"` | The label variant includes the label within the input field and showcases the selected menu item as additional details or sets the counter when in multi-select mode. The value variant replaces the label with the selected value directly within the input field. The detailed information is then displayed in a separate section dedicated to displaying additional details. However, it's important to note that the value variant cannot be used in conjunction with multi-select mode. |
474
+ | `shouldPutAColonAfterLabel` | `boolean` | `true` | If `true`, a colon (:) will be added after the label or value. |
475
+ | `shouldTruncateMinimalDetails` | `boolean` | `false` | If `true`, the details section of the minimal variant displays a truncated one-liner with an ellipsis (...), if `false` the details section expands to multiple lines for a comprehensive display. |
476
+ | `startIcon` | `ReactNode` | - | An element placed before the label, passed straight through to the underlying MUI Button. |
477
+ | `state` | `"default"` \| `"open"` | `"default"` | Draws the input in its open state. The input has no idea whether its menu is showing, so set this from whatever holds that state. |
478
+ | `style` | `CSSProperties` | - | Inline styles for the input's root element. |
479
+ | `value` | `ReactNode` | - | The value that will be displayed in the component for the value variant. |
480
+ | `width` | `string` | `"auto"` | How wide the input is. A bare number is read as pixels, so `"240"` means 240px, and any other value is used as the CSS width, such as `"100%"` or `"20rem"`. Values below 90px are ignored, since the input keeps that as its minimum. Left unset, the input is as wide as its content, or as wide as its container if MUI's `fullWidth` is set. |
481
+
482
+ There are more props that can be used with the InputDropdown component, via those available to [MUI's Button component](https://mui.com/material-ui/api/autocomplete/#props).
@@ -0,0 +1,173 @@
1
+ # InputRadio
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/blob/main/packages/components/src/core/InputRadio/index.tsx).
6
+
7
+ ## Import
8
+
9
+ **React TypeScript**
10
+
11
+ ```tsx
12
+ import { InputRadio } from "@czi-sds/components";
13
+ ```
14
+
15
+ ## Code examples
16
+
17
+ ### **Default InputRadio**
18
+
19
+ This example has the minimum props needed for the InputRadio component.
20
+
21
+ **Example: DefaultInputRadio**
22
+
23
+ ```tsx
24
+ import { InputRadio } from "@czi-sds/components";
25
+
26
+ function App() {
27
+ return (
28
+ <div className="app">
29
+ <InputRadio label="Label" value="label" />
30
+ </div>
31
+ );
32
+ }
33
+
34
+ export default App;
35
+ ```
36
+
37
+ ### InputRadio + Caption
38
+
39
+ This example shows the InputRadio with an additional caption beneath the label, presented in a lighter text color.
40
+
41
+ **Example: InputRadioCaption**
42
+
43
+ ```tsx
44
+ import { InputRadio } from "@czi-sds/components";
45
+
46
+ function App() {
47
+ return (
48
+ <div className="app">
49
+ <InputRadio caption="Caption" label="Label" value="label" />
50
+ </div>
51
+ );
52
+ }
53
+
54
+ export default App;
55
+ ```
56
+
57
+ ### InputRadio group
58
+
59
+ Radios are meant to be used as a set. Wrap them in MUI's RadioGroup, which selects the radio whose value matches the group's and handles arrow-key navigation. Add `row` to lay the options out horizontally.
60
+
61
+ **Example: InputRadioGroup**
62
+
63
+ ```tsx
64
+ // MUI's RadioGroup owns the selection: each InputRadio is checked when its
65
+ // `value` matches the group's. `row` lays the options out horizontally.
66
+ import { useState } from "react";
67
+ import { InputRadio } from "@czi-sds/components";
68
+ import { RadioGroup } from "@mui/material";
69
+
70
+ const OPTIONS = ["Option 1", "Option 2", "Option 3"];
71
+
72
+ function App() {
73
+ const [value, setValue] = useState(OPTIONS[0]);
74
+
75
+ return (
76
+ <div
77
+ className="app"
78
+ style={{ display: "flex", flexDirection: "column", gap: "24px" }}
79
+ >
80
+ <RadioGroup
81
+ name="vertical-options"
82
+ value={value}
83
+ onChange={(event) => setValue(event.target.value)}
84
+ >
85
+ {OPTIONS.map((option) => (
86
+ <InputRadio key={option} label={option} value={option} />
87
+ ))}
88
+ </RadioGroup>
89
+
90
+ {/* SDS removes the side margin MUI puts on labels, so a row needs its
91
+ own gap. */}
92
+ <RadioGroup
93
+ row
94
+ name="row-options"
95
+ value={value}
96
+ onChange={(event) => setValue(event.target.value)}
97
+ sx={{ gap: "24px" }}
98
+ >
99
+ {OPTIONS.map((option) => (
100
+ <InputRadio key={option} label={option} value={option} />
101
+ ))}
102
+ </RadioGroup>
103
+ </div>
104
+ );
105
+ }
106
+
107
+ export default App;
108
+ ```
109
+
110
+ ### InputRadio intents
111
+
112
+ Intent colors the border of the empty circle. Select any of these and the dot turns the same accent color.
113
+
114
+ **Example: InputRadioIntents**
115
+
116
+ ```tsx
117
+ // `intent` colors the empty circle only; a selected radio always uses the
118
+ // accent color.
119
+ import { InputRadio } from "@czi-sds/components";
120
+
121
+ function App() {
122
+ return (
123
+ <div className="app" style={{ display: "flex", gap: "24px" }}>
124
+ <InputRadio label="Default" value="default" intent="default" />
125
+ <InputRadio label="Positive" value="positive" intent="positive" />
126
+ <InputRadio label="Notice" value="notice" intent="notice" />
127
+ <InputRadio label="Negative" value="negative" intent="negative" />
128
+ <InputRadio label="Disabled" value="disabled" disabled />
129
+ </div>
130
+ );
131
+ }
132
+
133
+ export default App;
134
+ ```
135
+
136
+ ## SDS vs MUI
137
+
138
+ The following props and options differ in whether and how they function across MUI versus SDS's InputRadio component:
139
+
140
+ - `size`: Has no effect in SDS
141
+
142
+ - `color`: Has no effect in SDS
143
+
144
+ - `labelPlacement`: Has no effect in SDS
145
+
146
+ - `intent`: This is an SDS-specific prop that colors the border of the empty circle (`"default"`, `"positive"`, `"notice"`, or `"negative"`). It does not change the selected radio, which always uses the accent color.
147
+
148
+ - `caption`: This is an SDS-specific prop, which takes text that is displayed below the primary label text.
149
+
150
+ - `stage`: This SDS prop sets the radio as `"checked"` or `"unchecked"` and overrides `checked`. Inside a RadioGroup, leave it out and let the group drive the selection from each radio's `value`.
151
+
152
+ - `value`: Required in practice: a RadioGroup matches it against its own value to decide which radio is selected, and SDS also derives the label and caption element ids from it for screen readers.
153
+
154
+ - `row`: This boolean prop functions the same for both MUI and SDS's InputRadio component: its presence reformats the radio buttons (and their labels) within the RadioGroup parent component into a horizontal row.
155
+
156
+ ## MUI Documentation
157
+
158
+ Documentation for the underlying MUI component can be found [here](https://mui.com/material-ui/react-radio-button/).
159
+
160
+ ## Props
161
+
162
+ Any custom SDS props and MUI props required for implementation are found on the table below. See the MUI documentation for additional optional props.
163
+
164
+ | Name | Type | Default | Description |
165
+ | ------------ | --------------------------------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
166
+ | `caption` | `ReactNode` | - | The caption of the InputRadio appears beneath the label in a lighter text color. |
167
+ | `label` | `ReactNode` | - | The label of the InputRadio. |
168
+ | `value` | `string` | - | The value a RadioGroup compares against to decide whether this radio is selected. It also backs the label and caption element ids, so give every radio a unique one. |
169
+ | `radioProps` | `Partial<MUIRadioProps>` | `{}` | Directly pass these props to the underlying MUI radio. |
170
+ | `stage` | `"checked" \| "unchecked"` | - | Sets the radio as `"checked"` or `"unchecked"`, overriding `checked`. Omit it inside a RadioGroup, which drives the selection itself. |
171
+ | `intent` | `"default"` \| `"notice"` \| `"negative"` \| `"positive"` | `"default"` | Colors the border of the empty circle. The selected radio always uses the accent color. |
172
+ | `disabled` | `boolean` | `false` | If `true`, the component is disabled. |
173
+ | `classes` | `object` | `{}` | Class names for the internal elements: `root`, `labelCaptionContainer`, `label`, `caption`, `radioButton`, `radioCheckedIcon`, `radioCheckedIconDot`, and `radioDefaultIcon`. |