Solid Select

repository·main·Indexed 42 days ago

https://github.com/thisbeyond/solid-select

A flexible, zero-dependency selection component library for SolidJS. It provides a high-level Select component for single or multiple value selection, as well as low-level primitives like createSelect, createOptions, and createAsyncOptions for building custom UI controls. The library includes built-in fuzzy search utilities such as fuzzySearch, fuzzySort, and fuzzyHighlight to enhance search UX.

Tokens
3K
Snippets
12
Records
13
Agent score
50%

What's inside Solid Select

  1. Overview of Solid Select features and primitives

    main

    Solid Select provides several ways to implement selection logic depending on your needs:

    • Select component: A high-level component supporting static or dynamic option lists, and single or multiple value selection.
    • createOptions helper: Used for configuring filterable options based on input value. It supports match highlighting and can work with plain strings or objects (via a key property). It can also be used to create new options on the fly.
    • createSelect primitive: A lower-level primitive for developers who want to implement their own UI using the core selection logic.
    • Composable building blocks: The library provides primitives to build custom controls from scratch.

    Key characteristics:

    • Built for SolidJS using fine-grained reactivity.
    • Zero dependencies (only requires Solid).
    • Supports single and multi-select modes.
  2. Use the high-level Select component

    main

    The simplest way to use the library is via the Select component. You must import the component and its default CSS to ensure proper styling. The component accepts an options prop which can be an array of strings.

    For more complex use cases, refer to the official documentation at https://solid-select.com.

    import { Select } from "@thisbeyond/solid-select";
    import "@thisbeyond/solid-select/style.css";
    
    const App = () => {
      return (
        <div>
          <Select options={["apple", "banana", "pear", "pineapple", "kiwi"]} />
        </div>
      );
    };
    
    export default App;
  3. Configure Windi CSS for the solid-select site

    main

    The site/windi.config.ts file defines the styling configuration for the project's website using vite-plugin-windicss. It specifies the theme (fonts, colors, shadows, backgrounds), dark mode behavior, and custom utility shortcuts.

    Theme Configuration

    • darkMode: Set to false.
    • fontFamily:
      • sans: ["Poppins", "sans-serif"]
      • mono: ["Jetbrains Mono", "monospace"]
    • Extended Styles:
      • colors: Defines primary (#f97316) and secondary (#fb923c).
      • boxShadow: Defines inner-lg (inset 0 0 30px 20px rgba(0, 0, 0, 0.2)).
      • backgroundImage: Defines gradient (linear-gradient(90deg, #f97316 0%, #fb923c 100%)).

    Shortcuts

    The configuration includes a primary-button shortcut which combines multiple utility classes for consistent button styling.

    import { defineConfig } from "vite-plugin-windicss";
    
    export default defineConfig({
      darkMode: false,
      theme: {
        fontFamily: {
          sans: ["Poppins", "sans-serif"],
          mono: ["Jetbrains Mono", "monospace"],
        },
        extend: {
          colors: {
            primary: "#f97316",
            secondary: "#fb923c",
          },
          boxShadow: {
            "inner-lg": "inset 0 0 30px 20px rgba(0, 0, 0, 0.2)",
          },
          backgroundImage: {
            gradient: "linear-gradient(90deg, #f97316 0%, #fb923c 100%)",
          },
        },
      },
      shortcuts: {
        "primary-button":
          "text-white !bg-secondary " +
          "rounded-lg py-1 px-4 shadow " +
          "focus:outline-none focus:shadow-outline transform transition " +
          "!hover:scale-110 duration-300 ease-in-out " +
          "!active:scale-100",
      },
    });
  4. Highlight fuzzy matches with fuzzyHighlight

    main

    Use fuzzyHighlight to render a UI representation of a target string where the characters matching a search query are visually emphasized.

    It accepts a FuzzySearchResult object and an optional highlighter function. The highlighter function is called for each matched segment and should return a UI element (like a <mark> tag in SolidJS/React) to wrap the matched text.

    Note: The FuzzySearchResult must be obtained via fuzzySearch or fuzzySort first.

    import { fuzzyHighlight, fuzzySearch } from './fuzzy';
    
    const searchResult = fuzzySearch('ap', 'Apple');
    
    // Default usage (uses <mark> if in a JSX environment)
    const highlighted = fuzzyHighlight(searchResult);
    
    // Custom highlighter
    const customHighlighted = fuzzyHighlight(searchResult, (match) => (
      <span style={{ fontWeight: 'bold', color: 'red' }}>{match}</span>
    ));
  5. Manage options with createOptions and createAsyncOptions

    main

    The library provides utilities to manage the data source of your select component:

    • createOptions: Used for managing static or locally managed lists of options. It supports formatting and filtering.
    • createAsyncOptions: Used for fetching options from an external source (e.g., an API) asynchronously.
    import { createOptions, createAsyncOptions } from 'solid-select';
    
    // For local/static options
    const options = createOptions(data);
    
    // For remote/API options
    const asyncOptions = createAsyncOptions(fetchData);
  6. Initialize a select component with createSelect

    main

    Use createSelect to initialize a new select component instance. This is the primary entrypoint for setting up the component's logic and configuration.

    import { createSelect } from 'solid-select';
    
    // Usage depends on the implementation details of createSelect
    const select = createSelect(options);
  7. Perform fuzzy search on items with fuzzySort

    main

    Use fuzzySort to filter and rank a list of items based on a search string. It returns an array of results containing the original item, its original index, and the fuzzy match metadata (score and character matches).

    If a key is provided, it can be a string (representing a property name on the item) or a function that extracts the target string from the item. Only items with a non-zero score are included in the returned array. Results are sorted by score (descending) and then by their original index (ascending).

    import { fuzzySort } from './fuzzy';
    
    const items = [
      { name: 'Apple' },
      { name: 'Banana' },
      { name: 'Apricot' }
    ];
    
    // Sort by the 'name' property
    const results = fuzzySort('ap', items, 'name');
    
    // Or use a function to extract the target
    const resultsFunc = fuzzySort('ap', items, (item) => item.name);
  8. Use Select components and hooks

    main

    The library exports a suite of components and a hook for building custom select UIs:

    Components:

    • Select: The root component.
    • Container: The wrapper for the select element.
    • Control: The interactive part of the select (the area users click).
    • Placeholder: The text shown when no value is selected.
    • SingleValue / MultiValue: Components for displaying the currently selected value(s).
    • Input: The text input used for searching/filtering.
    • List: The dropdown container for options.
    • Option: Individual items within the list.

    Hooks:

    • useSelect: A hook to access the SelectContext within child components.
    import {
      Select,
      Container,
      Control,
      Placeholder,
      SingleValue,
      MultiValue,
      Input,
      List,
      Option,
      useSelect
    } from 'solid-select';
  9. Use fuzzy search and sorting utilities

    main

    The library includes fuzzy matching utilities to improve search UX:

    • fuzzySearch: Performs a fuzzy search against a string.
    • fuzzySort: Sorts items based on fuzzy match scores.
    • fuzzyHighlight: Provides logic for highlighting fuzzy matches in text.
    import { fuzzySearch, fuzzySort, fuzzyHighlight } from 'solid-select';
  10. Execute a single fuzzy search with fuzzySearch

    main

    Use fuzzySearch to calculate the match score and character positions for a single target string against a search value.

    It returns a FuzzySearchResult object containing:

    • target: The original string being searched.
    • score: A numeric value representing the quality of the match (higher is better).
    • matches: An array of booleans indicating which character indices in the target matched the search value.
    import { fuzzySearch } from './fuzzy';
    
    const result = fuzzySearch('ap', 'Apple');
    console.log(result.score); // Returns a score based on match quality
    console.log(result.matches); // Array of booleans for each char in 'Apple'
  11. Reference: Core Types

    main

    The following types are exported for use in your application logic and component definitions:

    // Select Creation Types
    export type CreateSelectOption = ...;
    export type CreateSelectValue = ...;
    
    // Options Management Types
    export type CreateOptionsOption = ...;
    export type CreateOptionsFormatFunction = ...;
    export type CreateOptionsFilterableFunction = ...;
    export type CreateOptionsCreateableFunction = ...;
    
    // Fuzzy Search Types
    export type FuzzySearchResult = ...;
    export type FuzzySortResult = ...;
    
    // Context and Component Types
    export type SelectContext = ...;