|
1 | 1 | ---
|
2 | 2 | description: "Choose from predefined options"
|
3 | 3 | icon: ListFilter
|
| 4 | +status: complete |
4 | 5 | ---
|
5 | 6 |
|
| 7 | +import { BrowserSupport } from "@app/_components/browser-support"; |
6 | 8 | import { Callout } from "nextra/components";
|
7 | 9 |
|
8 | 10 | # Selection Input
|
9 | 11 |
|
10 | 12 | **_(Also called dropdown, select)_**
|
11 | 13 |
|
12 |
| -<Callout type="warning"> |
13 |
| - This page is empty for now. Please help us by |
14 |
| - [contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md) |
15 |
| - to add content. |
16 |
| -</Callout> |
| 14 | +## Overview |
| 15 | + |
| 16 | +A **selection input** is a form control that allows users to choose one option from a predefined list of options. |
| 17 | + |
| 18 | +The selected option is typically displayed in a single-line text field, with the list of options hidden until the user interacts with the control. |
| 19 | + |
| 20 | +## Use Cases |
| 21 | + |
| 22 | +### When to use: |
| 23 | + |
| 24 | +- When users need to select a single option from a list of predefined choices |
| 25 | +- When the list of options is relatively short (less than 10-15 items) |
| 26 | +- When screen space is limited, and displaying all options at once is not feasible |
| 27 | +- When the selected option doesn't need to be visible at all times |
| 28 | + |
| 29 | +### When not to use: |
| 30 | + |
| 31 | +- When users need to select multiple options (use checkboxes or a [multi-select](/patterns/forms/multi-select-input) instead) |
| 32 | +- When the list of options is very long (consider using an [autocomplete](/patterns/forms/autocomplete) or a typeahead) |
| 33 | +- When users need to input free-form text (use a regular text input instead) |
| 34 | +- When the options are complex or require additional information or visual aids |
| 35 | + |
| 36 | +### Common scenarios and examples |
| 37 | + |
| 38 | +- Selecting a country from a list of all countries |
| 39 | +- Choosing a preferred language from a list of supported languages |
| 40 | +- Selecting a payment method during checkout |
| 41 | +- Choosing a size, color, or other product variant on an e-commerce site |
| 42 | + |
| 43 | +## Benefits |
| 44 | + |
| 45 | +- Saves screen space by hiding options until needed |
| 46 | +- Provides a clear and concise way to select from predefined options |
| 47 | +- Prevents user input errors by limiting choices to valid options |
| 48 | +- Allows for easy selection using a mouse, keyboard, or touch input |
| 49 | + |
| 50 | +## Anatomy |
| 51 | + |
| 52 | +### Component Structure |
| 53 | + |
| 54 | +```mermaid |
| 55 | +graph TD |
| 56 | + A[Selection Input Container] --> B[Text Field] |
| 57 | + A --> C[Dropdown List] |
| 58 | + B --> B1[Selected Value] |
| 59 | + B --> B2[Caret Icon] |
| 60 | + C --> D1[Option 1] |
| 61 | + C --> D2[Option 2] |
| 62 | + C --> D3[Option 3] |
| 63 | + C --> E[Scrollbar] |
| 64 | +``` |
| 65 | + |
| 66 | +1. **Container** |
| 67 | + |
| 68 | + - Wraps the selection input and its associated elements |
| 69 | + - Defines the overall dimensions and positioning of the component |
| 70 | + |
| 71 | +2. **Text Field** |
| 72 | + |
| 73 | + - Displays the currently selected option |
| 74 | + - Acts as a button to trigger the dropdown list |
| 75 | + - Often includes a caret or arrow icon to indicate the presence of a dropdown |
| 76 | + |
| 77 | +3. **Dropdown List** |
| 78 | + |
| 79 | + - Contains the list of available options |
| 80 | + - Appears when the text field is clicked or receives focus |
| 81 | + - Can be positioned above or below the text field, depending on available space |
| 82 | + |
| 83 | +4. **Options** |
| 84 | + |
| 85 | + - Individual items within the dropdown list |
| 86 | + - Represent the available choices for the user |
| 87 | + - Should have a clear and concise label |
| 88 | + - Can include icons, images, or other visual aids if necessary |
| 89 | + |
| 90 | +5. **Scrollbar (Optional)** |
| 91 | + |
| 92 | + - Allows users to scroll through the list of options if the list is too long to fit within the available space |
| 93 | + - Can be styled to match the overall design of the component |
| 94 | + |
| 95 | +## Best Practices |
| 96 | + |
| 97 | +### Content |
| 98 | + |
| 99 | +**Do's ✅** |
| 100 | + |
| 101 | +- Use clear and concise labels for each option |
| 102 | +- Keep the list of options relatively short (less than 10-15 items) |
| 103 | +- Order options logically (e.g., alphabetically, by popularity, or by relevance) |
| 104 | +- Provide a default or pre-selected option when applicable |
| 105 | + |
| 106 | +**Don'ts ❌** |
| 107 | + |
| 108 | +- Don't use overly long or complex option labels |
| 109 | +- Avoid using jargon or technical terms that users may not understand |
| 110 | +- Don't include options that are not relevant or applicable to the user's context |
| 111 | + |
| 112 | +### Accessibility & UX |
| 113 | + |
| 114 | +**Do's ✅** |
| 115 | + |
| 116 | +- Ensure the selection input is keyboard accessible (arrow keys to navigate, Enter to select) |
| 117 | +- Provide a clear focus state for the text field and individual options |
| 118 | +- Use ARIA attributes to communicate the component's state and purpose |
| 119 | +- Allow users to filter or search the list of options if the list is long |
| 120 | + |
| 121 | +**Don'ts ❌** |
| 122 | + |
| 123 | +- Don't rely solely on color to convey the state or purpose of the component |
| 124 | +- Avoid using auto-selection or auto-submission when an option is highlighted |
| 125 | +- Don't change the order or content of options unexpectedly |
| 126 | + |
| 127 | +### Visual Design |
| 128 | + |
| 129 | +**Do's ✅** |
| 130 | + |
| 131 | +- Use a consistent visual style for the text field, dropdown list, and options |
| 132 | +- Provide ample whitespace and padding to improve readability and usability |
| 133 | +- Use a contrasting color or style to indicate the selected option |
| 134 | +- Ensure the dropdown list is visually distinct from the text field |
| 135 | + |
| 136 | +**Don'ts ❌** |
| 137 | + |
| 138 | +- Don't use low-contrast colors or small font sizes that reduce legibility |
| 139 | +- Avoid using overly complex or decorative styles that distract from the content |
| 140 | +- Don't make the dropdown list too narrow or too wide relative to the text field |
| 141 | + |
| 142 | +### Layout & Positioning |
| 143 | + |
| 144 | +**Do's ✅** |
| 145 | + |
| 146 | +- Position the dropdown list close to the text field for easy association |
| 147 | +- Ensure the dropdown list doesn't obstruct other important content or UI elements |
| 148 | +- Align the text field and dropdown list with other form controls for a cohesive layout |
| 149 | + |
| 150 | +**Don'ts ❌** |
| 151 | + |
| 152 | +- Don't place the dropdown list too far away from the text field |
| 153 | +- Avoid positioning the dropdown list in a way that requires excessive scrolling or mouse movement |
| 154 | + |
| 155 | +## Code Examples |
| 156 | + |
| 157 | +### Basic Implementation |
| 158 | + |
| 159 | +```html |
| 160 | +<label for="fruits">Choose a fruit:</label> |
| 161 | +<select id="fruits" name="fruits"> |
| 162 | + <option value="apple">Apple</option> |
| 163 | + <option value="banana">Banana</option> |
| 164 | + <option value="orange">Orange</option> |
| 165 | + <option value="strawberry">Strawberry</option> |
| 166 | +</select> |
| 167 | +``` |
| 168 | + |
| 169 | +## Browser Support |
| 170 | + |
| 171 | +<BrowserSupport |
| 172 | + features={[ |
| 173 | + "html.elements.select", |
| 174 | + "html.elements.option", |
| 175 | + "html.elements.optgroup", |
| 176 | + "api.HTMLSelectElement", |
| 177 | + ]} |
| 178 | +/> |
| 179 | + |
| 180 | +## Design Tokens |
| 181 | + |
| 182 | +These design tokens follow the [Design Tokens Format](https://design-tokens.github.io/community-group/format/) specification and can be used with various token transformation tools to generate platform-specific variables. |
| 183 | + |
| 184 | +### Selection Input Tokens in DTF Format |
| 185 | + |
| 186 | +```json |
| 187 | +{ |
| 188 | + "$schema": "https://design-tokens.org/schema.json", |
| 189 | + "selectionInput": { |
| 190 | + "container": { |
| 191 | + "minWidth": { "value": "200px", "type": "dimension" } |
| 192 | + }, |
| 193 | + "textField": { |
| 194 | + "padding": { |
| 195 | + "vertical": { "value": "0.5rem", "type": "dimension" }, |
| 196 | + "horizontal": { "value": "1rem", "type": "dimension" } |
| 197 | + }, |
| 198 | + "border": { |
| 199 | + "width": { "value": "1px", "type": "dimension" }, |
| 200 | + "color": { "value": "{color.gray.300}", "type": "color" }, |
| 201 | + "radius": { "value": "0.25rem", "type": "dimension" } |
| 202 | + }, |
| 203 | + "background": { |
| 204 | + "color": { "value": "{color.white}", "type": "color" } |
| 205 | + }, |
| 206 | + "typography": { |
| 207 | + "fontSize": { "value": "1rem", "type": "dimension" }, |
| 208 | + "lineHeight": { "value": "1.5", "type": "number" } |
| 209 | + }, |
| 210 | + "color": { |
| 211 | + "default": { "value": "{color.gray.900}", "type": "color" }, |
| 212 | + "disabled": { "value": "{color.gray.500}", "type": "color" } |
| 213 | + }, |
| 214 | + "icon": { |
| 215 | + "size": { "value": "1.5rem", "type": "dimension" }, |
| 216 | + "color": { "value": "{color.gray.500}", "type": "color" } |
| 217 | + } |
| 218 | + }, |
| 219 | + "dropdownList": { |
| 220 | + "maxHeight": { "value": "300px", "type": "dimension" }, |
| 221 | + "border": { |
| 222 | + "width": { "value": "1px", "type": "dimension" }, |
| 223 | + "color": { "value": "{color.gray.300}", "type": "color" } |
| 224 | + }, |
| 225 | + "background": { |
| 226 | + "color": { "value": "{color.white}", "type": "color" } |
| 227 | + }, |
| 228 | + "shadow": { |
| 229 | + "offsetX": { "value": "0", "type": "dimension" }, |
| 230 | + "offsetY": { "value": "2px", "type": "dimension" }, |
| 231 | + "blurRadius": { "value": "4px", "type": "dimension" }, |
| 232 | + "color": { "value": "rgba(0, 0, 0, 0.1)", "type": "color" } |
| 233 | + } |
| 234 | + }, |
| 235 | + "option": { |
| 236 | + "padding": { |
| 237 | + "vertical": { "value": "0.5rem", "type": "dimension" }, |
| 238 | + "horizontal": { "value": "1rem", "type": "dimension" } |
| 239 | + }, |
| 240 | + "color": { |
| 241 | + "default": { "value": "{color.gray.700}", "type": "color" }, |
| 242 | + "hover": { "value": "{color.gray.900}", "type": "color" }, |
| 243 | + "selected": { "value": "{color.primary.600}", "type": "color" } |
| 244 | + }, |
| 245 | + "background": { |
| 246 | + "default": { "value": "{color.white}", "type": "color" }, |
| 247 | + "hover": { "value": "{color.gray.100}", "type": "color" }, |
| 248 | + "selected": { "value": "{color.primary.50}", "type": "color" } |
| 249 | + } |
| 250 | + } |
| 251 | + } |
| 252 | +} |
| 253 | +``` |
| 254 | + |
| 255 | +## Resources |
| 256 | + |
| 257 | +- [Request for developer feedback: customizable select](https://developer.chrome.com/blog/rfc-customizable-select) |
| 258 | + |
| 259 | +### Articles |
| 260 | + |
| 261 | +- [Designing Drop-Down Menus: Examples and Best Practices](https://www.smashingmagazine.com/2009/03/designing-drop-down-menus-examples-and-best-practices/) |
| 262 | +- [Listboxes vs. Dropdown Lists](https://www.nngroup.com/articles/listbox-dropdown/) |
| 263 | + |
| 264 | +## Libraries |
| 265 | + |
| 266 | +- [Select - shadcn/ui](https://ui.shadcn.com/docs/components/select) |
| 267 | +- [Select - OriginUI](https://originui.com/selects) |
0 commit comments