No Preview

Sorry, but you either have no stories or none are selected somehow.

If the problem persists, check the browser console, or the terminal you've run Storybook from.

The component failed to render properly, likely due to a configuration issue in Storybook. Here are some common causes and how you can address them:

  1. Missing Context/Providers: You can use decorators to supply specific contexts or providers, which are sometimes necessary for components to render correctly. For detailed instructions on using decorators, please visit the Decorators documentation.
  2. Misconfigured Webpack or Vite: Verify that Storybook picks up all necessary settings for loaders, plugins, and other relevant parameters. You can find step-by-step guides for configuring Webpack or Vite with Storybook.
  3. Missing Environment Variables: Your Storybook may require specific environment variables to function as intended. You can set up custom environment variables as outlined in the Environment Variables documentation.

Select

Select is the base for every component on this page. The approaches mentioned here are also applicable to AsyncSelect, MultiSelect, AsyncMultiSelect.

Select variants

Select is an input with the ability to search and create new values. It should be used when you have a list of options. If the data has a tree structure, consider using Cascader instead. Select has some features:

  • Search a list of values
  • Select multiple values
  • Select from async data
  • Create custom values that aren't in the list

Options format

There are four properties for each option:

  • label - Text that is visible in the menu.
  • value - Could be anything, but is usually a string. Used to identify what is actually selected.
  • description - Longer description that describes the choice. Use this sparingly.
  • imgUrl - URL to an image. Use this when an image or icon provides more context for the option.
const options = [ { label: 'Basic option', value: 0 }, { label: 'Option with description', value: 1, description: 'this is a description' }, { label: 'Option with description and image', value: 2, description: 'This is a very elaborate description, describing all the wonders in the world.', imgUrl: 'https://placekitten.com/40/40', }, ];

Creatable option

Creatable option is used when you want to be able to add a custom value to the list of options. allowCustomValue needs to be true and you must handle the value creation with onCreateOption.

import { Select } from "@grafana/ui"; const SelectComponent = () => { const [value, setValue] = useState<SelectableValue<number>>(); return ( <Select options={option} value={value} allowCustomValue onCreateOption={customValue => { setValue(customValue); }} /> ); };

Resetting selected value from outside the component

If you want to reset the selected value from outside the component, e.g. if there are two Select components that should be in sync, you can set the dependent Select value to null in the onChange handler of the first Select component.

import { useState } from 'react'; import { Select } from '@grafana/ui'; const SelectComponent = () => { const [person, setPerson] = useState<string | undefined>(''); const [team, setTeam] = useState<string | undefined | null>(''); return ( <form> <Select onChange={({ value }) => { setPerson(value); setTeam(null); // Setting the team to null will reset the selected value in the team Select }} options={[ { value: 'option1', label: 'Option 1', }, { value: 'option2', label: 'Option 2', }, ]} value={person} backspaceRemovesValue /> <Select onChange={({ value }) => setTeam(value)} options={[ { value: 'team1', label: 'Team 1', }, { value: 'team', label: 'Team 2', }, ]} value={team} /> </form> ); };

AsyncSelect

Like regular Select, but handles fetching options asynchronously. Use the loadOptions prop for the async function that loads the options. If defaultOptions is set to true, loadOptions will be called when the component is mounted.

import { AsyncSelect } from '@grafana/ui'; const basicSelectAsync = () => { const [value, setValue] = useState<SelectableValue<string>>(); return ( <AsyncSelect loadOptions={loadAsyncOptions} defaultOptions value={value} onChange={v => { setValue(v); }} /> ); };

Where the async function could look like this:

const loadAsyncOptions = () => { return new Promise<Array<SelectableValue<string>>>((resolve) => { setTimeout(() => { resolve(options); }, 2000); }); };

MultiSelect

Possible to Select multiple values at the same time.

import { MultiSelect } from '@grafana/ui'; const multiSelect = () => { const [value, setValue] = useState<Array<SelectableValue<string>>>([]); return ( <> <MultiSelect options={options} value={value} onChange={(v) => { setValue(v); }} /> </> ); };

AsyncMultiSelect

Like MultiSelect but handles data asynchronously with the loadOptions prop.

Testing

Using React Testing Library, you can select the <Select /> using its matching label, such as the label assigned with the inputId prop. Use the react-select-event package to select values from the options.

import { render, screen } from '@testing-library/react'; import selectEvent from 'react-select-event'; import { Select } from '@grafana/ui'; it('should call onChange', () => { const onChange = jest.fn(); render( <> <label htmlFor="my-select">My select</label> <Select onChange={onChange} options={options} inputId="my-select" /> </> ); const selectEl = screen.getByLabelText('My select'); expect(selectEl).toBeInTheDocument(); await selectEvent.select(selectEl, 'Option 2', { container: document.body }); expect(onChange).toHaveBeenCalledWith({ label: 'Option 2', value: 2, }); });

Props

NameDescriptionDefault
aria-label
Aria label applied to the input field
string
-
data-testid
string
-
allowCreateWhileLoading
boolean
-
allowCustomValue
boolean
-
autoFocus
Focus is set to the Select when rendered
boolean
-
backspaceRemovesValue
boolean
-
blurInputOnSelect
boolean
-
captureMenuScroll
boolean
-
className
string
-
closeMenuOnSelect
boolean
-
components
Used for custom components. For more information, see react-select
any
-
createOptionPosition
Sets the position of the createOption element in your options list. Defaults to 'last'
"first""last"
-
defaultValue
any
-
disabled
boolean
-
filterOption
((option: SelectableValue<T>, searchQuery: string) => boolean)
-
formatOptionLabel
((item: SelectableValue<T>, formatOptionMeta: FormatOptionLabelMeta<T>) => ReactNode)
-
formatCreateLabel
Function for formatting the text that is displayed when creating a new value
((input: string) => ReactNode)
-
getOptionLabel
((item: SelectableValue<T>) => ReactNode)
-
getOptionValue
((item: SelectableValue<T>) => T)
-
hideSelectedOptions
boolean
-
inputValue
string
-
invalid
boolean
-
isClearable
boolean
-
id
The id to set on the SelectContainer component. To set the id for a label (with htmlFor),
string
-
isLoading
boolean
-
isMulti
boolean
-
inputId
The id of the search input. Use this to set a matching label with htmlFor
string
-
isOpen
boolean
-
isSearchable
Disables the possibility to type into the input
boolean
-
showAllSelectedWhenOpen
boolean
-
maxMenuHeight
number
-
minMenuHeight
number
-
maxVisibleValues
number
-
menuPlacement
"auto""bottom""top"
-
menuPosition
"absolute""fixed"
-
menuShouldPortal
Setting to false will prevent the menu from portalling to the body.
boolean
-
noOptionsMessage
The message to display when no options could be found
string
-
onBlur
(() => void)
-
onChange*
(value: SelectableValue<T>, actionMeta: ActionMeta) => void | {}
-
onCloseMenu
(() => void)
-
onCreateOption
allowCustomValue must be enabled. Function decides what to do with that custom value.
((value: string) => void)
-
onInputChange
((value: string, actionMeta: InputActionMeta) => void)
-
onKeyDown
((event: KeyboardEvent<Element>) => void)
-
onMenuScrollToBottom
Callback which fires when the user scrolls to the bottom of the menu
((event: WheelEvent | TouchEvent) => void)
-
onMenuScrollToTop
Callback which fires when the user scrolls to the top of the menu
((event: WheelEvent | TouchEvent) => void)
-
onOpenMenu
(() => void)
-
onFocus
(() => void)
-
toggleAllOptions
{ enabled: boolean; optionsFilter?: ((v: SelectableValue<T>) => boolean); determineToggleAllState?: ((selectedValues: SelectableValue<T>[], options: SelectableValue<...>[]) => ToggleAllState); } | undefined
-
openMenuOnFocus
boolean
-
options
SelectableValue<T>[]
-
placeholder
string
-
prefix
item to be rendered in front of the input
stringElementnull
-
renderControl
Use a custom element to control Select. A proper ref to the renderControl is needed if 'portal' isn't set to null
ControlComponent<T>
-
tabSelectsValue
boolean
-
value
SelectValue<T> | null
-
virtualized
Will wrap the MenuList in a react-window FixedSizeVirtualList for improved performance, does not support options with "description" properties
boolean
-
width
Sets the width to a multiple of 8px. Should only be used with inline forms. Setting width of the container is preferred in other cases.
number"auto"
-
isOptionDisabled
((option: SelectableValue<T>) => boolean)
-
isValidNewOption
allowCustomValue must be enabled. Determines whether the "create new" option should be displayed based on the current input value, select value and options array.
((inputValue: string, value: SelectableValue<T> | null, options: OptionsOrGroups<SelectableValue<T>, GroupBase<SelectableValue<T>>>) => boolean)
-
loadingMessage
Message to display isLoading=true
string
-
noMultiValueWrap
Disables wrapping of multi value values when closed
boolean
-