Skip to main content
/
/
/
Select

Select

Input field with multiple options in a dropdown

import Select from "@intility/bifrost-react-select";
More props

The Select component uses react-select under the hood. See react-select props docs for full documentation.

Install package

The Select component is published as a separate @intility/bifrost-react-select package:

  1. Run the following command to install:
Shell
npm install @intility/bifrost-react-select
  1. Import component separately from other components
TSX
import Select from "@intility/bifrost-react-select";
  1. Use it in your JSX code
TSX
<Select label="Country" options={countries} />

Options and state

You can control and access the options and state of the select with the following props:

  • options - an array of objects with label (displayed string) and value (any data you want associated) properties.
  • value - sets currently selected option
  • onChange - function triggered when user selects an option, with the option object as argument

Commonly used props

isClearable

Use isClearable prop for possibility to remove selected option with button.

Select an option and you should see an "x" icon.

state and feedback

Select can indicate an alert state based on input. Set state prop to 'alert' to style it accordingly. Meanwhile, use feedback to provide additional information.

Use the required prop to render Select as required. This will add (required) text after the label. You can hide this label (but still have the select be required) with requiredNoLabel.

Read more

See usage demo at Forms example

isMulti

Using the isMulti prop makes it possible to select multiple options. This will make the onChange callback receive an array instead of a single option.

Grouped options

The array pased to the options prop can contain objects with a label and its own nested options array, which lets you group options. Also works with isMulti.

isDisabled

Disable a <Select> with isDisabled prop, or disable an option with isDisabled: true property on the option object.

loading

The loading prop displays a loading spinner on the right hand side of the input.

hideLabel

The label prop is required, but you can hide it with hideLabel.

small

The small prop reduces the height if the input field. It will still stretch to acommodate multi-select badges.

AsyncSelect

<AsyncSelect> can be used to load options from a source as the user types.

TSX
import { useState } from "react";
import { AsyncSelect } from "@intility/bifrost-react-select";

const countries = [
  { value: "Norway", label: "Norway" },
  { value: "Sweden", label: "Sweden" },
  { value: "Denmark", label: "Denmark" },
  { value: "Germany", label: "Germany" },
];

const [selected, setSelected] = useState();

function getAsyncOptions(inputValue) {
  return new Promise((resolve, reject) => {
    const filtered = countries.filter((c) =>
      String(c.label.toLowerCase()).startsWith(inputValue.toLowerCase()),
    );

    resolve(filtered.slice(0, 3));
  });
}

<AsyncSelect
  label="Country"
  placeholder="- Select country -"
  loadOptions={(inputValue) => getAsyncOptions(inputValue)}
  onChange={(item) => setSelected(item)}
  isClearable
/>;

CreatableSelect

<CreatableSelect> can be used to create new options.

TSX
import { useState } from "react";
import { CreatableSelect } from "@intility/bifrost-react-select";

const countries = [
  { value: "Norway", label: "Norway" },
  { value: "Sweden", label: "Sweden" },
  { value: "Denmark", label: "Denmark" },
  { value: "Germany", label: "Germany" },
];

const [selected, setSelected] = useState();
const [options, setOptions] = useState(countries);

const handleCreate = (option) => {
  const newOption = {
    value: option,
    label: option,
  };

  setOptions((options) => [...options, newOption]);
  setSelected(newOption);
};

<CreatableSelect
  label="Country"
  placeholder="- Select country -"
  options={options}
  value={selected}
  onChange={(item) => setSelected(item)}
  onCreateOption={(option) => handleCreate(option)}
  isClearable
/>;

Replace components

react-select allows you to replace internal components which allows for more advanced use cases.

Bifrost replaces the following components internally:

  • <ClearIndicator>
  • <DropdownIndicator>
  • <Input>
  • <LoadingIndicator>
  • <MenuList>
  • <Option>

To use or wrap our components in your own overrides, you can import selectComponents from @intility/bifrost-react-select

TSX
import { selectComponents } from "@intility/bifrost-react-select";
// ...
<selectComponents.Option>...</selectComponents.Option>;

Display number of selections

Let's say you have a multi-select, but don't want to display a badge for each selected item, but something like "Selected (4)" instead, you can replace the MultiValue component:

CustomMultiValue.js

TSX
import { selectComponents } from "@intility/bifrost-react-select";

export default function CustomMultiValue(props) {
  const totalSelected = props.getValue().length;

  // render the default badges if two or fewer options are selected
  const maxToShow = 2;
  if (totalSelected <= maxToShow) {
    return <selectComponents.MultiValue {...props} />;
  }

  // don't show selected count while filtering,
  // and avoid showing selected count more than once (for index 0)
  const inputValue = props.selectProps.inputValue;
  if (!inputValue && props.index === 0) {
    return <>Selected ({totalSelected})</>;
  } else {
    return <></>;
  }
}

Then supply the component to your Select:

TSX
<Select
  components={{
    MultiValue: CustomMultiValue,
  }}
  // ...
/>

Hierarchy

If you only need two levels, and the top level should not be selectable, see Grouped options above.

The <Select> component doesn't support hierarchy directly, but you can fake it by indenting:

  1. Add a level field to your list of options.
  2. Create a <CustomOption> wrapping selectComponents.Option to inherit default styling and functionality.
  3. Apply a paddingLeft based on level through innerProps.style.
  4. Override the default internal Option using the components prop.

CustomOption.js

TSX
import { selectComponents } from "@intility/bifrost-react-select";

export default function CustomOption(props) {
  const level = props.data.level ?? 0;

  return (
    <selectComponents.Option
      {...props}
      innerProps={{
        ...props.innerProps,
        style: { ...props.innerProps.style, paddingLeft: 12 + level * 16 },
      }}
    />
  );
}

Then supply the component to your Select:

TSX
<Select
  components={{
    Option: CustomOption,
  }}
  // ...
/>