ThekSelect
A lightweight, framework-agnostic select library built for modern interfaces. Accessible, customizable, and developer-friendly.
Quick Docs
Run Locally
npm install npm run dev
Use npm run preview only when you want to preview the built output.
Keyboard & Interaction
- Arrow keys: move focus in the dropdown.
- Enter: select focused option.
- Esc: close the dropdown.
- Backspace in multi mode: remove last selected tag.
Remote demo note: the GitHub search example depends on network availability and API
rate limits.
Initialize From Existing <select>
<select id="country-select" multiple>
<option value="us" selected>United States</option>
<option value="de">Germany</option>
<option value="jp" disabled>Japan (disabled)</option>
</select>
ThekSelectDom.init('#country-select');
Global Defaults
<div id="first"></div>
<div id="second"></div>
ThekSelect.setDefaults({
height: 40,
virtualize: true
});
ThekSelectDom.init('#first');
ThekSelectDom.init('#second', { height: 52 });
ThekSelect.resetDefaults();
Live: Existing <select>
<select id="quick-country-select" multiple>
<option value="us" selected>United States</option>
<option value="de">Germany</option>
<option value="jp" disabled>Japan (disabled)</option>
</select>
ThekSelectDom.init('#quick-country-select');
Live: Global Defaults
const demoOptions = [
{ value: 'alpha', label: 'Alpha' },
{ value: 'beta', label: 'Beta' }
];
ThekSelect.setDefaults({ height: 44 });
ThekSelectDom.init('#quick-defaults-first', { options: demoOptions });
ThekSelectDom.init('#quick-defaults-second', { options: demoOptions, height: 56 });
ThekSelect.resetDefaults();
Browser Usage (Script Tag)
<link rel="stylesheet" href="./dist/css/base.css" />
<script src="./dist/thekselect.umd.min.cjs"></script>
<select id="my-select">
<option value="react">React</option>
<option value="vue">Vue</option>
</select>
<script>
const { ThekSelect } = window.ThekSelect;
ThekSelectDom.init('#my-select');
</script>
Basic Usage
<select id="basic-select">
<option value="react">React</option>
<option value="vue">Vue.js</option>
<option value="angular">Angular</option>
</select>
ThekSelectDom.init('#basic-select', {
placeholder: 'Select a framework...'
});
Multi-select & Tagging
Try dragging tags to reorder them.
ThekSelectDom.init('#multi-select', {
multiple: true,
maxSelectedLabels: 3
});
Tag Creation
ThekSelectDom.init('#create-container', {
canCreate: true,
multiple: true,
createText: "Add skill: '{%t}'",
options: [
{ value: 'design', label: 'Design' },
{ value: 'marketing', label: 'Marketing' }
]
});
Remote Data
ThekSelectDom.init('#remote-container', {
loadOptions: async (query) => {
const res = await fetch(`https://api.github.com/search/users?q=${query}`);
const data = await res.json();
return data.items.map(u => ({ value: u.id, label: u.login }));
}
});
Virtualized Large List
Type to filter, use arrow keys to navigate, and keep scrolling smooth.
<div id="virtual-container"></div>
const bigOptions = Array.from({ length: 5000 }, (_, i) => ({
value: `opt_${i + 1}`,
label: `Option ${i + 1}`
}));
ThekSelectDom.init('#virtual-container', {
options: bigOptions,
searchable: true,
virtualize: true,
virtualThreshold: 80,
virtualItemHeight: 40,
virtualOverscan: 4
});
Custom Sizing
Small (sm) - Single
Small (sm) - Multi
Medium (md) - Single
Medium (md) - Multi
Large (lg) - Single
Large (lg) - Multi
// height accepts number(px) or CSS string
ThekSelectDom.init('#el', { height: 36, multiple: true });
Custom Fields
ThekSelectDom.init('#fields-container', {
displayField: 'name',
valueField: 'id',
options: [
{ id: 'usr_1', name: 'John Doe' },
{ id: 'usr_2', name: 'Jane Smith' }
]
});
API Methods
Properties & Methods
Configuration Options
| Property | Type | Default | Description |
|---|---|---|---|
| options | Option[] | [] | List of selectable option objects. |
| multiple | boolean | false | Enables multi-select with removable tags. |
| height | number | string | 40 | Control height (`number` = px, or CSS value string). |
| displayField | string | 'label' | Field used for visible option text. |
| valueField | string | 'value' | Field used as the internal selected value key. |
| maxOptions | number | null | null | Limits rendered filtered options (`null` = unlimited). |
Theme Object Properties
| Property | Description |
|---|---|
| primary | Main accent color (borders, focus, checkboxes). |
| bgSurface | Background color of the control and dropdown. |
| bgPanel | Hover color for options and tag background. |
| textMain | Primary text color. |
| textMuted | Color for placeholders and secondary text. |
| borderRadius | Corner rounding (e.g., '8px', '0px'). |
| fontFamily | Typography stack for the component. |
| height[Sm|Md|Lg] | Explicit heights for each size tier. |
| itemPadding | Padding for dropdown items (e.g., '8px 12px'). |
Public Methods
| Method | Parameters | Returns | Description |
|---|---|---|---|
| getValue() | none | string \| string[] \| undefined | Returns selected value(s). |
| getSelectedOptions() | none | Option \| Option[] \| undefined | Returns full option data objects. |
| setValue(val, silent) | val: string \| string[], silent?: boolean | void | Sets value. silent (default:false) triggers event. |
| setHeight(height) | height: number \| string | void | Sets instance control height (`number` = px). |
| setMaxOptions(limit) | limit: number \| null | void | Caps rendered filtered options (`null` for unlimited). |
| setRenderOption(fn) | fn: (option) => string \| HTMLElement | void | Overrides option row rendering. |
| on(event, cb) | event: string, cb: (payload) => void | () => void | Subscribes to events and returns unsubscribe callback. |
| destroy() | none | void | Cleans up instance and reverts DOM. |
Events
| Event | Payload | Description |
|---|---|---|
| change | value | values[] | Selection changed. |
| open / close | null | Dropdown visibility toggled. |
| search | string | User is typing in search. |
| tagAdded / removed | Option | Specific tag interaction (multi-select). |
| reordered | values[] | Tags reordered via drag-and-drop. |
Theme Configurator
Generated CSS Theme: