# Select

## Description

A dropdown selection component that allows users to choose from a list of options. Supports single and multiple selections, custom icons, placeholder text, and integrates seamlessly with form validation. Built with accessibility and keyboard navigation in mind.

## Aliases

- Select
- Dropdown
- ComboBox
- Picker
- OptionList

## Props Breakdown

**Extends:** `HTMLAttributes<HTMLElement>` (excluding `style`, `children`, `onClick`) + `ControlledFormComponentProps<FieldValue>`

| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `children` | `ReactElement<OptionProps> \| ReactElement<OptionProps>[]` | - | Yes | Options to render in the dropdown |
| `placeholder` | `string` | - | No | Placeholder text when no option is selected |
| `leadingIcon` | `ReactNode` | - | No | Icon displayed before the select input |
| `expandIcon` | `ReactNode` | - | No | Custom expand/collapse icon |
| `selectedView` | `React.FC<any>` | - | No | Component to render selected items |
| `popoverOffset` | `[number, number]` | - | No | Offset for the dropdown popover position |
| `menuProps` | `ContentProps` | - | No | Additional props for the dropdown menu |
| `multiple` | `boolean` | `false` | No | Whether multiple selection is allowed |
| `hasDefaultOption` | `boolean` | `false` | No | Whether to include a default empty option |
| `defaultOpen` | `boolean` | `false` | No | Whether the dropdown is open by default |
| `open` | `boolean` | `false` | No | Controls the open state in controlled mode |
| `state` | `'Default' \| 'Error'` | `'Default'` | No | Visual state of the select component |

Plus all `ControlledFormComponentProps` (initialValue, value, onValueChange, disabled, required, invalid, id).

## Examples

### Basic Usage
```tsx
import { Select, Option } from '@delightui/components';

function BasicExample() {
  return (
    <Select placeholder="Choose an option">
      <Option value="option1">Option 1</Option>
      <Option value="option2">Option 2</Option>
      <Option value="option3">Option 3</Option>
    </Select>
  );
}
```

### Controlled Select
```tsx
function ControlledExample() {
  const [selectedValue, setSelectedValue] = useState('');

  return (
    <Select 
      value={selectedValue}
      onValueChange={setSelectedValue}
      placeholder="Select a country"
    >
      <Option value="us">United States</Option>
      <Option value="uk">United Kingdom</Option>
      <Option value="ca">Canada</Option>
      <Option value="au">Australia</Option>
    </Select>
  );
}
```

### Multiple Selection
```tsx
function MultipleSelectionExample() {
  const [selectedValues, setSelectedValues] = useState([]);

  return (
    <Select 
      multiple
      value={selectedValues}
      onValueChange={setSelectedValues}
      placeholder="Select multiple options"
    >
      <Option value="red">Red</Option>
      <Option value="green">Green</Option>
      <Option value="blue">Blue</Option>
      <Option value="yellow">Yellow</Option>
      <Option value="purple">Purple</Option>
    </Select>
  );
}
```

### Select with Icons
```tsx
function IconSelectExample() {
  return (
    <div className="icon-selects">
      <Select 
        leadingIcon={<Icon icon="Location" />}
        placeholder="Select location"
      >
        <Option value="ny">New York</Option>
        <Option value="la">Los Angeles</Option>
        <Option value="sf">San Francisco</Option>
      </Select>
      
      <Select 
        leadingIcon={<Icon icon="Person" />}
        expandIcon={<Icon icon="ExpandMore" />}
        placeholder="Select user"
      >
        <Option value="john">John Doe</Option>
        <Option value="jane">Jane Smith</Option>
        <Option value="bob">Bob Johnson</Option>
      </Select>
    </div>
  );
}
```

### Form Integration
```tsx
function FormSelectExample() {
  const handleSubmit = (values, setError) => {
    if (!values.category) {
      setError('category', 'Please select a category');
      return;
    }
    console.log('Form submitted:', values);
  };

  return (
    <Form onSubmit={handleSubmit}>
      <FormField name="title" label="Title" required>
        <Input placeholder="Enter title" />
      </FormField>
      
      <FormField name="category" label="Category" required>
        <Select placeholder="Choose a category">
          <Option value="tech">Technology</Option>
          <Option value="business">Business</Option>
          <Option value="design">Design</Option>
          <Option value="marketing">Marketing</Option>
        </Select>
      </FormField>
      
      <FormField name="tags" label="Tags">
        <Select multiple placeholder="Select tags">
          <Option value="urgent">Urgent</Option>
          <Option value="important">Important</Option>
          <Option value="draft">Draft</Option>
          <Option value="review">Needs Review</Option>
        </Select>
      </FormField>
      
      <Button actionType="submit">Submit</Button>
    </Form>
  );
}
```

### Select with Validation
```tsx
function ValidationSelectExample() {
  const [selected, setSelected] = useState('');
  const [error, setError] = useState('');

  const handleChange = (value) => {
    setSelected(value);
    if (value) {
      setError('');
    }
  };

  const validateSelection = () => {
    if (!selected) {
      setError('Please make a selection');
      return false;
    }
    return true;
  };

  return (
    <div className="validation-select">
      <Select 
        value={selected}
        onValueChange={handleChange}
        placeholder="Select an option"
        state={error ? 'Error' : 'Default'}
      >
        <Option value="option1">Option 1</Option>
        <Option value="option2">Option 2</Option>
        <Option value="option3">Option 3</Option>
      </Select>
      
      {error && (
        <Text type="BodySmall" className="error-message">
          {error}
        </Text>
      )}
      
      <Button onClick={validateSelection}>
        Validate Selection
      </Button>
    </div>
  );
}
```

### Disabled Select
```tsx
function DisabledSelectExample() {
  return (
    <div className="disabled-selects">
      <Select disabled placeholder="Disabled select">
        <Option value="option1">Option 1</Option>
        <Option value="option2">Option 2</Option>
      </Select>
      
      <Select 
        disabled 
        value="option1"
        placeholder="Disabled with value"
      >
        <Option value="option1">Selected Option</Option>
        <Option value="option2">Option 2</Option>
      </Select>
    </div>
  );
}
```

### Select with Groups
```tsx
function GroupedSelectExample() {
  return (
    <Select placeholder="Select a framework">
      {/* Frontend Options */}
      <Option disabled>Frontend</Option>
      <Option value="react">React</Option>
      <Option value="vue">Vue.js</Option>
      <Option value="angular">Angular</Option>
      
      {/* Backend Options */}
      <Option disabled>Backend</Option>
      <Option value="node">Node.js</Option>
      <Option value="python">Python</Option>
      <Option value="ruby">Ruby</Option>
      
      {/* Database Options */}
      <Option disabled>Database</Option>
      <Option value="mongodb">MongoDB</Option>
      <Option value="postgresql">PostgreSQL</Option>
      <Option value="mysql">MySQL</Option>
    </Select>
  );
}
```

### Searchable Select
```tsx
function SearchableSelectExample() {
  const [searchTerm, setSearchTerm] = useState('');
  const options = [
    { value: 'apple', label: 'Apple' },
    { value: 'banana', label: 'Banana' },
    { value: 'cherry', label: 'Cherry' },
    { value: 'date', label: 'Date' },
    { value: 'elderberry', label: 'Elderberry' }
  ];

  const filteredOptions = options.filter(option =>
    option.label.toLowerCase().includes(searchTerm.toLowerCase())
  );

  const OptionComponent = ({ value, label }) => (
    <Option value={value}>
      {label}
    </Option>
  );

  return (
    <div className="searchable-select">
      <Input 
        placeholder="Search options..."
        value={searchTerm}
        onValueChange={setSearchTerm}
        leadingIcon={<Icon icon="Search" />}
      />
      
      <Select placeholder="Select a fruit">
        <List
          data={filteredOptions}
          component={OptionComponent}
          keyExtractor={(option) => option.value}
        />
      </Select>
    </div>
  );
}
```

### Custom Selected View
```tsx
function CustomSelectedViewExample() {
  const CustomSelectedView = ({ selectedItems }) => {
    const ChipComponent = ({ value, label }) => (
      <Chip size="Small">
        {label}
      </Chip>
    );

    return (
      <div className="custom-selected">
        {selectedItems.length > 0 ? (
          <div className="selected-items">
            <List
              data={selectedItems.slice(0, 2)}
              component={ChipComponent}
              keyExtractor={(item) => item.value}
            />
            {selectedItems.length > 2 && (
              <Text type="BodySmall">
                +{selectedItems.length - 2} more
              </Text>
            )}
          </div>
        ) : (
          <Text type="BodyMedium" className="placeholder">
            Select items...
          </Text>
        )}
      </div>
    );
  };

  return (
    <Select 
      multiple
      selectedView={CustomSelectedView}
      placeholder="Select multiple items"
    >
      <Option value="item1">Item 1</Option>
      <Option value="item2">Item 2</Option>
      <Option value="item3">Item 3</Option>
      <Option value="item4">Item 4</Option>
      <Option value="item5">Item 5</Option>
    </Select>
  );
}
```

### Dynamic Options
```tsx
function DynamicOptionsExample() {
  const [category, setCategory] = useState('');
  const [subcategory, setSubcategory] = useState('');

  const subcategories = {
    tech: ['Frontend', 'Backend', 'Mobile', 'DevOps'],
    business: ['Marketing', 'Sales', 'Operations', 'Strategy'],
    design: ['UI/UX', 'Graphic', 'Product', 'Branding']
  };

  return (
    <div className="dynamic-selects">
      <Select 
        value={category}
        onValueChange={(value) => {
          setCategory(value);
          setSubcategory(''); // Reset subcategory when category changes
        }}
        placeholder="Select category"
      >
        <Option value="tech">Technology</Option>
        <Option value="business">Business</Option>
        <Option value="design">Design</Option>
      </Select>
      
      {category && (
        <Select 
          value={subcategory}
          onValueChange={setSubcategory}
          placeholder="Select subcategory"
        >
          <List
            data={subcategories[category].map(sub => ({ label: sub, value: sub.toLowerCase() }))}
            component={({ label, value }) => (
              <Option value={value}>
                {label}
              </Option>
            )}
            keyExtractor={(item) => item.value}
          />
        </Select>
      )}
    </div>
  );
}
```