3.0.0-alpha.9 Alpha
Components

Select

<wa-select> Since 2.0 Stable

Selects allow you to choose items from a menu of predefined options.

Just want the styles? Check out the Select native styles!
Option 1 Option 2 Option 3 Option 4 Option 5 Option 6
<wa-select>
  <wa-option value="option-1">Option 1</wa-option>
  <wa-option value="option-2">Option 2</wa-option>
  <wa-option value="option-3">Option 3</wa-option>
  <wa-option value="option-4">Option 4</wa-option>
  <wa-option value="option-5">Option 5</wa-option>
  <wa-option value="option-6">Option 6</wa-option>
</wa-select>

This component works with standard <form> elements. Please refer to the section on form controls to learn more about form submission and client-side validation.

Examples

Labels

Use the label attribute to give the select an accessible label. For labels that contain HTML, use the label slot instead.

Option 1 Option 2 Option 3
<wa-select label="Select one">
  <wa-option value="option-1">Option 1</wa-option>
  <wa-option value="option-2">Option 2</wa-option>
  <wa-option value="option-3">Option 3</wa-option>
</wa-select>

Hint

Add descriptive hint to a select with the hint attribute. For hints that contain HTML, use the hint slot instead.

Novice Intermediate Advanced
<wa-select label="Experience" hint="Please tell us your skill level.">
  <wa-option value="1">Novice</wa-option>
  <wa-option value="2">Intermediate</wa-option>
  <wa-option value="3">Advanced</wa-option>
</wa-select>

Placeholders

Use the placeholder attribute to add a placeholder.

Option 1 Option 2 Option 3
<wa-select placeholder="Select one">
  <wa-option value="option-1">Option 1</wa-option>
  <wa-option value="option-2">Option 2</wa-option>
  <wa-option value="option-3">Option 3</wa-option>
</wa-select>

Clearable

Use the clearable attribute to make the control clearable. The clear button only appears when an option is selected.

Option 1 Option 2 Option 3
<wa-select clearable value="option-1">
  <wa-option value="option-1">Option 1</wa-option>
  <wa-option value="option-2">Option 2</wa-option>
  <wa-option value="option-3">Option 3</wa-option>
</wa-select>

Appearance

Use the appearance attribute to change the select's visual appearance.

Option 1 Option 2 Option 3
<wa-select appearance="filled">
  <wa-option value="option-1">Option 1</wa-option>
  <wa-option value="option-2">Option 2</wa-option>
  <wa-option value="option-3">Option 3</wa-option>
</wa-select>

Pill

Use the pill attribute to give selects rounded edges.

Option 1 Option 2 Option 3
<wa-select pill>
  <wa-option value="option-1">Option 1</wa-option>
  <wa-option value="option-2">Option 2</wa-option>
  <wa-option value="option-3">Option 3</wa-option>
</wa-select>

Disabled

Use the disabled attribute to disable a select.

Option 1 Option 2 Option 3
<wa-select placeholder="Disabled" disabled>
  <wa-option value="option-1">Option 1</wa-option>
  <wa-option value="option-2">Option 2</wa-option>
  <wa-option value="option-3">Option 3</wa-option>
</wa-select>

Multiple

To allow multiple options to be selected, use the multiple attribute. It's a good practice to use clearable when this option is enabled. To set multiple values at once, set value to a space-delimited list of values.

Option 1 Option 2 Option 3 Option 4 Option 5 Option 6
<wa-select label="Select a Few" value="option-1 option-2 option-3" multiple clearable>
  <wa-option value="option-1">Option 1</wa-option>
  <wa-option value="option-2">Option 2</wa-option>
  <wa-option value="option-3">Option 3</wa-option>
  <wa-option value="option-4">Option 4</wa-option>
  <wa-option value="option-5">Option 5</wa-option>
  <wa-option value="option-6">Option 6</wa-option>
</wa-select>

Note that multi-select options may wrap, causing the control to expand vertically. You can use the max-options-visible attribute to control the maximum number of selected options to show at once.

Setting Initial Values

Use the value attribute to set the initial selection.

When using multiple, the value attribute uses space-delimited values to select more than one option. Because of this, <wa-option> values cannot contain spaces. If you're accessing the value property through Javascript, it will be an array.

Option 1 Option 2 Option 3 Option 4
<wa-select value="option-1 option-2" multiple clearable>
  <wa-option value="option-1">Option 1</wa-option>
  <wa-option value="option-2">Option 2</wa-option>
  <wa-option value="option-3">Option 3</wa-option>
  <wa-option value="option-4">Option 4</wa-option>
</wa-select>

Grouping Options

Use <wa-divider> to group listbox items visually. You can also use <small> to provide labels, but they won't be announced by most assistive devices.

Section 1 Option 1 Option 2 Option 3 Section 2 Option 4 Option 5 Option 6
<wa-select>
  <small>Section 1</small>
  <wa-option value="option-1">Option 1</wa-option>
  <wa-option value="option-2">Option 2</wa-option>
  <wa-option value="option-3">Option 3</wa-option>
  <wa-divider></wa-divider>
  <small>Section 2</small>
  <wa-option value="option-4">Option 4</wa-option>
  <wa-option value="option-5">Option 5</wa-option>
  <wa-option value="option-6">Option 6</wa-option>
</wa-select>

Sizes

Use the size attribute to change a select's size. Note that size does not apply to listbox options.

Option 1 Option 2 Option 3
Option 1 Option 2 Option 3
Option 1 Option 2 Option 3
<wa-select placeholder="Small" size="small">
  <wa-option value="option-1">Option 1</wa-option>
  <wa-option value="option-2">Option 2</wa-option>
  <wa-option value="option-3">Option 3</wa-option>
</wa-select>

<br />

<wa-select placeholder="Medium" size="medium">
  <wa-option value="option-1">Option 1</wa-option>
  <wa-option value="option-2">Option 2</wa-option>
  <wa-option value="option-3">Option 3</wa-option>
</wa-select>

<br />

<wa-select placeholder="Large" size="large">
  <wa-option value="option-1">Option 1</wa-option>
  <wa-option value="option-2">Option 2</wa-option>
  <wa-option value="option-3">Option 3</wa-option>
</wa-select>

Placement

The preferred placement of the select's listbox can be set with the placement attribute. Note that the actual position may vary to ensure the panel remains in the viewport. Valid placements are top and bottom.

Option 1 Option 2 Option 3
<wa-select placement="top">
  <wa-option value="option-1">Option 1</wa-option>
  <wa-option value="option-2">Option 2</wa-option>
  <wa-option value="option-3">Option 3</wa-option>
</wa-select>

Prefix Icons

Use the prefix slot to prepend an icon to the control.

Option 1 Option 2 Option 3
Option 1 Option 2 Option 3
Option 1 Option 2 Option 3
<wa-select placeholder="Small" size="small" clearable>
  <wa-icon slot="prefix" name="house" variant="solid"></wa-icon>
  <wa-option value="option-1">Option 1</wa-option>
  <wa-option value="option-2">Option 2</wa-option>
  <wa-option value="option-3">Option 3</wa-option>
</wa-select>
<br />
<wa-select placeholder="Medium" size="medium" clearable>
  <wa-icon slot="prefix" name="house" variant="solid"></wa-icon>
  <wa-option value="option-1">Option 1</wa-option>
  <wa-option value="option-2">Option 2</wa-option>
  <wa-option value="option-3">Option 3</wa-option>
</wa-select>
<br />
<wa-select placeholder="Large" size="large" clearable>
  <wa-icon slot="prefix" name="house" variant="solid"></wa-icon>
  <wa-option value="option-1">Option 1</wa-option>
  <wa-option value="option-2">Option 2</wa-option>
  <wa-option value="option-3">Option 3</wa-option>
</wa-select>

Suffix Icons

Use the suffix slot to append an icon to the control.

Option 1 Option 2 Option 3
Option 1 Option 2 Option 3
Option 1 Option 2 Option 3
<wa-select placeholder="Small" size="small" clearable>
  <wa-icon name="house" slot="suffix"></wa-icon>
  <wa-option value="option-1">Option 1</wa-option>
  <wa-option value="option-2">Option 2</wa-option>
  <wa-option value="option-3">Option 3</wa-option>
</wa-select>
<br />
<wa-select placeholder="Medium" size="medium" clearable>
  <wa-icon name="house" slot="suffix"></wa-icon>
  <wa-option value="option-1">Option 1</wa-option>
  <wa-option value="option-2">Option 2</wa-option>
  <wa-option value="option-3">Option 3</wa-option>
</wa-select>
<br />
<wa-select placeholder="Large" size="large" clearable>
  <wa-icon name="house" slot="suffix"></wa-icon>
  <wa-option value="option-1">Option 1</wa-option>
  <wa-option value="option-2">Option 2</wa-option>
  <wa-option value="option-3">Option 3</wa-option>
</wa-select>

Custom Tags

When multiple options can be selected, you can provide custom tags by passing a function to the getTag property. Your function can return a string of HTML, a Lit Template, or an HTMLElement. The getTag() function will be called for each option. The first argument is an <wa-option> element and the second argument is the tag's index (its position in the tag list).

Remember that custom tags are rendered in a shadow root. To style them, you can use the style attribute in your template or you can add your own parts and target them with the ::part() selector.

Email Phone Chat
<wa-select
  placeholder="Select one"
  value="email phone"
  multiple
  clearable
  class="custom-tag"
>
  <wa-option value="email">
    <wa-icon slot="prefix" name="envelope" variant="solid"></wa-icon>
    Email
  </wa-option>
  <wa-option value="phone">
    <wa-icon slot="prefix" name="phone" variant="solid"></wa-icon>
    Phone
  </wa-option>
  <wa-option value="chat">
    <wa-icon slot="prefix" name="comment" variant="solid"></wa-icon>
    Chat
  </wa-option>
</wa-select>

<script type="module">
  await customElements.whenDefined("wa-select")
  const select = document.querySelector('.custom-tag');
  await select.updateComplete

  select.getTag = (option, index) => {
    // Use the same icon used in wa-option
    const name = option.querySelector('wa-icon[slot="prefix"]').name;

    // You can return a string, a Lit Template, or an HTMLElement here
    return `
      <wa-tag removable>
        <wa-icon name="${name}" style="padding-inline-end: .5rem;"></wa-icon>
        ${option.getTextLabel()}
      </wa-tag>
    `;
  };
</script>

Be sure you trust the content you are outputting! Passing unsanitized user input to getTag() can result in XSS vulnerabilities.

Lazy loading options

Lazy loading options is very hard to get right. <wa-select> largely follows how a native <select> works.

Here are the following conditions:

EX: <wa-select value="foo"> will have a value of "" until <wa-option value="foo">Foo</wa-option> connects, at which point its value will become "foo" when submitting.

This can be hard to conceptualize, so heres a fairly large example showing how lazy loaded options work with <wa-select> and <wa-select multiple> when given initial value attributes. Feel free to play around with it in a codepen.

Bar Baz
Add "foo" option


Add "foo" option

Bar Baz
Add "foo" option


Add "foo" option


Reset Show FormData


<form id="lazy-options-example">
  <div>
    <wa-select name="select-1" value="foo" label="Single select (with existing options)">
      <wa-option value="bar">Bar</wa-option>
      <wa-option value="baz">Baz</wa-option>
    </wa-select>
    <br>
    <wa-button type="button">Add "foo" option</wa-button>
  </div>

  <br>

  <div>
    <wa-select name="select-2" value="foo" label="Single select (with no existing options)">
    </wa-select>
    <br>
    <wa-button type="button">Add "foo" option</wa-button>
  </div>

  <br>

  <div>
    <wa-select name="select-3" value="foo bar baz" multiple label="Multiple Select (with existing options)">
      <wa-option value="bar">Bar</wa-option>
      <wa-option value="baz">Baz</wa-option>
    </wa-select>
    <br>
    <wa-button type="button">Add "foo" option</wa-button>
  </div>

  <br>

  <div>
    <wa-select name="select-4" value="foo" multiple label="Multiple Select (with no existing options)">
    </wa-select>
    <br>
    <wa-button type="button">Add "foo" option</wa-button>
  </div>

  <br><br>

  <div style="display: flex; gap: 16px;">
    <wa-button type="reset">Reset</wa-button>
    <wa-button type="submit" variant="brand">Show FormData</wa-button>
  </div>

  <br>

  <pre hidden><code id="lazy-options-example-form-data"></code></pre>

  <br>
</form>

<script type="module">
  function addFooOption(e) {
    const addFooButton = e.target.closest("wa-button[type='button']")
    if (!addFooButton) {
      return
    }
    const select = addFooButton.parentElement.querySelector("wa-select")

    if (select.querySelector("wa-option[value='foo']")) {
      // Foo already exists. no-op.
      return
    }

    const option = document.createElement("wa-option")
    option.setAttribute("value", "foo")
    option.innerText = "Foo"
    select.append(option)
  }

  function handleLazySubmit (event) {
    event.preventDefault()

    const formData = new FormData(event.target)
    const codeElement = document.querySelector("#lazy-options-example-form-data")

    const obj = {}
    for (const key of formData.keys()) {
      const val = formData.getAll(key).length > 1 ? formData.getAll(key) : formData.get(key)
      obj[key] = val
    }

    codeElement.textContent = JSON.stringify(obj, null, 2)

    const preElement = codeElement.parentElement
    preElement.removeAttribute("hidden")
  }

  const container = document.querySelector("#lazy-options-example")
  container.addEventListener("click", addFooOption)
  container.addEventListener("submit", handleLazySubmit)
</script>

Slots

Learn more about using slots.

Name Description
(default) The listbox options. Must be <wa-option> elements. You can use <wa-divider> to group items visually.
label The input's label. Alternatively, you can use the label attribute.
prefix Used to prepend a presentational icon or similar element to the combobox.
suffix Used to append a presentational icon or similar element to the combobox.
clear-icon An icon to use in lieu of the default clear icon.
expand-icon The icon to show when the control is expanded and collapsed. Rotates on open and close.
hint Text that describes how to use the input. Alternatively, you can use the hint attribute.

Attributes & Properties

Learn more about attributes and properties.

Name Description Reflects
validationTarget
Where to anchor native constraint validation
name
name
The name of the select, submitted as a name/value pair with form data.
Type string
Default ''
size
size
The select's size.
Type 'small' | 'medium' | 'large'
Default 'medium'
placeholder
placeholder
Placeholder text to show as a hint when the select is empty.
Type string
Default ''
multiple
multiple
Allows more than one option to be selected.
Type boolean
Default false
maxOptionsVisible
max-options-visible
The maximum number of selected options to show when multiple is true. After the maximum, "+n" will be shown to indicate the number of additional items that are selected. Set to 0 to remove the limit.
Type number
Default 3
disabled
disabled
Disables the select control.
Type boolean
Default false
clearable
clearable
Adds a clear button when the select is not empty.
Type boolean
Default false
open
open
Indicates whether or not the select is open. You can toggle this attribute to show and hide the menu, or you can use the show() and hide() methods and this attribute will reflect the select's open state.
Type boolean
Default false
hoist
hoist
Enable this option to prevent the listbox from being clipped when the component is placed inside a container with overflow: auto|scroll. Hoisting uses a fixed positioning strategy that works in many, but not all, scenarios.
Type boolean
Default false
appearance
appearance
The select's visual appearance.
Type 'filled' | 'outlined'
Default 'outlined'
pill
pill
Draws a pill-style select with rounded edges.
Type boolean
Default false
label
label
The select's label. If you need to display HTML, use the label slot instead.
Type string
Default ''
placement
placement
The preferred placement of the select's menu. Note that the actual placement may vary as needed to keep the listbox inside of the viewport.
Type 'top' | 'bottom'
Default 'bottom'
hint
hint
The select's hint. If you need to display HTML, use the hint slot instead.
Type string
Default ''
withLabel
with-label
Used for SSR purposes when a label is slotted in. Will show the label on first render.
Type boolean
Default false
withHint
with-hint
Used for SSR purposes when hint is slotted in. Will show the hint on first render.
Type boolean
Default false
form
form
By default, form controls are associated with the nearest containing <form> element. This attribute allows you to place the form control outside of a form and associate it with the form that has this id. The form must be in the same document or shadow root for this to work.
Type null
Default null
required
required
The select's required attribute.
Type boolean
Default false
getTag
A function that customizes the tags to be rendered when multiple=true. The first argument is the option, the second is the current tag's index. The function should return either a Lit TemplateResult or a string containing trusted HTML of the symbol to render at the specified value.
Type (option: WaOption, index: number) => TemplateResult | string | HTMLElement

Methods

Learn more about methods.

Name Description Arguments
show() Shows the listbox.
hide() Hides the listbox.
focus() Sets focus on the control. options: FocusOptions
blur() Removes focus from the control.

Events

Learn more about events.

Name Description
wa-change Emitted when the control's value changes.
wa-clear Emitted when the control's value is cleared.
wa-input Emitted when the control receives input.
wa-focus Emitted when the control gains focus.
wa-blur Emitted when the control loses focus.
wa-show Emitted when the select's menu opens.
wa-after-show Emitted after the select's menu opens and all animations are complete.
wa-hide Emitted when the select's menu closes.
wa-after-hide Emitted after the select's menu closes and all animations are complete.
wa-invalid Emitted when the form control has been checked for validity and its constraints aren't satisfied.

CSS custom properties

Learn more about CSS custom properties.

Name Description
--background-color
The background color of the select's combobox.
--border-color
The border color of the select's combobox.
--border-width
The width of the select's borders, including the listbox.
--box-shadow
The shadow effects around the edges of the select's combobox.

Custom States

Learn more about custom states.

Name Description CSS selector
blank The select is empty. :state(blank)

CSS parts

Learn more about CSS parts.

Name Description
form-control The form control that wraps the label, input, and hint.
form-control-label The label's wrapper.
form-control-input The select's wrapper.
hint The hint's wrapper.
combobox The container the wraps the prefix, suffix, combobox, clear icon, and expand button.
prefix The container that wraps the prefix slot.
suffix The container that wraps the suffix slot.
display-input The element that displays the selected option's label, an <input> element.
listbox The listbox container where options are slotted.
tags The container that houses option tags when multiselect is used.
tag The individual tags that represent each multiselect option.
tag__base The tag's base part.
tag__content The tag's content part.
tag__remove-button The tag's remove button.
tag__remove-button__base The tag's remove button base part.
clear-button The clear button.
expand-icon The container that wraps the expand icon.

Dependencies

This component automatically imports the following elements. Sub-dependencies, if any exist, will also be included in this list.

Importing

The autoloader is the recommended way to import components. If you prefer to do it manually, use one of the following code snippets.

CDN npm React

To manually import this component from the CDN, use the following code.

import 'https://early.webawesome.com/webawesome@3.0.0-alpha.9/dist/components/select/select.js';
Coming soon! Coming soon!
    No results