Single and multiple choice from a known set of 2 to ~200 options.
The qds-select component is a form-associated custom element that provides a dropdown listbox with optional filtering, grouping, and multi-select with tags. It uses a popover pattern (via PopoverController) that qds-date-picker will reuse.
<qds-select label="Country" placeholder="Choose…">
<option value="us">United States</option>
<option value="uk">United Kingdom</option>
<option value="ca">Canada</option>
</qds-select>
Programmatic options via the options property:
<qds-select id="mySelect" label="Priority"></qds-select>
<script>
document.getElementById('mySelect').options = [
{ value: 'low', label: 'Low' },
{ value: 'med', label: 'Medium', description: 'Default priority' },
{ value: 'high', label: 'High', group: 'Urgent' }
];
</script>
Multiple selection with tags:
<qds-select multiple label="Tags" placeholder="Select tags…">
<option value="a">Alpha</option>
<option value="b">Beta</option>
<option value="c">Gamma</option>
</qds-select>
value (string) - Selected value in single mode.multiple (boolean) - Enables multi-select mode. Reflected.placeholder (string, default Select…) - Trigger text when empty.filterable (boolean | auto) - true to force filter, false to disable, absent for auto (true above 10 options).clearable (boolean) - Shows a clear button when non-empty.max-selected (number) - Maximum selections in multiple mode.tag-threshold (number, default 3) - Above this count, trigger shows “N selected” instead of tags.placement (auto | bottom | top, default auto) - Popover placement; auto flips when insufficient space.open (boolean) - Reflected; settable to open/close programmatically.name (string) - Submitted form key.label (string) - Rendered as a real <label for> in the shadow root.hint (string) - Helper text below the trigger.error-text (string) - Overrides the built-in validation message.size (sm | md | lg, default md) - Control height.disabled (boolean) - Not focusable, not submitted. Reflected.readonly (boolean) - Focusable, submitted, no popup. Reflected.required (boolean) - Validation flag. Reflected.invalid (boolean) - Author-forced invalid state. Reflected.validate-on (blur | input | submit, default blur) - Validation timing.options (QdsOption[]) - Property only; arrays are not attributes. Each option: { value, label, disabled?, group?, icon?, description? }.values (string[]) - Selected values in multiple mode; property only.validity (ValidityState | QdsValidity) - Read-only.checkValidity() - Returns boolean.reportValidity() - Returns boolean, sets visible error.setCustomValidity(msg) - Empty string clears.container - Outer wrapper.label - The <label> element.trigger - The combobox trigger surface.trigger-text - Text or tags inside the trigger.tag - Individual selection tag (multiple mode).tag-remove - Remove button on a tag.chevron - Dropdown arrow icon.clear-button - Clear-all button.listbox - The popup listbox panel.filter - The filter input wrapper.group-label - Optgroup heading.option - Individual option row.option-check - Checkmark icon on selected option.option-description - Description text on an option.empty - Empty-state message.hint - Helper text.error - Error message.--qds-select-z (default 1000) - Z-index of the listbox popover.change - Selection committed. Bubbles, composed.input - Same as change; native parity for form libraries. Bubbles, composed.qds-open - Listbox opened. detail: { component }.qds-close - Listbox closed. detail: { component }.qds-filter - Filter text changed. detail: { component, query }.qds-validity-change - Validity transition. detail: QdsValidityChangeEventDetail.<form>
<qds-select
name="country"
label="Country"
required
placeholder="Select a country…"
clearable>
<option value="us">United States</option>
<option value="uk">United Kingdom</option>
<option value="ca" data-group="North America">Canada</option>
<option value="mx" data-group="North America">Mexico</option>
</qds-select>
<button type="submit">Submit</button>
</form>
<script>
const select = document.querySelector('qds-select');
select.addEventListener('change', () => {
console.log('Selected:', select.value);
});
</script>