woocommerce/packages/js/components/src/experimental-select-control
Sam Seay b076a7b521
Fix linter issues and update Syncpack (#38523)
2023-05-31 11:45:10 +12:00
..
hooks Add async filtering support to the select-control component (#35839) 2022-12-07 14:24:32 -03:00
stories Upstream changes from experimental-select-control back to @woocommerce/components (#36521) 2023-03-29 17:18:43 +08:00
test Add async filtering support to the select-control component (#35839) 2022-12-07 14:24:32 -03:00
README.md Add core profiler user profile page (#38328) 2023-05-22 11:21:16 +08:00
combo-box.scss Wrap selected items in experimental select control (#38284) 2023-05-16 15:15:26 -07:00
combo-box.tsx Show comma separated list in ready only mode of select tree control (#38052) 2023-05-08 04:17:52 -03:00
index.ts Add async filtering support to the select-control component (#35839) 2022-12-07 14:24:32 -03:00
menu-item.scss Add SearchControl component (#34159) 2022-08-18 10:36:20 -07:00
menu-item.tsx Upstream changes from experimental-select-control back to @woocommerce/components (#36521) 2023-03-29 17:18:43 +08:00
menu.scss Add popover support to select control dropdown (#34967) 2022-10-18 16:55:37 -03:00
menu.tsx Select tree dropdown menu SlotFill support (#37574) 2023-04-14 04:22:59 -03:00
select-control.scss Show comma separated list in ready only mode of select tree control (#38052) 2023-05-08 04:17:52 -03:00
select-control.tsx Fix linter issues and update Syncpack (#38523) 2023-05-31 11:45:10 +12:00
selected-items.scss Wrap selected items in experimental select control (#38284) 2023-05-16 15:15:26 -07:00
selected-items.tsx Show comma separated list in ready only mode of select tree control (#38052) 2023-05-08 04:17:52 -03:00
suffix-icon.scss Add async filtering support to the select-control component (#35839) 2022-12-07 14:24:32 -03:00
suffix-icon.tsx Add __experimentalSelectControl suffix prop (#35809) 2022-12-02 11:53:53 -05:00
types.ts Create experimental SelectTree component (#37319) 2023-03-24 14:49:45 -03:00
utils.ts Update/experimental select control (#34620) 2022-10-06 11:40:41 -03:00

README.md

SelectControl

A component that allows searching and selection of one or more items, providing accessibility for item and menu interaction.

Usage

SelectControl expects an array of item objects with value and label properties by default, with the option of passing your own ItemType to the component. Using the getItemLabel and getItemValue props will allow you to pass a function to determine the respective label and value used and customize this object's shape.

const [ selected, setSelected ] = useState< SelectedType >( [] );

const items = [
	{ value: 'item-1', label: 'Item 1' },
	{ value: 'item-2', label: 'Item 2' },
];

<SelectControl
    multiple
    items={ items }
    label="My select control"
    selected={ selected }
    onSelect={ ( item ) => item && setSelected( [ ...selected, item ] ) }
    onRemove={ () => setSelected( selected.filter( ( i ) => i !== item ) ) }
/>

And with a Custom Type to describe the item shape:

const [ selected, setSelected ] =
		useState< SelectedType< Array< CustomItemType > > >( null );

const customItems = [
  { id: 1, name: 'Joe', email: 'joe@notreally.com' },
  { id: 2, name: 'Jen' },
];

<SelectControl < CustomItemType >
  multiple
  items={ customItems }
  label="CustomItemType value"
  selected={ selected }
  onSelect={ ( item ) =>
    setSelected(
      Array.isArray( selected )
        ? [ ...selected, item ]
        : [ item ]
    )
  }
  onRemove={ ( item ) =>
    setSelected( selected.filter( ( i ) => i !== item ) )
  }
  getItemLabel={ ( item ) => item?.name }
  getItemValue={ ( item ) => String( item?.id ) }
/>

By default, the menu will render selectable items based on the provided items, but by passing a child function you can determine the render of those items.

<SelectControl
    label="Custom render"
    items={ items }
    selected={ selected }
    onSelect={ ( item ) => setSelectedItem( item ) }
    onRemove={ () => setSelectedItem( null ) }
>
    { ( {
        items,
        isOpen,
        highlightedIndex,
        getItemProps,
        getMenuProps,
        getItemLabel,
        getItemValue
    } ) => {
        return (
            <ul { ...getMenuProps() }>
                { isOpen && items.map( ( item, index: number ) => (
                    <li 
                        key={ `${ getItemValue(item) }${ index }` }
                        { ...getItemProps() }
                    >
                        { getItemLabel(item) }
                    </li>
                ) ) }
            </ul>
        );
    } }
</SelectControl>

Props

Name Type Default Description
children Function ( { items, highlightedIndex, getItemProps, getMenuProps, isOpen } ) => JSX.Element A function that renders the menu and menu items
multiple Boolean false Whether the input should allow multiple selections or a single selection
items Array undefined The items used in the dropdown as an array of objects with value and label properties
label String undefined A string shown above the input
getItemLabel Function ( item ) => item.label A function used to determine the label for an item
getItemValue Function ( item ) => item.value A function used to determine the value for an item
getFilteredItems Function ( allItems, inputValue, selectedItems ) => allItems.filter( ( item ) => selectedItems.indexOf( item ) < 0 && item.label.toLowerCase().startsWith( inputValue.toLowerCase() ) ) A function to determine how items should be filtered based on user input and previously selected items
onInputChange Function () => null A callback that fires when the user input has changed
onRemove Function () => null A callback that fires when a selected item has been removed
onSelect Function () => null A callback that fires when an item has been selected
selected Array or Item undefined An array of selected items or a single selected item\
onKeyDown Function () => null A callback that fires when a key is pressed
readOnlyWhenClosed Boolean false Whether the input should be read-only when the menu is closed