JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 4679
  • Score
    100M100P100Q137663F
  • License Licensed under MIT and Preline UI Fair Use License

Preline UI is an open-source set of prebuilt UI components based on the utility-first Tailwind CSS framework.

Package Exports

  • @preline/select
  • @preline/select/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@preline/select) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Advanced Select

Advanced select solutions for massive datasets.

npm License: MIT Demo

Contents

Overview

The Advanced Select component provides a customizable dropdown select interface with support for search, tags, API integration, and extensive styling options. It's designed for handling large datasets and complex selection scenarios.

Key Features:

  • Search functionality
  • Tags mode for multiple selections
  • API integration for dynamic options
  • Custom templates and styling
  • Multiple selection support
  • Option grouping
  • Icons and descriptions for options
  • Programmatic control via JavaScript API
  • Event system for selection tracking

Installation

To get started, install Select plugin via npm, else you can skip this step if you are already using Preline UI as a package.

npm i @preline/select

Some positioning features require Floating UI. Install it if you plan to use dropdownScope: "window", dropdownPlacement, or dropdownAutoPlacement:

npm i @floating-ui/dom

CSS

Use @source to register the plugin's JavaScript path for Tailwind CSS scanning, then @import the plugin's CSS files into your Tailwind CSS file.

@import "tailwindcss";

/* @preline/select */
@source "../node_modules/@preline/select/*.js";
@import "./node_modules/@preline/select/variants.css";
@import "./node_modules/@preline/select/theme.css";

JavaScript

Include the JavaScript that powers the interactive elements near the end of your </body> tag. If you use dropdownScope: "window", dropdownPlacement, or dropdownAutoPlacement, also load the Floating UI UMD bundle before the plugin. It exposes the FloatingUIDOM global the plugin relies on.

<!-- Optional: required for dropdownScope: "window", dropdownPlacement, dropdownAutoPlacement -->
<script src="https://cdn.jsdelivr.net/npm/@floating-ui/dom@latest/dist/floating-ui.dom.umd.min.js"></script>
<script src="./node_modules/@preline/select/index.js"></script>

Manual Initialization

Use the non-auto entry if you need manual initialization. In this mode, automatic initialization on page load is not included, so the component should be initialized explicitly.

<!-- Optional: required for dropdownScope: "window", dropdownPlacement, dropdownAutoPlacement -->
<script src="https://cdn.jsdelivr.net/npm/@floating-ui/dom@latest/dist/floating-ui.dom.umd.min.js"></script>
<script type="module">
  import HSSelect from "@preline/select/non-auto.mjs";

  new HSSelect(document.querySelector("#select"));
</script>

Via Bundler

When using a bundler (Vite, webpack, etc.), import the plugin directly as an ES module. If you use dropdownScope: "window", dropdownPlacement, or dropdownAutoPlacement, expose FloatingUIDOM on window before importing the plugin.

@preline/select is the auto-init entry: it scans the DOM and initializes matching elements automatically.

// Optional: required for dropdownScope: "window", dropdownPlacement, dropdownAutoPlacement
import * as FloatingUIDOM from "@floating-ui/dom";
window.FloatingUIDOM = FloatingUIDOM;

import "@preline/select";

@preline/select/non-auto is the manual entry: use it when you want explicit control over when initialization happens, either via autoInit() or by creating a specific instance yourself.

// Optional: required for dropdownScope: "window", dropdownPlacement, dropdownAutoPlacement
import * as FloatingUIDOM from "@floating-ui/dom";
window.FloatingUIDOM = FloatingUIDOM;

import HSSelect from "@preline/select/non-auto";

HSSelect.autoInit();

// Or initialize a specific element manually
const el = document.querySelector("#select");
if (el) new HSSelect(el);

TypeScript

This package ships with TypeScript type definitions. No additional @types/ package is needed.

Basic usage

The following example demonstrates the minimal HTML structure required for an advanced select component. This is a base template without custom styling - you can apply your own CSS classes and styles as needed. The component transforms a standard select element into an advanced dropdown.

<select data-hs-select='{
    "placeholder": "Select option...",
    "toggleTag": "<button type=\"button\"></button>",
    "toggleClasses": "",
    "dropdownClasses": "",
    "optionClasses": "hs-selected:"
  }'>
  <option>Select option</option>
  <option>Name</option>
  <option>Email address</option>
  <option>Description</option>
  <option>User ID</option>
</select>

Structure Requirements:

  • data-hs-select: Required on the <select> element, contains configuration options as JSON
  • Standard <option> elements inside the select
  • Optional <optgroup> elements for grouping

Initial State:

  • Select displays placeholder text when no option is selected
  • Dropdown is closed by default

Configuration Options

Data Options

Data options are specified in the data-hs-select attribute as a JSON object.

Option Target Element Type Default Description
data-hs-select Select element - - Activate a Custom Select by specifying on an element. Should be added to the select.
:isOpened Inside data-hs-select boolean false Opens the select if the value is true.
:placeholder Inside data-hs-select string "Select..." Define a default placeholder when nothing is selected.
:hasSearch Inside data-hs-select boolean false Define a search field inside the dropdown if the value is true.
:minSearchLength Inside data-hs-select number 0 Specifies the minimum number of characters that must be entered before the search function becomes active.
:preventSearchFocus Inside data-hs-select boolean false Sets autofocus for the search field inside a dropdown list if the value is true.
:preventSearchInsideDescription Inside data-hs-select boolean false Prevents searching inside the description when set to true.
:mode Inside data-hs-select 'default' | 'tags' 'default' Define a select mode. default for single/multiple selection, tags for tag-based selection.
:scrollToSelected Inside data-hs-select boolean false Scroll to the selected option when the dropdown is opened.
:toggleTag Inside data-hs-select string (HTML markup) - Define a markup for the select toggle. Note: data-title is required if you are using a custom placeholder.
:toggleClasses Inside data-hs-select string - Define CSS classes for the selects' toggle. CSS classes must be separated by a space.
:toggleSeparators Inside data-hs-select object - Define separators for the selects' toggle.
:toggleSeparators:items Inside data-hs-select string ", " Define which separator will be used for separate selected items.
:toggleSeparators:betweenItemsAndCounter Inside data-hs-select string "and" Define which separator will be used for separate selected items and counter text.
:toggleCountText Inside data-hs-select string - This option is only available for multiple select. Determines what text will be after the counter. It also activates the counting mode.
:toggleCountTextPlacement Inside data-hs-select 'postfix' | 'prefix' | 'postfix-no-space' | 'prefix-no-space' 'postfix' Allows to specify where the text specified in the toggleCountText parameter will be located relative to the counter.
:toggleCountTextMinItems Inside data-hs-select number 1 This option is only available for multiple select. Defines the minimum number of selected items at which the counting mode will be activated.
:toggleCountTextMode Inside data-hs-select 'countAfterLimit' | 'nItemsAndCount' 'countAfterLimit' This option is only available for multiple select. Controls the display of the contents of the button title.
:wrapperClasses Inside data-hs-select string - Define CSS classes for the selects' wrapper. CSS classes must be separated by a space.
:tagsItemTemplate Inside data-hs-select string (HTML markup) - This option is only available when tags mode is set up. Define template for the single tag. It could contain: data-icon if target option tag has data-hs-select-option:icon, data-title the text from the target option, data-remove the target tag will be deleted when click on tag with this data attribute.
:tagsItemClasses Inside data-hs-select string - This option is only available when tags mode is set up. Define CSS classes for the single tags. CSS classes must be separated by a space.
:tagsInputId Inside data-hs-select string - This option is only available when tags mode is set up. This option is useful if there is a need to associate a label outside the initialized element with the tags input.
:tagsInputClasses Inside data-hs-select string - This option is only available when tags mode is set up. Define CSS classes for the input. Defines CSS classes for the search field inside a dropdown list. CSS classes must be separated by a space.
:dropdownTag Inside data-hs-select string (HTML markup) - This option is only available when tags mode is set up. Define a markup for the dropdown.
:dropdownClasses Inside data-hs-select string - This option is only available when tags mode is set up. Define CSS classes for the dropdown. Defines CSS classes for the search field inside a dropdown list. CSS classes must be separated by a space.
:dropdownPlacement Inside data-hs-select "top" | "top-left" | "top-right" | "bottom" | "bottom-left" | "bottom-right" | "right" | "right-top" | "right-bottom" | "left" | "left-top" | "left-bottom" "bottom" Specifies the position of the menu when opened. Requires the Floating UI and dropdownScope option to be window.
:dropdownAutoPlacement Inside data-hs-select boolean false Automatically determine the placement of the menu based on the available space. Requires the Floating UI and dropdownScope option to be window.
:dropdownVerticalFixedPlacement Inside data-hs-select "top" | "bottom" | null null Specifies a fixed vertical position for the menu when opened. It will not change when scrolling.
:dropdownScope Inside data-hs-select "window" | "parent" "parent" Determines whether the dropdown will be moved outside the parent, for correct display in elements with hidden overflow. Requires the Floating UI plugin.
:searchId Inside data-hs-select string - This option is only available when hasSearch: true. This option is useful if there is a need to associate a label outside the initialized element with the search input.
:searchLimit Inside data-hs-select number Infinity This option is only available when hasSearch: true. If this option is enabled, the search will display only the first 'n' matching items.
:isSearchDirectMatch Inside data-hs-select boolean true This option is only available when hasSearch: true. If the option is disabled, then in the search results you will be able to see non-direct matches by text. For example, if you entered england in the search field, then Eng-land, Eng.land, Eng_land will also be shown.
:searchClasses Inside data-hs-select string "block w-[calc(100%-32px)] text-sm border-gray-200 rounded-md focus:border-blue-500 focus:ring-blue-500 dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 py-2 px-3 my-2 mx-4" This option is only available when :hasSearch attribute is true. Define CSS classes for the search field inside the dropdown. Defines CSS classes for the search field inside a dropdown list. CSS classes must be separated by a space.
:searchPlaceholder Inside data-hs-select string "Search..." This option is only available when :hasSearch attribute is true. Determines placeholder for the search field inside the dropdown.
:searchNoResultTemplate Inside data-hs-select string (HTML markup) "<span></span>" This option is only available when :hasSearch attribute is true. Define a markup for the "no result" text.
:searchNoResultText Inside data-hs-select string "No options found..." This option is only available when :hasSearch attribute is true. Defines the text that will be displayed if no results are found.
:searchNoResultClasses Inside data-hs-select string "px-4 text-sm" This option is only available when :hasSearch attribute is true. Defines CSS classes for the "no results" wrapper. CSS classes must be separated by a space.
:optionAllowEmptyOption Inside data-hs-select boolean false This option determines whether an empty option should be included in the list. When set to true, an additional option with an empty string ("") as its value will be displayed, allowing users to select a blank choice if needed.
:optionTemplate Inside data-hs-select string (HTML markup) - Define template for the single option. It could contain: data-icon if target option tag has data-hs-select-option:icon, data-title the text from the target option, data-description if target option tag has data-hs-select-option:description.
:optionTag Inside data-hs-select string (HTML markup) - Define a markup for the single option.
:optionClasses Inside data-hs-select string - Define CSS classes for the single option. CSS classes must be separated by a space.
:optionGroupTemplate Inside data-hs-select string (HTML markup) - Define template for the single option group.
:optgroupTag Inside data-hs-select string (HTML markup) - Define a markup for the single option group.
:optgroupClasses Inside data-hs-select string - Define CSS classes for the single option group. CSS classes must be separated by a space.
:extraMarkup Inside data-hs-select string | array (HTML markup) - Define a markup that could be extra added to the wrapper of the select for the decoration reasons. If it contains the --prevent-click class, clicking on this element will not trigger the open function.
:descriptionClasses Inside data-hs-select string - Define CSS classes for the description inside the single option. CSS classes must be separated by a space.
:iconClasses Inside data-hs-select string - Define CSS classes for the icon inside the single option. CSS classes must be separated by a space.
:isAddTagOnEnter Inside data-hs-select boolean true Determines whether a tag will be added when the enter key is pressed.
:isSelectedOptionOnTop Inside data-hs-select boolean false Controls whether selected options should appear at the top of the dropdown list. When set to true, selected options will be sorted to the top of the list.
:apiUrl Inside data-hs-select string | null null Defines the address where the API is located.
:apiQuery Inside data-hs-select string | null null Defines query parameters that are separated by ?.
:apiOptions Inside data-hs-select RequestInit | null null Defines options for the fetch function.
:apiDataPart Inside data-hs-select string | null null If data is in some first level parameter, then it allows you to specify the name of this parameter to extract the data.
:apiSearchQueryKey Inside data-hs-select string | null null Defines the key for the query search parameter.
:apiFieldsMap Inside data-hs-select { id: string; title: string; val?: string; icon?: string | null; description?: string | null; } | null null Allows you to convert fields from the API to the fields required for the plugin to work.
:apiLoadMore Inside data-hs-select boolean | { perPage?: number; scrollThreshold?: number; } false Defines the options for the load more feature.
:apiSelectedValues Inside data-hs-select string | string[] | null null Allows to preselect values when loading options from an API. Can be a single value or an array of values for multiple selection.
:apiIconTag Inside data-hs-select string | null null Allows to define an img tag that will be used when rendering options and in the trigger button.
data-hs-select-option Option element object - Allows to define the parameters for the single option. Should be added to the option.
:description Inside data-hs-select-option string - Allows to define the description of the option inside the element that have data-description attribute.
:icon Inside data-hs-select-option string - Allows to define the icon of the option inside the element that have data-icon attribute.
:additinalClasses Inside data-hs-select-option [string, string[]][] - Allows to define additional classes. The first string is the selector of the element to apply the classes to, the second string is an array of classes to apply. If the selector is set to null, the classes will be applied to the option itself.
:apiFields Inside data-hs-select-option { [key: string]: unknown; } - Allows to define the fields of the option from the API.

Tailwind Modifiers

Name Description
hs-select-opened:* A modifier that allows you to set Tailwind classes when select has been opened.
hs-select-disabled:* A modifier that allows you to set Tailwind classes when select has "disabled" attribute.

JavaScript API

The HSSelect object is available in the global window object after the plugin is loaded.

Instance Methods

These methods are called on a select instance.

Method Parameters Return Type Description
open() None void Opens the dropdown list programmatically.
close() None void Closes the dropdown list programmatically.
setValue(value) value: string | string[] void Set the select value. This should be a string for a simple select and an array if it's a multiple select.
addOption(items) items: { title: string; val: string; options?: { description: string; icon: string; }; } or array of such objects void Adds an option (several possible) to the select. The single option should follow this interface.
removeOption(val) val: string | string[] void Removes an option by value (several possible).
recalculateDirection() None void Force recalculation for dropdown list. Useful when dropdown position needs to be updated after layout changes.
destroy() None void Destroys the select instance, removes all generated markup, classes, and event listeners. Use when removing select from DOM.

Static Methods

These methods are called directly on the HSSelect class.

Method Parameters Return Type Description
HSSelect.getInstance(target, isInstance) target: HTMLElement | string (CSS selector)
isInstance: boolean (optional)
HTMLElement | { id: string | number, element: HSSelect } | null Returns the select instance or element associated with the target. If isInstance is true, returns collection item object { id, element } where element is the HSSelect instance. If isInstance is false or omitted, returns the DOM element (HTMLElement). Returns null if select instance is not found.

Usage Examples

Example 1: Opening and closing dropdown

// Get the select instance
const instance = HSSelect.getInstance('#hs-select', true);

if (instance) {
  const { element } = instance;

  // Open dropdown
  element.open();

  // Close dropdown
  element.close();
}

Example 2: Setting value programmatically

const instance = HSSelect.getInstance('#hs-select', true);

if (instance) {
  const { element } = instance;

  // Set value for single select
  element.setValue('option-value');

  // Set value for multiple select
  element.setValue(['value-1', 'value-2']);
}

Example 3: Adding and removing options

const instance = HSSelect.getInstance('#hs-select', true);

if (instance) {
  const { element } = instance;

  // Add option
  element.addOption({
    title: 'New Option',
    val: 'new-option',
    options: {
      description: 'Option description',
      icon: '<svg>...</svg>'
    }
  });

  // Remove option
  element.removeOption('new-option');
}

Example 4: Destroying select instance

const instance = HSSelect.getInstance('#hs-select', true);

if (instance) {
  const { element } = instance;
  const removeBtn = document.querySelector('#hs-remove-btn');

  removeBtn.addEventListener('click', () => {
    // Clean up before removing from DOM
    element.destroy();
    // Now safe to remove the element
    document.querySelector('#hs-select').remove();
  });
}

Events

Select instances emit events that can be listened to for selection lifecycle hooks.

Event Name When Fired Callback Parameter Description
on:change When the selected value changes `string string[]` (new selected value; array in multi-select / tags mode)

Event Usage Example

// Get select instance
const instance = HSSelect.getInstance('#hs-select', true);

if (instance) {
  const { element } = instance;

  // Listen for selection changes
  element.on('change', (value) => {
    console.log('Selected value:', value);
    // value is a string for single-select, string[] for multi-select / tags mode
  });
}

Common Patterns

Pattern 1: Search Enabled

Enable search functionality in dropdown.

<select data-hs-select='{
  "hasSearch": true,
  "searchPlaceholder": "Search options..."
}'>
  <!-- Options -->
</select>

Pattern 2: Tags Mode

Use tags mode for multiple selections.

<select multiple data-hs-select='{
  "mode": "tags"
}'>
  <!-- Options -->
</select>

Pattern 3: API Integration

Load options from API.

<select data-hs-select='{
  "apiUrl": "/api/options",
  "apiFieldsMap": {
    "id": "id",
    "title": "name",
    "val": "value"
  }
}'>
  <!-- Options -->
</select>

License

Copyright (c) 2026 Preline Labs.

Licensed under the MIT License.