Canvas Kit Select (with Canvas-styled Menu) This component is work in progress and currently in pre-release.
A Canvas-styled Select with a Canvas-styled menu. This is a controlled component.
Undocumented props (disabled
, name
, etc.) should behave similarly to how you would expect from a
standard <select>
element.
The menu is rendered using a portal by way of the Canvas Kit Popper.
Note: There is also a non-Labs Select. The non-Labs Select uses the standard browser-provided menu whereas the Labs Select uses a custom Canvas-styled menu.
Installation
yarn add @workday/canvas-kit-labs-react-select
Usage
Example
In this example, options
is an array of objects. Each option contains a label
(analagous to the
text content of an <option>
) and a value
(analagous to the value
attribute of an <option>
).
Note: While a base Select component is provided in this package, it is not accessible when
used as is. It should be used in tandem with FormField
to
be made fully accessible (see below).
import * as React from 'react';
import Select from '@workday/canvas-kit-labs-react-select';
function Example() {
const options = [
{label: 'E-mail', value: 'email'},
{label: 'Phone', value: 'phone'},
{label: 'Fax (disabled)', value: 'fax', disabled: true},
{label: 'Mail', value: 'mail'},
];
const [value, setValue] = React.useState('email');
const handleChange = (event) => {
setValue(event.currentTarget.value);
};
return (
<Select onChange={handleChange} options={options} value={value} />
);
}
Accessible Example
import * as React from 'react';
import Select from '@workday/canvas-kit-labs-react-select';
import FormField from '@workday/canvas-kit-react-form-field';
function Example() {
const options = [
{label: 'E-mail', value: 'email'},
{label: 'Phone', value: 'phone'},
{label: 'Fax (disabled)', value: 'fax', disabled: true},
{label: 'Mail', value: 'mail'},
];
const [value, setValue] = React.useState('email');
const handleChange = (event) => {
setValue(event.currentTarget.value);
};
return (
<FormField label="My Select Field" inputId="my-select-field">
<Select onChange={handleChange} options={options} value={value} />
</FormField>
);
}
Example with Array of Strings
options
may also be formatted as an array of strings rather than an array of objects.
import * as React from 'react';
import Select from '@workday/canvas-kit-labs-react-select';
import FormField from '@workday/canvas-kit-react-form-field';
function Example() {
const options = ['California', 'Florida', 'New York', 'Pennsylvania', 'Texas'];
const [value, setValue] = React.useState('California');
const handleChange = (event) => {
setValue(event.currentTarget.value);
};
return (
<FormField label="My Select Field" inputId="my-select-field">
<Select onChange={handleChange} options={options} value={value} />
</FormField>
);
}
Example with Custom Options Data
Each option in options
may contain a data
object with any number of key/value pairs. This data
object is carried over to the option
passed into the renderOption
function where it may then be
used to customize how each option is rendered.
import * as React from 'react';
import Select from '@workday/canvas-kit-labs-react-select';
import FormField from '@workday/canvas-kit-react-form-field';
import {colors, typeColors} from '@workday/canvas-kit-react-core';
import {
activityStreamIcon,
avatarIcon,
uploadCloudIcon,
userIcon,
} from '@workday/canvas-system-icons-web';
import {SystemIcon} from '@workday/canvas-kit-react-icon';
function Example() {
const options = [
{value: 'Activity Stream', data: {icon: activityStreamIcon}},
{value: 'Avatar', data: {icon: avatarIcon}},
{value: 'Upload Cloud', data: {icon: uploadCloudIcon}},
{value: 'User', data: {icon: userIcon}},
];
const renderOption = option => {
const iconColor = option.focused ? typeColors.inverse : colors.blackPepper100;
return (
<div style={{alignItems: 'center', display: 'flex', padding: '3px 0'}}>
<SystemIcon icon={option.data.icon} color={iconColor} colorHover={iconColor} />
<div style={{marginLeft: 5}}>{option.value}</div>
</div>
);
};
const [value, setValue] = React.useState('Activity Stream');
const handleChange = (event) => {
setValue(event.currentTarget.value);
};
return (
<FormField label="My Select Field" inputId="my-select-field">
<Select onChange={handleChange} options={options} renderOption={renderOption} value={value} />
</FormField>
);
}
Static Properties
ErrorType: ErrorType
<Select error={Select.ErrorType.Alert} />
Component Props
Required
options: (Option | string)[]
The options of the Select.
options
may be an array of objects or an array of strings.If
options
is an array of objects, each object must adhere to theOption
interface:
data: object
(optional)disabled: boolean
(optional)id: string
(optional, a randomid
will be assigned to the object if one isn't provided)label: string
(optional, analagous to the text content of an<option>
)value: string
(required, analagous to thevalue
attribute of an<option>
)If
label
is omitted, thevalue
will be used to render the option.The
data
object is carried over to theoption
passed into therenderOption
function where it may then be used to customize how each option is rendered.
Optional
error: ErrorType
The type of error associated with the Select (if applicable).
Type | Description |
---|---|
Error | Red outline. |
Alert | Orange outline. |
renderOption: (option: RenderableOption) => React.ReactNode
The function called to render the content of each option.
The
option
argument passed to the function is an object which contains the following:
data: object
(data object carried over from the corresponding option originally passed into the component)disabled: boolean
focused: boolean
(set totrue
if the option has keyboard focus)id: string
label: string
selected: boolean
(set totrue
if the option is selected)value: string
If you omit the
renderOption
prop, each option will be rendered using a defaultrenderOption
function provided by the component.
value: string
The value of the Select.