You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A mobile-first, single and multiple select / auto-complete solution in Material Design style, built with LitElement. Supports grouping, virtualization for large lists, keyboard navigation, form validation, and adaptive dialog types (popover, modal, fit, bottom-sheet).
1. User Guide
Installation & Setup
npm install @dreamworld/dw-select
// Single selectimport'@dreamworld/dw-select';// Multi-selectimport'@dreamworld/dw-multi-select';
// newItemProvider: returns {item, hint} or undefined, or a Promise resolving to either_newItemProvider(query){if(query.length<2)returnundefined;return{item: {_id: query,name: query},hint: 'Press Enter to add'};}
The newItemProvider function receives the current search query and must return:
{item: Item, hint: string} — a new item and optional hint text shown on the input
undefined or {item: undefined} — when the query is not yet complete
import{queryFilterGenerator}from'@dreamworld/dw-select/utils.js';// Search across multiple fieldsconstfilter=queryFilterGenerator(['name','code','alias']);// Or provide a fully custom filterconstcustomFilter=(item,query)=>item.name.toLowerCase().startsWith(query.toLowerCase());
<!-- Show helper text in tooltip on info icon --><dw-selecthintInTooltiphelper="Start typing to filter results"
></dw-select><!-- Show error in tooltip with an action --><dw-selecterrorInTooltip.errorTooltipActions="${[{ name: 'fix', label: 'Fix Now', danger: false }]}"
@action="${(e) => console.log(e.detail.name)}"
></dw-select>
Form Validation Integration
// Programmatic validationconstselect=document.querySelector('dw-select');// Check validity without showing UIconstisValid=select.checkValidity();// Check validity and show error to userconstisValid=select.reportValidity();// Custom validate callconstisValid=select.validate();
DwFormElement(LitElement) injects standard form validation API (checkValidity, reportValidity, validate, name) into both components.
Composite / Delegation
Each select component is split into a trigger (display) and a dialog (selection logic). The orchestrator (dw-select.js) coordinates state between the two.
Observer (Reactive Properties)
LitElement's @property decorator pattern drives all UI updates declaratively.
Strategy
valueProvider, queryFilter, renderItem, and renderGroupItem are pluggable function properties, allowing integrators to override behavior without subclassing.
Virtualizer
@lit-labs/virtualizer is activated automatically when the rendered item count exceeds VIRTUAL_LIST_MIN_LENGTH (500), ensuring smooth performance with large datasets.
Responsive / Adaptive
@dreamworld/device-info provides the current layout (small, medium, large, hd, fullhd). The dialog type is chosen accordingly — bottom-sheet on mobile, popover/fit on desktop.
Module Responsibilities
Module
Responsibility
dw-select.js
Orchestrator for single select. Manages validation, layout detection, value resolution, and delegates rendering to trigger + dialog.
dw-multi-select.js
Orchestrator for multi-select. Adds array-value management, "Select All" logic, and apply/cancel flow.
dw-select-trigger.js
The visible input field. Extends DwInput. Renders the trailing expand/clear icon and dispatches expand-toggle and clear-selection events.
dw-multi-select-trigger.js
Same as above for multi-select. Extends DwInput.
dw-select-base-dialog.js
Dialog for single select. Handles item filtering, keyboard navigation, group collapse, highlight, virtualization, and scroll-to-selected.
dw-multi-select-base-dialog.js
Dialog for multi-select. Adds checkbox toggle, "Select All" when ≥10 items, and an apply/done button.
dw-select-dialog-input.js
Search input component rendered inside the single-select dialog. Dispatches input-change, cancel, and clear-selection.
dw-multi-select-dialog-input.js
Search input for the multi-select dialog.
dw-select-group-item.js
Renders collapsible group header rows. Shows expand/collapse icon and ripple only when collapsible=true.
dw-multi-select-group-item.js
Renders non-collapsible group header rows for multi-select.
utils.js
Exports KeyCode, Direction, Position, NEW_VALUE_STATUS, filter(), and queryFilterGenerator().
sort-items.js
Exports sortItems(). Scores items by relevance to the query (prefix match, word match, exact word match) and returns them sorted.
Dialog Types & Adaptive Layout
The dialog type is selected automatically based on device layout and item count:
Dialog Type
When Used
popover
Default on desktop. Anchored to the trigger element.
fit
Full-height dialog with integrated search input. Used when item list overflows.
modal
Centered modal overlay.
bottom-sheet
On mobile (small layout / virtual keyboard present).
The popover property on both components can force popover mode regardless of layout.
Utility Functions
filter(value, query) — utils.js
import{filter}from'@dreamworld/dw-select/utils.js';filter('HDFC Bank','hdfc bank');// truefilter('State Bank of India','bank india');// truefilter('HDFC Bank','icici');// false
Returns true if every word in query appears (as a substring) in at least one word of value. Case-insensitive.
Sorts items by relevance to query. Scoring (lower = better):
-1 if item text starts with the query
-1 for each query word found anywhere in item text
-1 for each exact word match
NEW_VALUE_STATUS — utils.js
import{NEW_VALUE_STATUS}from'@dreamworld/dw-select/utils.js';// NEW_VALUE_STATUS.IN_PROGRESS — item is being created (spinner shown)// NEW_VALUE_STATUS.NEW_VALUE — item was created (shows "new" tag)// NEW_VALUE_STATUS.ERROR — creation failed (error shown)
Dependencies
Package
Purpose
@dreamworld/device-info
Detects device layout for adaptive dialog selection