{"_id":"@cliqthemes/glide-dropdown","_rev":"6-fcb7d6d516ee05fa7944b85a9711cc58","name":"@cliqthemes/glide-dropdown","dist-tags":{"latest":"0.4.0"},"versions":{"0.1.0":{"name":"@cliqthemes/glide-dropdown","version":"0.1.0","keywords":["select","dropdown","multiselect","combobox","autocomplete","select2","tom-select"],"author":{"name":"CliqThemes"},"license":"MIT","_id":"@cliqthemes/glide-dropdown@0.1.0","maintainers":[{"name":"cliqthemes","email":"cliqthemes@gmail.com"}],"homepage":"https://github.com/cliqthemes/glide-dropdown#readme","bugs":{"url":"https://github.com/cliqthemes/glide-dropdown/issues"},"dist":{"shasum":"4eb5bf2ab666f68301f099ea2eb4b635ba46ded4","tarball":"https://registry.npmjs.org/@cliqthemes/glide-dropdown/-/glide-dropdown-0.1.0.tgz","fileCount":25,"integrity":"sha512-k0cyXA2Yn/+0zD9/UTECX4KSWD2vXHR1aolnj3pK6pQ5oZ9Alv1C0sPrZe1Va0VfX/aSRbFMUK6Sbi6qKV0s2Q==","signatures":[{"sig":"MEUCIQD6rAts2/3ilU4DuO2J+FvR5hNWVFeQWqoJqQmFaXlAHgIgIj6MOylGeTKG/iue0fHkHOfsuRRHt2g1JtQDV92d6H4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":339780},"main":"./dist/glide.umd.cjs","type":"module","types":"./types/index.d.ts","unpkg":"./dist/glide.umd.cjs","module":"./dist/glide.js","exports":{".":{"types":"./types/index.d.ts","import":"./dist/glide.js","require":"./dist/glide.umd.cjs"},"./plugins/*":{"types":"./types/plugins/*.d.ts","import":"./dist/plugins/*.js"},"./style.css":"./dist/glide.css"},"gitHead":"dbc5e28f1b3c36b2b66c5bcea25462eb2b64091b","scripts":{"dev":"vite","test":"vitest run","build":"vite build && node scripts/build-extra.mjs","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"cliqthemes","email":"cliqthemes@gmail.com"},"repository":{"url":"git+https://github.com/cliqthemes/glide-dropdown.git","type":"git"},"_npmVersion":"11.7.0","description":"A tiny, dependency-free, accessible select/dropdown component. A modern replacement for Select2 / Tom Select.","directories":{},"sideEffects":["*.css"],"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.0.0","jsdom":"^25.0.1","vitest":"^2.1.8"},"_npmOperationalInternal":{"tmp":"tmp/glide-dropdown_0.1.0_1783324788355_0.6070594174186452","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@cliqthemes/glide-dropdown","version":"0.1.1","keywords":["select","dropdown","multiselect","combobox","autocomplete","select2","tom-select"],"author":{"name":"CliqThemes"},"license":"MIT","_id":"@cliqthemes/glide-dropdown@0.1.1","maintainers":[{"name":"cliqthemes","email":"cliqthemes@gmail.com"}],"homepage":"https://github.com/cliqthemes/glide-dropdown#readme","bugs":{"url":"https://github.com/cliqthemes/glide-dropdown/issues"},"dist":{"shasum":"8e74118fe51560db86199a4eb647fca224a394ea","tarball":"https://registry.npmjs.org/@cliqthemes/glide-dropdown/-/glide-dropdown-0.1.1.tgz","fileCount":25,"integrity":"sha512-jdCG7M+/Ot0Pq+tDeE3tBd3kIw+YiTYZrBAki+Fty4IcfeOJiX6jE03yF5Ok6GVnAxuRFkC5RUxUf7kJPPupkg==","signatures":[{"sig":"MEUCIQDTMDM5Hb92iAFwcEqIHdkCSj5PesbZdnqf1yGxq1wf6QIgV17n6ALckkv2DTVnVPHpianQUXKXRDjRIFiwCJEOerM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":340758},"main":"./dist/glide.umd.cjs","type":"module","types":"./types/index.d.ts","unpkg":"./dist/glide.umd.cjs","module":"./dist/glide.js","exports":{".":{"types":"./types/index.d.ts","import":"./dist/glide.js","require":"./dist/glide.umd.cjs"},"./plugins/*":{"types":"./types/plugins/*.d.ts","import":"./dist/plugins/*.js"},"./style.css":"./dist/glide.css"},"gitHead":"e020c62d3cc7dfdef0f941a2a8e3fbe3ae07e742","scripts":{"dev":"vite","test":"vitest run","build":"vite build && node scripts/build-extra.mjs","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"cliqthemes","email":"cliqthemes@gmail.com"},"repository":{"url":"git+https://github.com/cliqthemes/glide-dropdown.git","type":"git"},"_npmVersion":"11.7.0","description":"A tiny, dependency-free, accessible select/dropdown component. A modern replacement for Select2 / Tom Select.","directories":{},"sideEffects":["*.css"],"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.0.0","jsdom":"^25.0.1","vitest":"^2.1.8"},"_npmOperationalInternal":{"tmp":"tmp/glide-dropdown_0.1.1_1783336730813_0.3978460950482523","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@cliqthemes/glide-dropdown","version":"0.1.2","keywords":["select","dropdown","multiselect","combobox","autocomplete","select2","tom-select"],"author":{"name":"CliqThemes"},"license":"MIT","_id":"@cliqthemes/glide-dropdown@0.1.2","maintainers":[{"name":"cliqthemes","email":"cliqthemes@gmail.com"}],"homepage":"https://github.com/cliqthemes/glide-dropdown#readme","bugs":{"url":"https://github.com/cliqthemes/glide-dropdown/issues"},"dist":{"shasum":"36bec30170b6d2872e46469cde6a8564cce5268e","tarball":"https://registry.npmjs.org/@cliqthemes/glide-dropdown/-/glide-dropdown-0.1.2.tgz","fileCount":25,"integrity":"sha512-Asyy9j2iu4Em4RWgJ6axO/gw2FaBnRGGoWCs2dK/e4jkoL/Men2AgwHgE85qSZdAFjx3Tdk4uEEDEFlipB+mWQ==","signatures":[{"sig":"MEYCIQCeUUMX9QDXwxrJGgNeB5DnzUMeP6Zkja7xPnDGrsqrZQIhAJPn1aitzY27L0d3Y8XkYVWeSy10ksuRfIonAAj6sWH2","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":340721},"main":"./dist/glide.umd.cjs","type":"module","types":"./types/index.d.ts","unpkg":"./dist/glide.umd.cjs","module":"./dist/glide.js","exports":{".":{"types":"./types/index.d.ts","import":"./dist/glide.js","require":"./dist/glide.umd.cjs"},"./plugins/*":{"types":"./types/plugins/*.d.ts","import":"./dist/plugins/*.js"},"./style.css":"./dist/glide.css"},"gitHead":"fe1da4cbba40024078c82c3612b29986dd69b815","scripts":{"dev":"vite","test":"vitest run","build":"vite build && node scripts/build-extra.mjs","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"cliqthemes","email":"cliqthemes@gmail.com"},"repository":{"url":"git+https://github.com/cliqthemes/glide-dropdown.git","type":"git"},"_npmVersion":"11.7.0","description":"A tiny, dependency-free, accessible select/dropdown component. A modern replacement for Select2 / Tom Select.","directories":{},"sideEffects":["*.css"],"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.0.0","jsdom":"^25.0.1","vitest":"^2.1.8"},"_npmOperationalInternal":{"tmp":"tmp/glide-dropdown_0.1.2_1783336958575_0.7071296040734214","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@cliqthemes/glide-dropdown","version":"0.2.0","keywords":["select","dropdown","multiselect","combobox","autocomplete","select2","tom-select"],"author":{"name":"CliqThemes"},"license":"MIT","_id":"@cliqthemes/glide-dropdown@0.2.0","maintainers":[{"name":"cliqthemes","email":"cliqthemes@gmail.com"}],"homepage":"https://github.com/cliqthemes/glide-dropdown#readme","bugs":{"url":"https://github.com/cliqthemes/glide-dropdown/issues"},"dist":{"shasum":"f1b6797e506bb7e6965e3a43a6b557af6d020854","tarball":"https://registry.npmjs.org/@cliqthemes/glide-dropdown/-/glide-dropdown-0.2.0.tgz","fileCount":25,"integrity":"sha512-gEmI+71R4B+cDDe+LXTNWukP0aIybKvxAtLrizofccoXTeE4DFko+Llvnek6MKErK4YzRKyrQGFAeNthkjgL+Q==","signatures":[{"sig":"MEQCIAb6x1iNI/mJ3UTCnVPtTfIu/StzfYB/iBaDngvZOOVhAiA7Nhi/6crbrvYHdTGG27H3lu5p6OUnn2tU8/azcX0o0w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":350670},"main":"./dist/glide.umd.cjs","type":"module","types":"./types/index.d.ts","unpkg":"./dist/glide.umd.cjs","module":"./dist/glide.js","exports":{".":{"types":"./types/index.d.ts","import":"./dist/glide.js","require":"./dist/glide.umd.cjs"},"./plugins/*":{"types":"./types/plugins/*.d.ts","import":"./dist/plugins/*.js"},"./style.css":"./dist/glide.css"},"gitHead":"e8954368d30d48382c6bad4e811c61e448e36994","scripts":{"dev":"vite","test":"vitest run","build":"vite build && node scripts/build-extra.mjs","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"cliqthemes","email":"cliqthemes@gmail.com"},"repository":{"url":"git+https://github.com/cliqthemes/glide-dropdown.git","type":"git"},"_npmVersion":"11.7.0","description":"A tiny, dependency-free, accessible select/dropdown component. A modern replacement for Select2 / Tom Select.","directories":{},"sideEffects":["*.css"],"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.0.0","jsdom":"^25.0.1","vitest":"^2.1.8"},"_npmOperationalInternal":{"tmp":"tmp/glide-dropdown_0.2.0_1783360157341_0.9909466323834477","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@cliqthemes/glide-dropdown","version":"0.3.0","keywords":["select","dropdown","multiselect","combobox","autocomplete","select2","tom-select"],"author":{"name":"CliqThemes"},"license":"MIT","_id":"@cliqthemes/glide-dropdown@0.3.0","maintainers":[{"name":"cliqthemes","email":"cliqthemes@gmail.com"}],"homepage":"https://github.com/cliqthemes/glide-dropdown#readme","bugs":{"url":"https://github.com/cliqthemes/glide-dropdown/issues"},"dist":{"shasum":"04b5bbadfaa4ccaa443d871b519f7c926e9b6fdc","tarball":"https://registry.npmjs.org/@cliqthemes/glide-dropdown/-/glide-dropdown-0.3.0.tgz","fileCount":26,"integrity":"sha512-iSJFUiMF1B0lzfp2EwN0A2cQBpfxHA8LaBnNthg7+4lvXhCkzVQcB7yQAhorBHvokPvvLjnHRXfQgb93XjsRdA==","signatures":[{"sig":"MEQCIH16SaAyqfH1hyPsmwKIFidaZ9LtHDWjlmb4jPc3gH9kAiAavYBvFUN9D8RmC330HUJdMcPtD1B7oTY6zHaffZtW0g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":381878},"main":"./dist/glide.umd.cjs","type":"module","types":"./types/index.d.ts","unpkg":"./dist/glide.umd.cjs","module":"./dist/glide.js","exports":{".":{"types":"./types/index.d.ts","import":"./dist/glide.js","require":"./dist/glide.umd.cjs"},"./plugins/*":{"types":"./types/plugins/*.d.ts","import":"./dist/plugins/*.js"},"./style.css":"./dist/glide.css"},"gitHead":"8af4ea0f5b875b80ebf25d57fc73bb6e24b550d7","scripts":{"dev":"vite","test":"vitest run","build":"vite build && node scripts/build-extra.mjs && node scripts/build-demo.mjs","build:demo":"node scripts/build-demo.mjs","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"cliqthemes","email":"cliqthemes@gmail.com"},"repository":{"url":"git+https://github.com/cliqthemes/glide-dropdown.git","type":"git"},"_npmVersion":"11.7.0","description":"A tiny, dependency-free, accessible select/dropdown component. A modern replacement for Select2 / Tom Select.","directories":{},"sideEffects":["*.css"],"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.0.0","jsdom":"^25.0.1","vitest":"^2.1.8"},"_npmOperationalInternal":{"tmp":"tmp/glide-dropdown_0.3.0_1784109208249_0.19868602542917824","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@cliqthemes/glide-dropdown","version":"0.4.0","description":"A tiny, dependency-free, accessible select/dropdown component. A modern replacement for Select2 / Tom Select.","type":"module","publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/cliqthemes/glide-dropdown.git"},"homepage":"https://github.com/cliqthemes/glide-dropdown#readme","bugs":{"url":"https://github.com/cliqthemes/glide-dropdown/issues"},"author":{"name":"cliqthemes","email":"hello@cliqthemes.com"},"main":"./dist/glide.umd.cjs","module":"./dist/glide.js","types":"./types/index.d.ts","unpkg":"./dist/glide.umd.cjs","sideEffects":["*.css"],"exports":{".":{"types":"./types/index.d.ts","import":"./dist/glide.js","require":"./dist/glide.umd.cjs"},"./style.css":"./dist/glide.css","./plugins/*":{"types":"./types/plugins/*.d.ts","import":"./dist/plugins/*.js"}},"scripts":{"dev":"vite","build":"vite build && node scripts/build-extra.mjs && node scripts/build-demo.mjs","build:demo":"node scripts/build-demo.mjs","test":"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage"},"keywords":["select","dropdown","multiselect","combobox","autocomplete","select2","tom-select"],"license":"MIT","devDependencies":{"jsdom":"^25.0.1","vite":"^6.0.0","vitest":"^2.1.8"},"gitHead":"8be0106ea42388b437071d3813eb94ea8204d93c","_id":"@cliqthemes/glide-dropdown@0.4.0","_nodeVersion":"22.19.0","_npmVersion":"11.7.0","dist":{"integrity":"sha512-LMMG4ABYMnwqgA4VeShyKHwyoMdcp9/L3WDWPXbhu+a979uEGIDA/noUHM8g++6IualywYFwq2eerW1i4Rk82Q==","shasum":"aac66b53f1abac0953f3f746651ad08279bbb46f","tarball":"https://registry.npmjs.org/@cliqthemes/glide-dropdown/-/glide-dropdown-0.4.0.tgz","fileCount":26,"unpackedSize":385262,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD6S9TednfJRKtAEtbBnybbVOdYgZjCezljnNBOk/UL8gIgCNQKTnmk6GjNy/BDPDWK4U69FlJwpcHRmKUi+xrCu9A="}]},"_npmUser":{"name":"cliqthemes","email":"cliqthemes@gmail.com"},"directories":{},"maintainers":[{"name":"cliqthemes","email":"cliqthemes@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/glide-dropdown_0.4.0_1784184331773_0.2530922626009948"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-06T07:59:48.159Z","modified":"2026-07-16T06:45:32.196Z","0.1.0":"2026-07-06T07:59:48.507Z","0.1.1":"2026-07-06T11:18:50.969Z","0.1.2":"2026-07-06T11:22:38.703Z","0.2.0":"2026-07-06T17:49:17.511Z","0.3.0":"2026-07-15T09:53:28.399Z","0.4.0":"2026-07-16T06:45:31.900Z"},"bugs":{"url":"https://github.com/cliqthemes/glide-dropdown/issues"},"author":{"name":"cliqthemes","email":"hello@cliqthemes.com"},"license":"MIT","homepage":"https://github.com/cliqthemes/glide-dropdown#readme","keywords":["select","dropdown","multiselect","combobox","autocomplete","select2","tom-select"],"repository":{"type":"git","url":"git+https://github.com/cliqthemes/glide-dropdown.git"},"description":"A tiny, dependency-free, accessible select/dropdown component. A modern replacement for Select2 / Tom Select.","maintainers":[{"name":"cliqthemes","email":"cliqthemes@gmail.com"}],"readme":"# Glide\n\nA tiny, dependency-free, accessible select/dropdown component for the web. A modern\nreplacement for Select2: ~9 KB compressed, virtualized to handle\n20,000+ options smoothly, and built on plain ES modules — no jQuery, no framework.\n\n**[Live demo →](https://cliqthemes.github.io/glide-dropdown/)**\n\n- 🪶 **Tiny** — core is ~9 KB compressed, zero runtime dependencies\n- ⚡ **Fast** — virtualized option list; renders a bounded DOM window regardless of dataset size\n- ♿ **Accessible** — full ARIA combobox pattern, keyboard-only operable, screen-reader announcements\n- 🎨 **Themeable** — every color/spacing value is a CSS variable; ships light + dark themes\n- 🔌 **Extensible** — a small plugin API instead of a kitchen-sink core\n- 📦 **Modern data formats** — upgrades a native `<select>`, or accepts arrays / grouped arrays / async data\n\n## Installation\n\n```bash\nnpm install @cliqthemes/glide-dropdown\n```\n\n```js\nimport { Glide } from '@cliqthemes/glide-dropdown';\nimport '@cliqthemes/glide-dropdown/style.css';\n```\n\nOr drop in the UMD build directly — no bundler, no ES modules, no build\nstep. This is the one to use in a WordPress theme/plugin, a CMS template,\nor any plain HTML page:\n\n```html\n<link rel=\"stylesheet\" href=\"https://unpkg.com/@cliqthemes/glide-dropdown/dist/glide.css\" />\n<script src=\"https://unpkg.com/@cliqthemes/glide-dropdown/dist/glide.umd.cjs\"></script>\n<script>\n  const select = new Glide('#country');\n</script>\n```\n\n`window.Glide` is the constructor itself (not `Glide.Glide` or similar), and\nevery built-in plugin ships attached at `Glide.plugins.*` in this build —\nthere's no separate plugin file to load:\n\n```html\n<script>\n  const select = new Glide('#skills', {\n    multiple: true,\n    plugins: [Glide.plugins.clearButton(), Glide.plugins.checkboxSelection()],\n  });\n</script>\n```\n\n### WordPress\n\nSame two files, enqueued the normal WordPress way instead of linked directly\n— host them yourself (e.g. copy `dist/glide.umd.cjs` and `dist/glide.css`\ninto your theme) rather than pointing production at unpkg:\n\n```php\nfunction my_theme_enqueue_glide() {\n    wp_enqueue_style('glide', get_template_directory_uri() . '/assets/glide.css', [], '0.1.0');\n    wp_enqueue_script('glide', get_template_directory_uri() . '/assets/glide.umd.cjs', [], '0.1.0', true);\n}\nadd_action('wp_enqueue_scripts', 'my_theme_enqueue_glide');\n```\n\nThen initialize it in your own script (enqueued with `'glide'` as a\ndependency so it loads after), same API as everywhere else:\n\n```js\ndocument.addEventListener('DOMContentLoaded', () => {\n  new Glide('#my-select');\n});\n```\n\n### CDN\n\nEvery version published to npm is automatically mirrored on jsDelivr and\nunpkg — nothing to configure, no separate publish step:\n\n```html\n<!-- jsDelivr -->\n<link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/@cliqthemes/glide-dropdown/dist/glide.css\" />\n<script src=\"https://cdn.jsdelivr.net/npm/@cliqthemes/glide-dropdown/dist/glide.umd.cjs\"></script>\n\n<!-- unpkg -->\n<link rel=\"stylesheet\" href=\"https://unpkg.com/@cliqthemes/glide-dropdown/dist/glide.css\" />\n<script src=\"https://unpkg.com/@cliqthemes/glide-dropdown/dist/glide.umd.cjs\"></script>\n```\n\nPin an exact version for production (`@cliqthemes/glide-dropdown@0.1.0/...`)\nrather than the unpinned URLs above, which always resolve to latest —\nconvenient for docs/demos, riskier for something you don't control the\ntiming of.\n\n## Quick start\n\n```html\n<select id=\"country\">\n  <option value=\"\">Choose a country</option>\n  <option value=\"au\">Australia</option>\n  <option value=\"nz\">New Zealand</option>\n</select>\n```\n\n```js\nconst select = new Glide('#country', {\n  searchable: true,\n});\n\nselect.on('change', ({ value }) => console.log(value));\n```\n\nMulti-select works the same way — Glide reads `multiple` straight off the `<select>`:\n\n```html\n<select id=\"skills\" multiple>\n  <option value=\"js\">JavaScript</option>\n  <option value=\"ts\">TypeScript</option>\n</select>\n```\n\n```js\nnew Glide('#skills', { fuzzy: true });\n```\n\nYou don't need a `<select>` at all — pass data directly and mount on any element:\n\n```js\nnew Glide('#assignee', {\n  placeholder: 'Assign to…',\n  options: [\n    { value: 1, label: 'Grace Hopper' },\n    { value: 2, label: 'Ada Lovelace' },\n  ],\n});\n```\n\nSee it live at **[cliqthemes.github.io/glide-dropdown](https://cliqthemes.github.io/glide-dropdown/)**,\nor run it locally from [`examples/index.html`](examples/index.html) (single/multi\nselect, groups, creatable tags, custom rendering, async loading with infinite\nscroll, and a 20,000-option virtualization stress test) — `npm run dev` and open it.\n\n## Data formats\n\n```js\n// Flat array\nnew Glide(el, { options: [{ value: 1, label: 'One' }] });\n\n// Grouped array\nnew Glide(el, {\n  options: [\n    { label: 'Fruit', options: [{ value: 'a', label: 'Apple' }] },\n    { value: 'z', label: 'Zucchini' },\n  ],\n});\n\n// Native <select> / <optgroup> — parsed automatically, no `options` needed\nnew Glide('#el');\n\n// Async / remote\nnew Glide(el, {\n  async load(query, { page, signal }) {\n    const res = await fetch(`/api/search?q=${query}&page=${page}`, { signal });\n    const { items, hasMore } = await res.json();\n    return { items, hasMore };\n  },\n});\n```\n\n## Options\n\n| Option | Type | Default | Description |\n| --- | --- | --- | --- |\n| `multiple` | `boolean` | from `<select multiple>` or `false` | Multi-select mode |\n| `disabled` | `boolean` | `false` | Initial disabled state |\n| `searchable` | `boolean` | `true` | Show the search input (ignored — always on — when `load` is set) |\n| `fuzzy` | `boolean` | `false` | Enable subsequence fuzzy matching once exact/startsWith/contains all miss |\n| `theme` | `'light' \\| 'dark' \\| 'auto'` | `'light'` | `'auto'` follows `prefers-color-scheme`; dark never applies unless requested |\n| `presentation` | `'dropdown' \\| 'chips' \\| 'always-open' \\| 'accordion' \\| 'popup'` | `'dropdown'` | Choose classic overlay, wrapping option chips, persistent list, an in-flow accordion, or a wide responsive popup grid |\n| `showSelectedChips` | `boolean` | `true` | Show selected multi-select values as removable chips in the control. Set `false` for a cleaner always-open list; a searchable input remains available when enabled |\n| `staticControlLabel` | `string` | — | Keep the control text fixed instead of replacing it with selected values; useful for popup filter triggers and accordion headings |\n| `panelLabel` | `string` | — | Optional panel heading; especially useful for popup filters |\n| `className` | `string` | — | Extra class(es) on the root element, for scoping instance-specific CSS |\n| `controlClassName` | `string` | — | Extra class(es) on the control element — an official hook that survives internal re-renders |\n| `dropdownClassName` | `string` | — | Extra class(es) on the dropdown panel. The panel is portaled to `<body>` by default, so instance-scoped CSS can only reach it through this |\n| `portal` | `boolean \\| Element` | `true` | Panel container: `true` portals to `<body>` (escapes overflow/stacking contexts); `false` keeps it inside the root (scoped CSS, focus traps, shadow DOM); an `Element` portals it there |\n| `placeholder` | `string` | derived from an empty leading `<option>`, else `''` | Placeholder text |\n| `options` | `Array` | — | Flat or grouped data (ignored for a native `<select>`) |\n| `value` | value \\| value[] | — | Initial selection |\n| `load` | `(query, meta) => Promise` | — | Async data source. `meta` is `{ page, append, signal }`. Return an array, or `{ items, hasMore }` for pagination |\n| `debounceMs` | `number` | `200` | Debounce for `load()` on keystrokes |\n| `loadMoreThreshold` | `number` | `80` | Pixels from the bottom of the list that triggers the next page |\n| `loadOnInit` | `boolean` | `true` | Call `load('')` once on mount |\n| `plugins` | `GlidePlugin[]` | `[]` | See [Plugins](#plugins) |\n| `templates` | `Partial<Templates>` | — | Override `option`, `group`, `tag`, `value`, `noResults`, `loading` render functions |\n\n## API\n\n```js\nselect.open();\nselect.close();\nselect.toggle();\nselect.enable();\nselect.disable();\nselect.destroy();\n\nselect.clear();\nselect.select(value);\nselect.deselect(value);\nselect.setValue(value);      // single value, or an array in multiple mode\nselect.getValue();\n\nselect.setOptions(data);\nselect.addOption({ value, label });\nselect.removeOption(value);\nselect.getOptions();         // normalized items currently loaded\nselect.getGroups();\nselect.refresh();            // force a re-render (e.g. after mutating templates)\n\nselect.focus();\nselect.blur();\n\nconst unsubscribe = select.on('change', ({ value }) => { /* ... */ });\nselect.off('change', handler);\n```\n\n### Events\n\n`open`, `close`, `change`, `search`, `clear`, `create`, `select`, `deselect`, `error`, `destroy`.\n\n## Custom rendering\n\nTemplates return an HTML string and are inserted via `innerHTML` — **labels are\nescaped by default** (`escapeHtml` under the hood), so plain data can never inject\nmarkup. Opting into rich HTML (icons, avatars, badges) is explicit: you build the\nstring yourself in the template function, and you're responsible for escaping any\nuntrusted fields you interpolate.\n\n```js\nnew Glide('#assignee', {\n  options: people,\n  templates: {\n    option(item, { ranges }) {\n      return `<img class=\"avatar\" src=\"${item.data.avatarUrl}\"> ${item.label}`;\n    },\n  },\n});\n```\n\n## Keyboard support\n\n`Arrow Up/Down`, `Home`, `End`, `Page Up/Down`, `Enter`, `Escape`, `Tab`, `Backspace`\n(removes the last tag in multi-select when the input is empty), `Delete`. Typing\nfilters the list when `searchable` is on, or jumps to the first matching option\n(native-`<select>`-style typeahead) when it's off.\n\n## Theming\n\nEvery visual value is a CSS variable on `.glide`. Override them globally or scope\nan override to one instance:\n\n```css\n:root {\n  --glide-radius: 4px;\n  --glide-border-focus: #7c3aed;\n  --glide-active: #ede9fe;\n  --glide-active-color: #6d28d9;\n}\n```\n\nEvery instance defaults to `theme: 'light'` regardless of OS preference. Opt in\nper instance:\n\n```js\nnew Glide('#el', { theme: 'dark' });   // always dark\nnew Glide('#el', { theme: 'auto' });   // follows prefers-color-scheme\nselect.setTheme('dark');               // change it later\n```\n\nFull variable list: `--glide-bg`, `--glide-border`, `--glide-border-focus`,\n`--glide-radius`, `--glide-color`, `--glide-placeholder`, `--glide-hover`,\n`--glide-active`, `--glide-active-color`, `--glide-shadow`, `--glide-tag-bg`,\n`--glide-tag-color`, `--glide-highlight-bg`, `--glide-highlight-color`,\n`--glide-group-color`, `--glide-control-min-height`, `--glide-font-size`,\n`--glide-scrollbar-thumb`, `--glide-scrollbar-track` (WebKit + `scrollbar-color`,\nboth driven by the same pair), and `--glide-panel-max-h` (caps the option list's\nheight below the default 280px; the available-viewport clamp still applies).\n\n### Presentation modes\n\nThe same data, selection API, keyboard behavior, plugins, and theme variables\nwork across all presentations:\n\n```js\nnew Glide('#categories', {\n  multiple: true,\n  presentation: 'chips',\n});\n\nnew Glide('#facilities', {\n  multiple: true,\n  presentation: 'always-open',\n  showSelectedChips: false,\n  plugins: [checkboxSelection()],\n});\n\nnew Glide('#region', { presentation: 'accordion' });\n\nnew Glide('#property-type', {\n  presentation: 'popup',\n  panelLabel: 'Property type',\n});\n```\n\nChips and popup use a responsive static option grid; classic dropdown,\nalways-open, and accordion retain virtual scrolling. Useful layout variables\ninclude `--glide-option-gap`, `--glide-option-radius`, `--glide-chip-bg`,\n`--glide-chip-selected-bg`, `--glide-panel-max-h`, `--glide-popup-width`,\n`--glide-chip-selected-color`, `--glide-chip-radius`,\n`--glide-popup-columns`, and `--glide-popup-padding`.\n\nAccordion selection intentionally leaves the panel open so users can continue\nbrowsing or make additional choices; it closes only when explicitly toggled,\nwith Escape, or by clicking outside.\n\nAnimations are CSS-only (a subtle fade/scale on open) and respect\n`prefers-reduced-motion`.\n\n## Avoiding a flash of the native select\n\nLike any JS-driven progressive enhancement,\nthere's a brief window between first paint and your script running where the\nnative `<select>` is visible as-is. Glide hides it once it initializes, but\ncan't do anything before that. If it's noticeable, hide it yourself up front\nand only reveal Glide's markup:\n\n```css\nselect.glide-pending { visibility: hidden; }\n```\n\n```html\n<select id=\"country\" class=\"glide-pending\">...</select>\n```\n\nGlide's own markup (`.glide`) isn't hidden by this, since it's a sibling\nelement inserted only once JS runs — nothing extra to unhide.\n\n## Sizing\n\nThe root element is a block box, so — like most form controls — it stretches to\nfill its container by default. Constrain it with plain CSS, either against the\n`className` option or the fact that the root is always mounted immediately\nafter the original element:\n\n```js\nnew Glide('#country', { className: 'country-select' });\n```\n\n```css\n.country-select { max-width: 320px; }\n/* or, without className: */\n#country + .glide { max-width: 320px; }\n```\n\nThere's also a `--glide-max-width` variable (default `none`) if you'd rather\nset it globally for every instance on the page.\n\n## Plugins\n\nCore stays deliberately small; everything below is opt-in:\n\n```js\nimport { Glide } from '@cliqthemes/glide-dropdown';\nimport { clearButton } from '@cliqthemes/glide-dropdown/plugins/clearButton';\nimport { checkboxSelection } from '@cliqthemes/glide-dropdown/plugins/checkboxSelection';\nimport { selectAll } from '@cliqthemes/glide-dropdown/plugins/selectAll';\nimport { groupSelect } from '@cliqthemes/glide-dropdown/plugins/groupSelect';\nimport { tagCreate } from '@cliqthemes/glide-dropdown/plugins/tagCreate';\n\nnew Glide('#el', {\n  multiple: true,\n  plugins: [clearButton(), checkboxSelection(), selectAll(), groupSelect(), tagCreate()],\n});\n```\n\nUsing the [UMD build](#wordpress) instead? Every plugin above is already\nattached to the global — `Glide.plugins.clearButton()` and so on, no\nseparate import.\n\n| Plugin | Adds |\n| --- | --- |\n| `clearButton()` | An \"×\" button that clears the selection, hidden when empty |\n| `checkboxSelection()` | Checkbox indicators in front of every option |\n| `selectAll()` | A \"Select all / Clear all\" button above the list (multi-select) |\n| `groupSelect()` | A \"Select all\" affordance per group header (multi-select) |\n| `tagCreate({ validate, format })` | Press Enter on unmatched text to create a new option |\n\nVirtual scrolling and group-collapse are core behavior, not plugins — they're\nfundamental to the performance and Groups requirements, not optional add-ons.\nAnimations are pure CSS, so there's no JS plugin for them either.\n\n### Writing a plugin\n\nA plugin is a factory returning `{ name, init(instance), destroy(instance) }`.\n`instance` exposes the full public API above, plus `instance.dom` (`root`,\n`control`, `input`, `dropdown`, `viewport`, `content`), `instance.templates`\n(mutable — wrap a template function to change rendering), and\n`instance.getOptions()` / `instance.selectedSet`.\n\n```js\nexport function myPlugin() {\n  return {\n    name: 'myPlugin',\n    init(instance) {\n      instance.on('change', () => console.log(instance.getValue()));\n    },\n    destroy(instance) {\n      // undo whatever init() did\n    },\n  };\n}\n```\n\n## Performance\n\nThe option list is virtualized (`src/virtual/VirtualList.js`): regardless of\nwhether you load 10 or 20,000 options, only the rows intersecting the viewport\n(plus a small overscan) exist in the DOM, and elements are recycled between\nscroll frames rather than recreated. Search matching is a single linear pass\nper keystroke with early-exit ranking (startsWith beats contains beats fuzzy),\nand store updates are batched into a microtask so a burst of synchronous state\nchanges only triggers one render.\n\n## Browser support\n\nModern evergreen browsers (Chrome, Firefox, Safari, Edge). No IE support.\n\n## Project layout\n\n```\nsrc/\n  core/       Glide class, data normalization, async loader, row computation\n  store/      Small reactive state container\n  renderer/   Control, list, and dropdown-positioning DOM rendering\n  keyboard/   Key-to-intent mapping\n  search/     Matching (startsWith/contains/fuzzy) + highlighting\n  virtual/    Windowed list renderer\n  plugins/    Built-in opt-in plugins\n  utils/      DOM helpers, escaping, debounce, event emitter\n  styles/     Base structural CSS + light/dark themes\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}