# Select (w-select)

## Description

A dropdown component for selecting a single value.

[Warp component reference](https://warp-ds.github.io/docs/components/select/frameworks/elements)

## Usage

<elements-example>

```html
<w-select label="Berries">
    <option value="raspberries">Raspberries</option>
    <option value="strawberries">Strawberries</option>
    <option value="cloudberries">Cloudberries</option>
</w-select>
```

</elements-example>

### Validation

Set the `invalid` attribute to display a textfield as invalid.

`invalid` should be paired with `help-text` to provide feedback to the user about how to correct the error.

<elements-example>

```html
<w-select label="Berries" invalid help-text="Select a red berry">
    <option value="raspberries">Raspberries</option>
    <option value="strawberries">Strawberries</option>
    <option value="cloudberries" selected>Cloudberries</option>
</w-select>
```

</elements-example>

## Accessibility

If a visible label isn't specified, an `aria-label` must be provided to the text field for accessibility. If the field is labeled by a separate element, an `aria-labelledby` property must be provided using the `id` of the labeling element instead.

## Examples

<elements-example>

```html
<w-select label="Berries">
    <option value="raspberries">Raspberries</option>
    <option value="strawberries">Strawberries</option>
    <option value="cloudberries">Cloudberries</option>
</w-select>
```

</elements-example>

### Placeholder

A select doesn't have a `placeholder` as such, but an `<option>` with an empty value gives a similar result.

<elements-example>

```html
<w-select label="Berries">
    <option value="">Select an option</option>
    <option value="raspberries">Raspberries</option>
    <option value="strawberries">Strawberries</option>
    <option value="cloudberries">Cloudberries</option>
</w-select>
```

</elements-example>

### Optional

Add the `optional` prop to indicate that the select is not required. To make the select optional you must add an `<option>` with an empty value.

<elements-example>

```html
<w-select label="Berries" optional>
    <option value="">Select an option</option>
    <option value="raspberries">Raspberries</option>
    <option value="strawberries">Strawberries</option>
    <option value="cloudberries">Cloudberries</option>
</w-select>
```

</elements-example>

### Help text

Use `help-text` to give additional context when the label and options are not enough.

<elements-example>

```html
<w-select label="Berries" help-text="We assume this is your jam">
    <option value="raspberries">Raspberries</option>
    <option value="strawberries">Strawberries</option>
    <option value="cloudberries">Cloudberries</option>
</w-select>
```

</elements-example>

### No visual label

You must set either an `aria-label` or an [`aria-labelledby`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-labelledby).

<elements-example>

```html
<w-select aria-label="Berries">
    <option value="raspberries">Raspberries</option>
    <option value="strawberries" selected>Strawberries</option>
    <option value="cloudberries">Cloudberries</option>
</w-select>
```

</elements-example>


### Disabled

Keep in mind that using disabled is an anti-pattern.

There will always be users who don't understand why an element is disabled, or users who can't even see that
it is disabled because of poor lighting conditions or other reasons.

Please consider more informative alternatives before choosing to use disabled on an element.

<elements-example>
    
```html
<w-select label="Berries" disabled>
    <option value="raspberries">Raspberries</option>
    <option value="strawberries">Strawberries</option>
    <option value="cloudberries">Cloudberries</option>
</w-select>
```

</elements-example>

### Read only

The `readonly` boolean attribute makes the selection immutable. Unlike disabled the select remains focusable. See [MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/readOnly) for more information.

<elements-example>

```html
<w-select label="Berries" readonly>
    <option value="raspberries">Raspberries</option>
    <option value="strawberries">Strawberries</option>
    <option value="cloudberries">Cloudberries</option>
</w-select>
```

</elements-example>

## Styling API

This section documents the supported styling hooks for `<w-select>`.

Use these hooks to customize appearance without relying on internal structure or selectors.

Before changing the default styles, remember that doing so can result in less consistent experiences for users across the product. Prefer defaults.

- Prefer **component tokens** for size, spacing, and state styling.
- Use **parts** only for small, local tweaks.
- Avoid relying on internal class names or selectors.

### Parts

The select exposes a minimal set of parts that can be targeted for last‑mile layout or typography tweaks.

| Part | Targets | Typical use |
|---|---|---|
| `input` | native select element | minor typography or spacing tweaks |

Example:

```css
w-select::part(input) {
  letter-spacing: 0.5px;
}
```

Parts are intended as an **escape hatch**.
Prefer component tokens for anything state‑ or size‑related.


### Component tokens

Component tokens (`--w-c-input-*`) act as inputs to the select styling.
They can be set directly on the component or inherited from a parent container.

These tokens are **shared across textfield, textarea, and select** for consistent form styling.

```css
.form-section {
  --w-c-input-label-font-weight: 600;
  --w-c-input-help-text-color: var(--w-s-color-text);
}
```

Defaults are defined internally; setting a token is always optional.


#### Label tokens

| Token | Purpose | Default |
|---|---|---|
| `--w-c-input-label-color` | label text color | `--w-s-color-text` |
| `--w-c-input-label-font-size` | label font size | `--w-font-size-s` |
| `--w-c-input-label-line-height` | label line height | `--w-line-height-s` |
| `--w-c-input-label-font-weight` | label font weight | `700` |
| `--w-c-input-label-padding-bottom` | space below label | `0.4rem` |
| `--w-c-input-label-cursor` | cursor when hovering label | `pointer` |
| `--w-c-input-label-display` | label display mode | `block` |


#### Optional indicator tokens

When `optional` attribute is set, these tokens control the "(optional)" text styling:

| Token | Purpose | Default |
|---|---|---|
| `--w-c-input-optional-color` | optional text color | `--w-s-color-text-subtle` |
| `--w-c-input-optional-font-size` | optional text font size | `--w-font-size-s` |
| `--w-c-input-optional-line-height` | optional text line height | `--w-line-height-s` |
| `--w-c-input-optional-font-weight` | optional text font weight | `400` |
| `--w-c-input-optional-padding-left` | space before optional text | `0.8rem` |


#### Help text tokens

| Token | Purpose | Default |
|---|---|---|
| `--w-c-input-help-text-color` | help text color (normal state) | `--w-s-color-text-subtle` |
| `--w-c-input-help-text-color-invalid` | help text color when invalid | `--w-s-color-text-negative` |
| `--w-c-input-help-text-font-size` | help text font size | `--w-font-size-xs` |
| `--w-c-input-help-text-line-height` | help text line height | `--w-line-height-xs` |
| `--w-c-input-help-text-margin-top` | space above help text | `0.4rem` |
| `--w-c-input-help-text-display` | help text display mode | `block` |


## Implementation notes

### Shared token system

Select shares its label, optional indicator, and help text tokens with `w-textfield` and `w-textarea`. This ensures consistent form styling across all text input components.

## `<w-select>` API

Unless otherwise noted all properties are HTML attributes (as opposed to JavaScript object properties).

### Properties

| Name | Type | Default | Summary |
|-|-|-|-|
| always | `boolean` | `false` | Whether to always show a hint. **Deprecated**: Use `help-text` instead and only set it if you want to display the help text. |
| auto-focus | `boolean` | `false` | Whether the element should receive focus on render. **Deprecated**: Use the native `autofocus` attribute instead. |
| autofocus | `boolean` | `false` | Whether the element should receive focus on render |
| disabled | `boolean` | `false` | Renders the field in a disabled state. |
| help-text | `string \| undefined` | `-` | The content displayed as the help text. |
| hint | `string \| undefined` | `-` | The content displayed as the help text. **Deprecated**: Use `help-text` instead. |
| invalid | `boolean` | `false` | Renders the field in an invalid state. |
| label | `string \| undefined` | `-` | The content to display as the label. |
| name | `string \| undefined` | `-` | The [name](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input#name) of the select when submitting the form. |
| optional | `boolean` | `false` | Whether to show the optional indicator after the label. |
| read-only | `boolean` | `false` | Renders the field in a readonly state. **Deprecated**: Use the native readonly attribute instead. |
| readonly | `boolean` | `false` | Renders the field in a readonly state. |
| value | `string \| undefined` | `-` | Lets you set the current value. |

### Property Details

#### always

**Deprecated**: Use `help-text` instead and only set it if you want to display the help text.

Whether to always show a hint.

- Type: `boolean`
- Default: `false`

#### auto-focus

**Deprecated**: Use the native `autofocus` attribute instead.

Whether the element should receive focus on render.

- Type: `boolean`
- Default: `false`

#### autofocus

Whether the element should receive focus on render

- Type: `boolean`
- Default: `false`

#### disabled

Renders the field in a disabled state.

- Type: `boolean`
- Default: `false`

#### help-text

The content displayed as the help text.

Paired with `invalid` to show the text as a validation error.

- Type: `string | undefined`
- Default: `-`

#### hint

**Deprecated**: Use `help-text` instead.

The content displayed as the help text.

- Type: `string | undefined`
- Default: `-`

#### invalid

Renders the field in an invalid state.

Paired with `help-text` to provide feedback about the error.

- Type: `boolean`
- Default: `false`

#### label

The content to display as the label.

- Type: `string | undefined`
- Default: `-`

#### name

The [name](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input#name) of the select when submitting the form.

- Type: `string | undefined`
- Default: `-`

#### optional

Whether to show the optional indicator after the label.

- Type: `boolean`
- Default: `false`

#### read-only

**Deprecated**: Use the native readonly attribute instead.

Renders the field in a readonly state.

- Type: `boolean`
- Default: `false`

#### readonly

Renders the field in a readonly state.

- Type: `boolean`
- Default: `false`

#### value

Lets you set the current value.

- Type: `string | undefined`
- Default: `-`

### Events

#### change



- Type: `CustomEvent`


