import { ArgsTable, Meta, Story } from "@storybook/addon-docs";
import { Avatar } from "@components/avatar";
import { ComponentInfo, Preview, Tagline } from "@stories/components";
import { PlaceholderMajorIcon, IconList, MagnifierMajorIcon, UfoMajorIcon, TelescopeMajorIcon, RocketMajorIcon } from "@components/icons";
import { HiddenSelect, InnerHiddenSelect, InnerSelect, Select } from "@components/select";
import { InnerItem, InnerSection, Item, Section } from "@components/collection";
import { Text } from "@components/typography";
import { Tooltip, TooltipTrigger } from "@components/tooltip";

<Meta
    title="Components/Select"
    id="select"
/>

# Select

<Tagline>A select allow users to choose a single option from a collapsible list of options.</Tagline>

<ComponentInfo
    usage={"import { Select, Item, Section, HiddenSelect, useSelect } from \"@sharegate/orbit-ui\";"}
    ariaPath="listbox"
    githubPath="/packages/components/src/select/src"
/>

## Guidelines

### Accessibility

- If you provide an [`aria-label`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label) attribute, make sure its value is in sync with the selected item, otherwise screen readers won't be able to anounce the new selected item.

## Usage

### Default

A default select.

<Preview>
    <Story name="default">
        <Select placeholder="Planets">
            <Item key="earth">Earth</Item>
            <Item key="jupiter">Jupiter</Item>
            <Item key="mars">Mars</Item>
            <Item key="mercury">Mercury</Item>
            <Item key="neptune">Neptune</Item>
            <Item key="saturn">Saturn</Item>
            <Item key="uranus">Uranus</Item>
        </Select>
    </Story>
</Preview>

### Sections

A select items can be group by sections.

<Preview>
    <Story name="sections">
        <Select placeholder="Planets">
            <Section title="Visited">
                <Item key="earth">Earth</Item>
                <Item key="mars">Mars</Item>
                <Item key="saturn">Saturn</Item>
            </Section>
            <Section title="Not Visited">
                <Item key="jupiter">Jupiter</Item>
                <Item key="mercury">Mercury</Item>
                <Item key="neptune">Neptune</Item>
                <Item key="uranus">Uranus</Item>
            </Section>
        </Select>
    </Story>
</Preview>

### Item icon

A select item can have [icons](?path=/docs/icon-gallery--page).

<Preview>
    <Story name="item icon">
        <Select placeholder="Planets">
            <Item key="earth">
                <PlaceholderMajorIcon />
                <Text>Earth</Text>
            </Item>
            <Item key="jupiter">
                <PlaceholderMajorIcon />
                <Text>Jupiter</Text>
            </Item>
            <Item key="mars">
                <PlaceholderMajorIcon />
                <Text>Mars</Text>
            </Item>
        </Select>
    </Story>
</Preview>

### Item end icon

A select item can have *non standard* end [icons](?path=/docs/icon-gallery--page) can be provided to handle special cases like displaying a list of icons. However, think twice before adding *end* icons, *start* icons should be your go to.

<Preview>
    <Story name="item end icon">
        <Select placeholder="Planets">
            <Item key="earth">
                <Text>Earth</Text>
                <IconList slot="end-icon">
                    <UfoMajorIcon />
                    <TelescopeMajorIcon />
                    <RocketMajorIcon />
                </IconList>
            </Item>
            <Item key="jupiter">
                <Text>Jupiter</Text>
                <PlaceholderMajorIcon slot="end-icon" />
            </Item>
            <Item key="mars">
                <Text>Mars</Text>
                <IconList slot="end-icon">
                    <UfoMajorIcon />
                    <TelescopeMajorIcon />
                    <RocketMajorIcon />
                </IconList>
            </Item>
        </Select>
    </Story>
</Preview>

### Item description

A select item can have a description.

<Preview>
    <Story name="item description">
        <Select placeholder="Planets">
            <Item key="earth">
                <Text>Earth</Text>
                <Text slot="description">Home sweet home!</Text>
            </Item>
            <Item key="jupiter">
                <Text>Jupiter</Text>
                <Text slot="description">The fourth-brightest object in the sky</Text>
            </Item>
            <Item key="mars">
                <Text>Mars</Text>
                <Text slot="description">See you in 2026</Text>
            </Item>
        </Select>
    </Story>
</Preview>

A description can be paired with an [icon](?path=/docs/icon-gallery--page).

<Preview>
    <Story name="item description + icon">
        <Select placeholder="Planets">
            <Item key="earth">
                <PlaceholderMajorIcon />
                <Text>Earth</Text>
                <Text slot="description">Home sweet home!</Text>
            </Item>
            <Item key="jupiter">
                <PlaceholderMajorIcon />
                <Text>Jupiter</Text>
                <Text slot="description">The fourth-brightest object in the sky</Text>
            </Item>
            <Item key="mars">
                <PlaceholderMajorIcon />
                <Text>Mars</Text>
                <Text slot="description">See you in 2026</Text>
            </Item>
        </Select>
    </Story>
</Preview>

A description can be paired with an [avatar](?path=/docs/avatar--default-story).

<Preview>
    <Story name="item description + avatar">
        <Select placeholder="Planets">
            <Item key="earth">
                <Avatar name="Earth" />
                <Text>Earth</Text>
                <Text slot="description">Home sweet home!</Text>
            </Item>
            <Item key="jupiter">
                <Avatar name="Jupiter" />
                <Text>Jupiter</Text>
                <Text slot="description">The fourth-brightest object in the sky</Text>
            </Item>
            <Item key="mars">
                <Avatar name="Mars" />
                <Text>Mars</Text>
                <Text slot="description">See you in 2026</Text>
            </Item>
        </Select>
    </Story>
</Preview>

### Item tooltip

A select can have a basic tooltip.

<Preview>
    <Story name="item tooltip">
        <Select placeholder="Planets">
            <TooltipTrigger>
                <Item key="earth">Earth</Item>
                <Tooltip>Home sweet home!</Tooltip>
            </TooltipTrigger>
            <TooltipTrigger>
                <Item key="jupiter">Jupiter</Item>
                <Tooltip>The fourth-brightest object in the sky</Tooltip>
            </TooltipTrigger>
            <TooltipTrigger>
                <Item key="mars">Mars</Item>
                <Tooltip>See you in 2026</Tooltip>
            </TooltipTrigger>
        </Select>
    </Story>
</Preview>

### Disabled item

A select item can be disabled.

<Preview>
    <Story name="disabled item">
        <Select placeholder="Planets">
            <Item disabled key="earth">Earth</Item>
            <Item key="jupiter">Jupiter</Item>
            <Item key="mars">Mars</Item>
            <Item disabled key="mercury">Mercury</Item>
            <Item key="neptune">Neptune</Item>
            <Item key="saturn">Saturn</Item>
            <Item key="uranus">Uranus</Item>
        </Select>
    </Story>
</Preview>

### Trigger icon

A select trigger can have an icon.

<Preview>
    <Story name="trigger icon">
        <Select icon={<MagnifierMajorIcon />} placeholder="Planets">
            <Item key="earth">Earth</Item>
            <Item key="jupiter">Jupiter</Item>
            <Item key="mars">Mars</Item>
            <Item key="mercury">Mercury</Item>
            <Item key="neptune">Neptune</Item>
            <Item key="saturn">Saturn</Item>
            <Item key="uranus">Uranus</Item>
        </Select>
    </Story>
</Preview>

### Disabled

<Preview>
    <Story name="disabled">
        <Select disabled placeholder="Planets">
            <Item key="earth">Earth</Item>
            <Item key="jupiter">Jupiter</Item>
            <Item key="mars">Mars</Item>
            <Item key="mercury">Mercury</Item>
            <Item key="neptune">Neptune</Item>
            <Item key="saturn">Saturn</Item>
            <Item key="uranus">Uranus</Item>
        </Select>
    </Story>
</Preview>

### Readonly

<Preview>
    <Story name="readonly">
        <Select readOnly placeholder="Planets">
            <Item key="earth">Earth</Item>
            <Item key="jupiter">Jupiter</Item>
            <Item key="mars">Mars</Item>
            <Item key="mercury">Mercury</Item>
            <Item key="neptune">Neptune</Item>
            <Item key="saturn">Saturn</Item>
            <Item key="uranus">Uranus</Item>
        </Select>
    </Story>
</Preview>

### Fluid

A select can take the width of it's container.

<Preview>
    <Story name="fluid">
        <Select fluid placeholder="Planets">
            <Item key="earth">Earth</Item>
            <Item key="jupiter">Jupiter</Item>
            <Item key="mars">Mars</Item>
            <Item key="mercury">Mercury</Item>
            <Item key="neptune">Neptune</Item>
            <Item key="saturn">Saturn</Item>
            <Item key="uranus">Uranus</Item>
        </Select>
    </Story>
</Preview>

### Validation

A select can display a validation state to communicate to the user whether the current value is valid or invalid. Implement your own validation logic in your app and pass either `"valid"` or `"invalid"` to the select via the `validationState` prop.

The example below illustrates how one would validate that a specific value have been selected.

<Preview filePath="/select/docs/SelectedValueValidation" />

### Form

A select can be part of a form. To submit the value of a select, make sure you specify the `name` property.

<Preview>
    <Story name="form">
        <form>
            <Select name="planet" placeholder="Planets">
                <Item key="earth">Earth</Item>
                <Item key="jupiter">Jupiter</Item>
                <Item key="mars">Mars</Item>
                <Item key="mercury">Mercury</Item>
                <Item key="neptune">Neptune</Item>
                <Item key="saturn">Saturn</Item>
                <Item key="uranus">Uranus</Item>
            </Select>
        </form>
    </Story>
</Preview>

### Dynamic items

A select items can be rendered dynamically.

<Preview>
    <Story name="dynamic items">
        <Select placeholder="Planets" aria-label="Planets">
            {["Earth", "Jupiter", "Mars", "Mercury", "Neptune", "Saturn", "Uranus"].map(x => (
                <Item key={x.toLowerCase()}>{x}</Item>
            ))}
        </Select>
    </Story>
</Preview>

### Controlled

The `selectedKey` and `open` state can be handled in controlled mode.

<Preview filePath="/select/docs/ControlledSelect" />

### Ghost

A select can be more discrete.

<Preview>
    <Story name="ghost">
        <Select variant="ghost" placeholder="Planets">
            <Item key="earth">Earth</Item>
            <Item key="jupiter">Jupiter</Item>
            <Item key="mars">Mars</Item>
            <Item key="mercury">Mercury</Item>
            <Item key="neptune">Neptune</Item>
            <Item key="saturn">Saturn</Item>
            <Item key="uranus">Uranus</Item>
        </Select>
    </Story>
</Preview>

### Headless select

For advanced customization use cases, Orbit helps by providing an headless `useSelect` hook.

Make sure your trigger accepts a `ref` and any other props returned by the hook.

<Preview filePath="/select/docs/CustomSelect" />

## API

### Select

<ComponentInfo
    usage={"import { Select } from \"@sharegate/orbit-ui\";"}
    inherits={[InnerSelect.defaultElement, "styled-component"]}
    compact
/>

<ArgsTable of={InnerSelect} sort="alpha" />

### Item

<ComponentInfo
    usage={"import { Item } from \"@sharegate/orbit-ui\";"}
    slots={["icon", "avatar", "text", "description", "end-icon"]}
    compact
/>

<ArgsTable of={InnerItem} sort="alpha" />

### Section

<ComponentInfo
    usage={"import { Section } from \"@sharegate/orbit-ui\";"}
    compact
/>

<ArgsTable of={InnerSection} sort="alpha" />

### HiddenSelect

<ComponentInfo
    usage={"import { HiddenSelect } from \"@sharegate/orbit-ui\";"}
    inherits={[InnerHiddenSelect.defaultElement, "styled-component"]}
    compact
/>

<ArgsTable of={InnerHiddenSelect} sort="alpha" />


