Skip to content

afiiif/headless-custom-select

Folders and files

NameName
Last commit message
Last commit date

Latest commit

e8aa41c Β· Aug 3, 2024

History

3 Commits
Jul 30, 2024
Jul 30, 2024
Aug 3, 2024
Aug 3, 2024

Repository files navigation

Headless Custom Select Component

A lightweight, flexible, and fully customizable select component library with zero dependencies.

Features

  • Zero dependencies
  • Highly customizable
  • Single or multiple selections
  • Grouping options
  • Search functionality
  • Keyboard navigation
  • Accessible

Installation

Since this is a vanilla JavaScript component with no dependencies, you can simply copy the index.min.js file into your project.
If you want to use it in your TypeScript project, you can simply copy the index.ts file.

Usage

Basic Usage

const mySelect = window.customSelect('#my-select-container', {
  data: [
    {
      groupName: 'Fruits',
      options: ['Apple', 'Banana', 'Cherry', 'Date'],
    },
    {
      groupName: 'Vegetables',
      options: ['Carrot', 'Broccoli', 'Spinach'],
    },
  ],
  className: {
    container: 'relative',
    buttonContainer:
      'flex border rounded-md overflow-hidden data-[has-value=true]:border-blue-500 focus-within:ring-2',
    triggerButton: 'py-2 px-4 flex-1 text-left',
    deselectButton: 'pt-1 pb-1.5 px-3 bg-blue-300 text-white text-xl',
    dropdownContainer:
      'absolute top-full mt-0.5 w-full bg-white shadow-lg z-10 overflow-hidden rounded-md',
    helpText: 'py-1 px-4 text-sm border-b',
    searchInput: 'px-4 py-3 w-full outline-none shadow',
    optionsContainer: 'max-h-96 overflow-y-auto',
    optionGroup: 'bg-gray-50 border-t px-4 py-1 font-semibold text-sm',
    optionItem:
      'px-8 py-2 cursor-pointer hover:bg-gray-100 [&[aria-disabled]]:bg-gray-300 [&[aria-disabled]]:opacity-50',
    optionHighlighted: '!bg-blue-500 text-white',
    optionSelected: 'bg-blue-200',
  },
});

Advanced Usage

Multiple selection with custom option object:

/** @type {import('./index.d.ts').createCustomSelect} */
const customSelect = window.customSelect;

const myMultiSelect = customSelect('#my-multi-select-container', {
  isMultiple: true,
  enableSearch: false,
  data: [
    {
      groupName: 'Group 1',
      options: [
        { id: 1, name: 'Option 1', icon: '🍎' },
        { id: 2, name: 'Option 2', icon: '🍌' },
        { id: 3, name: 'Option 3', icon: 'πŸ’' },
      ],
    },
  ],
  content: {
    optionItem: {
      label: (option, { isSelected }) => {
        const elm = document.createElement('div');
        elm.className = 'flex gap-3 items-center';
        elm.innerHTML = `
          <div>${option.icon}</div>
          <b>${option.name}</b>
          ${isSelected ? '<div>βœ“</div>' : ''}
        `;
        return elm;
      },
    },
  },
  className: {
    // ... custom class names
  },
});

About

A simple headless custom select component

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published