Select
Select
components allow users to select a single option from a popup list.
This component mimics the API for a native <select>
element but supports
additional styling.
See the AutoComplete component for typeahead or fuzzy searching of options.
Simple Select
A select can be created by using the Select
and Option
components together.
Each option should have a unique value
and some sort of text.
import { Form } from "@react-md/core/form/Form";
import { Option } from "@react-md/core/form/Option";
import { Select } from "@react-md/core/form/Select";
import { type ReactElement } from "react";
export default function SimpleSelect(): ReactElement {
return (
<Form>
<Select label="Label">
<Option value="a">Option 1</Option>
<Option value="b">Option 2</Option>
<Option value="c">Option 3</Option>
<Option value="d">Option 4</Option>
</Select>
</Form>
);
}
Select Theme
Just like other form components, the Select
supports multiple themes:
outline
(default), filled
, or underline
.
import { box } from "@react-md/core/box/styles";
import { Form } from "@react-md/core/form/Form";
import { Option } from "@react-md/core/form/Option";
import { Select } from "@react-md/core/form/Select";
import { type ReactElement } from "react";
export default function SelectTheme(): ReactElement {
return (
<Form className={box({ stacked: true, align: "stretch" })}>
<Select label="Label" theme="outline">
<Option value="a">Option 1</Option>
<Option value="b">Option 2</Option>
<Option value="c">Option 3</Option>
<Option value="d">Option 4</Option>
</Select>
<Select label="Label" theme="filled">
<Option value="a">Option 1</Option>
<Option value="b">Option 2</Option>
<Option value="c">Option 3</Option>
<Option value="d">Option 4</Option>
</Select>
<Select label="Label" theme="underline">
<Option value="a">Option 1</Option>
<Option value="b">Option 2</Option>
<Option value="c">Option 3</Option>
<Option value="d">Option 4</Option>
</Select>
</Form>
);
}
Controlled Select
The value
for the select can be controlled by providing a value
and
onChange
handler where the value
should match one of the Option
's value
s.
The event.currentTarget.value
will be strongly typed for Typescript users.
"use client";
import { Form } from "@react-md/core/form/Form";
import { Option } from "@react-md/core/form/Option";
import { Select } from "@react-md/core/form/Select";
import { type ReactElement, useState } from "react";
export default function ControlledSelectExample(): ReactElement {
const [value, setValue] = useState<StateAbbreviation | "">("");
return (
<Form>
<Select
label="Label"
value={value}
onChange={(event) => {
setValue(event.currentTarget.value);
}}
>
{states.map(({ name, abbreviation }) => (
<Option key={abbreviation} value={abbreviation}>
{name}
</Option>
))}
</Select>
</Form>
);
}
export const states = [
{
name: "Alabama",
abbreviation: "AL",
},
{
name: "Alaska",
abbreviation: "AK",
},
{
name: "American Samoa",
abbreviation: "AS",
},
{
name: "Arizona",
abbreviation: "AZ",
},
{
name: "Arkansas",
abbreviation: "AR",
},
{
name: "California",
abbreviation: "CA",
},
{
name: "Colorado",
abbreviation: "CO",
},
{
name: "Connecticut",
abbreviation: "CT",
},
{
name: "Delaware",
abbreviation: "DE",
},
{
name: "District Of Columbia",
abbreviation: "DC",
},
{
name: "Federated States Of Micronesia",
abbreviation: "FM",
},
{
name: "Florida",
abbreviation: "FL",
},
{
name: "Georgia",
abbreviation: "GA",
},
{
name: "Guam",
abbreviation: "GU",
},
{
name: "Hawaii",
abbreviation: "HI",
},
{
name: "Idaho",
abbreviation: "ID",
},
{
name: "Illinois",
abbreviation: "IL",
},
{
name: "Indiana",
abbreviation: "IN",
},
{
name: "Iowa",
abbreviation: "IA",
},
{
name: "Kansas",
abbreviation: "KS",
},
{
name: "Kentucky",
abbreviation: "KY",
},
{
name: "Louisiana",
abbreviation: "LA",
},
{
name: "Maine",
abbreviation: "ME",
},
{
name: "Marshall Islands",
abbreviation: "MH",
},
{
name: "Maryland",
abbreviation: "MD",
},
{
name: "Massachusetts",
abbreviation: "MA",
},
{
name: "Michigan",
abbreviation: "MI",
},
{
name: "Minnesota",
abbreviation: "MN",
},
{
name: "Mississippi",
abbreviation: "MS",
},
{
name: "Missouri",
abbreviation: "MO",
},
{
name: "Montana",
abbreviation: "MT",
},
{
name: "Nebraska",
abbreviation: "NE",
},
{
name: "Nevada",
abbreviation: "NV",
},
{
name: "New Hampshire",
abbreviation: "NH",
},
{
name: "New Jersey",
abbreviation: "NJ",
},
{
name: "New Mexico",
abbreviation: "NM",
},
{
name: "New York",
abbreviation: "NY",
},
{
name: "North Carolina",
abbreviation: "NC",
},
{
name: "North Dakota",
abbreviation: "ND",
},
{
name: "Northern Mariana Islands",
abbreviation: "MP",
},
{
name: "Ohio",
abbreviation: "OH",
},
{
name: "Oklahoma",
abbreviation: "OK",
},
{
name: "Oregon",
abbreviation: "OR",
},
{
name: "Pennsylvania",
abbreviation: "PA",
},
{
name: "Puerto Rico",
abbreviation: "PR",
},
{
name: "Rhode Island",
abbreviation: "RI",
},
{
name: "South Carolina",
abbreviation: "SC",
},
{
name: "South Dakota",
abbreviation: "SD",
},
{
name: "Tennessee",
abbreviation: "TN",
},
{
name: "Texas",
abbreviation: "TX",
},
{
name: "Utah",
abbreviation: "UT",
},
{
name: "Vermont",
abbreviation: "VT",
},
{
name: "Virgin Islands",
abbreviation: "VI",
},
{
name: "Virginia",
abbreviation: "VA",
},
{
name: "Washington",
abbreviation: "WA",
},
{
name: "West Virginia",
abbreviation: "WV",
},
{
name: "Wisconsin",
abbreviation: "WI",
},
{
name: "Wyoming",
abbreviation: "WY",
},
] as const;
export type StateName = (typeof states)[number]["name"];
export type StateAbbreviation = (typeof states)[number]["abbreviation"];
export interface State {
name: StateName;
abbreviation: StateAbbreviation;
}
Uncontrolled Select with a Default Value
If the Select
does not need to be controlled, a defaultValue
can be provided
instead.
import { Form } from "@react-md/core/form/Form";
import { Option } from "@react-md/core/form/Option";
import { Select } from "@react-md/core/form/Select";
import { type ReactElement } from "react";
export default function UncontrolledSelectExample(): ReactElement {
return (
<Form>
<Select label="Label" defaultValue="b">
<Option value="a">Option 1</Option>
<Option value="b">Option 2</Option>
<Option value="c">Option 3</Option>
<Option value="d">Option 4</Option>
</Select>
</Form>
);
}
Grouped Options
Related options can be wrapped in an OptGroup
to provide additional context
for the options. The OptGroup
must have a label for accessibility.
import { Form } from "@react-md/core/form/Form";
import { OptGroup } from "@react-md/core/form/OptGroup";
import { Option } from "@react-md/core/form/Option";
import { Select } from "@react-md/core/form/Select";
import { typography } from "@react-md/core/typography/typographyStyles";
import { type ReactElement } from "react";
export default function SelectionGroupsExample(): ReactElement {
return (
<Form>
<Select label="Select a fruit">
<OptGroup label="A">
<Option value="apple">Apple</Option>
<Option value="apricot">Apricot</Option>
<Option value="avocado">Avocado</Option>
</OptGroup>
<OptGroup label="B">
<Option value="blueberry">Blueberry</Option>
</OptGroup>
<OptGroup
label={
<span
className={typography({
type: null,
fontStyle: "italic",
fontWeight: "bold",
})}
>
C
</span>
}
>
<Option value="cranberry">Cranberry</Option>
<Option value="currant">Currant</Option>
</OptGroup>
</Select>
</Form>
);
}
Custom Dropdown Icon
The Select
component will use the
dropdown icon from the ICON_CONFIG
by
default for the dropdown icon. The icon can be configured by using the icon
prop if the icon should animate and rotate while opened or rightAddon
prop
for no rotation and animation.
import { box } from "@react-md/core/box/styles";
import { Form } from "@react-md/core/form/Form";
import { Option } from "@react-md/core/form/Option";
import { Select } from "@react-md/core/form/Select";
import FavoriteIcon from "@react-md/material-icons/FavoriteIcon";
import { type ReactElement } from "react";
export default function CustomDropdownIcon(): ReactElement {
return (
<Form className={box({ stacked: true, align: "stretch" })}>
<Select label="Rotates" icon={<FavoriteIcon />}>
<Option value="a">Option 1</Option>
<Option value="b">Option 2</Option>
<Option value="c">Option 3</Option>
<Option value="d">Option 4</Option>
</Select>
<Select label="No Rotation" rightAddon={<FavoriteIcon />}>
<Option value="a">Option 1</Option>
<Option value="b">Option 2</Option>
<Option value="c">Option 3</Option>
<Option value="d">Option 4</Option>
</Select>
</Form>
);
}
Select with Addons
Just like the TextField, the Select
supports
rendering a leftAddon
. It does not really support a rightAddon
out of the
box since that is normally the dropdown icon.
import { Avatar } from "@react-md/core/avatar/Avatar";
import { box } from "@react-md/core/box/styles";
import { Form } from "@react-md/core/form/Form";
import { Option } from "@react-md/core/form/Option";
import { Select } from "@react-md/core/form/Select";
import FavoriteIcon from "@react-md/material-icons/FavoriteIcon";
import { type ReactElement } from "react";
export default function SelectWithAddons(): ReactElement {
return (
<Form className={box({ stacked: true, align: "stretch" })}>
<Select label="Label" leftAddon={<FavoriteIcon />}>
<Option value="a">Option 1</Option>
<Option value="b">Option 2</Option>
<Option value="c">Option 3</Option>
<Option value="d">Option 4</Option>
</Select>
<Select label="Label" leftAddon={<Avatar size="icon">O</Avatar>}>
<Option value="a">Option 1</Option>
<Option value="b">Option 2</Option>
<Option value="c">Option 3</Option>
<Option value="d">Option 4</Option>
</Select>
</Form>
);
}
Using Option Addons
If an option provides the leftAddon
prop, it will automatically be added as
the leftAddon
to the Select
once it has been selected. This behavior can be
disabled by setting disableOptionAddon
to true
.
import { Avatar } from "@react-md/core/avatar/Avatar";
import { box } from "@react-md/core/box/styles";
import { Form } from "@react-md/core/form/Form";
import { Option } from "@react-md/core/form/Option";
import { Select } from "@react-md/core/form/Select";
import FavoriteIcon from "@react-md/material-icons/FavoriteIcon";
import { type ReactElement } from "react";
export default function UsingOptionAddons(): ReactElement {
return (
<Form className={box({ stacked: true, align: "stretch" })}>
<Select label="Include Addon">
<Option value="a" leftAddon={<Avatar size="icon">1</Avatar>}>
Option 1
</Option>
<Option value="b" leftAddon={<FavoriteIcon />}>
Option 2
</Option>
<Option value="c" leftAddon={<Avatar size="icon">3</Avatar>}>
Option 3
</Option>
<Option value="d" leftAddon={<Avatar size="icon">4</Avatar>}>
Option 4
</Option>
</Select>
<Select label="Disable Addon" disableOptionAddon>
<Option value="a" leftAddon={<Avatar size="icon">1</Avatar>}>
Option 1
</Option>
<Option value="b" leftAddon={<FavoriteIcon />}>
Option 2
</Option>
<Option value="c" leftAddon={<Avatar size="icon">3</Avatar>}>
Option 3
</Option>
<Option value="d" leftAddon={<Avatar size="icon">4</Avatar>}>
Option 4
</Option>
</Select>
</Form>
);
}
Removing Option Selected Icon
The Option
component will use the
selected icon from the ICON_CONFIG
by
default to help show which option has been selected. This can be disabled by
setting disableSelectedIcon
to true
on the Select
component.
import { Form } from "@react-md/core/form/Form";
import { Option } from "@react-md/core/form/Option";
import { Select } from "@react-md/core/form/Select";
import { type ReactElement } from "react";
export default function RemovingOptionSelectedIconExample(): ReactElement {
return (
<Form>
<Select label="Label" disableSelectedIcon>
<Option value="a">Option 1</Option>
<Option value="b">Option 2</Option>
<Option value="c">Option 3</Option>
<Option value="d">Option 4</Option>
</Select>
</Form>
);
}
Selected Icon After
The selected icon can be rendered after the children
by enabling the
selectedIconAfter
prop on each option.
import { Form } from "@react-md/core/form/Form";
import { Option } from "@react-md/core/form/Option";
import { Select } from "@react-md/core/form/Select";
import { type ReactElement } from "react";
export default function SelectedIconAfterExample(): ReactElement {
return (
<Form>
<Select label="Label">
<Option value="a" selectedIconAfter>
Option 1
</Option>
<Option value="b" selectedIconAfter>
Option 2
</Option>
<Option value="c" selectedIconAfter>
Option 3
</Option>
<Option value="d" selectedIconAfter>
Option 4
</Option>
</Select>
</Form>
);
}
Adding an Unselected Icon
An icon could also be added for the unselected state with the unselectedIcon
prop on the Option
.
import { Form } from "@react-md/core/form/Form";
import { Option } from "@react-md/core/form/Option";
import { Select } from "@react-md/core/form/Select";
import RadioButtonCheckedIcon from "@react-md/material-icons/RadioButtonCheckedIcon";
import RadioButtonUncheckedIcon from "@react-md/material-icons/RadioButtonUncheckedIcon";
import { type ReactElement } from "react";
export default function AddingAnUnselectedIcon(): ReactElement {
return (
<Form>
<Select label="Label">
<Option
value="a"
unselectedIcon={<RadioButtonUncheckedIcon />}
selectedIcon={<RadioButtonCheckedIcon />}
>
Option 1
</Option>
<Option
value="b"
unselectedIcon={<RadioButtonUncheckedIcon />}
selectedIcon={<RadioButtonCheckedIcon />}
>
Option 2
</Option>
<Option
value="c"
unselectedIcon={<RadioButtonUncheckedIcon />}
selectedIcon={<RadioButtonCheckedIcon />}
>
Option 3
</Option>
<Option
value="d"
unselectedIcon={<RadioButtonUncheckedIcon />}
selectedIcon={<RadioButtonCheckedIcon />}
>
Option 4
</Option>
</Select>
</Form>
);
}
Menu Options
The Select
uses the Menu behind the scenes and can pass
additional props via the menuProps
.
The example below will showcase how the select's menu can be updated to use
equal
width instead of min
and preventing the menu from overlapping the
input. Try changing the width
value and the long-text Option
props to see
how the menu behaves.
import { Form } from "@react-md/core/form/Form";
import { Option } from "@react-md/core/form/Option";
import { Select } from "@react-md/core/form/Select";
import { type ReactElement } from "react";
export default function MenuOptionsExample(): ReactElement {
return (
<Form>
<Select
label="Label"
menuProps={{
// this is the default
// width: "min",
// width: "auto",
width: "equal",
preventOverlap: true,
}}
>
<Option value="a">Option 1</Option>
<Option value="b" height="auto" disableTextChildren>
Donec sed pulvinar mauris. Mauris pretium placerat tellus, ut
sollicitudin leo vestibulum eget. Proin ullamcorper metus congue nunc
semper ullamcorper. Curabitur vel nisl tortor. Cras ultricies a ex sed
aliquam. Pellentesque ultricies tortor cursus enim dapibus molestie.
Cras auctor nisi eu augue iaculis sagittis. Etiam posuere augue vitae
lobortis sollicitudin. Mauris placerat neque at nisl vehicula, in
pulvinar felis consectetur. Ut accumsan faucibus ultricies. In
pharetra faucibus iaculis.
</Option>
<Option value="c">Option 3</Option>
<Option value="d">Option 4</Option>
</Select>
</Form>
);
}
Rendering in a Sheet
The options can be rendered within a sheet on mobile or other screen sizes if needed. Check out the Rendering in a Sheet menu documentation for more information.
import { Avatar } from "@react-md/core/avatar/Avatar";
import { Form } from "@react-md/core/form/Form";
import { Option } from "@react-md/core/form/Option";
import { Select } from "@react-md/core/form/Select";
import FavoriteIcon from "@react-md/material-icons/FavoriteIcon";
import { type ReactElement } from "react";
export default function RenderingWithinASheet(): ReactElement {
return (
<Form>
<Select label="Select a state" menuProps={{ renderAsSheet: true }}>
{states.map(({ name, abbreviation }) => (
<Option
key={abbreviation}
value={abbreviation}
leftAddon={<Avatar size="icon">{abbreviation}</Avatar>}
rightAddon={<FavoriteIcon theme="secondary" />}
>
{name}
</Option>
))}
</Select>
</Form>
);
}
export const states = [
{
name: "Alabama",
abbreviation: "AL",
},
{
name: "Alaska",
abbreviation: "AK",
},
{
name: "American Samoa",
abbreviation: "AS",
},
{
name: "Arizona",
abbreviation: "AZ",
},
{
name: "Arkansas",
abbreviation: "AR",
},
{
name: "California",
abbreviation: "CA",
},
{
name: "Colorado",
abbreviation: "CO",
},
{
name: "Connecticut",
abbreviation: "CT",
},
{
name: "Delaware",
abbreviation: "DE",
},
{
name: "District Of Columbia",
abbreviation: "DC",
},
{
name: "Federated States Of Micronesia",
abbreviation: "FM",
},
{
name: "Florida",
abbreviation: "FL",
},
{
name: "Georgia",
abbreviation: "GA",
},
{
name: "Guam",
abbreviation: "GU",
},
{
name: "Hawaii",
abbreviation: "HI",
},
{
name: "Idaho",
abbreviation: "ID",
},
{
name: "Illinois",
abbreviation: "IL",
},
{
name: "Indiana",
abbreviation: "IN",
},
{
name: "Iowa",
abbreviation: "IA",
},
{
name: "Kansas",
abbreviation: "KS",
},
{
name: "Kentucky",
abbreviation: "KY",
},
{
name: "Louisiana",
abbreviation: "LA",
},
{
name: "Maine",
abbreviation: "ME",
},
{
name: "Marshall Islands",
abbreviation: "MH",
},
{
name: "Maryland",
abbreviation: "MD",
},
{
name: "Massachusetts",
abbreviation: "MA",
},
{
name: "Michigan",
abbreviation: "MI",
},
{
name: "Minnesota",
abbreviation: "MN",
},
{
name: "Mississippi",
abbreviation: "MS",
},
{
name: "Missouri",
abbreviation: "MO",
},
{
name: "Montana",
abbreviation: "MT",
},
{
name: "Nebraska",
abbreviation: "NE",
},
{
name: "Nevada",
abbreviation: "NV",
},
{
name: "New Hampshire",
abbreviation: "NH",
},
{
name: "New Jersey",
abbreviation: "NJ",
},
{
name: "New Mexico",
abbreviation: "NM",
},
{
name: "New York",
abbreviation: "NY",
},
{
name: "North Carolina",
abbreviation: "NC",
},
{
name: "North Dakota",
abbreviation: "ND",
},
{
name: "Northern Mariana Islands",
abbreviation: "MP",
},
{
name: "Ohio",
abbreviation: "OH",
},
{
name: "Oklahoma",
abbreviation: "OK",
},
{
name: "Oregon",
abbreviation: "OR",
},
{
name: "Pennsylvania",
abbreviation: "PA",
},
{
name: "Puerto Rico",
abbreviation: "PR",
},
{
name: "Rhode Island",
abbreviation: "RI",
},
{
name: "South Carolina",
abbreviation: "SC",
},
{
name: "South Dakota",
abbreviation: "SD",
},
{
name: "Tennessee",
abbreviation: "TN",
},
{
name: "Texas",
abbreviation: "TX",
},
{
name: "Utah",
abbreviation: "UT",
},
{
name: "Vermont",
abbreviation: "VT",
},
{
name: "Virgin Islands",
abbreviation: "VI",
},
{
name: "Virginia",
abbreviation: "VA",
},
{
name: "Washington",
abbreviation: "WA",
},
{
name: "West Virginia",
abbreviation: "WV",
},
{
name: "Wisconsin",
abbreviation: "WI",
},
{
name: "Wyoming",
abbreviation: "WY",
},
] as const;
export type StateName = (typeof states)[number]["name"];
export type StateAbbreviation = (typeof states)[number]["abbreviation"];
export interface State {
name: StateName;
abbreviation: StateAbbreviation;
}
Accessibility
The Select
component implements everything for a select only combobox
which means:
- Space will open the menu to show all the options and an option can be chosen by Enter or Space
- the ArrowUp, ArrowDown, Home, and End keys can be used to select a value while the list is open or closed
- the first match will be found when typing a letter or number and repeated
presses will loop through all options that start with that letter or number
Shift
+ a letter will always select the first match`
- the Enter key will submit the
<form>
while the list is closed like a native<select>
import { Form } from "@react-md/core/form/Form";
import { Option } from "@react-md/core/form/Option";
import { Select } from "@react-md/core/form/Select";
import { type ReactElement } from "react";
export default function AccessibilityExample(): ReactElement {
return (
<Form>
<Select label="Select a state" name="states">
{states.map(({ name, abbreviation }) => (
<Option key={abbreviation} value={abbreviation}>
{name}
</Option>
))}
</Select>
</Form>
);
}
export const states = [
{
name: "Alabama",
abbreviation: "AL",
},
{
name: "Alaska",
abbreviation: "AK",
},
{
name: "American Samoa",
abbreviation: "AS",
},
{
name: "Arizona",
abbreviation: "AZ",
},
{
name: "Arkansas",
abbreviation: "AR",
},
{
name: "California",
abbreviation: "CA",
},
{
name: "Colorado",
abbreviation: "CO",
},
{
name: "Connecticut",
abbreviation: "CT",
},
{
name: "Delaware",
abbreviation: "DE",
},
{
name: "District Of Columbia",
abbreviation: "DC",
},
{
name: "Federated States Of Micronesia",
abbreviation: "FM",
},
{
name: "Florida",
abbreviation: "FL",
},
{
name: "Georgia",
abbreviation: "GA",
},
{
name: "Guam",
abbreviation: "GU",
},
{
name: "Hawaii",
abbreviation: "HI",
},
{
name: "Idaho",
abbreviation: "ID",
},
{
name: "Illinois",
abbreviation: "IL",
},
{
name: "Indiana",
abbreviation: "IN",
},
{
name: "Iowa",
abbreviation: "IA",
},
{
name: "Kansas",
abbreviation: "KS",
},
{
name: "Kentucky",
abbreviation: "KY",
},
{
name: "Louisiana",
abbreviation: "LA",
},
{
name: "Maine",
abbreviation: "ME",
},
{
name: "Marshall Islands",
abbreviation: "MH",
},
{
name: "Maryland",
abbreviation: "MD",
},
{
name: "Massachusetts",
abbreviation: "MA",
},
{
name: "Michigan",
abbreviation: "MI",
},
{
name: "Minnesota",
abbreviation: "MN",
},
{
name: "Mississippi",
abbreviation: "MS",
},
{
name: "Missouri",
abbreviation: "MO",
},
{
name: "Montana",
abbreviation: "MT",
},
{
name: "Nebraska",
abbreviation: "NE",
},
{
name: "Nevada",
abbreviation: "NV",
},
{
name: "New Hampshire",
abbreviation: "NH",
},
{
name: "New Jersey",
abbreviation: "NJ",
},
{
name: "New Mexico",
abbreviation: "NM",
},
{
name: "New York",
abbreviation: "NY",
},
{
name: "North Carolina",
abbreviation: "NC",
},
{
name: "North Dakota",
abbreviation: "ND",
},
{
name: "Northern Mariana Islands",
abbreviation: "MP",
},
{
name: "Ohio",
abbreviation: "OH",
},
{
name: "Oklahoma",
abbreviation: "OK",
},
{
name: "Oregon",
abbreviation: "OR",
},
{
name: "Pennsylvania",
abbreviation: "PA",
},
{
name: "Puerto Rico",
abbreviation: "PR",
},
{
name: "Rhode Island",
abbreviation: "RI",
},
{
name: "South Carolina",
abbreviation: "SC",
},
{
name: "South Dakota",
abbreviation: "SD",
},
{
name: "Tennessee",
abbreviation: "TN",
},
{
name: "Texas",
abbreviation: "TX",
},
{
name: "Utah",
abbreviation: "UT",
},
{
name: "Vermont",
abbreviation: "VT",
},
{
name: "Virgin Islands",
abbreviation: "VI",
},
{
name: "Virginia",
abbreviation: "VA",
},
{
name: "Washington",
abbreviation: "WA",
},
{
name: "West Virginia",
abbreviation: "WV",
},
{
name: "Wisconsin",
abbreviation: "WI",
},
{
name: "Wyoming",
abbreviation: "WY",
},
] as const;
export type StateName = (typeof states)[number]["name"];
export type StateAbbreviation = (typeof states)[number]["abbreviation"];
export interface State {
name: StateName;
abbreviation: StateAbbreviation;
}