|
1 |
| -import React, { useState } from "react"; |
| 1 | +import React, { useState, useCallback, useMemo } from "react"; |
2 | 2 | import { Dropdown, DropdownMenuItemType, SearchBox } from "@fluentui/react";
|
3 | 3 |
|
4 | 4 | // Credits for this code belong to: https://github.com/microsoft/fluentui/issues/16566#issuecomment-853933969
|
5 | 5 | const SearchableDropdown = (props) => {
|
| 6 | + const {options, customProps, searchProps, ...dropdownProps} = props; |
| 7 | + const {searchProps: customSearchProps, ...customDropdownProps} = customProps ?? {}; |
| 8 | + |
6 | 9 | const [searchText, setSearchText] = useState("");
|
7 | 10 |
|
8 |
| - function renderOption(option) { |
| 11 | + const onSearchChange = useCallback((ev, newValue) => setSearchText(newValue), [setSearchText]); |
| 12 | + |
| 13 | + const calloutProps = { shouldRestoreFocus: false, setInitialFocus: false }; //not working |
| 14 | + |
| 15 | + const renderOption = useCallback((option) => { |
9 | 16 | return (option.itemType === DropdownMenuItemType.Header
|
10 | 17 | && option.key === "FilterHeader")
|
11 | 18 | ? <SearchBox
|
12 |
| - onChange={(ev, newValue) => setSearchText(newValue)} |
| 19 | + onChange={onSearchChange} |
13 | 20 | underlined={true}
|
14 |
| - placeholder="Search options" |
| 21 | + placeholder={searchProps?.placeholder} |
| 22 | + {...(customSearchProps ?? {})} |
15 | 23 | />
|
16 | 24 | : <>{option.text}</>;
|
17 |
| - } |
| 25 | + }, [SearchBox, onSearchChange, customSearchProps, searchProps]); |
| 26 | + |
| 27 | + const onDismiss = useCallback(() => setSearchText(""), [setSearchText]); |
| 28 | + |
| 29 | + const dropdownOptions = useMemo(() => ([ |
| 30 | + { key: "FilterHeader", text: "-", itemType: DropdownMenuItemType.Header }, |
| 31 | + { key: "divider_filterHeader", text: "-", itemType: DropdownMenuItemType.Divider }, |
| 32 | + ...options.map(option => !option.disabled && option.text.toLowerCase().indexOf(searchText.toLowerCase()) > -1 |
| 33 | + ? option : { ...option, hidden: true } |
| 34 | + ), |
| 35 | + ]), [options, searchText]); |
18 | 36 |
|
19 | 37 | return (
|
20 | 38 | <Dropdown
|
21 |
| - {...props} |
22 |
| - options={[ |
23 |
| - { key: "FilterHeader", text: "-", itemType: DropdownMenuItemType.Header }, |
24 |
| - { key: "divider_filterHeader", text: "-", itemType: DropdownMenuItemType.Divider }, |
25 |
| - ...props.options.map(option => !option.disabled && option.text.toLowerCase().indexOf(searchText.toLowerCase()) > -1 |
26 |
| - ? option : { ...option, hidden: true } |
27 |
| - ), |
28 |
| - ]} |
29 |
| - calloutProps={{ shouldRestoreFocus: false, setInitialFocus: false }} //not working |
| 39 | + options={dropdownOptions} |
| 40 | + calloutProps={calloutProps} |
30 | 41 | onRenderOption={renderOption}
|
31 |
| - onDismiss={() => setSearchText("")} |
| 42 | + onDismiss={onDismiss} |
| 43 | + {...dropdownProps} |
| 44 | + {...customDropdownProps} |
32 | 45 | />
|
33 | 46 | );
|
34 | 47 | };
|
|
0 commit comments