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: