Skip Navigation
React Magma

Select

Select components are used for collecting user provided information from a list of options.

For combobox/autocomplete functionality, please see the Combobox component.

If you are migrating from the Legacy Select, please see the Select Migration docs for details on how to make the transition.

Basic Usage

By default when passing in a selectedItem it will be checked to make sure it is in your items array. The check will use the itemToString function on both the selectedItem and each item in the array. The default itemToString function is able to be used for items that are either strings or an object with the shape {label: string; value: string;}.

If you are using a custom items format see the Custom Items example.

import React from 'react';
import { Select } from 'react-magma-dom';
export function Example() {
const [selectedItem, updateSelectedItem] = React.useState('');
function onSelectedItemChange(changes) {
updateSelectedItem(changes.selectedItem);
}
return (
<>
<Select
id="basicSelectId"
labelText="Basic"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
selectedItem={selectedItem}
onSelectedItemChange={onSelectedItemChange}
/>
<Select
id="badSelectedItemId"
labelText="Bad selected item"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
selectedItem={{ label: 'Purple', value: 'purple' }}
/>
</>
);
}

Initial State

Set initial state using the initialSelectedItem, initialSelectedItems, and initialHighlightedIndex props.

When using any of the initial* props be aware that passing in the controlled version of that prop will overwrite the initial version.

Ex: selectedItem takes precedence over initialSelectedItem
import React from 'react';
import { Select } from 'react-magma-dom';
export function Example() {
return (
<>
<Select
id="initialSelectedByItemSelectId"
labelText="Initial selected by item"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
initialSelectedItem={{ label: 'Green', value: 'green' }}
/>
<Select
id="initialHighlightedIndexSelectId"
labelText="Initial highlighted index"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
initialHighlightedIndex={1}
/>
</>
);
}

Label Position

The labelPosition prop can be used to set the position of the text label relative to the form field. It accepts either top or left, with top as the default.

Left-aligned lables are not recommended for use in standard forms; instead they are designed for smaller spaces where vertical space is limited, such as in a toolbar.

import React from 'react';
import { Select, LabelPosition } from 'react-magma-dom';
export function Example() {
return (
<Select
labelPosition={LabelPosition.left}
labelText="Left-aligned label"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
/>
);
}

Disabled

import React from 'react';
import { Select } from 'react-magma-dom';
export function Example() {
return (
<Select
id="disabledSelectId"
disabled
labelText="Disabled"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
/>
);
}

Disabled Items

To disable specific items in the Select component, add a disabled: true property to each item object. Disabled items specified as defaultSelectedItem or initialSelectedItem will not be selected by default or initially. If initialHighlightedIndex points to a disabled item, the component will not highlight it.

Example:

import React from 'react';
import { Select } from 'react-magma-dom';
export function Example() {
return (
<>
<Select
id="disabledItemsSelectId"
labelText="Select with Disabled Items"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue', disabled: true },
{ label: 'Green', value: 'green' },
]}
isClearable
initialHighlightedIndex={1}
defaultSelectedItem={{ label: 'Blue', value: 'blue', disabled: true }}
initialSelectedItem={{ label: 'Blue', value: 'blue', disabled: true }}
/>
<br />
<Select
id="disabledItemsSelectId"
labelText="Multi Select with Disabled Items"
isMulti
items={[
{ label: 'Red', value: 'red' },
{ label: 'Green', value: 'green' },
{ label: 'Blue-Disabled', value: 'blue', disabled: true },
{ label: 'Purple mountain majesty', value: 'purple' },
{ label: 'Orange', value: 'orange', disabled: false },
{
label: 'Yellow-Disabled',
value: 'Yellow-Disabled',
disabled: true,
},
]}
isClearable
initialHighlightedIndex={2}
defaultSelectedItems={[
{ label: 'Red', value: 'red' },
{ label: 'Orange', value: 'orange', disabled: false },
{
label: 'Yellow-Disabled',
value: 'Yellow-Disabled',
disabled: true,
},
]}
initialSelectedItems={[
{ label: 'Red', value: 'red' },
{ label: 'Orange', value: 'orange', disabled: false },
{
label: 'Yellow-Disabled',
value: 'Yellow-Disabled',
disabled: true,
},
]}
/>
</>
);
}

Clearable

The optional isClearable prop allows the user to clear the field once a selection has been made.

When using the isClearable prop you can choose a default selected item to be set once the select is cleared using the defaultSelectedItem prop.

import React from 'react';
import { Select } from 'react-magma-dom';
export function Example() {
return (
<>
<Select
id="clearableSelectId"
labelText="Clearable"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
initialSelectedItem={{ label: 'Green', value: 'green' }}
isClearable
/>
<Select
id="clearableWithDefaultsId"
labelText="Clearable with defaults"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
isClearable
defaultSelectedItem={{ label: 'Blue', value: 'blue' }}
/>
</>
);
}

Error Message

If a select has an errorMessage, the select will be styled to highlight its error state and the error message will appear below the field. If an error message is present, it will replace the helper text. Can be a node or a string.

import React from 'react';
import { Select } from 'react-magma-dom';
export function Example() {
return (
<>
<Select
id="errorMessage"
labelText="Error message"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
errorMessage="Please select a color"
/>
</>
);
}

Helper Message

The helperMessage appears underneath the select field. It will not appear if an error message is present. Can be a node or a string.

import React from 'react';
import { Select } from 'react-magma-dom';
export function Example() {
return (
<>
<Select
id="helperMessage"
labelText="Helper message"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
helperMessage="Helper text goes here"
/>
</>
);
}

Placeholder

The placeholder prop can be used to replace the default text shown before an item is chosen. Placeholder text should be used to provide supplemental information about the input field. It should not be relied upon to take the place of the label text.

import React from 'react';
import { Select } from 'react-magma-dom';
export function Example() {
return (
<Select
id="placeholderSelect"
labelText="Placeholder example"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
placeholder="Choose a color"
/>
);
}

Multi Select

import React from 'react';
import { Select } from 'react-magma-dom';
export function Example() {
const [selectedItems, updateSelectedItems] = React.useState([]);
function handleSelectedItemsChange(changes) {
updateSelectedItems(changes.selectedItems);
}
function handleRemoveSelectedItem(removedItem) {
updateSelectedItems(selectedItems.filter(item => item !== removedItem));
}
return (
<>
<Select
id="multiSelectId"
isMulti
labelText="Multi select"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
{ label: 'Orange', value: 'orange' },
{ label: 'Aqua', value: 'aqua' },
{ label: 'Gold', value: 'gold' },
{ label: 'Periwinkle', value: 'periwinkle' },
{ label: 'Lavender', value: 'lavender' },
{ label: 'Marigold', value: 'marigold' },
{ label: 'Yellow', value: 'yellow' },
{ label: 'Purple', value: 'purple' },
{ label: 'Dusty Rose', value: 'dusty_rose' },
{ label: 'Burnt Sienna', value: 'burnt_sienna' },
]}
initialSelectedItems={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Blah', value: 'blah' },
]}
/>
<Select
id="multiSelectControlledId"
isMulti
labelText="Multi select controlled"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
{ label: 'Orange', value: 'orange' },
{ label: 'Aqua', value: 'aqua' },
{ label: 'Gold', value: 'gold' },
{ label: 'Periwinkle', value: 'periwinkle' },
{ label: 'Lavender', value: 'lavender' },
{ label: 'Marigold', value: 'marigold' },
{ label: 'Yellow', value: 'yellow' },
{ label: 'Purple', value: 'purple' },
{ label: 'Dusty Rose', value: 'dusty_rose' },
{ label: 'Burnt Sienna', value: 'burnt_sienna' },
]}
selectedItems={selectedItems}
onSelectedItemsChange={handleSelectedItemsChange}
onRemoveSelectedItem={handleRemoveSelectedItem}
/>
</>
);
}

When a select needs additional context related to the user, additionalContent allows child elements to help. It is encouraged to use this prop with a Tooltip wrapping an IconButton.

By default, the child element will display inline with a Select label on the right.

When labelPosition is set to left, the label, select, and child elements all display inline.

If no label is required, use isLabelVisuallyHidden and the same inline layout will persist.

import React from 'react';
import {
Select,
LabelPosition,
Tooltip,
IconButton,
ButtonSize,
ButtonType,
ButtonVariant,
} from 'react-magma-dom';
import { HelpIcon } from 'react-magma-icons';
export function Example() {
const helpLinkLabel = 'Learn more';
const onHelpLinkClick = () => {
alert('Help link clicked!');
};
return (
<>
<Select
additionalContent={
<Tooltip content={helpLinkLabel}>
<IconButton
aria-label={helpLinkLabel}
icon={<HelpIcon />}
onClick={onHelpLinkClick}
type={ButtonType.button}
size={ButtonSize.small}
variant={ButtonVariant.link}
/>
</Tooltip>
}
labelText="Default positioning"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
/>
<br />
<Select
additionalContent={
<Tooltip content={helpLinkLabel}>
<IconButton
aria-label={helpLinkLabel}
icon={<HelpIcon />}
onClick={onHelpLinkClick}
type={ButtonType.button}
size={ButtonSize.small}
variant={ButtonVariant.link}
/>
</Tooltip>
}
labelPosition={LabelPosition.left}
labelText="Left positioning"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
/>
</>
);
}

Inverse

import React from 'react';
import { Select, Card, CardBody } from 'react-magma-dom';
export function Example() {
const [selectedItem, updateSelectedItem] = React.useState('');
function onSelectedItemChange(changes) {
updateSelectedItem(changes.selectedItem);
}
return (
<Card isInverse>
<CardBody>
<Select
id="basicSelectInverseId"
isInverse
labelText="Basic"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
selectedItem={selectedItem}
onSelectedItemChange={onSelectedItemChange}
/>
<Select
id="multiSelectInverseId"
isInverse
isMulti
labelText="Multi select"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
/>
</CardBody>
</Card>
);
}

Specific State Changes

You can track specific changes made to the internal state of the select using the following functions: onHighlightedIndexChange, onIsOpenChange, and onSelectedItemChange. Each of these functions will have a changes object as a parameter that includes the changes made to the corresponding state from each action.

import React from 'react';
import { Select } from 'react-magma-dom';
export function Example() {
const [highlightedIndexChangeCount, updateHighlightedIndexChangeCount] =
React.useState(0);
const [isOpenChangeCount, updateIsOpenChangeCount] = React.useState(0);
const [selectedItem, updateSelectedItem] = React.useState(undefined);
function onHighlightedIndexChange(changes) {
updateHighlightedIndexChangeCount(highlightedIndexChangeCount + 1);
}
function onIsOpenChange(changes) {
updateIsOpenChangeCount(isOpenChangeCount + 1);
}
function onSelectedItemChange(changes) {
updateSelectedItem(changes.selectedItem);
}
return (
<>
<strong>Selected Item: </strong>
<pre>{JSON.stringify(selectedItem, null, 2)}</pre>
<p>
<strong>Highlighted Index Change Count: </strong>
{highlightedIndexChangeCount}
</p>
<p>
<strong>Is Open Change Count: </strong>
{isOpenChangeCount}
</p>
<Select
id="stateChangesId1"
labelText="State changes"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
onHighlightedIndexChange={onHighlightedIndexChange}
onIsOpenChange={onIsOpenChange}
onSelectedItemChange={onSelectedItemChange}
/>
</>
);
}

Generic State Change

Using onStateChange and controlling every piece of state will result in losing most of the functionality that has been built in to this component. Only use this feature as a last resort.

onStateChange is called when any internal state is changed. Therefore, it is best used when using the select in a controlled state.

The onStateChange function passes a changes object that includes properties that have changed since the last state change. The changes object also includes a type property that describes the action taken to change the state. You can see the full list of the types in the stateChangeTypes section.

import React from 'react';
import { Select } from 'react-magma-dom';
export function Example() {
const [changes, updateChanges] = React.useState({});
const [highlightedIndex, updateHighlightedIndex] = React.useState(-1);
const [isOpen, updateIsOpen] = React.useState(false);
const [selectedItem, updateSelectedItem] = React.useState('');
function onStateChange(newChanges) {
const { type } = newChanges;
updateChanges(newChanges);
switch (type) {
case SelectStateChangeTypes.ToggleButtonClick:
updateIsOpen(!isOpen);
break;
case SelectStateChangeTypes.ToggleButtonKeyDownArrowDown:
updateIsOpen(newChanges.isOpen);
updateHighlightedIndex(newChanges.highlightedIndex);
break;
case SelectStateChangeTypes.ItemMouseMove:
case SelectStateChangeTypes.FunctionSetHighlightedIndex:
case SelectStateChangeTypes.MenuKeyDownArrowDown:
case SelectStateChangeTypes.MenuKeyDownArrowUp:
updateHighlightedIndex(newChanges.highlightedIndex);
break;
case SelectStateChangeTypes.MenuKeyDownEscape:
case SelectStateChangeTypes.MenuBlur:
updateIsOpen(false);
updateHighlightedIndex(newChanges.highlightedIndex);
break;
case SelectStateChangeTypes.ItemClick:
updateHighlightedIndex(newChanges.highlightedIndex);
updateIsOpen(newChanges.isOpen);
updateSelectedItem(newChanges.selectedItem);
break;
default:
break;
}
}
return (
<>
<pre>{JSON.stringify(changes, null, 2)}</pre>
<Select
id="stateChangesId2"
labelText="State changes"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
onStateChange={onStateChange}
highlightedIndex={highlightedIndex}
isOpen={isOpen}
selectedItem={selectedItem}
/>
</>
);
}

Controlled

If you wish to control the state rather than having it handled internally you can use the control props provided. These props are isOpen, selectedItem, and highlightedIndex. If you are using these control props you will have to use the handlers mentioned above in the State Changes section.

import React from 'react';
import { Select } from 'react-magma-dom';
export function Example() {
const [highlightedIndex, updateHighlightedIndex] = React.useState(0);
const [isOpen, updateIsOpen] = React.useState(false);
const [selectedItem, updateSelectedItem] = React.useState('');
function onHighlightedIndexChange(changes) {
updateHighlightedIndex(changes.highlightedIndex);
}
function onIsOpenChange(changes) {
updateIsOpen(changes.isOpen);
}
function onSelectedItemChange(changes) {
updateSelectedItem(changes.selectedItem);
}
return (
<>
<strong>Selected Item: </strong>
<pre>{JSON.stringify(selectedItem, null, 2)}</pre>
<p>
<strong>Highlighted Index: </strong>
{highlightedIndex}
</p>
<p>
<strong>Is Open: </strong>
{isOpen.toString()}
</p>
<Select
id="controlledId"
labelText="Controlled"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
isOpen={isOpen}
highlightedIndex={highlightedIndex}
selectedItem={selectedItem}
onHighlightedIndexChange={onHighlightedIndexChange}
onIsOpenChange={onIsOpenChange}
onSelectedItemChange={onSelectedItemChange}
/>
</>
);
}

Accessibility

The getA11yStatusMessage prop is a passed in function that allows for customization of the screen-reader accessible message whenever the following props are changed: items, highlightedIndex, inputValue or isOpen.

The getA11ySelectionMessage prop is a passed in function that allows for customization of the screen-reader accessible message whenever an item has been selected.

For both the getA11yStatusMessage and getA11ySelectionMessage functions there is an object passed with internal state data.

import React from 'react';
import { Select } from 'react-magma-dom';
export function Example() {
return (
<>
<Select
id="newA11yStatusMessageId"
labelText="New accessibility status message"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
getA11yStatusMessage={({ highlightedItem }) =>
`custom message saying that ${highlightedItem} is highlighted`
}
getA11ySelectionMessage={({ selectedItem }) =>
`custom message saying that ${selectedItem} is now selected`
}
/>
</>
);
}

Internationalization

Some of the internationalization overrides use placeholders to insert selected values in to the message. Placeholders are specific keywords surrounded by curly braces.

  • {labelText} will be replaced with the comboboxes labelText.
  • {selectedItem} will be replaced by the current itemToString representation of the selectedItem of the select.

Full example of internationalization override options

import React from 'react';
import { Select, I18nContext, defaultI18n } from 'react-magma-dom';
export function Example() {
return (
<I18nContext.Provider
value={{
...defaultI18n,
select: {
...defaultI18n.select,
placeholder: 'Custom Select Placeholder...',
clearIndicatorAriaLabel:
'Click to reset selection for {labelText}. {selectedItem} is currently selected',
},
multiSelect: {
...defaultI18n.multiSelect,
selectedItemButtonAriaLabel:
'Click to reset the selected item {selectedItem}',
},
}}
>
<Select
labelText="Internationalization"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
initialSelectedItem={{ label: 'Red', value: 'red' }}
isClearable
/>
<Select
labelText="Multi internationalization"
isMulti
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
initialSelectedItems={[{ label: 'Red', value: 'red' }]}
/>
</I18nContext.Provider>
);
}

Events

import React from 'react';
import { Select } from 'react-magma-dom';
export function Example() {
const [currentSelectEvent, updateCurrentSelectEvent] =
React.useState(undefined);
function handleSelectBlur(event) {
updateCurrentSelectEvent('Blur');
}
function handleSelectFocus(event) {
updateCurrentSelectEvent('Focus');
}
function handleSelectKeyPress(event) {
updateCurrentSelectEvent('KeyPress');
}
return (
<>
<p>
<strong>{currentSelectEvent || 'No'} event was triggered</strong>
</p>
<Select
id="selectFocusEventId"
labelText="Select focus events"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
onBlur={handleSelectBlur}
onFocus={handleSelectFocus}
onKeyPress={handleSelectKeyPress}
/>
</>
);
}

Custom Items List Height

The items list menu has a default max height that can be changed in the theme or using the itemListMaxHeight prop.

import React from 'react';
import { Select } from 'react-magma-dom';
export function Example() {
return (
<Select
labelText="Select small item list menu"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
itemListMaxHeight="50px"
/>
);
}

Custom Items

By default each component accepts an array of items with either a string or an object with the shape {item: string; label: string;} for each item. If you need to pass in a custom shape for your items you can pass in an additional prop named itemToString which is a function that returns the string representation of your item which will be applied as the label.

WARNING Your function must include a null check.

If you are using a custom shape for your items in a typescript project refer to our example of using your custom type.

import React from 'react';
import { Select } from 'react-magma-dom';
export function Example() {
function itemToString(item) {
return item ? `${item.representation} (${item.hex})` : '';
}
return (
<>
<Select
id="itemToStringId"
labelText="Item to string"
items={[
{
id: 1,
actual: 'red',
representation: 'Red',
hex: '#FF0000',
},
{
id: 2,
actual: 'blue',
representation: 'Blue',
hex: '#0000FF',
},
{
id: 3,
actual: 'green',
representation: 'Green',
hex: '#008000',
},
]}
itemToString={itemToString}
/>
</>
);
}

Custom Items Typescript

When using a custom shape for your items in a typescript project you will need to provide the Select element with the shape of the items you are passing in.

import React from 'react';
import { Select } from 'react-magma-dom';
export function Example() {
interface CustomSelectItem {
id: number;
actual: string;
representation: string;
hex?: string;
}
const customItems: CustomSelectItem[] = [
{
id: 1,
actual: 'red',
representation: 'Red',
hex: '#FF0000',
},
{
id: 2,
actual: 'blue',
representation: 'Blue',
hex: '#0000FF',
},
{
id: 3,
actual: 'green',
representation: 'Green',
hex: '#008000',
},
];
function itemToString(item: CustomSelectItem) {
return item ? `${item.representation} (${item.hex})` : '';
}
return (
<>
<Select<CustomSelectItem>
id="customItemToStringTypescriptId"
labelText="Custom items with typescript"
items={customItems}
itemToString={itemToString}
/>
</>
);
}

Custom Styles

Custom styles can be passed into the Select component. The containerStyle property will apply to the container. Additional labelStyle, inputStyle and messageStyle properties are available to style the respective elements. Please use discretion when adding custom styles.

import React from 'react';
import { Select } from 'react-magma-dom';
export function Example() {
const [selectedItem, updateSelectedItem] = React.useState('');
function onSelectedItemChange(changes) {
updateSelectedItem(changes.selectedItem);
}
return (
<>
<Select
containerStyle={{ marginBottom: '32px' }}
helperMessage="Helper message"
inputStyle={{ border: '2px dotted green', width: '200px' }}
items={['Red', 'Blue', 'Green']}
labelStyle={{ fontStyle: 'italic' }}
labelText="Basic with custom styles"
messageStyle={{ border: '1px solid blue' }}
selectedItem={selectedItem}
onSelectedItemChange={onSelectedItemChange}
/>
<Select
containerStyle={{ marginBottom: '32px' }}
helperMessage="Helper message"
inputStyle={{ border: '2px dotted green', width: '200px' }}
isMulti
items={['Red', 'Blue', 'Green']}
labelStyle={{ fontStyle: 'italic' }}
labelText="Multi with custom styles"
messageStyle={{ border: '1px solid blue' }}
selectedItem={selectedItem}
onSelectedItemChange={onSelectedItemChange}
/>
</>
);
}

Custom Item Component

By default each item will be rendered with the itemToString value in a styled li. If you would like to add more information or would just like to be able to fully customize the look of your items you can pass in an Item component that uses the props that we use internally.

Be aware. You must pass a ref to your custom item component to make sure the functionality of the entire Select continues to work.
import React from 'react';
import styled from '@emotion/styled';
import { Select } from 'react-magma-dom';
export function Example() {
const CustomStyledItem = styled.li(props => ({
alignSelf: 'center',
background: props.isFocused ? props.theme.colors.neutral200 : 'transparent',
lineHeight: '24px',
margin: '0',
padding: '8px 16px',
}));
const ContainerSpan = styled.span(props => ({
display: 'flex',
alignItems: 'center',
}));
const Hex = styled.span(props => ({
background: props.color,
border: `2px solid ${props.theme.colors.neutral}`,
borderRadius: props.theme.borderRadius,
display: 'inline-flex',
height: '16px',
marginRight: '4px',
width: '16px',
}));
const Description = styled.div(props => ({
fontSize: '12px',
color: props.theme.colors.neutral,
}));
function itemToString(item) {
return item ? item.representation : '';
}
const CustomItem = props => {
const { itemRef, itemString, item, ...other } = props;
return (
<CustomStyledItem {...other} ref={itemRef}>
<ContainerSpan>
<Hex color={item.hex} theme={props.theme} />
{itemString}
</ContainerSpan>
<Description theme={props.theme}>{item.description}</Description>
</CustomStyledItem>
);
};
return (
<Select
components={{ Item: CustomItem }}
labelText="Select with custom item render"
items={[
{
id: 0,
name: 'red',
representation: 'Red',
hex: '#FF0000',
description: 'The color of roses',
},
{
id: 1,
name: 'blue',
representation: 'Blue',
hex: '#0000FF',
description: 'The color of blueberries',
},
{
id: 2,
name: 'green',
representation: 'Green',
hex: '#008000',
description: 'The color of grass',
},
]}
itemToString={itemToString}
/>
);
}

Custom Components

Out of the box, the Select component uses React Magma-styled iconography for the button used to clear the selection and the caret for the dropdown. However, these can be overridden by providing custom components to the components prop, in an object containing a ClearIndicator and a DropdownIndicator.

import React from 'react';
import { Select } from 'react-magma-dom';
export function Example() {
return (
<Select
id="customComponentsId"
labelText="Custom components"
items={[
{ label: 'Red', value: 'red' },
{ label: 'Blue', value: 'blue' },
{ label: 'Green', value: 'green' },
]}
initialSelectedItem={{ label: 'Green', value: 'green' }}
isClearable
components={{
ClearIndicator: props => <button onClick={props.onClick}>Clear</button>,
DropdownIndicator: () => (
<span style={{ border: '1px solid' }}>Dropdown</span>
),
}}
/>
);
}

State Change Types

The type property in the changes object that is returned from the onStateChange function corresponds to a stateChangeTypes property. The list of all the possible types for a select or a multi-select are listed below.

In the development environment these types equate to strings
(eg: ComboboxStateChangeTypes.InputKeyDownArrowDown = '__input_keydown_arrow_down__'). However, in the production environment the types equate to numbers
(eg: ComboboxStateChangeTypes.InputKeyDownArrowDown = 0).

Select

  • SelectStateChangeTypes.MenuKeyDownArrowDown
  • SelectStateChangeTypes.MenuKeyDownArrowUp
  • SelectStateChangeTypes.MenuKeyDownEscape
  • SelectStateChangeTypes.MenuKeyDownHome
  • SelectStateChangeTypes.MenuKeyDownEnd
  • SelectStateChangeTypes.MenuKeyDownEnter
  • SelectStateChangeTypes.MenuKeyDownSpaceButton
  • SelectStateChangeTypes.MenuKeyDownCharacter
  • SelectStateChangeTypes.MenuBlur
  • SelectStateChangeTypes.MenuMouseLeave
  • SelectStateChangeTypes.ItemMouseMove
  • SelectStateChangeTypes.ItemClick
  • SelectStateChangeTypes.ToggleButtonKeyDownCharacter
  • SelectStateChangeTypes.ToggleButtonKeyDownArrowDown
  • SelectStateChangeTypes.ToggleButtonKeyDownArrowUp
  • SelectStateChangeTypes.ToggleButtonClick
  • SelectStateChangeTypes.FunctionToggleMenu
  • SelectStateChangeTypes.FunctionOpenMenu
  • SelectStateChangeTypes.FunctionCloseMenu
  • SelectStateChangeTypes.FunctionSetHighlightedIndex
  • SelectStateChangeTypes.FunctionSelectItem
  • SelectStateChangeTypes.FunctionSetInputValue
  • SelectStateChangeTypes.FunctionReset

MultiSelect

  • MultipleSelectionStateChangeTypes.SelectedItemClick
  • MultipleSelectionStateChangeTypes.SelectedItemKeyDownDelete
  • MultipleSelectionStateChangeTypes.SelectedItemKeyDownBackspace
  • MultipleSelectionStateChangeTypes.SelectedItemKeyDownNavigationNext
  • MultipleSelectionStateChangeTypes.SelectedItemKeyDownNavigationPrevious
  • MultipleSelectionStateChangeTypes.DropdownKeyDownNavigationPrevious
  • MultipleSelectionStateChangeTypes.DropdownKeyDownBackspace
  • MultipleSelectionStateChangeTypes.DropdownClick
  • MultipleSelectionStateChangeTypes.FunctionAddSelectedItem
  • MultipleSelectionStateChangeTypes.FunctionRemoveSelectedItem
  • MultipleSelectionStateChangeTypes.FunctionSetSelectedItems
  • MultipleSelectionStateChangeTypes.FunctionSetActiveIndex
  • MultipleSelectionStateChangeTypes.FunctionReset

Select Props

additionalContent

Description

Content above the select. For use with Icon Buttons to relay information.

Type

React.ReactNode

Default

-


ariaDescribedBy

Description

Id of the element that describes the select trigger button

Type

string

Default

-


circularNavigation

Type

boolean

Default

-


components

Description

This complex object includes all the compositional components that are used. If you wish to overwrite a component, pass in a component to the appropriate namespace

Type

SelectComponents

Default

-


containerStyle

Description

Style properties for the component container

Type

CSSProperties

Default

-


defaultHighlightedIndex

Type

number

Default

-


defaultIsOpen

Type

boolean

Default

-


defaultSelectedItem

Type

Generic

Default

-


disabled

Description

If true, item will be disabled; it will appear dimmed and events will not fire

Type

boolean

Default

false


environment

Type

Environment

Default

-


errorMessage

Description

Content of the error message. If a value is provided, the component will be styled to show an error state

Type

React.ReactNode

Default

-


getA11ySelectionMessage

Type

function

Default

-


getA11yStatusMessage

Type

function

Default

-


getItemId

Type

function

Default

-


helperMessage

Description

Content of the helper message

Type

React.ReactNode

Default

-


highlightedIndex

Type

number

Default

-


id

Type

string

Default

-


initialHighlightedIndex

Description

Index of the item that should be highlighted by default. Use this prop when you want to set a specific item on the list to be highlighted when the component is first rendered.

Type

number

Default

-


initialIsOpen

Type

boolean

Default

-


initialSelectedItem

Type

Generic

Default

-


innerRef

Description

Reference to the trigger button element in the select

Type

React.Ref

Default

-


inputStyle

Description

Style properties for the select trigger or combobox input

Type

CSSProperties

Default

-


isClearable

Description

If true, the component include a button for clearing the field

Type

boolean

Default

false


isInverse

Description

If true, the component will have inverse styling to better appear on a dark background

Type

boolean

Default

false


isLabelVisuallyHidden

Description

If true, label text will be hidden visually, but will still be read by assistive technology

Type

boolean

Default

false


isOpen

Type

boolean

Default

-


itemListMaxHeight

Description

Max-height for the item menu list ul element

Type

number | string

Default

-


itemToString

Type

function

Default

-


items

Required

Type

Generic[]

Default

-


labelId

Type

string

Default

-


labelPosition

Description

Position of text label relative to form field

Type

enum, one of:
LabelPosition.left
LabelPosition.top

Default

-


labelStyle

Description

Style properties for the label

Type

CSSProperties

Default

-


labelText

Required

Description

Text for label

Type

string

Default

-


labelWidth

Description

If the labelPosition value is 'left' then Input labels have a specified width in percentage, otherwise no width is set.

Type

number

Default

-


menuId

Type

string

Default

-


menuStyle

Description

Style properties for the items menu

Type

CSSProperties

Default

-


messageStyle

Description

Style properties for the helper or error message

Type

CSSProperties

Default

-


onBlur

Description

Event that fires when the trigger button loses focus

Type

function

Default

-


onFocus

Description

Event that fires when the trigger button gains focus

Type

function

Default

-


onHighlightedIndexChange

Type

function

Default

-


onIsOpenChange

Type

function

Default

-


onKeyDown

Description

Event that fires when the trigger button receives keypress

Type

function

Default

-


onKeyPress

Description

Event that will fire when a character is typed while focused on the trigger button

Type

function

Default

-


onKeyUp

Description

Event that will fire when a keypress is released while focused on the trigger button

Type

function

Default

-


onSelectedItemChange

Type

function

Default

-


onStateChange

Type

function

Default

-


placeholder

Description

Text for select trigger button or combobox input placeholder

Type

string

Default

-


scrollIntoView

Type

function

Default

-


selectedItem

Type

Generic

Default

-


stateReducer

Type

function

Default

-


toggleButtonId

Type

string

Default

-


On this page

Deploys by Netlify