Files
sigpro-ui/docs/components/select.md
2026-04-02 19:31:39 +02:00

11 KiB

Select

Dropdown select component with full DaisyUI styling, reactive items, and form integration.

Tag

Select

Props

Prop Type Default Description
label string - Label text above select
items Array<{value: string, label: string}> [] Array of items with value and label
value string | Signal<string> '' Selected value
class string '' Additional CSS classes (DaisyUI + Tailwind)
disabled boolean | Signal<boolean> false Disabled state
onchange function - Change event handler

Live Examples

Basic Select

Live Demo

const BasicDemo = () => {
  const selected = $('apple');
  
  return Select({
    label: 'Choose a fruit',
    items: [
      { value: 'apple', label: '🍎 Apple' },
      { value: 'banana', label: '🍌 Banana' },
      { value: 'orange', label: '🍊 Orange' },
      { value: 'grape', label: '🍇 Grape' }
    ],
    value: selected,
    onchange: (e) => selected(e.target.value)
  });
};
$mount(BasicDemo, '#demo-basic');

With Reactive Display

Live Demo

const ReactiveDemo = () => {
  const selected = $('small');
  return Div({ class: 'flex flex-col gap-4 w-full' }, [
    Select({
      label: 'Select size',
      items: [
        { value: 'small', label: 'Small' },
        { value: 'medium', label: 'Medium' },
        { value: 'large', label: 'Large' }
      ],
      value: selected,
      onchange: (e) => selected(e.target.value)
    }),
    Div({ class: 'alert alert-info' }, [
      () => `You selected: ${selected()}`
    ])
  ]);
};
$mount(ReactiveDemo, '#demo-reactive');

Disabled State

Live Demo

const DisabledDemo = () => {
  return Select({
    label: 'Country (disabled)',
    items: [
      { value: 'mx', label: 'Mexico' },
      { value: 'us', label: 'United States' },
      { value: 'ca', label: 'Canada' }
    ],
    value: 'mx',
    disabled: true
  });
};
$mount(DisabledDemo, '#demo-disabled');

Dynamic items

Live Demo

const DynamicDemo = () => {
  const category = $('fruits');
  
  const items = {
    fruits: [
      { value: 'apple', label: '🍎 Apple' },
      { value: 'banana', label: '🍌 Banana' }
    ],
    vegetables: [
      { value: 'carrot', label: '🥕 Carrot' },
      { value: 'broccoli', label: '🥦 Broccoli' }
    ]
  };
  
  return Div({ class: 'flex flex-col gap-4 w-full' }, [
    Select({
      label: 'Category',
      items: [
        { value: 'fruits', label: 'Fruits' },
        { value: 'vegetables', label: 'Vegetables' }
      ],
      value: category,
      onchange: (e) => category(e.target.value)
    }),
    Select({
      label: 'Item',
      items: () => items[category()] || [],
      value: $(''),
      onchange: (e) => console.log('Selected:', e.target.value)
    })
  ]);
};
$mount(DynamicDemo, '#demo-dynamic');

All Variants

Live Demo

const VariantsDemo = () => {
  const primary = $('option1');
  const secondary = $('option2');
  const accent = $('');
  
  return Div({ class: 'flex flex-col gap-4' }, [
    Select({
      label: 'Primary Select',
      class: 'select-primary',
      items: [
        { value: 'option1', label: 'Option 1' },
        { value: 'option2', label: 'Option 2' },
        { value: 'option3', label: 'Option 3' }
      ],
      value: primary,
      onchange: (e) => primary(e.target.value)
    }),
    Select({
      label: 'Secondary Select',
      class: 'select-secondary',
      items: [
        { value: 'option1', label: 'Option 1' },
        { value: 'option2', label: 'Option 2' }
      ],
      value: secondary,
      onchange: (e) => secondary(e.target.value)
    }),
    Select({
      label: 'Ghost Select',
      class: 'select-ghost',
      items: [
        { value: '', label: 'Select an option' },
        { value: 'opt1', label: 'Option 1' },
        { value: 'opt2', label: 'Option 2' }
      ],
      value: accent,
      onchange: (e) => accent(e.target.value)
    })
  ]);
};
$mount(VariantsDemo, '#demo-variants');
<script> (function() { const initSelectExamples = () => { // 1. Basic Select const basicTarget = document.querySelector('#demo-basic'); if (basicTarget && !basicTarget.hasChildNodes()) { const BasicDemo = () => { const selected = $('apple'); return Select({ label: 'Choose a fruit', items: [ { value: 'apple', label: '🍎 Apple' }, { value: 'banana', label: '🍌 Banana' }, { value: 'orange', label: '🍊 Orange' }, { value: 'grape', label: '🍇 Grape' } ], value: selected, onchange: (e) => selected(e.target.value) }); }; $mount(BasicDemo, basicTarget); } // 2. Reactive Display const reactiveTarget = document.querySelector('#demo-reactive'); if (reactiveTarget && !reactiveTarget.hasChildNodes()) { const ReactiveDemo = () => { const selected = $('small'); return Div({ class: 'flex flex-col gap-4 w-full' }, [ Select({ label: 'Select size', items: [ { value: 'small', label: 'Small' }, { value: 'medium', label: 'Medium' }, { value: 'large', label: 'Large' } ], value: selected, onchange: (e) => selected(e.target.value) }), Div({ class: 'alert alert-info' }, [ `You selected: ${selected()}` ]) ]); }; $mount(ReactiveDemo, reactiveTarget); } // 3. Disabled State const disabledTarget = document.querySelector('#demo-disabled'); if (disabledTarget && !disabledTarget.hasChildNodes()) { const DisabledDemo = () => { return Select({ label: 'Country (disabled)', items: [ { value: 'mx', label: 'Mexico' }, { value: 'us', label: 'United States' }, { value: 'ca', label: 'Canada' } ], value: 'mx', disabled: true }); }; $mount(DisabledDemo, disabledTarget); } // 4. Dynamic items const dynamicTarget = document.querySelector('#demo-dynamic'); if (dynamicTarget && !dynamicTarget.hasChildNodes()) { const DynamicDemo = () => { const category = $('fruits'); const items = { fruits: [ { value: 'apple', label: '🍎 Apple' }, { value: 'banana', label: '🍌 Banana' } ], vegetables: [ { value: 'carrot', label: '🥕 Carrot' }, { value: 'broccoli', label: '🥦 Broccoli' } ] }; return Div({ class: 'flex flex-col gap-4 w-full' }, [ Select({ label: 'Category', items: [ { value: 'fruits', label: 'Fruits' }, { value: 'vegetables', label: 'Vegetables' } ], value: category, onchange: (e) => category(e.target.value) }), Select({ label: 'Item', items: () => items[category()] || [], value: $(''), onchange: (e) => console.log('Selected:', e.target.value) }) ]); }; $mount(DynamicDemo, dynamicTarget); } // 5. All Variants const variantsTarget = document.querySelector('#demo-variants'); if (variantsTarget && !variantsTarget.hasChildNodes()) { const VariantsDemo = () => { const primary = $('option1'); const secondary = $('option2'); const accent = $(''); return Div({ class: 'flex flex-col gap-4' }, [ Select({ label: 'Primary Select', class: 'select-primary', items: [ { value: 'option1', label: 'Option 1' }, { value: 'option2', label: 'Option 2' }, { value: 'option3', label: 'Option 3' } ], value: primary, onchange: (e) => primary(e.target.value) }), Select({ label: 'Secondary Select', class: 'select-secondary', items: [ { value: 'option1', label: 'Option 1' }, { value: 'option2', label: 'Option 2' } ], value: secondary, onchange: (e) => secondary(e.target.value) }), Select({ label: 'Ghost Select', class: 'select-ghost', items: [ { value: '', label: 'Select an option' }, { value: 'opt1', label: 'Option 1' }, { value: 'opt2', label: 'Option 2' } ], value: accent, onchange: (e) => accent(e.target.value) }) ]); }; $mount(VariantsDemo, variantsTarget); } }; initSelectExamples(); if (window.$docsify) { window.$docsify.plugins = [].concat(window.$docsify.plugins || [], (hook) => { hook.doneEach(initSelectExamples); }); } })(); </script>