npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@magic-spells/dropdown-select

v0.3.0

Published

Accessible custom dropdown web component.

Readme

Dropdown Select Web Component

A fully accessible custom dropdown web component that can be used as a replacement for the native <select> element with enhanced styling options and keyboard navigation.

🔍 Live Demo - See it in action!

Features

  • 🎨 Fully customizable styling
  • ♿ WAI-ARIA compliant for accessibility
  • ⌨️ Complete keyboard navigation support
  • 📱 Mobile-friendly
  • 🔍 Typeahead search functionality
  • 📜 Auto-scroll to selected items in long lists
  • 🧩 Zero dependencies
  • 📦 Small footprint (~3KB minified and gzipped)

Installation

NPM

npm install @magic-spells/dropdown-select

CDN

<link
	rel="stylesheet"
	href="https://unpkg.com/@magic-spells/dropdown-select/dist/dropdown-select.min.css"
/>
<script src="https://unpkg.com/@magic-spells/dropdown-select/dist/dropdown-select.min.js"></script>

Distribution Formats

This package provides multiple distribution formats for different environments:

  • ES Module: dropdown-select.esm.js

    import { DropdownSelect } from '@magic-spells/dropdown-select';
  • CommonJS: dropdown-select.cjs.js

    const { DropdownSelect } = require('@magic-spells/dropdown-select');
  • UMD: dropdown-select.js and dropdown-select.min.js

    • Works in browsers via script tag
    • Compatible with AMD loaders (RequireJS)
    • Works in Node.js
    <script src="dropdown-select.min.js"></script>
    <script>
      // Available as global variable DropdownSelect
      console.log(DropdownSelect);
    </script>

Usage

Basic Usage

<dropdown-select>
	<dropdown-select-trigger>
		<span class="dropdown-label">Select an option</span>
	</dropdown-select-trigger>

	<input type="hidden" class="dropdown-hidden-input" name="selected-option" />

	<dropdown-options>
		<dropdown-option value="option1">Option 1</dropdown-option>
		<dropdown-option value="option2">Option 2</dropdown-option>
		<dropdown-option value="option3">Option 3</dropdown-option>
	</dropdown-options>
</dropdown-select>

Opening Direction

The dropdown automatically detects if there's enough space below and will open upward if needed. You can explicitly set the direction with the position attribute:

<!-- Force dropdown to open upward -->
<dropdown-select position="up">
  <!-- dropdown content -->
</dropdown-select>

<!-- Force dropdown to open downward (default) -->
<dropdown-select position="down">
  <!-- dropdown content -->
</dropdown-select>

Getting the Selected Value

The selected value is stored in the hidden input element. You can also listen for the change event:

document
	.querySelector("dropdown-select")
	.addEventListener("change", function (e) {
		console.log("Selected value:", e.detail.value);
		console.log("Selected text:", e.detail.text);
	});

Keyboard Navigation

| Key | Action | | ------------- | ---------------------------------------------- | | Tab | Focus the dropdown trigger | | Enter / Space | Open the dropdown or select the focused option | | Escape | Close the dropdown without selecting | | Arrow Down | Move to the next option | | Arrow Up | Move to the previous option | | Home | Jump to the first option | | End | Jump to the last option | | Any letter | Jump to an option starting with that letter |

Styling

The component comes with default styling, but you can customize it by overriding the CSS variables or using your own CSS.

SCSS Integration

This package provides multiple ways to integrate with your SCSS workflow:

// Option 1: Use the main entry point (recommended)
@use "@magic-spells/dropdown-select/scss" with (
  $color-primary: #ff5722,
  $border-radius: 0.5rem
);

// Option 2: Import individual files
@use "@magic-spells/dropdown-select/scss/variables" with (
  $color-primary: #ff5722,
  $border-radius: 0.5rem
);
@use "@magic-spells/dropdown-select/scss/dropdown-select";

// Option 3: Direct paths (if needed)
@use "node_modules/@magic-spells/dropdown-select/dist/dropdown-select.scss";
@use "node_modules/@magic-spells/dropdown-select/dist/scss/dropdown-select";

CSS Variables

You can customize the dropdown appearance using CSS custom properties. All styling aspects are available as variables:

dropdown-select {
	/* Sizing */
	--select-dropdown-width: 400px;
	--select-options-max-height: 15rem;
	--select-caret-size: 0.25rem;
	
	/* Colors */
	--select-color-text: #333;
	--select-color-background: #fff;
	--select-color-border: #ddd;
	--select-color-border-hover: #aaa;
	--select-color-border-dark: #666;
	--select-color-primary: #ff5722;
	--select-color-primary-rgb: 255, 87, 34; /* For alpha transparency */
	--select-color-hover: #f5f5f5;
	--select-color-focus: #e6f7ff;
	--select-color-selected: #ffede6;
	
	/* Spacing */
	--select-spacing-xs: 0.25rem;
	--select-spacing-sm: 0.75rem;
	--select-spacing-md: 1rem;
	
	/* Misc */
	--select-border-radius: 0.5rem;
	--select-box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
	--select-z-index-dropdown: 10;
	--select-transition-duration: 0.2s;
}

This enables theme switching and custom styling without modifying the component itself.

Examples

Preselected Option

<dropdown-select id="fruit-dropdown">
	<dropdown-trigger id="fruit-trigger">
		<span class="dropdown-label">Apple</span>
	</dropdown-select-trigger>

	<input
		type="hidden"
		class="dropdown-hidden-input"
		name="selected-fruit"
		value="apple"
	/>

	<dropdown-options>
		<dropdown-option value="apple" aria-selected="true">Apple</dropdown-option>
		<dropdown-option value="banana">Banana</dropdown-option>
		<dropdown-option value="cherry">Cherry</dropdown-option>
	</dropdown-options>
</dropdown-select>

Integration with Form

<form id="myForm">
	<div class="form-group">
		<label for="fruit-dropdown">Select a fruit:</label>
		<dropdown-select id="fruit-dropdown">
			<dropdown-trigger id="fruit-trigger">
				<span class="dropdown-label">Select a fruit</span>
			</dropdown-select-trigger>

			<input
				type="hidden"
				class="dropdown-hidden-input"
				name="fruit"
				id="fruit-input"
			/>

			<dropdown-options>
				<dropdown-option value="apple">Apple</dropdown-option>
				<dropdown-option value="banana">Banana</dropdown-option>
				<dropdown-option value="cherry">Cherry</dropdown-option>
			</dropdown-options>
		</dropdown-select>
	</div>

	<button type="submit">Submit</button>
</form>

<script>
	document.getElementById("myForm").addEventListener("submit", function (e) {
		e.preventDefault();
		const formData = new FormData(this);
		console.log("Selected fruit:", formData.get("fruit"));
	});
</script>

API

Events

  • change - Fired when an option is selected
    • detail.value - The value of the selected option
    • detail.text - The text content of the selected option

Methods

  • show() - Opens the dropdown
  • hide() - Closes the dropdown
  • toggleDropdown() - Toggles the dropdown open/closed
  • selectOption(event) - Selects an option and updates the value

Browser Support

The component works in all modern browsers that support Custom Elements v1.

License

MIT