import { Meta, Preview, Props, Story } from "@storybook/addon-docs/blocks";
import {
  ComponentHeading,
  EnumTable,
  Accessibility,
} from "../../storybook-components";
import { SingleSelect } from "./SingleSelect";
import { STATUS_VARIANT } from "../../types";

import {
  DemoSingleSelectSimple,
  DemoSingleSelectCategories,
  DemoSingleSelectForm,
  DemoSingleSelectNoResults,
  DemoSingleSelectNoResultsCustom,
  DemoSingleSelectLoading,
  DemoSingleSelectLoadingCustom,
  DemoSingleSelectAsyncExample,
  DemoSingleSelectPlaceholder,
  DemoSingleSelectPlaceholderElements,
  DemoSingleSelectClearable,
  DemoSingleSelectCreatable,
  DemoSingleSelectCategoriesCreatable,
  DemoSingleSelectVariants,
  DemoSingleSelectDisabledOption,
  DemoSingleSelectDisabled,
  DemoSelectInModal,
} from "./SingleSelectCSF.story";

<Meta title="Components/Forms/SingleSelect" component={SingleSelect} />

<ComponentHeading
  componentName="SingleSelect"
  description="Select component that utilizes downshift to select a single value"
  sourcePath="src/components/SelectNew/SingleSelect.tsx"
/>

```jsx
import { SingleSelect } from "@aptible/arrow-ds";
```

<Preview>
  <Story story={DemoSingleSelectSimple} />
</Preview>

## Props

### `SingleSelect`

<Props of={SingleSelect} />

### `SingleSelect.Option`

Extends `HTMLAttributes<HTMLDivElement>`. Passing `children` will replace the default label.

<Props of={SingleSelect.Option} />

### `SingleSelect.Category`

This component also accepts `children`.

<Props of={SingleSelect.Category} />

### `SingleSelect.Status`

This component only accepts `children`.

## Enums

<EnumTable enums={{ STATUS_VARIANT }} />

<Accessibility
  keyboardInteractions={[
    {
      key: "Escape",
      description: "Closes the menu, if open",
    },
    {
      key: "Up Arrow / Down Arrow",
      description: "Changes highlighted item when menu is open",
    },
    {
      key: "Tab / Shift + Tab",
      description: "Changes highlighted item when menu is open",
    },
    {
      key: "Space / Enter",
      description:
        "If the component is focused and closed, either of these keys will open it. Pressing either of these when the menu is open will select the currently highlighted item or close the menu if none is highlighted.",
    },
  ]}
/>

## Demos

### Option Categories

<Preview>
  <Story story={DemoSingleSelectCategories} />
</Preview>

### FormGroup

<Preview>
  <Story story={DemoSingleSelectForm} />
</Preview>

### No Matches Found

When an `inputValue` is provided but `children` is just an empty array, a default "No matches found" message is shown.

<Preview>
  <Story story={DemoSingleSelectNoResults} />
</Preview>

You can override the default "No matches found" message with a custom one passed to `children`.

<Preview>
  <Story story={DemoSingleSelectNoResultsCustom} />
</Preview>

### Loading

When `isLoading` is set to `true`, a loading indicator will be visible. If `children` is an empty array, a default "Loading..." message will appear in the dropdown.

<Preview>
  <Story story={DemoSingleSelectLoading} />
</Preview>

When `isLoading` is `true`, you can override the default "Loading..." message with a custom one passed to `children`.

<Preview>
  <Story story={DemoSingleSelectLoadingCustom} />
</Preview>

Here is a full example of an `SingleSelect` that fetches results from a server.

<Preview>
  <Story story={DemoSingleSelectAsyncExample} />
</Preview>

### Placeholder

If a `placeholder` is provided, it will show when there is a `null` value provided to `selected`.

<Preview>
  <Story story={DemoSingleSelectPlaceholder} />
</Preview>

The `placeholder` prop will also accept more than a string.

<Preview>
  <Story story={DemoSingleSelectPlaceholderElements} />
</Preview>

### Clearable

<Preview>
  <Story story={DemoSingleSelectClearable} />
</Preview>

### Creatable

When a function is provided to the `onCreateOption` prop, it adds a "Create..." option to the top of the list when searching. This will only be visible when the `inputValue` is not an empty string.

<Preview>
  <Story story={DemoSingleSelectCreatable} />
</Preview>

This next demo is a semi-ridiculous use case and is just meant to demonstrate the flexibility of the component.

To create an option in the "Nuts" category, include "nuts" somewhere in your query before creating.

To create an option where `hasDairy` is set to `true`, include the word "dairy" somewhere in your query before creating.

<Preview>
  <Story story={DemoSingleSelectCategoriesCreatable} />
</Preview>

### Variants

If inside a `FormGroup`, `SingleSelect` will use the value provided via context. To override, provide a `STATUS_VARIANT` directly to the `variant` prop.

<Preview>
  <Story story={DemoSingleSelectVariants} />
</Preview>

### Disabled

<Preview>
  <Story story={DemoSingleSelectDisabled} />
</Preview>

### Disabled Options

<Preview>
  <Story story={DemoSingleSelectDisabledOption} />
</Preview>

### In a modal

Nothing fancy here. This is just to test that the select menu displays correctly from inside a modal.

<Preview>
  <Story story={DemoSelectInModal} />
</Preview>
