Select
Select allows users to choose one option from a list of items in a Menu.
Component Type
Input
Platform
Web
Component
Sana Canvas
Delivery Channels
Web
Version
16.1.7Experience Surfaces
Page Body Inline
Anatomy

- Label: Title of the input.
- Input Container: Rectangular container that houses the icon and placeholder text.
- Placeholder Text (Optional): Placeholder text like “Select One” is typically displayed in the Select field. After the user makes a selection, the placeholder text is replaced with the user’s selection.
- Icon: Caret icon positioned to the right of the container visually distinguishes this as a Select input.
Usage Guidance
- Clicking or tapping anywhere in a Select opens the Menu.
- A checkmark icon indicates which value is currently selected in the list.
- Each Menu option should be distinct. If the option isn’t discrete, combine it with another option.
- The list of Menu options should be sorted in a logical order alphabetically, chronologically, or by order of importance.
When to Use
- Use Select as a form element where users are only allowed to select one item from a list of more than 7 predefined options.
- Typically, Selects work best when the list is between 7 to 15 items to prevent overwhelming the user with too many options.
When to Use Something Else
- Consider using a Switch if the only options are yes or no.
- For a list between 2 to 7 predefined options, consider using Radio Buttons to select one option or Checkboxes to select multiple options. Radio and Checkbox groups display all options upfront and do not require the user to interact with the input to view the list of options.
- Use a Prompt when the number of list items is large or unknown. Prompts have search capabilities and folders which provide users with the means to browse options. Prompts can be configured to support single or multi-select.
Examples
Basic Example
Select supports a dynamic API
where you pass an array of items via the items prop and provide a render function to display the
items. The items may be provided as an
array of strings or an
array of objects.
Select should be used in tandem with Form Field to ensure proper
label association and screen reader support. Wrap Select with FormField, and compose
FormField.Input as={Select.Input} so the combobox receives the field label. Include
Select.Popper, Select.Card, Select.List, and Select.Item.
import React from 'react';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {Flex} from '@workday/canvas-kit-react/layout';
import {Select} from '@workday/canvas-kit-react/select';
import {createStyles} from '@workday/canvas-kit-styling';
const parentContainerStyles = createStyles({
flexDirection: 'column',
});
const options = [
'E-mail',
'Phone',
'Fax',
'Mail',
'Mobile Phone',
'The Ontologically Anthropocentric Sensory Immersive Simulation',
'Thisisalongstringwithnobreaksandwillwrap',
];
export default () => {
const [value, setValue] = React.useState('');
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
console.log('change', event.currentTarget.value);
setValue(event.target.value);
};
return (
<Flex cs={parentContainerStyles}>
<FormField>
<FormField.Label>Contact</FormField.Label>
<FormField.Field>
<Select items={options}>
<FormField.Input as={Select.Input} onChange={handleChange} />
<Select.Popper>
<Select.Card>
<Select.List>
{item => {
return <Select.Item>{item}</Select.Item>;
}}
</Select.List>
</Select.Card>
</Select.Popper>
</Select>
</FormField.Field>
</FormField>
Selected Value: {value}
</Flex>
);
};
Our example uses React state to track the
value of the Select.
Hoisted Model
By default, Select will create and use its own model internally. Alternatively, you may configure
your own model with useSelectModel and pass it to Select via the model prop. This pattern is
referred to as
hoisting the model
and provides direct access to its state and events outside of the Select component.
In this example, we set up external observation of the model state and create an external button to trigger an event to change the selected item.
Note: If your array of objects uses an id property and a text property there is no need to use
the helper functions of getId or getTextValue. The collection system and the Select use these
properties by default for keyboard navigation and selected the id based on the item clicked.
Selected Value: fax-3
import React from 'react';
import {SecondaryButton} from '@workday/canvas-kit-react/button';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {Select, useSelectModel} from '@workday/canvas-kit-react/select';
import {BodyText} from '@workday/canvas-kit-react/text';
const options = [
{text: 'E-mail', id: 'email-1'},
{text: 'Phone', id: 'phone-2'},
{text: 'Fax', id: 'fax-3'},
{text: 'Mail', id: 'mail-4'},
{text: 'Mobile Phone', id: 'mobile-phone-5'},
];
export default () => {
const model = useSelectModel({
items: options,
initialSelectedIds: ['fax-3'],
});
return (
<>
<FormField>
<FormField.Label>Contact</FormField.Label>
<FormField.Field>
<Select model={model}>
<FormField.Input as={Select.Input} />
<Select.Popper>
<Select.Card>
<Select.List>{item => <Select.Item>{item.text}</Select.Item>}</Select.List>
</Select.Card>
</Select.Popper>
</Select>
</FormField.Field>
</FormField>
<BodyText size="small">Selected Value: {model.state.selectedIds[0]}</BodyText>
<SecondaryButton
onClick={() => {
model.events.select({id: 'phone-2'});
}}
>
Select Phone Item
</SecondaryButton>
</>
);
};
Label Position Horizontal
Set the orientation prop of the Form Field to designate the position of the label relative to the
input component. By default, the orientation will be set to vertical.
Choose a form of contact
import React from 'react';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {Flex} from '@workday/canvas-kit-react/layout';
import {Select, useSelectModel} from '@workday/canvas-kit-react/select';
const options = [
'E-mail',
'Phone',
'Fax',
'Mail',
'Mobile Phone',
'The Ontologically Anthropocentric Sensory Immersive Simulation',
];
export default () => {
const model = useSelectModel({
items: options,
});
return (
<Flex>
<FormField orientation="horizontalStart">
<FormField.Label>Contact</FormField.Label>
<FormField.Field>
<Select model={model}>
<FormField.Input as={Select.Input} />
<Select.Popper>
<Select.Card>
<Select.List>{item => <Select.Item>{item}</Select.Item>}</Select.List>
</Select.Card>
</Select.Popper>
<FormField.Hint>Choose a form of contact</FormField.Hint>
</Select>
</FormField.Field>
</FormField>
</Flex>
);
};
Required
Set the isRequired prop of the wrapping FormField to true to indicate that the field is
required. Labels for required fields are suffixed by a red asterisk.
import React from 'react';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {Flex} from '@workday/canvas-kit-react/layout';
import {Select} from '@workday/canvas-kit-react/select';
import {createStyles} from '@workday/canvas-kit-styling';
const parentContainerStyles = createStyles({
flexDirection: 'column',
});
const options = [
'E-mail',
'Phone',
'Fax',
'Mail',
'Mobile Phone',
'The Ontologically Anthropocentric Sensory Immersive Simulation',
];
export default () => {
const [value, setValue] = React.useState('');
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value);
};
return (
<Flex cs={parentContainerStyles}>
<FormField isRequired>
<FormField.Label>Contact</FormField.Label>
<FormField.Field>
<Select items={options}>
<FormField.Input as={Select.Input} onChange={e => handleChange(e)} />
<Select.Popper>
<Select.Card>
<Select.List>{item => <Select.Item>{item}</Select.Item>}</Select.List>
</Select.Card>
</Select.Popper>
</Select>
</FormField.Field>
</FormField>
Selected Value: {value}
</Flex>
);
};
Disabled
Set the disabled prop on FormField.Input as={Select.Input} to prevent users from interacting
with the combobox.
import React from 'react';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {Flex} from '@workday/canvas-kit-react/layout';
import {Select} from '@workday/canvas-kit-react/select';
import {createStyles} from '@workday/canvas-kit-styling';
const parentContainerStyles = createStyles({
flexDirection: 'column',
});
const options = [
'E-mail',
'Phone',
'Fax (disabled)',
'Mail',
'Mobile Phone',
'The Ontologically Anthropocentric Sensory Immersive Simulation',
];
export default () => {
const [_, setValue] = React.useState('');
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value);
};
return (
<Flex cs={parentContainerStyles}>
<FormField>
<FormField.Label>Contact</FormField.Label>
<FormField.Field>
<Select items={options} nonInteractiveIds={['Fax (disabled)']}>
<FormField.Input as={Select.Input} disabled onChange={e => handleChange(e)} />
<Select.Popper>
<Select.Card>
<Select.List>
{item => (
<Select.Item aria-disabled={item === 'Fax (disabled)' ? true : undefined}>
{item}
</Select.Item>
)}
</Select.List>
</Select.Card>
</Select.Popper>
</Select>
</FormField.Field>
</FormField>
</Flex>
);
};
Disabled Items
In order to disable items and prevent users from interacting with them:
-
Set the
nonInteractiveIdsprop ofSelectto an array of disabled itemids. If your items are an array ofstringsthis will be just the text value. If your items are an array ofobjects, this will be that value of theidproperty. This will disable interaction for those items and exclude them from type-ahead. -
Set the
aria-disabledattribute of all disabledSelect.Items totrue. This ensures the items are styled as disabled.
The following example adds the string value of the items we want disable to nonInteractiveIds and
sets aria-disabled for the disabled items.
import React from 'react';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {Flex} from '@workday/canvas-kit-react/layout';
import {Select} from '@workday/canvas-kit-react/select';
import {createStyles} from '@workday/canvas-kit-styling';
const parentContainerStyles = createStyles({
flexDirection: 'column',
});
const options = [
'E-mail',
'Phone',
'Fax (disabled)',
'Mail',
'Mobile Phone',
'The Ontologically Anthropocentric Sensory Immersive Simulation',
];
export default () => {
const [value, setValue] = React.useState('');
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value);
};
return (
<Flex cs={parentContainerStyles}>
<FormField>
<FormField.Label>Contact</FormField.Label>
<FormField.Field>
<Select items={options} nonInteractiveIds={['Fax (disabled)', 'Mobile Phone']}>
<FormField.Input as={Select.Input} onChange={e => handleChange(e)} />
<Select.Popper>
<Select.Card>
<Select.List>
{item => (
<Select.Item
aria-disabled={
item === 'Mobile Phone' || item === 'Fax (disabled)' ? true : undefined
}
>
{item}
</Select.Item>
)}
</Select.List>
</Select.Card>
</Select.Popper>
</Select>
</FormField.Field>
</FormField>
Selected Value: {value}
</Flex>
);
};
With Icons
Use Select.Item.Icon to render an icon for a Select.Item. The icon prop for Select.Item.Icon
accepts system icons from @workday/canvas-system-icons-web.
In order to render the icon for the selected item on FormField.Input as={Select.Input}:
- Obtain a reference to the
modelby registering youritemswithuseSelectModel. - Get the selected item:
const selectedItem = model.navigation.getItem(model.state.selectedIds[0], model) - Pass the icon for the selected item to the input:
<FormField.Input as={Select.Input} inputStartIcon={selectedItem?.value.icon} />
Note: Dynamic
{item => <Select.Item>}registration already uses the collectionid. Setdata-idonly on staticSelect.Itemchildren (see Grouped Items), and keep it equal to that id (idorgetId).
import React from 'react';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {Flex} from '@workday/canvas-kit-react/layout';
import {Select, useSelectModel} from '@workday/canvas-kit-react/select';
import {createStyles, px2rem} from '@workday/canvas-kit-styling';
import {cloudArrowUpIcon, cloudIcon, commentIcon, userIcon} from '@workday/canvas-system-icons-web';
const styleOverrides = {
formfieldInputStyles: createStyles({
width: px2rem(300),
}),
selectCardStyles: createStyles({
maxHeight: px2rem(200),
}),
};
const customOptions = [
{text: 'Activity Stream', id: 'activity-stream', icon: commentIcon},
{text: 'Avatar', id: 'avatar', icon: cloudIcon},
{text: 'Upload Cloud', id: 'upload-cloud', icon: cloudArrowUpIcon},
{text: 'User', id: 'user', icon: userIcon},
];
export default () => {
const model = useSelectModel({
items: customOptions,
});
const selectedItem = model.navigation.getItem(model.state.selectedIds[0], model);
return (
<Flex>
<FormField>
<FormField.Label>Contact</FormField.Label>
<FormField.Field>
<Select model={model}>
<FormField.Input
as={Select.Input}
cs={styleOverrides.formfieldInputStyles}
inputStartIcon={selectedItem?.value.icon}
/>
<Select.Popper>
<Select.Card cs={styleOverrides.selectCardStyles}>
{model.state.items.length > 0 && (
<Select.List>
{item => (
<Select.Item>
<Select.Item.Icon icon={item.icon} />
{item.text}
</Select.Item>
)}
</Select.List>
)}
</Select.Card>
</Select.Popper>
</Select>
</FormField.Field>
</FormField>
</Flex>
);
};
Note: that FormField.Input as={Select.Input} will only render an icon if an item is selected.
Grow
Set the grow prop of the wrapping FormField to true to configure the Select.Input to expand
to the width of its container.
import React from 'react';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {Flex} from '@workday/canvas-kit-react/layout';
import {Select, useSelectModel} from '@workday/canvas-kit-react/select';
const options = [
'E-mail',
'Phone',
'Fax',
'Mail',
'Mobile Phone',
'The Ontologically Anthropocentric Sensory Immersive Simulation',
];
export default () => {
const model = useSelectModel({
items: options,
});
return (
<Flex>
<FormField grow>
<FormField.Label>Contact</FormField.Label>
<FormField.Field>
<Select model={model}>
<FormField.Input as={Select.Input} />
<Select.Popper>
<Select.Card>
<Select.List>{item => <Select.Item>{item}</Select.Item>}</Select.List>
</Select.Card>
</Select.Popper>
</Select>
</FormField.Field>
</FormField>
</Flex>
);
};
Menu Height
Select.Card has a default maximum height of 300px to restrict the height of the dropdown menu.
Set its maxHeight prop to override this value.
import {FormField} from '@workday/canvas-kit-react/form-field';
import {Box} from '@workday/canvas-kit-react/layout';
import {Select} from '@workday/canvas-kit-react/select';
import {createStyles, px2rem} from '@workday/canvas-kit-styling';
const selectCardStyles = createStyles({
maxHeight: px2rem(200),
});
const cities = [
'Atlanta (United States)',
'Amsterdam (Europe)',
'Austin (United States)',
'Beaverton (United States)',
'Belfast (Europe)',
'Berlin (Europe)',
'Boston (United States)',
'Boulder (United States)',
'Chicago (United States)',
'Dallas (United States)',
'Denver (United States)',
'Dublin (Europe)',
'Irvine (United States)',
'Minneapolis (United States)',
'New York (United States)',
'Orlando (United States)',
'Palo Alto (United States)',
'Philadelphia (United States)',
'Pleasanton (United States)',
'Raleigh (United States)',
'San Francisco (United States)',
'San Mateo (United States)',
'Stockholm (Europe)',
'Toronto (Canada)',
'Victoria (Canada)',
'Vienna (Europe)',
'Warsaw (Europe)',
'Washington, DC (United States)',
'Zurich (Europe)',
];
export default () => {
return (
<Box>
<FormField>
<FormField.Label>Choose a City</FormField.Label>
<FormField.Field>
<Select items={cities}>
<FormField.Input as={Select.Input} />
<Select.Popper>
<Select.Card cs={selectCardStyles}>
<Select.List>{item => <Select.Item>{item}</Select.Item>}</Select.List>
</Select.Card>
</Select.Popper>
</Select>
</FormField.Field>
</FormField>
</Box>
);
};
Ref Forwarding
Select.Input supports ref forwarding . It will
forward ref to its underlying <input type="text" role="combobox"> element.
import React from 'react';
import {PrimaryButton} from '@workday/canvas-kit-react/button';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {Select} from '@workday/canvas-kit-react/select';
const options = [
'E-mail',
'Phone',
'Fax',
'Mail',
'Mobile Phone',
'The Ontologically Anthropocentric Sensory Immersive Simulation',
];
export default () => {
// @ts-ignore
const [value, setValue] = React.useState('medium');
const ref = React.useRef(null);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value);
};
const handleClick = () => {
if (ref && ref.current) {
console.log(ref);
ref.current.focus();
}
};
return (
<>
<FormField>
<FormField.Label>Contact</FormField.Label>
<FormField.Field>
<Select items={options}>
<FormField.Input as={Select.Input} ref={ref} onChange={e => handleChange(e)} />
<Select.Popper>
<Select.Card>
<Select.List>{item => <Select.Item>{item}</Select.Item>}</Select.List>
</Select.Card>
</Select.Popper>
</Select>
</FormField.Field>
</FormField>
<PrimaryButton onClick={handleClick}>Focus Select</PrimaryButton>
</>
);
};
Error States
Form Field provides error and caution states for Select. Set the error prop on Form Field to
"error" or "caution" and use FormField.Hint to provide messages. See
Form Field’s Error documentation for examples and
accessibility guidance.
Caution
Use the alert state when a selection is valid but there is additional information.
Please choose a form of contact.
import React from 'react';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {Flex} from '@workday/canvas-kit-react/layout';
import {Select} from '@workday/canvas-kit-react/select';
import {createStyles} from '@workday/canvas-kit-styling';
const parentContainerStyles = createStyles({
flexDirection: 'column',
});
const options = [
'E-mail',
'Phone',
'Fax',
'Mail',
'Mobile Phone',
'The Ontologically Anthropocentric Sensory Immersive Simulation',
];
export default () => {
const [value, setValue] = React.useState('');
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value);
};
return (
<Flex cs={parentContainerStyles}>
<FormField error="caution">
<FormField.Label>Contact</FormField.Label>
<FormField.Field>
<Select items={options}>
<FormField.Input as={Select.Input} onChange={e => handleChange(e)} id="alert-select" />
<Select.Popper>
<Select.Card>
<Select.List>{item => <Select.Item>{item}</Select.Item>}</Select.List>
</Select.Card>
</Select.Popper>
<FormField.Hint>Please choose a form of contact.</FormField.Hint>
</Select>
</FormField.Field>
</FormField>
Selected value: {value}
</Flex>
);
};
Error
Use the error state when the selection is no longer valid.
Fax is disabled. Please choose a different option.
import React from 'react';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {Flex} from '@workday/canvas-kit-react/layout';
import {Select} from '@workday/canvas-kit-react/select';
import {createStyles} from '@workday/canvas-kit-styling';
const parentContainerStyles = createStyles({
flexDirection: 'column',
});
const options = [
'E-mail',
'Phone',
'Fax (disabled)',
'Mail',
'Mobile Phone',
'The Ontologically Anthropocentric Sensory Immersive Simulation',
];
export default () => {
const [value, setValue] = React.useState('');
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value);
};
return (
<Flex cs={parentContainerStyles}>
<FormField error="error">
<FormField.Label>Contact</FormField.Label>
<FormField.Field>
<Select items={options} nonInteractiveIds={['Fax (disabled)']}>
<FormField.Input as={Select.Input} onChange={e => handleChange(e)} />
<Select.Popper>
<Select.Card>
<Select.List>
{item => (
<Select.Item aria-disabled={item === 'Fax (disabled)' ? true : undefined}>
{item}
</Select.Item>
)}
</Select.List>
</Select.Card>
</Select.Popper>
<FormField.Hint>Fax is disabled. Please choose a different option.</FormField.Hint>
</Select>
</FormField.Field>
</FormField>
Selected Value: {value}
</Flex>
);
};
Initial Selected Item
You can set initialSelectedIds to the value that you want initially selected.
Id: da594226446c11de98360015c5e6daf6
Value: English (United States)
import React from 'react';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {Flex} from '@workday/canvas-kit-react/layout';
import {Select} from '@workday/canvas-kit-react/select';
import {createStyles} from '@workday/canvas-kit-styling';
const parentContainerStyles = createStyles({
flexDirection: 'column',
});
const options = [
{
id: 'b310c757b2d341f99d40d76f4d563c5b',
descriptor: 'Arabic',
languageCode: 'ar',
label: 'Arabic',
nativeLanguageName: 'العربية',
},
{
id: 'a675a6b6e22d100017d7fe2a784d1255',
descriptor: 'Bulgarian (Bulgaria)',
languageCode: 'bg_BG',
label: 'Bulgarian (Bulgaria)',
nativeLanguageName: 'български (Република България)',
},
{
id: 'da594226446c11de98360015c5e6daf6',
descriptor: 'English (United States)',
languageCode: 'en_US',
label: 'English (United States)',
nativeLanguageName: 'English',
},
];
export default () => {
const [value, setValue] = React.useState('English (United States)');
const [id, setId] = React.useState('da594226446c11de98360015c5e6daf6');
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setId(event.target.value);
setValue(options.find(item => item.id === event.target.value).label);
};
return (
<Flex cs={parentContainerStyles}>
<FormField>
<FormField.Label>Contact</FormField.Label>
<FormField.Field>
<Select
items={options}
initialSelectedIds={['da594226446c11de98360015c5e6daf6']}
getId={item => item.id}
getTextValue={item => item.label}
>
<Select.Input onChange={e => handleChange(e)} />
<Select.Popper>
<Select.Card>
<Select.List>{item => <Select.Item>{item.label}</Select.Item>}</Select.List>
</Select.Card>
</Select.Popper>
</Select>
</FormField.Field>
</FormField>
<p>Id: {id}</p>
<p>Value: {value}</p>
</Flex>
);
};
Placeholder
You can change the placeholder text by passing a string to the placeholder prop on
FormField.Input as={Select.Input}. Placeholder text is not a substitute for
FormField.Label.
import React from 'react';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {Flex} from '@workday/canvas-kit-react/layout';
import {Select} from '@workday/canvas-kit-react/select';
import {createStyles} from '@workday/canvas-kit-styling';
const parentContainerStyles = createStyles({
flexDirection: 'column',
});
const options = [
'E-mail',
'Phone',
'Fax',
'Mail',
'Mobile Phone',
'The Ontologically Anthropocentric Sensory Immersive Simulation',
];
export default () => {
const [value, setValue] = React.useState('');
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value);
};
return (
<Flex cs={parentContainerStyles}>
<FormField>
<FormField.Label>Contact</FormField.Label>
<FormField.Field>
<Select items={options}>
<Select.Input placeholder="Make a Selection" onChange={e => handleChange(e)} />
<Select.Popper>
<Select.Card>
<Select.List>
{item => {
return <Select.Item>{item}</Select.Item>;
}}
</Select.List>
</Select.Card>
</Select.Popper>
</Select>
</FormField.Field>
</FormField>
Selected Value: {value}
</Flex>
);
};
Fetching Dynamic Items
It’s common to load items from a server call. Hoisting the model and setting your items on state
allows you to pass those items to your model. You can leverage React state to set your items on
load as well as displaying a placeholder indicating when items are loaded.
Note: In this case we need to use getId and getTextValue because our data doesn’t have the
properties of id or text. Using these helper functions sets the serverId to be id and
label to be text.
import React from 'react';
import {PrimaryButton} from '@workday/canvas-kit-react/button';
import {useMount} from '@workday/canvas-kit-react/common';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {Flex} from '@workday/canvas-kit-react/layout';
import {Select, useSelectModel} from '@workday/canvas-kit-react/select';
import {createStyles, px2rem} from '@workday/canvas-kit-styling';
const parentContainerStyles = createStyles({
flexDirection: 'column',
maxWidth: px2rem(300),
});
const movieListItems = [
{
label: 'The Lion King',
serverId: '123',
Year: '2019',
Runtime: '118 min',
},
{
label: 'Mowgli: Legend of the Jungle',
serverId: '234',
Year: '2018',
Runtime: '104 min',
},
{
label: 'Doctor Strange',
serverId: '345',
Year: '2016',
Runtime: '115 min',
},
{
label: 'John Wick',
Year: '2014',
serverId: '456',
Runtime: '101 min',
},
{
label: 'The Notebook',
serverId: '567',
Year: '2004',
Runtime: '123 min',
},
];
export default () => {
const [id, setId] = React.useState('456');
const [moviesLists, setMoviesList] = React.useState<typeof movieListItems>([]);
const [loadingStatus, setLoadingStatus] = React.useState<'idle' | 'loading' | 'success'>('idle');
const loadingRef = React.useRef<ReturnType<typeof setTimeout>>();
const model = useSelectModel({
items: moviesLists,
getTextValue: item => item.label,
getId: item => item.serverId,
initialSelectedIds: [id],
});
const stringValue = moviesLists.find(item => item.serverId === id)?.label || '';
function loadItems() {
setLoadingStatus('loading');
loadingRef.current = setTimeout(() => {
setLoadingStatus('success');
setMoviesList(movieListItems);
}, 1500);
}
useMount(() => {
return () => {
clearTimeout(loadingRef.current);
};
});
return (
<Flex cs={parentContainerStyles}>
<FormField>
<FormField.Label>Choose a Film</FormField.Label>
<FormField.Field>
<Select model={model}>
<FormField.Input
as={Select.Input}
onChange={e => {
setId(e.target.value);
}}
placeholder={loadingStatus}
/>
<Select.Popper>
<Select.Card>
<Select.List>
{item => {
return <Select.Item>{item.label}</Select.Item>;
}}
</Select.List>
</Select.Card>
</Select.Popper>
</Select>
</FormField.Field>
</FormField>
<div data-testid="selected-id">Selected Id: {id}</div>
<div data-testid="selected-value">Selected value: {stringValue}</div>
<PrimaryButton
onClick={() => {
loadItems();
}}
>
Get Items
</PrimaryButton>
</Flex>
);
};
Complex
When registering items in an array of objects, it’s common to have the text that is displayed to the
user be different than an id. In this example, serverId and label properties need to be remapped
to id and text hence the usage of getId and getTextValue. If your object has the properties
text and id, there would be no need for this.
Id:
Value:
import React from 'react';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {Flex} from '@workday/canvas-kit-react/layout';
import {Select} from '@workday/canvas-kit-react/select';
import {createStyles} from '@workday/canvas-kit-styling';
const parentContainerStyles = createStyles({
flexDirection: 'column',
});
const options = [
{serverId: 'email', label: 'E-mail'},
{serverId: 'phone', label: 'Phone'},
{serverId: 'fax', label: 'Fax'},
{serverId: 'mail', label: 'Mail'},
{serverId: 'mobile', label: 'Mobile Phone'},
{
serverId: 'oasis',
label: 'The Ontologically Anthropocentric Sensory Immersive Simulation',
},
];
export default () => {
const [value, setValue] = React.useState('');
const [id, setId] = React.useState('');
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setId(event.target.value);
setValue(options.find(item => item.serverId === event.target.value)!.label);
};
return (
<Flex cs={parentContainerStyles}>
<FormField>
<FormField.Label>Contact</FormField.Label>
<FormField.Field>
<Select items={options} getId={item => item.serverId} getTextValue={item => item.label}>
<FormField.Input as={Select.Input} onChange={e => handleChange(e)} />
<Select.Popper>
<Select.Card>
<Select.List>{item => <Select.Item>{item.label}</Select.Item>}</Select.List>
</Select.Card>
</Select.Popper>
</Select>
</FormField.Field>
</FormField>
<p>Id: {id}</p>
<p>Value: {value}</p>
</Flex>
);
};
Note: By default, the identifier and text value are id and text properties respectively. If
your data object for each item is different, provide getId and/or getTextValue. If a custom
getId does not return the display text, also pass getTextValue — otherwise the model uses
getId for type-ahead and the selected value. For example:
const items = [
{
serverId: '1',
label: 'First Option',
},
];
<Select items={items} getId={item => item.serverId} getTextValue={item => item.label}>
{/* etc */}
</Select>;Controlled
The Select can be a
controlled input
component by passing the value and onChange to either the <Select> component or the
<Select.Input> component. Internally, the Select.Input watches for changes on the value React
prop as well as the value DOM property and will update the model accordingly.
Id:
Label:
import React from 'react';
import {SecondaryButton} from '@workday/canvas-kit-react/button';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {Flex} from '@workday/canvas-kit-react/layout';
import {Select} from '@workday/canvas-kit-react/select';
import {createStyles} from '@workday/canvas-kit-styling';
import {system} from '@workday/canvas-tokens-web';
const parentContainerStyles = createStyles({
flexDirection: 'column',
});
const options = [
{serverId: 'email', label: 'E-mail'},
{serverId: 'phone', label: 'Phone'},
{serverId: 'fax', label: 'Fax'},
{serverId: 'mail', label: 'Mail'},
{serverId: 'mobile', label: 'Mobile Phone'},
{
serverId: 'oasis',
label: 'The Ontologically Anthropocentric Sensory Immersive Simulation',
},
];
export default () => {
const [value, setValue] = React.useState('');
const [label, setLabel] = React.useState('');
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setValue(event.currentTarget.value);
setLabel(options.find(item => item.serverId === event.currentTarget.value)?.label || '');
};
return (
<Flex cs={parentContainerStyles}>
<FormField>
<FormField.Label>Contact</FormField.Label>
<FormField.Field>
<Select items={options} getId={item => item.serverId} getTextValue={item => item.label}>
<FormField.Input
as={Select.Input}
onChange={handleChange}
value={value}
name="contact"
/>
<Select.Popper>
<Select.Card>
<Select.List>{item => <Select.Item>{item.label}</Select.Item>}</Select.List>
</Select.Card>
</Select.Popper>
</Select>
</FormField.Field>
</FormField>
<p>Id: {value}</p>
<p>Label: {label}</p>
<Flex cs={{gap: system.gap.md}}>
<SecondaryButton
onClick={e => {
setValue('fax');
}}
>
Set to "Fax"
</SecondaryButton>
<SecondaryButton
onClick={e => {
setValue('');
}}
>
Clear
</SecondaryButton>
</Flex>
</Flex>
);
};
When to use getId, or getTextValue
-
getId: This is an optional function to return the id of an item. If not provided, the default function will return theidproperty from the object of each item. If you did not provideitems, do not override this function. Instead provide static items via JSX. the list will create an internal array of items whereidis the only property and the defaultgetIdwill return the desired result. Note: If your array of objects has a different property forid, likeserverId, use this function to set the id. If that function does not return the display text, also passgetTextValue.const options = [{text: 'Pizza', serverId: 'pizza-1'}, {text: 'Cheeseburger', serverId: 'cheeseburger'}] <FormField> <FormField.Label>Your Label</FormField.Label> <FormField.Field> <Select items={options} getId={(item) => item.serverId} getTextValue={(item) => item.text}> <FormField.Input as={Select.Input} onChange={e => handleChange(e)} /> <Select.Popper> <Select.Card> <Select.List>{item => <Select.Item>{item.text}</Select.Item>}</Select.List> </Select.Card> </Select.Popper> </Select> </FormField.Field> </FormField> -
getTextValue: Optional function to return the text representation of an item. If not provided, the default function will return thetextproperty of the object of each item or an empty string if there is notextproperty. If you did not provideitems, do not override this function. Note: If your array of objects has a different property fortext, likelabel, use this function to set the text.const options = [{label: 'Pizza', id: 'pizza-1'}, {label: 'Cheeseburger', id: 'cheeseburger'}] <FormField> <FormField.Label>Your Label</FormField.Label> <FormField.Field> <Select items={options} getTextValue={(item) => item.label}> <FormField.Input as={Select.Input} onChange={e => handleChange(e)} /> <Select.Popper> <Select.Card> <Select.List>{item => <Select.Item>{item.label}</Select.Item>}</Select.List> </Select.Card> </Select.Popper> </Select> </FormField.Field> </FormField>
Grouped Items
In order to group items, use the static item API with Menu.Group inside Select.List, and
still pass items whose ids match each Select.Item data-id.
import React from 'react';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {Menu} from '@workday/canvas-kit-react/menu';
import {Select} from '@workday/canvas-kit-react/select';
const items = [
{
id: 'first',
text: 'First Item',
},
{
id: 'second',
text: 'Second Item',
},
{
id: 'third',
text: 'Third Item',
},
{
id: 'fourth',
text: 'Fourth Item',
},
];
export default () => {
return (
<FormField>
<FormField.Label>Contact</FormField.Label>
<FormField.Field>
<Select items={items} getId={item => item.id} getTextValue={item => item.text}>
<FormField.Input as={Select.Input} />
<Select.Popper>
<Select.Card>
<Select.List>
<Menu.Group title="First Group">
<Select.Item data-id="first">First Item</Select.Item>
<Select.Item data-id="second">Second Item</Select.Item>
</Menu.Group>
<Menu.Group title="Second Group">
<Select.Item data-id="third">
Third Item (with a really, really, really long label)
</Select.Item>
<Select.Item data-id="fourth">Fourth Item</Select.Item>
</Menu.Group>
</Select.List>
</Select.Card>
</Select.Popper>
</Select>
</FormField.Field>
</FormField>
);
};
Custom Styles
Select and its subcomponents support custom styling via the cs prop. For more information, check
our
“How To Customize Styles” .
Accessibility
The primary accessibility goal for Select is a visible, persistent label and a single choice from
a known list that assistive technology identifies as a combobox. Use Select when the user must
pick one option. For multiple selections, use MultiSelect.
For a value outside a fixed list, use Combobox. See
FormField’s accessibility documentation for label,
hint, error, and required wiring. This follows the WAI-ARIA
Select-Only Combobox
pattern.
Minimum Accessible Structure
Build on the Basic Example: label first, then Select inside
FormField.Field, with the combobox, popup, list, and items in this order.
import {FormField} from '@workday/canvas-kit-react/form-field';
import {Select} from '@workday/canvas-kit-react/select';
const options = ['E-mail', 'Phone', 'Fax'];
<FormField>
<FormField.Label>Contact</FormField.Label>
<FormField.Field>
<Select items={options}>
<FormField.Input as={Select.Input} />
<Select.Popper>
<Select.Card>
<Select.List>{item => <Select.Item>{item}</Select.Item>}</Select.List>
</Select.Card>
</Select.Popper>
</Select>
</FormField.Field>
</FormField>;Every Select requires FormField, a visible FormField.Label, and
FormField.Input as={Select.Input} so the combobox has a programmatically determinable name,
relationships, and instructions. See
FormField’s accessibility documentation for hint,
error, and required wiring.
Built-in Behaviors
Canvas Kit applies these automatically when you compose Select with FormField subcomponents.
Do not duplicate them in consuming code.
ARIA and DOM (applied by subcomponents):
Select.Input: Visual<input>withrole="combobox",aria-haspopup="listbox",aria-expandedfrom menu visibility,aria-autocomplete="list"(do not change to"none"),aria-controlspointing at the listbox id ({modelId}-list), andaria-activedescendantwhile the list is open (removed when the list is closed).autoCompleteis"off". Keyboard characters are not inserted into the input; type-ahead is handled by the model.FormField.Label(viaFormField.Input) is the accessible name of the combobox — do not add a second name on the listbox.- Hidden form input: A second input holds the selected id(s) for form submission. It is
aria-hidden, hastabIndex={-1}, and is not in the tab order.onChangeandnameapply to this input. Focus and blur on arefare forwarded to the visual combobox. Select.List:role="listbox"with an id that matches the comboboxaria-controls. Options are not in the tab order; keyboard focus stays on the combobox. Listbox labelling is library-owned — do not setaria-labelledby(oraria-label) onSelect.List.Select.Item:role="option"andaria-selectedfrom selection state. Disabled options needaria-disabledfrom application code (see Accessibility Requirements).Menu.Group(when used insideSelect.List):role="group"witharia-labelledbyreferencing the group heading (titleorMenu.Group.Heading).Select.Item.Iconand the caret / start icons onSelect.Input: Canvas Kit icons userole="presentation"andfocusable="false". Decorative icons need no extra attributes.disabledonSelect.Input: Maps to the nativedisabledattribute on both inputs; the combobox is removed from the tab order.ref: Forwards to the visual combobox (<input type="text" role="combobox">).
Keyboard (select-only combobox; focus remains on Select.Input):
- Tab / Shift+Tab move to and from the combobox (native tab order). Other keys are prevented from editing the input.
- Clicking
FormField.Labelmoves focus to the combobox. Clicking the combobox opens or closes the list. - ArrowDown / ArrowUp open the list. While the list is open, those keys move
the active option (skipping ids in
nonInteractiveIds). Home / End move to the first or last option while the list is open. - Space opens the list when it is closed and no type-ahead string is in progress. While the list is open and type-ahead is empty, Space selects the active option and closes the list.
- Printable characters type-ahead: with the list closed, matching options are selected; with the list open, assistive focus moves to the matching option. Consecutive keys within 500ms form a search string.
- Enter while the list is open selects the active option (unless
aria-disabled) and closes the list in single-select mode. It does not submit the form while the list is open. - Escape closes the list. Blur also hides the list. After close,
aria-activedescendantis removed; the active option returns to the selected item when one is selected. - Activating an option with the pointer keeps focus on the combobox and closes the list.
Screen reader expectations (when built-in behaviors are used as intended):
- On focus, assistive technology announces the field label and, when applicable: required state,
invalid state (
error="error"), hint or error text viaaria-describedby, and the current selected text (or the placeholder when nothing is selected). - The control is announced as a combobox. Collapsed vs expanded follows
aria-expanded. While the list is open, the active option is exposed througharia-activedescendant. - Options are announced with selected or not-selected state (
aria-selected). Disabled options are announced as disabled whenaria-disabledis set. - The Caution state is visual only —
aria-invalidis not set forerror="caution". - Disabled comboboxes may be announced as unavailable and are skipped in the tab order.
- The hidden form input and decorative icons are not announced.
For rendered label, input, and hint association markup, see the DOM examples in FormField’s Built-in Behaviors.
Accessibility Requirements
Required in application code for an accessible Select. Rows marked (conditional) apply only when
the situation matches—otherwise omit.
If no design spec is provided: use a visible FormField.Label, wrap Select with
FormField, use FormField.Input as={Select.Input}, include Select.Popper,
Select.Card, Select.List, and Select.Item, and pass items. Omit isHidden,
omit a custom id unless testing or composition requires it, omit a ref unless programmatic focus
is required, omit disabled, nonInteractiveIds, icons, grouped list items, and a custom
placeholder unless the spec includes them.
Programmatic focus (conditional — omit by default):
Use a ref when the product needs to move focus to the combobox after an action. Do not attach a
ref or call focus() unless the design or developer asks for it. See
Ref Forwarding under Usage for a complete Storybook example (imports, ref on
FormField.Input as={Select.Input}, and a button that calls focus()).
Disabled options (conditional):
When an option is unavailable, set nonInteractiveIds on Select and aria-disabled
on those **Select.Item**s. See Disabled Items under Usage for a complete
Storybook example. Do not use styling alone.
| Requirement | How to satisfy |
|---|---|
| Input wiring | FormField.Input as={Select.Input} for the combobox, with Select.Popper, Select.Card, Select.List, and Select.Item. See FormField accessibility for label, hint, error, and required wiring |
| Disabled combobox (conditional) | disabled on FormField.Input as={Select.Input}. See Disabled |
| Disabled options (conditional) | nonInteractiveIds on Select (ids skipped by keyboard and type-ahead) and aria-disabled on those **Select.Item**s. See Disabled Items |
| Grouped list items (conditional) | Keep items. Inside Select.List, render static Menu.Group (title or Menu.Group.Heading) and **Select.Item**s with matching data-id — not {item => …}. See Grouped Items |
| Option icons (conditional) | Select.Item.Icon on each item; inputStartIcon on FormField.Input as={Select.Input} for the selected item. Decorative icons need no extra attributes; meaning beyond the label must be text |
| Custom placeholder (conditional) | placeholder on FormField.Input as={Select.Input} only as short prompt text—never as the only name. Default is "Choose an option" |
| Programmatic focus (conditional) | ref on FormField.Input as={Select.Input} and call focus() when moving focus to the field after an action—omit by default (see Programmatic focus above) |
Summary for code generation:
- REQUIRED: visible label,
FormField.Input as={Select.Input}, popup list composition (Select.Popper,Select.Card,Select.List,Select.Item),items. Default list rendering is{item => <Select.Item>{item}</Select.Item>}(oritem.text/getTextValue). - CONDITIONAL: disabled combobox, disabled options (
nonInteractiveIds+aria-disabled), grouped list items (itemsplus staticMenu.Group/data-idchildren — do not omititems), option icons, custom placeholder, programmatic focus viaref,getIdandgetTextValuewhen item shape is not{id, text}(always passgetTextValueif customgetIdis not the display text),data-idon static JSX **Select.Item**s. See FormField accessibility for shared FormField conditionals (hint/error, required, stableid).
Anti-Patterns
Do not generate code that does the following (see Accessibility Requirements above for what to supply instead):
- Missing
FormFieldwiring: Do not useSelectwithoutFormFieldandFormField.Label, and do not render a bareSelect.Inputwhen aFormFieldis present. UseFormField.Input as={Select.Input}(see Minimum accessible structure). For shared FormField anti-patterns (manual ARIA, placeholder-only labels, color-only errors, broken ID references), see FormField Anti-Patterns. - Duplicating combobox or listbox ARIA: Do not set
role,aria-haspopup,aria-expanded,aria-autocomplete(including"none"),aria-controls,aria-activedescendant,autoComplete, or listboxrole/id/aria-labelledby/aria-label. Do not makeSelect.Itemfocusable — the active option isaria-activedescendanton the combobox. - Wrong component: Do not use a native
<select>,Menu,Combobox,TextInput, orFormFieldGroupfor a single submitted list value. Use MultiSelect when more than one option can be selected. - Item identity / grouping: Do not set
data-idon{item => <Select.Item>}. Do not omititemswhen grouping, and do not group with a render callback alone — useMenu.Groupanddata-id(see Static item ids and Grouped list items). - Free-text keyboard on the combobox: Do not add
onKeyDownthat types into the input or callspreventDefaulton Tab — Select is select-only.
Component API
Select
Use Select to allow users to choose an option from a list or type characters to select a matching option.
Note: Wrap Select with FormField and compose FormField.Input as={Select.Input} so the combobox receives the field label.
<FormField>
<FormField.Label>Contact</FormField.Label>
<FormField.Field>
<Select items={options}>
<FormField.Input as={Select.Input} onChange={e => handleChange(e)} />
<Select.Popper>
<Select.Card>
<Select.List>{item => <Select.Item>{item}</Select.Item>}</Select.List>
</Select.Card>
</Select.Popper>
</Select>
</FormField.Field>
</FormField>
Props
Props extend from . If a model is passed, props from SelectModelConfig are ignored.
| Name | Type | Description | Default |
|---|---|---|---|
children | ReactNode | Children of the | |
model | | Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context. | |
elemPropsHook | ( | Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one. |
Select.Input
Select.Input renders a that handles keyboard navigation and interaction defined by WAI.
This component can either be controlled or uncontrolled.
Compose it as FormField.Input as={Select.Input} so label, required, and error wiring apply.
<FormField>
<FormField.Label>Contact</FormField.Label>
<FormField.Field>
<Select items={options}>
<FormField.Input as={Select.Input} onChange={event => handleChange(event)} />
...
</Select>
</FormField.Field>
</FormField>
Props
Props extend from . Changing the as prop will change the element interface.
| Name | Type | Description | Default |
|---|---|---|---|
inputStartIcon | | The Icon to render at the start of the | |
error | | The type of error associated with the TextInput (if applicable). | |
width | number | string | The width of the TextInput. | |
grow | boolean | True if the component should grow to its container's width. False otherwise. | |
cs | | The | |
children | React.ReactNode | ||
as | React.ElementType | Optional override of the default element used by the component. Any valid tag or Component. If you provided a Component, this component should forward the ref using Note: Not all elements make sense and some elements may cause accessibility issues. Change this value with care. | |
ref | React.Ref<R = > | Optional ref. If the component represents an element, this ref will be a reference to the real DOM element of the component. If | |
model | | Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context. | |
elemPropsHook | ( | Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one. |
useSelectInput
useSelectInput extends and and adds type ahead functionality and Select-specific keyboard support.
(
(
model: ,
elemProps: {
keySoFar: string;
placeholder: string;
value: string;
},
ref: React.Ref
) => {
onKeyDown: (event: ) => void;
autoComplete: 'off';
keySoFar: null;
ref: (instance: | null) => void;
},
,
,
,
,
)Select.Card
Select.Card renders a . You have access to all Card props.
Note: The card will be the width of its corresponding Select.Input.
<FormField>
<FormField.Label>Contact</FormField.Label>
<FormField.Field>
<Select items={options}>
<FormField.Input as={Select.Input} onChange={event => handleChange(event)} />
<Select.Popper>
<Select.Card>...</Select.Card>
</Select.Popper>
</Select>
</FormField.Field>
</FormField>
Layout Component
Select.Card supports all props from thelayout component.
Props
Props extend from div. Changing the as prop will change the element interface.
| Name | Type | Description | Default |
|---|---|---|---|
variant | 'alt' | 'tonal' | The variant of the Card. Can be | 'default' |
cs | | The | |
children | React.ReactNode | ||
as | React.ElementType | Optional override of the default element used by the component. Any valid tag or Component. If you provided a Component, this component should forward the ref using Note: Not all elements make sense and some elements may cause accessibility issues. Change this value with care. | div |
ref | React.Ref<R = div> | Optional ref. If the component represents an element, this ref will be a reference to the real DOM element of the component. If | |
model | | Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context. | |
elemPropsHook | ( | Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one. |
useSelectCard
Sets the width of the SelectCard to the Select.Input width.
(
model: ,
elemProps: {},
ref: React.Ref
) => {
width: number;
}Select.Item
Select.Item renders a with aria role of option. You can optionally render a Icon.
<FormField>
<FormField.Label>Contact</FormField.Label>
<FormField.Field>
<Select items={options}>
<FormField.Input as={Select.Input} onChange={event => handleChange(event)} />
<Select.Popper>
<Select.Card>
<Select.List>
{item => (
<Select.Item>
<Select.Item.Icon icon={icon} />
{item}
</Select.Item>
)}
</Select.List>
</Select.Card>
</Select.Popper>
</Select>
</FormField.Field>
</FormField>
Props
Props extend from li. Changing the as prop will change the element interface.
| Name | Type | Description | Default |
|---|---|---|---|
index | number | Optionally pass index to menu item. This should be done if | |
children | ReactNode | The label text of the MenuItem. | |
data-id | string | The name of the menu item. This name will be used in the | |
aria-disabled | boolean |
| |
isDisabled | boolean | If true, set the StyledMenuItem to the disabled state so it is not clickable. | false |
cs | | The | |
as | React.ElementType | Optional override of the default element used by the component. Any valid tag or Component. If you provided a Component, this component should forward the ref using Note: Not all elements make sense and some elements may cause accessibility issues. Change this value with care. | li |
ref | React.Ref<R = li> | Optional ref. If the component represents an element, this ref will be a reference to the real DOM element of the component. If | |
model | | Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context. | |
elemPropsHook | ( | Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one. |
Model
useSelectModel
SelectModel extends the . Selecting items from
the menu will dispatch an
input event on the
input which should work with form libraries, automation and autofill.
const model = useSelectModel({items: ['Mobile', 'Phone', 'E-Mail']})
<Select model={model}>
...
</Select>
useSelectModel (config: ): Content Guidelines
- The list of Menu items should be scannable, with concise labels written in title case. Don’t write sentences and omit articles (a, an, the) unless needed for clarity.
- Placeholder text for a Select must begin with the verb “Select”.