Socket
Book a DemoInstallSign in
Socket

@crasman/multiselect

Package Overview
Dependencies
Maintainers
8
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@crasman/multiselect

Custom UI for HTML select element.

1.4.1
latest
Source
npmnpm
Version published
Maintainers
8
Created
Source

multiselect

multiselect is a custom UI for HTML select element. It attaches to a native select element, replaces it visually with an accessible custom UI, and updates changes between the two.

This component been split into two versions: old Multiselect as is, and a slightly updated version called MirrorSelect. Old version is still available to use and works for backwards compatibility for those who wish to still use it.

The key difference with multiselect and mirrorselect is that mirrorselect reflects the changes in native select options as DOM attribute changes. This will trigger eventListeners and such. It will also listen to changes in the native select options, so you can toggle options with something like select.options[n].toggleAttribute('selected') and the change will be updated in the MirrorSelect component. This was something the old MultiSelct didn't do, and was the motivation for this upgrade.

Installation

npm install @crasman/multiselect

Usage

HTML

Nothing fancy, just native HTML.

<label for="makes-select">Valitse merkit</label>

<select id="makes-select" name="makes" multiple required>
  <option value="" hidden>Merkki</option>
  <option value="Alfa Romeo">Alfa Romeo</option>
  <option value="Audi">Audi</option>
  <option value="BMW">BMW</option>
  <option value="Chevrolet">Chevrolet</option>
</select>

JavaScript

Create a new Multiselect instance for each select element to provide a custom UI for. Old MultiSelect:

import { Multiselect } from '@crasman/multiselect';

const settings = { listElement: { size: 12 } };

document.querySelector('select').forEach((select) => {
  new Multiselect(select, settings);
});

OR new MirrorSelect:

import { MirrorSelect } from '@crasman/multiselect';

const settings = { listElement: { size: 12 } };

document.querySelector('select').forEach((select) => {
  new MirrorSelect(select, settings);
});

Customization

Settings

Following settings may be passed to the constructor:

  • containerElement.className (string) - Class name for the container element, that contains all elements belonging to the multiselect. Defaults to "multiselect-container".
  • buttonElement.idPrefix (string) - Prefix for ID of the button element. Defaults to "multiselect".
  • buttonElement.className (string) - Class name for the button element. Defaults to "multiselect-button".
  • buttonElement.placeholderClassName (string) - Additional class name for the button element, to help styling of the button when the "placeholder" text should be shown. Defaults to "placeholder".
  • buttonElement.textContent (string) - Text content of the button element, when no selections are present. Defaults to text content of the first option.
  • buttonElement.showPlaceholder (boolean) - Show original text content of the button above selected options, when any are present. Defaults to true.
  • buttonElement.preventScrollOnFocus (boolean) - Prevent scrolling to button element on focus. Defaults to false.
  • innerContainerElement.className (string) - Class name for the inner container element, that contains the button and list elements. Defaults to "multiselect-inner-container".
  • labelElement.idPrefix (string) - Prefix for ID of the label element. Defaults to "multiselect-label".
  • labelElement.className (string) - Class name for the label element. Defaults to "multiselect-label".
  • labelElement.disabledClassName (string) - Additional class name for the label element, when multiselect is disabled. Defaults to "disabled".
  • listElement.className (string) - Class name for the list element. Defaults to "multiselect-list".
  • listElement.multipleClassName (string) - Additional class name for the list element, when selection type is multiple. Defaults to "multiple".
  • listElement.size (number) - Number of list items to show at once in the scrolling list box. Defaults to 8.
  • listElement.preventScrollOnFocus (boolean) - Prevent scrolling to list element on focus. Defaults to true.
  • listItemElement.idPrefix (string) - Prefix for IDs of the list item elements. Defaults to "multiselect-option".
  • listItemElement.className (string) - Class name for the list item elements. Defaults to "multiselect-option".
  • listItemElement.focusClassName (string) - Additional class name for the list item elements, when one is the active item in navigation, be it through mouseover or keydown event. This should be used instead of CSS :hover selector, to prevent a list item from having hover styles when navigating with keyboard in the list box. Defaults to "focus".
  • listItemElement.selectedClassName (string) - Additional class name for the list item elements, when one has been selected. Defaults to "selected".
  • listItemElement.disabledClassName (string) - Additional class name for the list item elements, when one is disabled. Defaults to "disabled".
  • listGroupElement.className (string) - Class name for the group container elements of list items. Defaults to "multiselect-group".
  • listGroupListElement.className (string) - Class name for the group list elements, which contain the grouped list items. Defaults to "multiselect-group-list".
  • listGroupListElement.disabledClassName (string) - Additional class name for the group list elements, when one is disabled. Defaults to "disabled".

MirrorSelect only settings

  • baseClassName (string) - Optional parameter for rewriting all the className's basenames for the default styles. Defaults to 'multiselect-'. For example baseClassName: 'project-multiselect__' produces class names like 'project-multiselect__group', 'project-multiselect__container', etc...

  • mirrorNative (boolean) - You can turn the native select's mirror feature off, and run this as if it were the old MultiSelect

  • cloneAttributesWhitelist (string[]) - array of strings to select which attributes from native selects options are passed thru to constructed ul / li component. This can be used for example to pass style and dataset options thru, and use those to style individual options

  • setCssProperties (boolean) - Wether or not to set the CSS-variable style properties --item-height and --list-size for the list elements. In some cases this may be unwanted, for example if you wish to set a custom height options for a specific select element. Disabling this prevents individual options from resetting the size vars, which means the values will cascade normally from the CSS inheritance tree.

  • searchable.searchable (boolean) - Determines whether the search functionality is enabled. By default, this is set to false. If this isn't true, none of the rest searchable params matter.

  • searchable.idPrefix (string) - Prefix for the IDs of the search-related elements. Optional, defaults to 'multiselect-search'.

  • searchable.className (string) - Additional class name that can be applied to the search-related elements, allowing for custom styling. Optional, defaults to 'multiselect-search'.

  • searchable.element (string) - Specifies the HTML element type used to create the search functionality container. Optional, the default element type is 'div'.

  • searchable.autocomplete (string) - Specifies the autocomplete attribute for the search input element. Optional, the default autocomplete is 'off'.

  • searchable.selectionClears (boolean) - Wether selecting an option from the list clears the select box. Defaults to false.

  • searchable.enterSelects (boolean) - Wether hitting enter should select an option from the list (if there is only one option). Defaults to false.

  • searchable.autocomplete (string) - The autocomplete on the search input, on or off. Defaults to 'off'.

Search Functionality

The component now seamlessly integrates an optional search functionality. Users can easily filter options by typing into the provided search input, activated by clicking on the input. The user's input is lowercased and scrubbed of special characters and compared against the select's keys and values, which are also normalized. This enhances the user experience, allowing for a more tolerant search that doesn't require precise typing, such as "Über" or "Škoda"; "uber" or "skoda" will find the right options just as well.

CSS

Default styles are provided in the index.scss file. To use them in your project, you may either import the Sass stylesheet and extend and overwrite the styles as you wish, or copy the contents of the file and edit them as needed. To style the elements, you should use the class names specified in the settings.

To use stylesheet with the default prefixes, something like this should suffice:

@import '../../node_modules/@crasman/multiselect/index.scss';

The styles are provided via a mixin called multiselectStyles, which receives the classname prefix as a parameter. This allows you to use the styles with a custom prefix. Default index.scss provides default styles with the prefix 'multiselect-' which the JS uses by default as well.

To import and use multiselect styles with your custom prefix that fits your BEM convention etc., something like this would work:

@use '../../node_modules/@crasman/multiselect/src/multiselectMixin.scss' as msm;
@include msm.multiselectStyles('project-multiselect__');

.project-multiselect {
  &__own {
    /*...*/
  }

  &__BEM {
    /*...*/
  }

  &__modifications {
    /*...*/
  }
}

In this case, also use the same prefix in the JS settings object:

import Multiselect from '@crasman/multiselect';

const settings = {
  listElement: { size: 12 },
  baseClassName: 'project-multiselect__',
};

document.querySelector('select').forEach((select) => {
  new Multiselect(select, settings);
});

Development

Publishing updates

You'll need:

  • An npmjs registry account, logged into the account on current machine. Use npm login to sign in, if not.
  • Membership in the Crasman organization. (You can log in to the _crasman admin account to add yourself. Password in Zoho, OTP goes to crasman@crasman.fi)

Given that you have the code changes you wanted merged in the admin branch:

  • Did you remember to build the project? You need to do that so that src gets built to dist, and push this as well.
  • npm run build
  • Update the package version.
  • npm version major|minor|patch --message 'patched doohickey in thingamabob' This should increment the version number in package.json, create a version tag and commit changes.
  • Push changes, including the tags.
  • git push && git push --tags
  • Once admin has the updated code, the correct package number, and the git branch has the tag, run
  • npm publish

Keywords

multiselect

FAQs

Package last updated on 10 Apr 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.