React Select

A flexible and beautiful Select Input control for ReactJS with multiselect, autocomplete, async and creatable support.

🎉 Feature Highlights
Styles
Style Object
Provided Styles and State
Select Props
cx and custom Components
Using classNames
Overriding the theme

Styles

React-Select offers a flexible, light-weight styling framework which is a thin abstraction over simple javascript objects using emotion.

/**
 * @param {Object} provided -- the component's default styles
 * @param {Object} state -- the component's current state e.g. `isFocused`
 * @returns {Object}
 */
function styleFn(provided, state) {
  return { ...provided, color: state.isFocused ? 'blue' : 'red' };
}

Style Object

Each component is keyed, and ships with default styles. The component's default style object is passed as the first argument to the function when it's resolved.

The second argument is the current state of the select, features like isFocused, isSelected etc. allowing you to implement dynamic styles for each of the components.

Style Keys
  • clearIndicator
  • container
  • control
  • dropdownIndicator
  • group
  • groupHeading
  • indicatorsContainer
  • indicatorSeparator
  • input
  • loadingIndicator
  • loadingMessage
  • menu
  • menuList
  • menuPortal
  • multiValue
  • multiValueLabel
  • multiValueRemove
  • noOptionsMessage
  • option
  • placeholder
  • singleValue
  • valueContainer

Provided Styles and State

Spreading the provided styles into your returned object lets you extend it however you like while maintaining existing styles. Alternatively, you can omit the provided styles and completely take control of the component's styles.

const customStyles = {
  option: (provided, state) => ({
    ...provided,
    borderBottom: '1px dotted pink',
    color: state.isSelected ? 'red' : 'blue',
    padding: 20,
  }),
  control: () => ({
    // none of react-select's styles are passed to <Control />
    width: 200,
  }),
  singleValue: (provided, state) => {
    const opacity = state.isDisabled ? 0.5 : 1;
    const transition = 'opacity 300ms';

    return { ...provided, opacity, transition };
  }
}

  const App = () => (
    <Select
      styles={customStyles}
      options={...}
    />
  );

Select Props

In the second argument state, you have access to selectProps which will allow you to gain access to your own arguments passed into the Select body.

const customStyles = {
  menu: (provided, state) => ({
    ...provided,
    width: state.selectProps.width,
    borderBottom: '1px dotted pink',
    color: state.selectProps.menuColor,
    padding: 20,
  }),

  control: (_, { selectProps: { width }}) => ({
    width: width
  }),

  singleValue: (provided, state) => {
    const opacity = state.isDisabled ? 0.5 : 1;
    const transition = 'opacity 300ms';

    return { ...provided, opacity, transition };
  }
}

  const App = () => (
    <Select
      styles={customStyles}
      width='200px'
      menuColor='red'
      options={...}
    />
  );

Customised Styles for Single Select

Purple

Customised styles for Multi Select

Ocean
Blue

cx and custom Components

In the event that you need to rewrite a particular component, you'll also have to compose together the styling functionality. Thankfully all the requisite parts are supplied to you via props as below:

cx

cx is an internal utility function that manages the composition of emotion style declarations, className/classNamePrefixes and additional BEM style modifiers into a selector value for each component. It has the following signature:

(prefix ?: string,
  cssKey?: string,
  state?: {},
  className?: string) => string
  • prefix: is the value of the optional classNamePrefix,
  • cssKey: is the uid generated by the invocation of the css method imported from emotion
  • state: an object declaring state based modifiers to be applied to our selector
  • className: any className prop specified for custom components will also be composed into the selector string produced by the cx functions

getStyles

Each component gets passed a getStyles method which has the following signature:

(key: string, props: Object) => stylesObject;

The key is a lowercased string value corresponding to the component that the styles apply to, i.e. option for the Option component, menuplacer for the MenuPlacer component.

The props argument is an object of relevant properties/ state values that are relevant to computing styles, i.e. isFocused or isSelected. Additional props can be added here for computation using the styles api.

In the end configuring your custom component with the correct styling functionality should look like this

import { css } from 'emotion';

const CustomOption = ({ cx, children, getStyles, innerRef, ...props }) => (
  <div
    ref={innerRef}
    className={cx(
      css(getStyles('option', props)),
      {
        'option': true,
        'option--is-disabled': isDisabled,
        'option--is-focused': isFocused,
        'option--is-selected': isSelected,
      }
    )}
  >
    {children}
  </div>
)

Style composition for custom components

Orange

Using classNames

If you provide the className prop to react-select, the SelectContainer will be given a className based on the provided value.

If you provide the classNamePrefix prop to react-select, all inner elements will be given a className with the provided prefix.

For example, given className='react-select-container' and classNamePrefix="react-select", the DOM structure is similar to this:

<div class="react-select-container">
  <div class="react-select__control">
    <div class="react-select__value-container">...</div>
    <div class="react-select__indicators">...</div>
  </div>
  <div class="react-select__menu">
    <div class="react-select__menu-list">
      <div class="react-select__option">...</div>
    </div>
  </div>
</div>

While we encourage you to use the new Styles API, you still have the option of styling via CSS classes. This ensures compatibility with styled components, CSS modules and other libraries.

Overriding the theme

The default styles are derived from a theme object, which you can mutate like styles.

The theme object is available for the styles functions as well.

Customised theme

Strawberry
Theme colors
primary
primary75
primary50
primary25
danger
dangerLight
neutral0
neutral5
neutral10
neutral20
neutral30
neutral40
neutral50
neutral60
neutral70
neutral80
neutral90

Copyright © Jed Watson, 2019. MIT Licensed.