Skip to content

Select

Select

Selects allow you to choose one or more items from a dropdown menu, usually you wrap this component with a html form. If you're looking for a dropdown menu to trigger actions, you should try six-dropdown.

Option 1Option 2Option 3Option 4Option 5Option 6Option 7Option 8Option 9
html
<six-select>
  <six-menu-item value="option-1">Option 1</six-menu-item>
  <six-menu-item value="option-2">Option 2</six-menu-item>
  <six-menu-item value="option-3">Option 3</six-menu-item>
  <six-menu-item value="option-4">Option 4</six-menu-item>
  <six-menu-item value="option-5">Option 5</six-menu-item>
  <six-menu-item value="option-6">Option 6</six-menu-item>
  <six-menu-item value="option-7">Option 7</six-menu-item>
  <six-menu-item value="option-8">Option 8</six-menu-item>
  <six-menu-item value="option-9">Option 9</six-menu-item>
</six-select>

Examples

Placeholders

Use the placeholder attribute to add a placeholder.

Option 1Option 2Option 3
html
<six-select placeholder="Select one">
  <six-menu-item value="option-1">Option 1</six-menu-item>
  <six-menu-item value="option-2">Option 2</six-menu-item>
  <six-menu-item value="option-3">Option 3</six-menu-item>
</six-select>

Clearable

Use the clearable attribute to make the control clearable.

Option 1Option 2Option 3
html
<six-select placeholder="Clearable" clearable>
  <six-menu-item value="option-1">Option 1</six-menu-item>
  <six-menu-item value="option-2">Option 2</six-menu-item>
  <six-menu-item value="option-3">Option 3</six-menu-item>
</six-select>

Preselecting a Value

Use the value attribute to preselect a default value

Option 1Option 2Option 3
html
<six-select value="option-2" clearable>
  <six-menu-item value="option-1">Option 1</six-menu-item>
  <six-menu-item value="option-2">Option 2</six-menu-item>
  <six-menu-item value="option-3">Option 3</six-menu-item>
</six-select>

Default Value

If you want the select to be reset to a default value use the attribute default-value

Option 1Option 2Option 3
html
<six-select value="option-2" default-value="option-3" clearable>
  <six-menu-item value="option-1">Option 1</six-menu-item>
  <six-menu-item value="option-2">Option 2</six-menu-item>
  <six-menu-item value="option-3">Option 3</six-menu-item>
</six-select>

Pill

Use the pill prop to give selects rounded edges.

Option 1Option 2Option 3
html
<six-select pill>
  <six-menu-item value="option-1">Option 1</six-menu-item>
  <six-menu-item value="option-2">Option 2</six-menu-item>
  <six-menu-item value="option-3">Option 3</six-menu-item>
</six-select>

Line

Use the line prop to give show selection in line style.

Option 1Option 2Option 3
html
<six-select line>
  <six-menu-item value="option-1">Option 1</six-menu-item>
  <six-menu-item value="option-2">Option 2</six-menu-item>
  <six-menu-item value="option-3">Option 3</six-menu-item>
</six-select>

Disabled

Use the disabled prop to disable a select.

Option 1Option 2Option 3
html
<six-select placeholder="Disabled" disabled>
  <six-menu-item value="option-1">Option 1</six-menu-item>
  <six-menu-item value="option-2">Option 2</six-menu-item>
  <six-menu-item value="option-3">Option 3</six-menu-item>
</six-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. When using this option, value will be an array instead of a string.

Option 1Option 2Option 3Option 4Option 5Option 6 (with tooltip due to long text)
html
<six-select filter placeholder="Select a few" multiple clearable>
  <six-menu-item value="option-1">Option 1</six-menu-item>
  <six-menu-item value="option-2">Option 2</six-menu-item>
  <six-menu-item value="option-3">Option 3</six-menu-item>
  <six-menu-item value="option-4">Option 4</six-menu-item>
  <six-menu-item value="option-5">Option 5</six-menu-item>
  <six-menu-item value="option-6">Option 6 (with tooltip due to long text)</six-menu-item>
</six-select>

Grouping Options

Options can be grouped visually using menu labels and menu dividers.

Group 1Option 1Option 2Option 3Group 2Option 4Option 5Option 6
html
<six-select placeholder="Select one">
  <six-menu-label>Group 1</six-menu-label>
  <six-menu-item value="option-1">Option 1</six-menu-item>
  <six-menu-item value="option-2">Option 2</six-menu-item>
  <six-menu-item value="option-3">Option 3</six-menu-item>
  <six-menu-divider></six-menu-divider>
  <six-menu-label>Group 2</six-menu-label>
  <six-menu-item value="option-4">Option 4</six-menu-item>
  <six-menu-item value="option-5">Option 5</six-menu-item>
  <six-menu-item value="option-6">Option 6</six-menu-item>
</six-select>

Sizes

Use the size attribute to change a select's size.

Option 1Option 2Option 3
Option 1Option 2Option 3
Option 1Option 2Option 3
html
<six-select placeholder="Small" size="small" multiple>
  <six-menu-item value="option-1">Option 1</six-menu-item>
  <six-menu-item value="option-2">Option 2</six-menu-item>
  <six-menu-item value="option-3">Option 3</six-menu-item>
</six-select>

<br>

<six-select placeholder="Medium" size="medium" multiple>
  <six-menu-item value="option-1">Option 1</six-menu-item>
  <six-menu-item value="option-2">Option 2</six-menu-item>
  <six-menu-item value="option-3">Option 3</six-menu-item>
</six-select>

<br>

<six-select placeholder="Large" size="large" multiple>
  <six-menu-item value="option-1">Option 1</six-menu-item>
  <six-menu-item value="option-2">Option 2</six-menu-item>
  <six-menu-item value="option-3">Option 3</six-menu-item>
</six-select>

Selecting Options Programmatically

The value prop is bound to the current selection. As the selection changes, so will the value. To programmatically manage the selection, update the value property.

Option 1Option 2Option 3
Set 1Set 2Set 3
html
<div class="selecting-example">
  <six-select placeholder="">
    <six-menu-item value="option-1">Option 1</six-menu-item>
    <six-menu-item value="option-2">Option 2</six-menu-item>
    <six-menu-item value="option-3">Option 3</six-menu-item>
  </six-select>

  <br>

  <six-button data-option="option-1">Set 1</six-button>
  <six-button data-option="option-2">Set 2</six-button>
  <six-button data-option="option-3">Set 3</six-button>
</div>

<script type="module">
  (() => {
    const container = document.querySelector('.selecting-example');
    const select = container.querySelector('six-select');

    [...container.querySelectorAll('six-button')].map((button) => {
      button.addEventListener('click', () => {
        select.value = button.dataset.option;
      });
    });
  })();
</script>

Labels

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

Option 1Option 2Option 3
html
<six-select label="Select one">
  <six-menu-item value="option-1">Option 1</six-menu-item>
  <six-menu-item value="option-2">Option 2</six-menu-item>
  <six-menu-item value="option-3">Option 3</six-menu-item>
</six-select>

Help Text

Add descriptive help text to a select with the help-text attribute. For help texts that contain HTML, use the help-text slot instead.

NoviceIntermediateAdvanced
html
<six-select label="Experience" help-text="Please tell us your skill level.">
  <six-menu-item value="option-1">Novice</six-menu-item>
  <six-menu-item value="option-2">Intermediate</six-menu-item>
  <six-menu-item value="option-3">Advanced</six-menu-item>
</six-select>

Hoisting

Dropdown panels will be clipped if they're inside a container that has overflow: auto|hidden. The hoist attribute forces the panel to use a fixed positioning strategy, allowing it to break out of the container. In this case, the panel will be positioned relative to its containing block, which is usually the viewport unless an ancestor uses a transform, perspective, or filter.

NoviceIntermediateAdvancedNoviceIntermediateAdvanced
html
<div style="overflow: hidden; border: solid 1px grey; padding: 0.5em; display: flex">
  <six-select placeholder="No Hoisting" style="width: 10em">
    <six-menu-item value="option-1">Novice</six-menu-item>
    <six-menu-item value="option-2">Intermediate</six-menu-item>
    <six-menu-item value="option-3">Advanced</six-menu-item>
  </six-select>

  <six-select placeholder="Hoisting" filter="true" hoist style="width: 10em">
    <six-menu-item value="option-1">Novice</six-menu-item>
    <six-menu-item value="option-2">Intermediate</six-menu-item>
    <six-menu-item value="option-3">Advanced</six-menu-item>
  </six-select>
</div>

Hoisting inside Drawer

There was a bug where hoisting inside drawers caused a problem

Open Drawer Lorem ipsum dolor sit amet, consectetur adipiscing elit. Close
some tooltip
NoviceIntermediateAdvancedNoviceIntermediateAdvanced
No HoistItem 1Item 2Item 3HoistItem 1Item 2Item 3
html
<six-button id="hoistingDrawerBtn">Open Drawer</six-button>
<six-drawer id="hoistingDrawer" label="Drawer" class="drawer-overview">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit.
  <six-button slot="footer">Close</six-button>
  <div class="demo" style="width: 300px">
    <six-tooltip content="something">
      <div>some tooltip</div>
    </six-tooltip>
    <div style="overflow: hidden; border: solid 1px grey; padding: 0.5em; display: flex">
      <six-select placeholder="No Hoisting" style="width: 10em">
        <six-tooltip content="something">
          <six-menu-item value="option-1">Novice</six-menu-item>
        </six-tooltip>
        <six-menu-item value="option-2">Intermediate</six-menu-item>
        <six-menu-item value="option-3">Advanced</six-menu-item>
      </six-select>

      <six-select placeholder="Hoisting" hoist style="width: 10em">
        <six-menu-item value="option-1">Novice</six-menu-item>
        <six-menu-item value="option-2">Intermediate</six-menu-item>
        <six-menu-item value="option-3">Advanced</six-menu-item>
      </six-select>
    </div>

    <div style="overflow: hidden; border: solid 1px grey; padding: 0.5em; display: flex">
      <six-dropdown>
        <six-button slot="trigger" caret>No Hoist</six-button>
        <six-menu>
          <six-menu-item>Item 1</six-menu-item>
          <six-menu-item>Item 2</six-menu-item>
          <six-menu-item>Item 3</six-menu-item>
        </six-menu>
      </six-dropdown>

      <six-dropdown hoist>
        <six-button slot="trigger" caret>Hoist</six-button>
        <six-menu>
          <six-menu-item>Item 1</six-menu-item>
          <six-menu-item>Item 2</six-menu-item>
          <six-menu-item>Item 3</six-menu-item>
        </six-menu>
      </six-dropdown>
    </div>
  </div>
</six-drawer>

<script type="module">
  const sixDrawerBtn = document.querySelector('#hoistingDrawerBtn');
  const sixDrawer = document.querySelector('#hoistingDrawer');
  sixDrawerBtn.addEventListener('click', () => (sixDrawer.open = true));
</script>

Enable Filtering Items

You can filter the items shown by simply adding filter="true" to six-select

You can also pass a custom placeholder with filter-placeholder to be shown in the filter input field (will be 'Filter...' by default)

AustraliaBrazilChinaEgyptFranceGermanyIndiaJapanSpainUnited States
html
<six-select label="Experience" filter multiple select-all-button clearable>
  <six-menu-item value="AUSTRALIA">Australia</six-menu-item>
  <six-menu-item value="BRAZIL">Brazil</six-menu-item>
  <six-menu-item value="CHINA">China</six-menu-item>
  <six-menu-item value="EGYPT">Egypt</six-menu-item>
  <six-menu-item value="FRANCE">France</six-menu-item>
  <six-menu-item value="GERMANY">Germany</six-menu-item>
  <six-menu-item value="INDIA">India</six-menu-item>
  <six-menu-item value="JAPAN">Japan</six-menu-item>
  <six-menu-item value="SPAIN">Spain</six-menu-item>
  <six-menu-item value="UNITED_STATES">United States</six-menu-item>
</six-select>

Async Filtering

You might have a usecase where the full list of items in the dropdown would be too large and you need to call a backend when filtering the dropdown

In such a scenario simply add the async-filter attribute to your dropdown component

If you want to change the default debounce timeout use e.g. filter-debounce="500"

Use search to show entries
html
<six-select id="async-select" async-filter filter-placeholder="Enter a number">
  <six-menu-item id="async-menu-item" value="search_list_prompt">Use search to show entries</six-menu-item>
</six-select>
<script type="module">
  const asyncSelect = document.querySelector('#async-select');
  const asyncMenu = document.querySelector('#async-menu-item').parentElement;

  for (let i = 0; i < 500; i++) {
    const child = document.createElement('six-menu-item');
    child.innerText = `Value ${i}`;
    child.value = `value-${i}`;
    asyncMenu.appendChild(child);
  }

  const removeAllChildNodes = (parent) => {
    while (parent.firstChild) {
      parent.removeChild(parent.firstChild);
    }
  };

  asyncSelect.addEventListener('six-async-filter-fired', ($event) => {
    const filterValue = $event.detail.filterValue;
    removeAllChildNodes(asyncMenu);
    for (let i = 0; i < 500; i++) {
      const child = document.createElement('six-menu-item');
      child.innerText = `Value ${i}`;
      child.value = `value-${i}`;
      if (
        filterValue.includes(`${i}`) ||
        filterValue.toLocaleLowerCase().includes(`value`) ||
        filterValue.toLocaleLowerCase().includes(`value ${i}`) ||
        filterValue === ''
      ) {
        asyncMenu.appendChild(child);
      }
    }
  });
</script>

Infinite Scrolling

If you have huge amounts of data you want to present in the dropdown you can't render all at once or it will crash your browser. For these usescases listen to the scroll event to decide which data to present.

Value 0
html
<six-select id="infinite-scoll-dropdown">
  <six-menu-item id="infinite-scroll-menu" value="search_list_prompt">Value 0</six-menu-item>
</six-select>
<script type="module">
  const asyncSelect = document.querySelector('#infinite-scoll-dropdown');
  const asyncMenu = document.querySelector('#infinite-scroll-menu').parentElement;

  let id = 1;

  for (let i = 0; i < 20; i++) {
    const child = document.createElement('six-menu-item');
    child.innerText = `Value ${id}`;
    child.value = `value-${id}`;
    asyncMenu.appendChild(child);
    id++;
  }

  asyncSelect.addEventListener('six-dropdown-scroll', ($event) => {
    const { scrollRatio } = $event.detail;

    // add new elements once we reach almost bottom
    if (scrollRatio > 0.8) {
      for (let i = 0; i < 20; i++) {
        const child = document.createElement('six-menu-item');
        child.innerText = `Value ${id}`;
        child.value = `value-${id}`;
        asyncMenu.appendChild(child);
        id++;
      }
    }
  });
</script>

Autocomplete

AutoComplete is an input element providing a panel with real-time suggestions on typing.

Autocomplete does currently not support multiselect!

You can adjust the debounce timeout via the input-debounce attribute

html
<six-select id="autocomplete-example" autocomplete clearable></six-select>
<script type="module">
  (() => {
    const clearAllChildren = (node) => {
      let child = node.lastElementChild;
      while (child) {
        node.removeChild(child);
        child = node.lastElementChild;
      }
    };

    const createMenuItem = (value, label) => {
      const menuItem = document.createElement('six-menu-item');
      menuItem.innerText = label;
      menuItem.setAttribute('value', value);
      return menuItem;
    };

    const select = document.getElementById('autocomplete-example');

    select.addEventListener('six-select-change', (event) => {
      if (event.detail.isSelected) {
        // don't fetch new values on selection
        return;
      }
      clearAllChildren(select);

      const enteredText = event.detail.value || 'All Values';
      new Array(5).fill('').forEach((item, idx) => {
        select.append(createMenuItem(`option ${enteredText} ${idx}`, `Option ${enteredText} ${idx}`));
      });
    });
  })();
</script>

Passing items via options attribute

If you don't want to create a six-menu-item but simply want to pass an array with all options, you can do so via the options attribute.

html
<six-select filter multiple id="six-select-dynamic-options"></six-select>
<script type="module">
  const sixSelectDynamicOptions = document.getElementById('six-select-dynamic-options');
  sixSelectDynamicOptions.options = Array.from(Array(100).keys()).map((idx) => ({
    label: `label ${idx}`,
    value: `value ${idx}`,
  }));
</script>

Virtual Scrolling

If you have a lot of items in the menu (100'000 in the following example), rendering all of them might lead to some performance issues. To avoid such issues use virtual-scroll

html
<six-select id="six-select-virtual-scroll" virtual-scroll></six-select>
<script type="module">
  const sixSelectDynamicOptions = document.getElementById('six-select-virtual-scroll');
  sixSelectDynamicOptions.options = Array.from(Array(100000).keys()).map((idx) => ({
    label: `label ${idx}`,
    value: `value ${idx}`,
  }));
</script>

Virtually scrolled Autocomplete

In the following example you see the combination of autocomplete with virtual-scroll. The list contains 10'000 entries. Enter a number in the input field and you can virtually scroll through all elements which contain this number.

html
<six-select id="virtual-autocomplete-example" autocomplete clearable virtual-scroll></six-select>
<script type="module">
  const virtualAutocomplete = document.getElementById('virtual-autocomplete-example');

  // generate some options
  const allOptions = Array.from(Array(10000).keys()).map((idx) => ({
    label: `label ${idx}`,
    value: `value ${idx}`,
  }));

  // assign the options to the six-select
  virtualAutocomplete.options = allOptions;

  // set up an eventlistener on change
  virtualAutocomplete.addEventListener('six-select-change', (event) => {
    if (event.detail.isSelected) {
      // don't fetch new values on selection
      return;
    }

    const enteredText = event.detail.value;
    if (!enteredText) {
      // if no text has been entered all options should be available
      virtualAutocomplete.options = allOptions;
    }

    // otherwise if a text has been entered filter for all options which contain the entered text
    virtualAutocomplete.options = allOptions.filter(
      (option) => option.label.includes(enteredText) || option.value.includes(enteredText)
    );
  });
</script>

Error Text

Add a descriptive error message using either the error-text prop, or the equally named slot.

warning There are two caveats when using the error-text prop/slot:

  1. Remember to set the invalid prop as well! If you only provide some content to the error-text prop/slot, it won't be shown unless the invalid prop is set to true
  2. When using the prop, and you need to show more than one message, remember to also set the error-text-count prop to a value that is the same or bigger than the length of the list of messages you are using. Otherwise only one message will be shown at a time

The error-text prop accepts either a simple string message, or a list of messages.

html
<six-select label="Simple string message" error-text="This is a simple string message" invalid> </six-select>
html
<six-select id="multiple-error-text" label="List of string message" invalid></six-select>
<script type="module">
  const sixSelect = document.getElementById('multiple-error-text');
  sixSelect.errorText = ['Message 1', 'Message 2'];
  sixSelect.errorTextCount = 3;
</script>

When using the error-text slot, it is recommended to use the six-error component to wrap the error message(s). This will provide the correct styling out of the box

An error message with a link
html
<six-select invalid>
  <div slot="error-text">
    <six-error               >An error message
      <a href="https://github.com/six-group/six-webcomponents" target="_blank">with a link</a></six-error>
  </div>
</six-select>

Properties

PropertyAttributeDescriptionTypeDefault
asyncFilterasync-filterSet to true to allow async filtering. When you enter something in the search field the component will only emit an event but not filter any elements itself. You can then simply listen to the 'six-async-filter-fired' event to manage the shown menu-items yourselfbooleanfalse
autocompleteautocompleteSet to true to turn the six-select into an autocomplete.booleanfalse
clearableclearableSet to true to add a clear button when the select is populated.booleanfalse
disableddisabledSet to true to disable the select control.booleanfalse
errorTexterror-textThe error message shown, if invalid is set to true.string | string[]''
errorTextCounterror-text-countThe number of error texts to be shown (if the error-text slot isn't used). Defaults to 1number | undefinedundefined
filterfilterSet to true to allow filtering for entries in the dropdownbooleanfalse
filterDebouncefilter-debounceThe debounce for the filter callbacks.number | undefinedundefined
filterPlaceholderfilter-placeholderThe filter's placeholder text.string | undefinedundefined
helpTexthelp-textThe select's help text. Alternatively, you can use the help-text slot.string''
hoisthoistEnable this option to prevent the panel from being clipped when the component is placed inside a container with overflow: auto|scroll.booleanfalse
inputDebounceinput-debounceThe debounce for when the input changes for autocompletes should be emittednumberDEFAULT_DEBOUNCE_FAST
invalidinvalidIf this property is set to true and an error message is provided by errorText, the error message is displayed.booleanfalse
labellabelThe label text.string''
linelineSet to render as linebooleanfalse
maxTagsVisiblemax-tags-visible[DEPRECATED] : This property is ignored. The component now displays as many items as possible and computes the "+n" dynamically.

The maximum number of tags 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 -1 to remove the limit.
number3
multiplemultipleSet to true to enable multiselect.booleanfalse
namenameThe select's name.string''
options--Set the options to be shown in the dropdown (alternative to setting the elements via html)SixMenuItemData[] | nullnull
pillpillSet to true to draw a pill-style select with rounded edges.booleanfalse
placeholderplaceholderThe select's placeholder text.string''
requiredrequiredSet to true to show an asterisk beneath the label.booleanfalse
selectAllButtonselect-all-buttonEnables the select all button.booleanfalse
selectAllTextselect-all-textCustom text for the "select all" button. Defaults to "Select all" and equivalents in supported languages.string | undefinedundefined
sizesizeThe select's size."large" | "medium" | "small"'medium'
valuevalueThe value of the control. This will be a string or an array depending on multiple.string | string[]''
virtualScrollvirtual-scrollDefines whether the menu list will be rendered virtually i.e. only the elements actually shown (and a couple around) are actually rendered in the DOM. If you use virtual scrolling pass the elements via prop instead of via slot.booleanfalse

Events

EventDescriptionType
six-select-blurEmitted when the control loses focus.CustomEvent<undefined>
six-select-changeEmitted when the control's value changes.CustomEvent<SixSelectChangePayload>
six-select-focusEmitted when the control gains focus.CustomEvent<undefined>

Methods

setFocus(options?: FocusOptions) => Promise<void>

Sets focus on the select.

Parameters

NameTypeDescription
optionsFocusOptions | undefined

Returns

Type: Promise<void>

Slots

SlotDescription
The select's options in the form of menu items.
"error-text"Error text that is shown for validation errors. Alternatively, you can use the error-text prop.
"help-text"Help text that describes how to use the select.
"label"The select's label. Alternatively, you can use the label prop.

Shadow Parts

PartDescription
"base"The component's base wrapper.
"clear-button"The input's clear button, exported from six-input.
"form-control"The form control that wraps the label, input, and help text.
"help-text"The select's help text.
"icon"The select's icon.
"label"The select's label.
"menu"The select menu, a six-menu element.
"tag"The multiselect option, a six-tag element.
"tags"The container in which multiselect options are rendered.

Dependencies

Depends on

Graph


Copyright © 2021-present SIX-Group