question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[API] Single Select Component

See original GitHub issue

Following 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

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.
  • 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 press escape
  • 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 have aria-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:closed
  • Created 4 years ago
  • Reactions:15
  • Comments:32 (19 by maintainers)

github_iconTop GitHub Comments

19reactions
tomdohnalcommented, Nov 20, 2020

@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.

11reactions
csandmancommented, Sep 22, 2021

@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, and lg 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

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found