woocommerce/packages/js/components/src/experimental-select-control
Chi-Hsuan Huang e9a4d6c9ba
Add an optional "InputProps" to experimental SelectControl component (#36470)
* Add inputProps to experimental SelectControl component so we can pass custom props to the input

* Add changelog
2023-01-18 11:56:33 +08:00
..
hooks Add async filtering support to the select-control component (#35839) 2022-12-07 14:24:32 -03:00
stories Add async filtering support to the select-control component (#35839) 2022-12-07 14:24:32 -03:00
test Add async filtering support to the select-control component (#35839) 2022-12-07 14:24:32 -03:00
README.md Allowing generic item type in new experimental SelectControl (#34547) 2022-09-16 13:35:14 -07:00
combo-box.scss Add __experimentalSelectControl suffix prop (#35809) 2022-12-02 11:53:53 -05:00
combo-box.tsx Add __experimentalSelectControl suffix prop (#35809) 2022-12-02 11:53:53 -05: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 Add category field dropdown field (#34400) 2022-10-14 09:05:39 -03:00
menu.scss Add popover support to select control dropdown (#34967) 2022-10-18 16:55:37 -03:00
menu.tsx Add/34 create new category field modal (#35132) 2022-11-16 12:30:42 -04:00
select-control.scss Add __experimentalSelectControl suffix prop (#35809) 2022-12-02 11:53:53 -05:00
select-control.tsx Add an optional "InputProps" to experimental SelectControl component (#36470) 2023-01-18 11:56:33 +08:00
selected-items.scss Allow external tags in SelectControl component (#34823) 2022-10-05 13:29:30 -07:00
selected-items.tsx Update text input placement in SelectControl (#34788) 2022-10-05 12:08:10 -07: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 Add category field dropdown field (#34400) 2022-10-14 09:05:39 -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