[API] Single Select Component
See original GitHub issueFollowing our discussion in Issue #38. I thought to put down my thoughts about the Single Select component and the API I have in mind.
NB: I know there are other use cases, like Multiple Selects and ComboBox, but we’re keeping it simple for now. We’ll start with a Single Select Component
The Goal:
Create a select component that works just like the native select and accessible, composable and super easy to style.
The single select will follow WAI-ARIA specs for the list box pattern. These are the key resources we need to create this Select
- https://ebay.gitbook.io/mindpatterns/input/listbox
- https://www.w3.org/TR/wai-aria-practices/examples/listbox/listbox-scrollable.html
- https://www.w3.org/TR/wai-aria-practices/examples/listbox/listbox-collapsible.html
- https://www.w3.org/TR/wai-aria-practices/#kbd_focus_vs_selection
Key Features:
- Typeahead support: When the select is open and focus is on the select list box
- Typing the first letter of an option sends focus to that option.
- Type multiple characters in rapid succession: focus moves to the next item with a name that starts with the string of characters typed.
- Keyboard navigation:
- Using the up and down arrow should navigate the options. Any option that’s disabled should be skipped in the navigation.
- The Home and End key should select the first and last option respectively.
- Scrolling into view: In the event, the options are quite many and we navigate
via keyboard or typeahead, any option is focused that isn’t (fully) visible
should be scrolled into view. Perhaps
scroll-into-view-if-needed
might help. - Auto select:
- If
autoSelect
is true, highlighting an option must also select that option - If
autoSelect
is false, a highlighted option must be manually selected using the SPACEBAR or ENTER key.
- If
- Virtualize Menu: If there’s a large number of options, we might need to
improve render performance by using
react-virtualized
Import
Component Parts:
- Select: The wrapper that provides the context and functionalities
- SelectControl: The element that triggers the list box. By default, it renders a
button
but can also use a render prop in case user needs full control of the rendering. - SelectMenu: The wrapper for the popover. It composes the
Popper
component. It can also use a render prop incase user needs access to the interal state. - SelectMenuList: The listbox that wraps the options. It provides the keyboard navigation and typeahead functions.
- SelectIndicator: The wrapper for the dropdown icon.
- SelectOption: Each option in the select.
- SelectOptionGroup: A wrapper for a set of options that can be labeled. Similar
to the
<optgroup>
in the native browser select.
Usage
<Select>
<SelectControl>
<SelectLabel>Option 1</SelectLabel>
<SelectIndicator>
<Icon name="down-up-arrow" />
</SelectIndicator>
</SelectControl>
<SelectMenu>
<SelectMenuList>
<SelectOption value="opt1">SelectOption 1</SelectOption>
<SelectOption value="opt2">SelectOption 2</SelectOption>
<SelectOption value="opt3">SelectOption 3</SelectOption>
</SelectMenuList>
</SelectMenu>
</Select>
The Select should also be able to render an option group. If passed
isDisabled
, the options should also be disabled.
<Select defaultIsOpen={true} defaultValue="css">
<SelectControl>Select Option</SelectControl>
<SelectMenu>
<SelectMenuList>
<SelectOption value="html">HTML</SelectOption>
<SelectOption value="css">CSS</SelectOption>
<SelectOptionGroup label="Frameworks" isDisabled>
<SelectOption value="react">React</SelectOption>
<SelectOption value="vue">Vue</SelectOption>
<SelectOption value="angular">Angular</SelectOption>
</SelectOptionGroup>
</SelectMenuList>
</SelectMenu>
</Select>
Props
Select Props (Provides Context)
- defaultIsOpen: If
true
, the select should be open initially. - isOpen: If
true
, the select should be open in controlled mode. - defaultHighlightedIndex: the index of the item that should be highlighted initially.
- autoSelect: If
true
, the option will be selected as you navigate through them. - closeOnBlur: If
true
, the select menu will close on blur or outside click - closeOnEsc: If
true
, the select menu will close when you pressescape
- closeOnSelect: If
true
, the select menu will close when you select an option. - defaultValue: The initial selected value
- value: The selected value
- onChange: Callback fired when an option is selected
- isDisabled: If
true
the select control will be disabled - isInvalid: If
true
, the select control will havearia-invalid
set to true - isReadOnly: If
true
, the select will be in read-only mode - children: the content of the select. It can also take a render prop that
provides:
- selectedItem
- highlightedIndex
- isOpen
- onClose
SelectOptionGroup Props (composes Box)
- isDisabled: If
true
, all the SelectOption that it wraps will be disabled - label: The label for the option group
SelectOption Props (composes PseudoBox)
- isSelected
- isHighlighted
- value
- children
Issue Analytics
- State:
- Created 4 years ago
- Reactions:15
- Comments:32 (19 by maintainers)
Top Results From Across the Web
Select API - Material UI - MUI
Name Type Default
autoWidth bool false
children node
classes object
Read more >Single-Select - Intercom Developer Hub
A single select component is used to capture a choice from the teammate or end user. It requires a collection of single select...
Read more >Single Select ComboBox Component - Infragistics
Selection API. The simple combobox component exposes API that allows getting and manipulating the current selection state of the control. One way to...
Read more >API - React Select
A flexible and beautiful Select Input control for ReactJS with multiselect, autocomplete and ajax support.
Read more >ion-select: Select One or Multiple Value Boxes or Placeholders
Selects are form controls to select an option, or options, from a set of options, similar to a native <select> element. When a...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@segunadebayo Hi, now that the v1 is released (congrats!), is this component something you would consider adding to the library? I’d be happy to help you out with that if that’s something you’d consider.
@TaylorFacen You should check out my wrapper for react-select. I spent a decent amount of time replacing the react-select styles with the chakra ones, in some cases just replacing the components entirely.
EDIT
I’ve noticed that this has gotten a positive reception so I figured I’d post an update. The wrapper I posted is now updated to more accurately work with the react-select controls, and also now has a size prop! it can accept
sm
,md
, andlg
and it reflects the sizes of the normal chakra text input. I also included a wrapper for the async version.EDIT 2
I made it into an NPM package! https://www.npmjs.com/package/chakra-react-select