Select
Storybook
Browse the props, controls and all the stories of Select in Storybook: all layouts, HTML5, Choices.js and React Select.
Select renders a single or multiple choice field wrapped in a FormControl. It supports flat options, grouped options, disabled options and a placeholder. The dropdown itself is provided by one of three implementations, chosen with the layout prop.
Usage
import { useState } from "react";
import { Select } from "@tsed/react-formio/molecules/forms/select/all";
const options = [
{ label: "Option 1", value: "option-1" },
{ label: "Option 2", value: "option-2" },
{ label: "Option 3", value: "option-3" }
];
export function MySelect() {
const [value, setValue] = useState("option-1");
return <Select name="name" label="Label" layout="choicesjs" options={options} value={value} onChange={(name, value) => setValue(value)} />;
}@tsed/react-formio/molecules/forms/select/all exports Select and registers the three implementations. To keep only the ones you need in your bundle, import them explicitly:
import "@tsed/react-formio/molecules/forms/form-control/FormControl";
import "@tsed/react-formio/molecules/forms/select/components/ChoicesSelect"; // register only the Choices.js implementation
import { Select } from "@tsed/react-formio/molecules/forms/select/Select";Layouts
Select does not import its implementations. It resolves them from the components registry at render time, using the layout prop:
layout | Registry name | Implementation |
|---|---|---|
"html5" | Select.html5 | HTMLSelect, a native <select> (with <optgroup> for groups). |
"choicesjs" | Select.choicesjs | ChoiceSelect, a <select> enhanced by Choices.js. |
"react" | Select.react | ReactSelect, based on react-select. |
When layout is omitted, or when no component is registered under Select.<layout>, Select falls back to Select.html5. The wrapper is resolved the same way, from the FormControl registry entry.
Each implementation is registered when its module is imported (components/HtmlSelect, components/ChoicesSelect, components/ReactSelect), which is done for you by select/all and by @tsed/react-formio/all.
Props
| Name | Type | Default | Description |
|---|---|---|---|
layout | "html5" | "react" | "choicesjs" | html5 (fallback) | Implementation to use. See Layouts. |
options | SelectOptionProps[] | Options, groups of options, or options with a group key. See Options. | |
name | string | "" | Field name, passed back as the first argument of onChange. |
id | string | field-select-<n> | Field id. Generated when omitted. |
value | string | string[] | Selected value, or array of values when multiple is true. | |
multiple | boolean | Allows several values. value and the onChange value become arrays. | |
onChange | (name: string | undefined, value) => void | Called with the new value (or values). | |
placeholder | string | Placeholder. Rendered as an empty disabled first option with the HTML5 layout (single mode only). | |
disabled | boolean | Disables the field. | |
required | boolean | Marks the field as required. With Choices.js and a placeholder, the placeholder option cannot be selected back. | |
searchEnabled | boolean | true | React Select: enables search (isSearchable). |
disableSearch | boolean | Choices.js: disables the search input. | |
customProperties | Record<string, any> | Extra options passed to the underlying library: Choices.js options or react-select props. | |
errorMessage | string | Declared in SelectProps; not rendered by the built-in implementations. | |
readonly | boolean | Declared in SelectProps; not used by the built-in implementations. |
Plus the FormControl props (label, description, before, after, size, className, ...).
With Choices.js, the library sets allowHTML: true, removeItemButton: true, shouldSort: false and itemSelectText: "" by default; all of them can be overridden through customProperties.
Options
Each option has the following shape:
| Name | Type | Description |
|---|---|---|
label | string | JSX.Element | Displayed label. |
value | string | Option value. |
disabled | boolean | Disables the option. |
options | SelectOptionProps[] | Child options. An item with options is rendered as a group. |
group | string | Legacy grouping: options sharing the same group are grouped. |
data | any | Extra data attached to the option. |
customProperties | Record<string, any> | Choices.js: extra data attached to the choice, including template. |
Examples
HTML5
Choices.js
React Select
Groups
Pass items with an options key to render groups.
import { Select } from "@tsed/react-formio/molecules/forms/select/all";
<Select
layout="choicesjs"
name="name"
label="Label"
options={[
{
label: "Group 1",
options: [
{ label: "Option 1", value: "option-1" },
{ label: "Option 2", value: "option-2" }
]
},
{
label: "Group 2",
options: [
{ label: "Option 3", value: "option-3" },
{ label: "Option 4", value: "option-4" }
]
}
]}
/>;The legacy format, where each option carries a group key, is also supported. See the WithGroupsLegacy story.
Multiple
Set multiple to allow several values. value must then be an array.
Custom option template (Choices.js)
With the Choices.js layout, pass a React component as customProperties.template on each option to customize how it is rendered in the dropdown. The component receives the Choices item and a data prop merging the item and its customProperties. The library keeps the attributes Choices.js needs (data-choice, data-value, roles) around the rendered template.
import { Select } from "@tsed/react-formio/molecules/forms/select/all";
const OptionTemplate = ({ label, data }: any) => (
<span style={{ display: "flex", justifyContent: "space-between", width: "100%" }}>
<span>{label}</span>
<small style={{ opacity: 0.7 }}>{data?.hint}</small>
</span>
);
<Select
layout="choicesjs"
name="name"
label="Label"
placeholder="Select an option"
options={[
{ label: "Option 1", value: "option-1", customProperties: { hint: "alpha", template: OptionTemplate } },
{ label: "Option 2", value: "option-2", customProperties: { hint: "beta", template: OptionTemplate } }
]}
/>;More examples
Placeholder, disabled field, disabled option, size, before/after content, description and groups with multiple selection are available for each layout in Storybook: HTML5, Choices.js and React Select.
Override
Select is registered under the name Select, and its implementations under Select.html5, Select.choicesjs and Select.react. Register your own component under one of these names to replace an implementation:
import { registerComponent } from "@tsed/react-formio/registries/components";
import type { AllSelectProps } from "@tsed/react-formio/molecules/forms/select/Select.interface";
registerComponent("Select.html5", (props: AllSelectProps) => <MySelect {...props} />);