@khanacademy/wonder-blocks-dropdown 2.7.3 → 2.7.6

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 (29) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/es/index.js +92 -162
  3. package/dist/index.js +285 -374
  4. package/package.json +6 -6
  5. package/src/components/__docs__/action-menu.argtypes.js +44 -0
  6. package/src/components/__docs__/action-menu.stories.js +435 -0
  7. package/src/components/__docs__/base-select.argtypes.js +54 -0
  8. package/src/components/__docs__/multi-select.stories.js +509 -0
  9. package/src/components/__docs__/single-select.accessibility.stories.mdx +59 -0
  10. package/src/components/__docs__/single-select.argtypes.js +54 -0
  11. package/src/components/__docs__/single-select.stories.js +464 -0
  12. package/src/components/__tests__/dropdown-core-virtualized.test.js +0 -15
  13. package/src/components/__tests__/dropdown-core.test.js +114 -208
  14. package/src/components/__tests__/multi-select.test.js +1 -3
  15. package/src/components/__tests__/single-select.test.js +15 -47
  16. package/src/components/action-menu.js +11 -0
  17. package/src/components/dropdown-core-virtualized.js +0 -5
  18. package/src/components/dropdown-core.js +140 -126
  19. package/src/components/multi-select.js +17 -33
  20. package/src/components/single-select.js +15 -30
  21. package/src/util/__tests__/dropdown-menu-styles.test.js +0 -26
  22. package/src/util/constants.js +0 -11
  23. package/src/util/dropdown-menu-styles.js +0 -5
  24. package/src/util/types.js +2 -5
  25. package/src/components/__tests__/search-text-input.test.js +0 -212
  26. package/src/components/action-menu.stories.js +0 -48
  27. package/src/components/multi-select.stories.js +0 -124
  28. package/src/components/search-text-input.js +0 -115
  29. package/src/components/single-select.stories.js +0 -247
@@ -8,7 +8,6 @@ import type {AriaProps, StyleType} from "@khanacademy/wonder-blocks-core";
8
8
  import ActionItem from "./action-item.js";
9
9
  import DropdownCore from "./dropdown-core.js";
10
10
  import DropdownOpener from "./dropdown-opener.js";
11
- import SearchTextInput from "./search-text-input.js";
12
11
  import SelectOpener from "./select-opener.js";
13
12
  import SeparatorItem from "./separator-item.js";
14
13
  import {
@@ -211,6 +210,17 @@ type State = {|
211
210
  *
212
211
  * The multi select stays open until closed by the user. The onChange callback
213
212
  * happens every time there is a change in the selection of the items.
213
+ *
214
+ * ## Usage
215
+ *
216
+ * ```jsx
217
+ * import {OptionItem, MultiSelect} from "@khanacademy/wonder-blocks-dropdown";
218
+ *
219
+ * <MultiSelect onChange={setSelectedValues} selectedValues={selectedValues}>
220
+ * <OptionItem value="pear">Pear</OptionItem>
221
+ * <OptionItem value="mango">Mango</OptionItem>
222
+ * </MultiSelect>
223
+ * ```
214
224
  */
215
225
  export default class MultiSelect extends React.Component<Props, State> {
216
226
  labels: Labels;
@@ -329,32 +339,6 @@ export default class MultiSelect extends React.Component<Props, State> {
329
339
  }
330
340
  }
331
341
 
332
- getSearchField(): Array<DropdownItem> {
333
- if (!this.props.isFilterable) {
334
- return [];
335
- }
336
-
337
- const {clearSearch, filter} = this.state.labels;
338
-
339
- return [
340
- {
341
- component: (
342
- <SearchTextInput
343
- key="search-text-input"
344
- onChange={this.handleSearchTextChanged}
345
- searchText={this.state.searchText}
346
- labels={{
347
- clearSearch,
348
- filter,
349
- }}
350
- />
351
- ),
352
- focusable: true,
353
- populatedProps: {},
354
- },
355
- ];
356
- }
357
-
358
342
  getShortcuts(numOptions: number): Array<DropdownItem> {
359
343
  const {selectedValues, shortcuts} = this.props;
360
344
  const {selectAllLabel, selectNoneLabel} = this.state.labels;
@@ -556,7 +540,8 @@ export default class MultiSelect extends React.Component<Props, State> {
556
540
  isFilterable,
557
541
  } = this.props;
558
542
  const {open, searchText} = this.state;
559
- const {noResults, someSelected} = this.state.labels;
543
+ const {clearSearch, filter, noResults, someSelected} =
544
+ this.state.labels;
560
545
 
561
546
  const allChildren = React.Children.toArray(children).filter(Boolean);
562
547
  const numOptions = allChildren.length;
@@ -572,11 +557,8 @@ export default class MultiSelect extends React.Component<Props, State> {
572
557
  selectDropdownStyle,
573
558
  dropdownStyle,
574
559
  ]}
575
- items={[
576
- ...this.getSearchField(),
577
- ...this.getShortcuts(numOptions),
578
- ...filteredItems,
579
- ]}
560
+ isFilterable={isFilterable}
561
+ items={[...this.getShortcuts(numOptions), ...filteredItems]}
580
562
  light={light}
581
563
  onOpenChanged={this.handleOpenChanged}
582
564
  open={open}
@@ -589,6 +571,8 @@ export default class MultiSelect extends React.Component<Props, State> {
589
571
  }
590
572
  searchText={isFilterable ? searchText : ""}
591
573
  labels={{
574
+ clearSearch,
575
+ filter,
592
576
  noResults,
593
577
  someSelected,
594
578
  }}
@@ -9,14 +9,12 @@ import DropdownCore from "./dropdown-core.js";
9
9
  import DropdownOpener from "./dropdown-opener.js";
10
10
  import SelectOpener from "./select-opener.js";
11
11
  import {
12
- defaultLabels,
13
12
  selectDropdownStyle,
14
13
  filterableDropdownStyle,
15
14
  } from "../util/constants.js";
16
15
 
17
16
  import typeof OptionItem from "./option-item.js";
18
17
  import type {DropdownItem, OpenerProps} from "../util/types.js";
19
- import SearchTextInput from "./search-text-input.js";
20
18
 
21
19
  type Props = {|
22
20
  ...AriaProps,
@@ -144,11 +142,23 @@ type DefaultProps = {|
144
142
  * The single select dropdown closes after the selection of an item. If the same
145
143
  * item is selected, there is no callback.
146
144
  *
147
- * *NOTE:* The component automatically uses
145
+ * **NOTE:** If there are more than 125 items, the component automatically uses
148
146
  * [react-window](https://github.com/bvaughn/react-window) to improve
149
147
  * performance when rendering these elements and is capable of handling many
150
148
  * hundreds of items without performance problems.
151
149
  *
150
+ * ## Usage
151
+ *
152
+ * ```jsx
153
+ * import {OptionItem, SingleSelect} from "@khanacademy/wonder-blocks-dropdown";
154
+ *
155
+ * const [selectedValue, setSelectedValue] = useState("");
156
+ *
157
+ * <SingleSelect placeholder="Choose a fruit" onChange={setSelectedValue} selectedValue={selectedValue}>
158
+ * <OptionItem value="pear">Pear</OptionItem>
159
+ * <OptionItem value="mango">Mango</OptionItem>
160
+ * </SingleSelect>
161
+ * ```
152
162
  */
153
163
  export default class SingleSelect extends React.Component<Props, State> {
154
164
  selectedIndex: number;
@@ -275,28 +285,6 @@ export default class SingleSelect extends React.Component<Props, State> {
275
285
  );
276
286
  }
277
287
 
278
- getSearchField(): ?DropdownItem {
279
- if (!this.props.isFilterable) {
280
- return null;
281
- }
282
-
283
- return {
284
- component: (
285
- <SearchTextInput
286
- key="search-text-input"
287
- onChange={this.handleSearchTextChanged}
288
- searchText={this.state.searchText}
289
- labels={{
290
- clearSearch: defaultLabels.clearSearch,
291
- filter: defaultLabels.filter,
292
- }}
293
- />
294
- ),
295
- focusable: true,
296
- populatedProps: {},
297
- };
298
- }
299
-
300
288
  handleSearchTextChanged: (searchText: string) => void = (searchText) => {
301
289
  this.setState({searchText});
302
290
  };
@@ -385,12 +373,8 @@ export default class SingleSelect extends React.Component<Props, State> {
385
373
  } = this.props;
386
374
  const {searchText} = this.state;
387
375
  const allChildren = React.Children.toArray(children).filter(Boolean);
388
- const filteredItems = this.getMenuItems(allChildren);
376
+ const items = this.getMenuItems(allChildren);
389
377
  const opener = this.renderOpener(allChildren.length);
390
- const searchField = this.getSearchField();
391
- const items = searchField
392
- ? [searchField, ...filteredItems]
393
- : filteredItems;
394
378
 
395
379
  return (
396
380
  <DropdownCore
@@ -410,6 +394,7 @@ export default class SingleSelect extends React.Component<Props, State> {
410
394
  openerElement={this.state.openerElement}
411
395
  style={style}
412
396
  className={className}
397
+ isFilterable={isFilterable}
413
398
  onSearchTextChanged={
414
399
  isFilterable ? this.handleSearchTextChanged : null
415
400
  }
@@ -1,7 +1,6 @@
1
1
  // @flow
2
2
  import * as React from "react";
3
3
  import OptionItem from "../../components/option-item.js";
4
- import SearchTextInput from "../../components/search-text-input.js";
5
4
  import SeparatorItem from "../../components/separator-item.js";
6
5
 
7
6
  import {getDropdownMenuHeight} from "../dropdown-menu-styles.js";
@@ -30,19 +29,6 @@ const optionItems = [
30
29
  },
31
30
  ];
32
31
 
33
- const searchFieldItem = {
34
- component: (
35
- <SearchTextInput
36
- testId="item-0"
37
- key="search-text-input"
38
- onChange={jest.fn()}
39
- searchText={""}
40
- />
41
- ),
42
- focusable: true,
43
- populatedProps: {},
44
- };
45
-
46
32
  const separatorItem = {
47
33
  component: <SeparatorItem />,
48
34
  focusable: false,
@@ -74,18 +60,6 @@ describe("getDropdownMenuHeight", () => {
74
60
  expect(height).toBe(130);
75
61
  });
76
62
 
77
- it("should get a valid height for a filterable dropdown", () => {
78
- // Arrange
79
- const items = [searchFieldItem, ...optionItems];
80
-
81
- // Act
82
- const height = getDropdownMenuHeight(items);
83
-
84
- // Assert
85
- // search field + 3 option items
86
- expect(height).toBe(172);
87
- });
88
-
89
63
  it("should get a valid height for a dropdown with a SeparatorItem", () => {
90
64
  // Arrange
91
65
  const items = [separatorItem, ...optionItems];
@@ -21,14 +21,6 @@ export const filterableDropdownStyle = {
21
21
  minHeight: 100,
22
22
  };
23
23
 
24
- export const searchInputStyle = {
25
- margin: Spacing.xSmall_8,
26
- marginTop: Spacing.xxxSmall_4,
27
- // Set `minHeight` to "auto" to stop the search field from having
28
- // a height of 0 and being cut off.
29
- minHeight: "auto",
30
- };
31
-
32
24
  // The default item height
33
25
  export const DROPDOWN_ITEM_HEIGHT = 40;
34
26
 
@@ -41,9 +33,6 @@ export const MAX_VISIBLE_ITEMS = 9;
41
33
 
42
34
  export const SEPARATOR_ITEM_HEIGHT = 9;
43
35
 
44
- export const SEARCH_ITEM_HEIGHT: number =
45
- DROPDOWN_ITEM_HEIGHT + searchInputStyle.margin + searchInputStyle.marginTop;
46
-
47
36
  // The default labels that will be used by different components
48
37
  export const defaultLabels = {
49
38
  clearSearch: "Clear search",
@@ -6,12 +6,10 @@ import type {StyleType} from "@khanacademy/wonder-blocks-core";
6
6
  import {
7
7
  DROPDOWN_ITEM_HEIGHT,
8
8
  MAX_VISIBLE_ITEMS,
9
- SEARCH_ITEM_HEIGHT,
10
9
  SEPARATOR_ITEM_HEIGHT,
11
10
  } from "./constants.js";
12
11
 
13
12
  import SeparatorItem from "../components/separator-item.js";
14
- import SearchTextInput from "../components/search-text-input.js";
15
13
 
16
14
  import type {DropdownItem} from "./types.js";
17
15
 
@@ -33,9 +31,6 @@ export function getDropdownMenuHeight(
33
31
  return items.slice(0, MAX_VISIBLE_ITEMS).reduce((sum, item) => {
34
32
  if (SeparatorItem.isClassOf(item.component)) {
35
33
  return sum + SEPARATOR_ITEM_HEIGHT;
36
- } else if (SearchTextInput.isClassOf(item.component)) {
37
- // search text input height
38
- return sum + SEARCH_ITEM_HEIGHT;
39
34
  } else {
40
35
  return sum + DROPDOWN_ITEM_HEIGHT;
41
36
  }
package/src/util/types.js CHANGED
@@ -5,18 +5,15 @@ import type {ClickableState} from "@khanacademy/wonder-blocks-clickable";
5
5
 
6
6
  import typeof ActionItem from "../components/action-item.js";
7
7
  import typeof OptionItem from "../components/option-item.js";
8
- import typeof SearchTextInput from "../components/search-text-input.js";
9
8
  import typeof SeparatorItem from "../components/separator-item.js";
10
9
 
11
10
  //TODO: rename into something more descriptive
12
11
  export type Item =
13
12
  | false
14
- | React.Element<ActionItem | OptionItem | SeparatorItem | SearchTextInput>;
13
+ | React.Element<ActionItem | OptionItem | SeparatorItem>;
15
14
 
16
15
  export type DropdownItem = {|
17
- component: React.Element<
18
- ActionItem | OptionItem | SeparatorItem | SearchTextInput,
19
- >,
16
+ component: React.Element<ActionItem | OptionItem | SeparatorItem>,
20
17
  focusable: boolean,
21
18
  populatedProps: any,
22
19
  // extra props used by DropdownCore
@@ -1,212 +0,0 @@
1
- // @flow
2
- import * as React from "react";
3
- import {render, screen} from "@testing-library/react";
4
- import userEvent from "@testing-library/user-event";
5
-
6
- import SearchTextInput from "../search-text-input.js";
7
-
8
- describe("SearchTextInput", () => {
9
- test("text input container should be focused when focusing on the input", () => {
10
- // Arrange
11
- render(
12
- <SearchTextInput
13
- searchText=""
14
- testId="search-text-input"
15
- onChange={jest.fn()}
16
- />,
17
- );
18
-
19
- const input = screen.getByTestId("search-text-input");
20
-
21
- // Act
22
- input.focus();
23
-
24
- // Assert
25
- expect(input).toHaveFocus();
26
- });
27
-
28
- test("text input should not be focused when losing focus", () => {
29
- // Arrange
30
- render(
31
- <SearchTextInput
32
- searchText=""
33
- testId="search-text-input"
34
- onChange={jest.fn()}
35
- />,
36
- );
37
-
38
- const input = screen.getByTestId("search-text-input");
39
- // focus in
40
- input.focus();
41
-
42
- // Act
43
- // focus out
44
- input.blur();
45
-
46
- // Assert
47
- expect(input).not.toHaveFocus();
48
- });
49
-
50
- test("onChange should be invoked if text input changes", () => {
51
- // Arrange
52
- const onChangeMock = jest.fn();
53
-
54
- render(
55
- <SearchTextInput
56
- searchText=""
57
- testId="search-text-input"
58
- onChange={onChangeMock}
59
- />,
60
- );
61
-
62
- const input = screen.getByTestId("search-text-input");
63
-
64
- // Act
65
- userEvent.paste(input, "value");
66
-
67
- // Assert
68
- expect(onChangeMock).toHaveBeenCalledWith("value");
69
- });
70
-
71
- test("displays the dismiss button when search text exists", () => {
72
- // Arrange
73
- const SearchFieldWrapper = () => {
74
- const [value, setValue] = React.useState("");
75
- return (
76
- <SearchTextInput
77
- searchText={value}
78
- testId="search-text-input"
79
- onChange={setValue}
80
- />
81
- );
82
- };
83
-
84
- render(<SearchFieldWrapper />);
85
-
86
- const input = screen.getByTestId("search-text-input");
87
-
88
- // Act
89
- userEvent.paste(input, "value");
90
-
91
- // Assert
92
- const clearIconButton = screen.queryByRole("button");
93
- expect(clearIconButton).toBeInTheDocument();
94
- });
95
-
96
- test("search should be cleared if the clear icon is clicked", () => {
97
- // Arrange
98
- const SearchFieldWrapper = () => {
99
- const [value, setValue] = React.useState("initial value");
100
- return (
101
- <SearchTextInput
102
- searchText={value}
103
- testId="search-text-input"
104
- onChange={setValue}
105
- />
106
- );
107
- };
108
-
109
- render(<SearchFieldWrapper />);
110
-
111
- const input = screen.getByTestId("search-text-input");
112
- const clearIconButton = screen.queryByRole("button");
113
-
114
- // Act
115
- userEvent.click(clearIconButton);
116
-
117
- // Assert
118
- expect(input).toHaveValue("");
119
- });
120
-
121
- test("focus should return to the input element after clear button is clicked", () => {
122
- // Arrange
123
- const SearchFieldWrapper = () => {
124
- const [value, setValue] = React.useState("");
125
- return (
126
- <SearchTextInput
127
- searchText={value}
128
- testId="search-text-input"
129
- onChange={setValue}
130
- />
131
- );
132
- };
133
-
134
- render(<SearchFieldWrapper />);
135
-
136
- const input = screen.getByTestId("search-text-input");
137
- userEvent.paste(input, "something");
138
-
139
- // Act
140
- const clearIconButton = screen.queryByRole("button");
141
- userEvent.click(clearIconButton);
142
-
143
- // Assert
144
- expect(input).toHaveFocus();
145
- });
146
-
147
- test("placeholder should be updated by the parent component", () => {
148
- // Arrange
149
- const {rerender} = render(
150
- <SearchTextInput
151
- searchText="query"
152
- onChange={() => {}}
153
- labels={{
154
- clearSearch: "Clear",
155
- filter: "Filter",
156
- }}
157
- testId="search-text-input"
158
- />,
159
- );
160
-
161
- const input = screen.getByTestId("search-text-input");
162
-
163
- // Act
164
- rerender(
165
- <SearchTextInput
166
- searchText="query"
167
- onChange={() => {}}
168
- labels={{
169
- clearSearch: "Dismiss",
170
- filter: "Search",
171
- }}
172
- testId="search-text-input"
173
- />,
174
- );
175
-
176
- // Assert
177
- expect(input).toHaveAttribute("placeholder", "Search");
178
- });
179
-
180
- test("button label should be updated by the parent component", () => {
181
- // Arrange
182
- const {rerender} = render(
183
- <SearchTextInput
184
- searchText="query"
185
- onChange={() => {}}
186
- labels={{
187
- clearSearch: "Clear",
188
- filter: "Filter",
189
- }}
190
- testId="search-text-input"
191
- />,
192
- );
193
-
194
- const clearIconButton = screen.queryByRole("button");
195
-
196
- // Act
197
- rerender(
198
- <SearchTextInput
199
- searchText="query"
200
- onChange={() => {}}
201
- labels={{
202
- clearSearch: "Dismiss",
203
- filter: "Search",
204
- }}
205
- testId="search-text-input"
206
- />,
207
- );
208
-
209
- // Assert
210
- expect(clearIconButton).toHaveAttribute("aria-label", "Dismiss");
211
- });
212
- });
@@ -1,48 +0,0 @@
1
- // @flow
2
- import * as React from "react";
3
-
4
- import type {StoryComponentType} from "@storybook/react";
5
- import ActionMenu from "./action-menu.js";
6
- import ActionItem from "./action-item.js";
7
-
8
- export default {
9
- title: "Dropdown / ActionMenu",
10
- component: ActionMenu,
11
- };
12
-
13
- export const ActionMenuWithLang: StoryComponentType = () => (
14
- <ActionMenu menuText="Locales">
15
- {locales.map((locale) => (
16
- <ActionItem
17
- key={locale.locale}
18
- label={locale.localName}
19
- lang={locale.locale}
20
- testId={"language_picker_" + locale.locale}
21
- />
22
- ))}
23
- </ActionMenu>
24
- );
25
-
26
- ActionMenuWithLang.storyName = "Using the ActionMenu with the lang attribute";
27
-
28
- ActionMenuWithLang.parameters = {
29
- docs: {
30
- storyDescription:
31
- "You can use the `lang` attribute to specify the language of the action item(s). This is useful if you want to avoid issues with Screen Readers trying to read the proper language for the rendered text.",
32
- },
33
- chromatic: {
34
- disableSnapshot: true,
35
- },
36
- };
37
-
38
- const locales = [
39
- {id: "az", locale: "az", localName: "Azərbaycanca"},
40
- {id: "id", locale: "id", localName: "Bahasa Indonesia"},
41
- {id: "cs", locale: "cs", localName: "čeština"},
42
- {id: "da", locale: "da", localName: "dansk"},
43
- {id: "de", locale: "de", localName: "Deutsch"},
44
- {id: "en", locale: "en", localName: "English"},
45
- {id: "es", locale: "es", localName: "español"},
46
- {id: "fr", locale: "fr", localName: "français"},
47
- {id: "it", locale: "it", localName: "italiano"},
48
- ];
@@ -1,124 +0,0 @@
1
- // @flow
2
- import * as React from "react";
3
- import {StyleSheet} from "aphrodite";
4
-
5
- import {View} from "@khanacademy/wonder-blocks-core";
6
-
7
- import type {Labels} from "@khanacademy/wonder-blocks-dropdown";
8
- import type {StoryComponentType} from "@storybook/react";
9
-
10
- import {MultiSelect, OptionItem} from "../index.js";
11
-
12
- export default {
13
- title: "Dropdown / MultiSelect",
14
- };
15
-
16
- // Custom MultiSelect labels
17
- const dropdownLabels: $Shape<Labels> = {
18
- noneSelected: "Solar system",
19
- someSelected: (numSelectedValues) => `${numSelectedValues} planets`,
20
- };
21
-
22
- type Props = {|
23
- opened: boolean,
24
- |};
25
-
26
- type State = {|
27
- opened: boolean,
28
- selectedValues: Array<string>,
29
- |};
30
-
31
- type DefaultProps = {|
32
- opened: $PropertyType<Props, "opened">,
33
- |};
34
-
35
- class MultiSelectWithCustomStyles extends React.Component<Props, State> {
36
- static defaultProps: DefaultProps = {
37
- opened: false,
38
- };
39
-
40
- state: State = {
41
- selectedValues: [],
42
- opened: this.props.opened,
43
- };
44
-
45
- handleChange: (update: Array<string>) => void = (update) => {
46
- this.setState({
47
- selectedValues: update,
48
- });
49
- };
50
-
51
- handleToggleMenu: (opened: boolean) => void = (opened) => {
52
- this.setState({
53
- opened,
54
- });
55
- };
56
-
57
- render(): React.Node {
58
- return (
59
- <View style={styles.wrapper}>
60
- <MultiSelect
61
- onChange={this.handleChange}
62
- selectedValues={this.state.selectedValues}
63
- style={styles.setWidth}
64
- dropdownStyle={styles.customDropdown}
65
- labels={dropdownLabels}
66
- opened={this.state.opened}
67
- onToggle={this.handleToggleMenu}
68
- >
69
- <OptionItem label="Mercury" value="1" />
70
- <OptionItem label="Venus" value="2" />
71
- <OptionItem label="Earth" value="3" disabled />
72
- <OptionItem label="Mars" value="4" />
73
- <OptionItem label="Jupiter" value="5" />
74
- <OptionItem label="Saturn" value="6" />
75
- <OptionItem label="Neptune" value="7" />
76
- <OptionItem label="Uranus" value="8" />
77
- </MultiSelect>
78
- </View>
79
- );
80
- }
81
- }
82
-
83
- export const CustomStyles: StoryComponentType = () => (
84
- <MultiSelectWithCustomStyles />
85
- );
86
-
87
- CustomStyles.parameters = {
88
- chromatic: {
89
- // we don't need screenshots because this story only tests behavior.
90
- disableSnapshot: true,
91
- },
92
- };
93
-
94
- export const CustomStylesOpened: StoryComponentType = () => (
95
- <MultiSelectWithCustomStyles opened={true} />
96
- );
97
-
98
- export const DisabledMultiSelect: StoryComponentType = () => (
99
- <MultiSelect disabled={true} onChange={() => {}}>
100
- <OptionItem label="Mercury" value="1" />
101
- <OptionItem label="Venus" value="2" />
102
- </MultiSelect>
103
- );
104
-
105
- DisabledMultiSelect.parameters = {
106
- docs: {
107
- storyDescription:
108
- "`MultiSelect` can be disabled by passing `disabled={true}`. This can be useful when you want to disable a control temporarily.",
109
- },
110
- };
111
-
112
- const styles = StyleSheet.create({
113
- setWidth: {
114
- minWidth: 170,
115
- width: "100%",
116
- },
117
- customDropdown: {
118
- maxHeight: 200,
119
- },
120
- wrapper: {
121
- height: "800px",
122
- width: "1200px",
123
- },
124
- });