Files
sigpro-ui/docs/components/autocomplete.md
2026-03-31 19:15:18 +02:00

12 KiB

Autocomplete

Searchable dropdown with autocomplete functionality, keyboard navigation, and reactive options.

Tag

Autocomplete

Props

Prop Type Default Description
label string - Label text for the input
options Array<string | {value: string, label: string}> [] Options to search from
value string | Signal<string> '' Selected value
placeholder string 'Search...' Placeholder text
onSelect function - Called when an option is selected
class string '' Additional CSS classes (DaisyUI + Tailwind)

Live Examples

Basic Autocomplete

Live Demo

const BasicDemo = () => {
  const selected = $('');
  const fruits = ['Apple', 'Banana', 'Orange', 'Grape', 'Strawberry', 'Mango', 'Pineapple', 'Watermelon'];
  
  return Autocomplete({
    label: 'Search fruit',
    options: fruits,
    value: selected,
    onSelect: (value) => selected(value)
  });
};
$mount(BasicDemo, '#demo-basic');

With Objects

Live Demo

const ObjectsDemo = () => {
  const selected = $('');
  const selectedLabel = $('');
  
  const countries = [
    { value: 'mx', label: 'Mexico' },
    { value: 'us', label: 'United States' },
    { value: 'ca', label: 'Canada' },
    { value: 'br', label: 'Brazil' },
    { value: 'ar', label: 'Argentina' },
    { value: 'es', label: 'Spain' }
  ];
  
  return Div({ class: 'flex flex-col gap-4 w-full' }, [
    Autocomplete({
      label: 'Search country',
      options: countries,
      value: selectedLabel,
      onSelect: (item) => {
        const selectedItem = typeof item === 'string' 
          ? countries.find(c => c.label === item) 
          : item;
        selected(selectedItem?.value || '');
        selectedLabel(selectedItem?.label || '');
      }
    }),
    Div({ class: 'alert alert-success' }, [
      `Selected: ${selected()} - ${selectedLabel()}`
    ])
  ]);
};
$mount(ObjectsDemo, '#demo-objects');

With Reactive Display

Live Demo

const ReactiveDemo = () => {
  const selected = $('');
  
  const programmingLanguages = [
    'JavaScript', 'Python', 'Java', 'C++', 'Ruby', 'Go', 'Rust', 'TypeScript', 'Swift', 'Kotlin'
  ];
  
  return Div({ class: 'flex flex-col gap-4 w-full' }, [
    Autocomplete({
      label: 'Programming language',
      options: programmingLanguages,
      value: selected,
      onSelect: (value) => selected(value)
    }),
    () => selected() ? Div({ class: 'alert alert-info' }, [
      `You selected: ${selected()}`
    ]) : null
  ]);
};
$mount(ReactiveDemo, '#demo-reactive');

Dynamic Options

Live Demo

const DynamicDemo = () => {
  const selected = $('');
  const filterType = $('all');
  
  const allItems = {
    fruits: ['Apple', 'Banana', 'Orange', 'Mango'],
    vegetables: ['Carrot', 'Broccoli', 'Spinach', 'Potato'],
    all: ['Apple', 'Banana', 'Orange', 'Mango', 'Carrot', 'Broccoli', 'Spinach', 'Potato']
  };
  
  return Div({ class: 'flex flex-col gap-4 w-full' }, [
    Select({
      label: 'Category',
      options: [
        { value: 'all', label: 'All items' },
        { value: 'fruits', label: 'Fruits' },
        { value: 'vegetables', label: 'Vegetables' }
      ],
      value: filterType,
      onchange: (e) => filterType(e.target.value)
    }),
    Autocomplete({
      label: 'Search item',
      options: () => allItems[filterType()],
      value: selected,
      onSelect: (value) => selected(value)
    })
  ]);
};
$mount(DynamicDemo, '#demo-dynamic');

All Variants

Live Demo

const VariantsDemo = () => {
  const colors = ['Red', 'Blue', 'Green', 'Yellow', 'Purple', 'Orange', 'Pink', 'Brown', 'Black', 'White'];
  
  return Div({ class: 'flex flex-col gap-4' }, [
    Div({}, [
      Autocomplete({
        label: 'Primary style',
        class: 'input-primary',
        options: colors,
        value: $(''),
        placeholder: 'Search colors...'
      })
    ]),
    Div({}, [
      Autocomplete({
        label: 'Secondary style',
        class: 'input-secondary',
        options: colors,
        value: $(''),
        placeholder: 'Search colors...'
      })
    ]),
    Div({}, [
      Autocomplete({
        label: 'Ghost style',
        class: 'input-ghost',
        options: colors,
        value: $(''),
        placeholder: 'Search colors...'
      })
    ])
  ]);
};
$mount(VariantsDemo, '#demo-variants');
<script> (function() { const initAutocompleteExamples = () => { // 1. Basic Autocomplete const basicTarget = document.querySelector('#demo-basic'); if (basicTarget && !basicTarget.hasChildNodes()) { const BasicDemo = () => { const selected = $(''); const fruits = ['Apple', 'Banana', 'Orange', 'Grape', 'Strawberry', 'Mango', 'Pineapple', 'Watermelon']; return Autocomplete({ label: 'Search fruit', options: fruits, value: selected, onSelect: (value) => selected(value) }); }; $mount(BasicDemo, basicTarget); } // 2. With Objects const objectsTarget = document.querySelector('#demo-objects'); if (objectsTarget && !objectsTarget.hasChildNodes()) { const ObjectsDemo = () => { const selected = $(''); const selectedLabel = $(''); const countries = [ { value: 'mx', label: 'Mexico' }, { value: 'us', label: 'United States' }, { value: 'ca', label: 'Canada' }, { value: 'br', label: 'Brazil' }, { value: 'ar', label: 'Argentina' }, { value: 'es', label: 'Spain' } ]; return Div({ class: 'flex flex-col gap-4 w-full' }, [ Autocomplete({ label: 'Search country', options: countries, value: selectedLabel, onSelect: (item) => { const selectedItem = typeof item === 'string' ? countries.find(c => c.label === item) : item; selected(selectedItem?.value || ''); selectedLabel(selectedItem?.label || ''); } }), Div({ class: 'alert alert-success' }, [ `Selected: ${selected()} - ${selectedLabel()}` ]) ]); }; $mount(ObjectsDemo, objectsTarget); } // 3. Reactive Display const reactiveTarget = document.querySelector('#demo-reactive'); if (reactiveTarget && !reactiveTarget.hasChildNodes()) { const ReactiveDemo = () => { const selected = $(''); const programmingLanguages = [ 'JavaScript', 'Python', 'Java', 'C++', 'Ruby', 'Go', 'Rust', 'TypeScript', 'Swift', 'Kotlin' ]; return Div({ class: 'flex flex-col gap-4 w-full' }, [ Autocomplete({ label: 'Programming language', options: programmingLanguages, value: selected, onSelect: (value) => selected(value) }), () => selected() ? Div({ class: 'alert alert-info' }, [ `You selected: ${selected()}` ]) : null ]); }; $mount(ReactiveDemo, reactiveTarget); } // 4. Dynamic Options const dynamicTarget = document.querySelector('#demo-dynamic'); if (dynamicTarget && !dynamicTarget.hasChildNodes()) { const DynamicDemo = () => { const selected = $(''); const filterType = $('all'); const allItems = { fruits: ['Apple', 'Banana', 'Orange', 'Mango'], vegetables: ['Carrot', 'Broccoli', 'Spinach', 'Potato'], all: ['Apple', 'Banana', 'Orange', 'Mango', 'Carrot', 'Broccoli', 'Spinach', 'Potato'] }; return Div({ class: 'flex flex-col gap-4 w-full' }, [ Select({ label: 'Category', options: [ { value: 'all', label: 'All items' }, { value: 'fruits', label: 'Fruits' }, { value: 'vegetables', label: 'Vegetables' } ], value: filterType, onchange: (e) => filterType(e.target.value) }), Autocomplete({ label: 'Search item', options: () => allItems[filterType()], value: selected, onSelect: (value) => selected(value) }) ]); }; $mount(DynamicDemo, dynamicTarget); } // 5. All Variants const variantsTarget = document.querySelector('#demo-variants'); if (variantsTarget && !variantsTarget.hasChildNodes()) { const VariantsDemo = () => { const colors = ['Red', 'Blue', 'Green', 'Yellow', 'Purple', 'Orange', 'Pink', 'Brown', 'Black', 'White']; return Div({ class: 'flex flex-col gap-4' }, [ Div({}, [ Autocomplete({ label: 'Primary style', class: 'input-primary', options: colors, value: $(''), placeholder: 'Search colors...' }) ]), Div({}, [ Autocomplete({ label: 'Secondary style', class: 'input-secondary', options: colors, value: $(''), placeholder: 'Search colors...' }) ]), Div({}, [ Autocomplete({ label: 'Ghost style', class: 'input-ghost', options: colors, value: $(''), placeholder: 'Search colors...' }) ]) ]); }; $mount(VariantsDemo, variantsTarget); } }; initAutocompleteExamples(); if (window.$docsify) { window.$docsify.plugins = [].concat(window.$docsify.plugins || [], (hook) => { hook.doneEach(initAutocompleteExamples); }); } })(); </script>