import {
  Story,
  Canvas,
  ArgsTable,
  Meta,
  SourceState,
} from "@storybook/blocks";
import { ComponentHeading } from "../../storybook-components";
import { STATUS_VARIANT, THEME, ORIENTATION } from "../../types";
import { ICON_TYPE } from "../Icon";
import { Tooltip } from "../Tooltip";
import { Stack } from "../Stack";
import { Label } from "../Label";
import { Input, INPUT_ICON_POSITION } from "./Input";

export const decorators = [
  (storyFn) => <div className="p-8 bg-gray-800">{storyFn()}</div>,
];

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

<ComponentHeading
  componentName="Input"
  description="Creates text inputs for a form"
  sourcePath="src/components/Input/Input.tsx"
/>

## Installation

```jsx
import { Input } from "@conveyorhq/arrow-ds";
```

## Basic usage

<Canvas withSource={SourceState.OPEN}>
  <Story name="Text Input">
    <Input type="text" />
  </Story>
</Canvas>

## API

These are the custom props that extend [`React.HTMLProps<HTMLInputElement>`](/?path=/docs/resources-element-props-input--page).

<ArgsTable of={Input} />

## Demos

### Light theme (default)

#### Disabled

<Canvas withSource={SourceState.OPEN}>
  <Story name="Text Input Disabled">
    <Input type="text" value="Disabled" disabled />
  </Story>
</Canvas>

#### With Placeholder

<Canvas withSource={SourceState.OPEN}>
  <Story name="Text Input Placeholder">
    <Input type="text" placeholder="Placeholder Text" />
  </Story>
</Canvas>

#### With Icon

<Canvas isColumn>
  <Story name="Text Input Icon Left">
    <Input type="text" icon={ICON_TYPE.SEARCH} placeholder="Left" />
  </Story>
  <Story name="Text Input Icon Right">
    <Input
      type="text"
      icon={ICON_TYPE.SEARCH}
      iconPosition={INPUT_ICON_POSITION.RIGHT}
      placeholder="Right"
    />
  </Story>
  <Story name="Text Input Loading Icon">
    <Input
      type="text"
      icon={ICON_TYPE.SPINNER}
      iconPosition={INPUT_ICON_POSITION.RIGHT}
      iconProps={{
        spin: true,
      }}
      placeholder="Loading…"
    />
  </Story>
</Canvas>

#### Changing the icon color

You can change the color of the icon in two ways:

1. Set the `className` prop in `iconProps`
2. Set the `color` prop in `iconProps`

The `className` value can be any Tailwind `text-*` color value, e.g.
`text-green-400`.

The `color` value must be the color keyword from the Tailwind `text-*`
classname, e.g. `blue-400`. Also, for the color keyword to work, the Tailwind
classname must exist in the CSS. If the classname has never been used prior,
then the keyword won't work and you should use the `className` prop instead.
This is because Tailwind only builds and outputs the classnames in use.

<Canvas isColumn>
  <Story name="Text Input Icon Color Classname">
    <Input
      type="text"
      icon={ICON_TYPE.USER}
      iconPosition={INPUT_ICON_POSITION.LEFT}
      iconProps={{
        className: "text-green-400",
      }}
      placeholder="Green icon"
    />
  </Story>
  <Story name="Text Input Icon Color">
    <Input
      type="text"
      icon={ICON_TYPE.USER}
      iconPosition={INPUT_ICON_POSITION.LEFT}
      iconProps={{
        color: "blue-400",
      }}
      placeholder="Blue icon"
    />
  </Story>
</Canvas>

#### Variants

<Canvas isColumn>
  <Story name="Text Input Success">
    <Input type="text" variant={STATUS_VARIANT.SUCCESS} />
  </Story>
  <Story name="Text Input Warning">
    <Input type="text" variant={STATUS_VARIANT.WARNING} />
  </Story>
  <Story name="Text Input Danger">
    <Input type="text" variant={STATUS_VARIANT.DANGER} />
  </Story>
</Canvas>

#### Monospace

<Canvas withSource={SourceState.OPEN}>
  <Story name="Text Input Monospace">
    <Input type="text" placeholder="Monospace font" className="font-mono" />
  </Story>
</Canvas>

#### With a tooltip

The tooltip makes uses of `onFocus` and `onBlur` on the reference element to
show or hide the popover. This demo shows how you can pass through custom
`onFocus` and `onBlur` events to the reference element.

<Canvas withSource={SourceState.OPEN}>
  <Story name="Text Input tooltip">
    <Tooltip
      placement="top"
      referenceElement={
        <Input
          type="text"
          onFocus={() => console.log("onFocus from input")}
          onBlur={() => console.log("onBlur from input")}
        />
      }
    >
      Please don’t leave me blank
    </Tooltip>
  </Story>
</Canvas>

#### Applying classnames

The `className` prop when set, will apply styles to the input element. However,
when you pass an icon with the Input, an extra wrapping `div` is added. To
control the styles of the wrapping `div`, you will need to set
`wrapperClassName`.

Both classname props can work together. Note that `wrapperClassName` only works
when there’s an icon.

<Canvas withSource={SourceState.OPEN}>
  <Story name="Text Input classnames">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Label htmlFor="input-1">
        Input with icon, className and wrapperClassName
      </Label>
      <Input
        id="input-1"
        className="bg-gray-300 border-gray-300"
        wrapperClassName="w-1/2"
        icon={ICON_TYPE.CHECK}
        iconPosition={INPUT_ICON_POSITION.RIGHT}
        iconProps={{
          className: "text-brandGreen-400",
        }}
        type="text"
      />
      <Label htmlFor="input-2">Input without icon and className</Label>
      <Input
        id="input-2"
        className="bg-gray-300 border-gray-300 w-1/2"
        type="text"
      />
      <Label htmlFor="input-2">Input disabled</Label>
      <Input
        id="input-2"
        className="bg-gray-300 border-gray-300 w-1/2"
        type="text"
        disabled
      />
    </Stack>
  </Story>
</Canvas>

### Dark theme

By passing `theme="brand"` to the component, you will get a dark themed input.
Supported functionaliy for the dark (brand) theme input is shown below. If an
input is within a dark (brand) themed [`FormGroup`](http://localhost:9002/?path=/docs/components-aptible-branding-formgroup--form-group), it will inherit its theme.
To override this, provide a value to the input's `theme` prop.

#### Default

<Canvas withSource={SourceState.OPEN}>
  <Story name="Text Input Dark" decorators={decorators}>
    <Input type="text" theme={THEME.BRAND} />
  </Story>
</Canvas>

#### Disabled

<Canvas withSource={SourceState.OPEN}>
  <Story name="Text Input Disabled Dark" decorators={decorators}>
    <Input type="text" theme={THEME.BRAND} value="Disabled" disabled />
  </Story>
</Canvas>

#### With Placeholder

<Canvas withSource={SourceState.OPEN}>
  <Story name="Text Input Placeholder Dark" decorators={decorators}>
    <Input type="text" theme={THEME.BRAND} placeholder="Placeholder Text" />
  </Story>
</Canvas>

#### With Icon

<Canvas isColumn>
  <Story name="Text Input Icon Left Dark" decorators={decorators}>
    <Input
      type="text"
      theme={THEME.BRAND}
      icon={ICON_TYPE.SEARCH}
      placeholder="Left"
    />
  </Story>
  <Story name="Text Input Icon Right Dark" decorators={decorators}>
    <Input
      type="text"
      theme={THEME.BRAND}
      icon={ICON_TYPE.SEARCH}
      iconPosition={INPUT_ICON_POSITION.RIGHT}
      placeholder="Right"
    />
  </Story>
  <Story name="Text Input Loading Icon Dark" decorators={decorators}>
    <Input
      type="text"
      theme={THEME.BRAND}
      icon={ICON_TYPE.SPINNER}
      iconPosition={INPUT_ICON_POSITION.RIGHT}
      iconProps={{
        spin: true,
      }}
      placeholder="Loading…"
    />
  </Story>
</Canvas>

#### Variants

<Canvas isColumn>
  <Story name="Text Input Success Dark" decorators={decorators}>
    <Input type="text" theme={THEME.BRAND} variant={STATUS_VARIANT.SUCCESS} />
  </Story>
  <Story name="Text Input Warning Dark" decorators={decorators}>
    <Input type="text" theme={THEME.BRAND} variant={STATUS_VARIANT.WARNING} />
  </Story>
  <Story name="Text Input Danger Dark" decorators={decorators}>
    <Input type="text" theme={THEME.BRAND} variant={STATUS_VARIANT.DANGER} />
  </Story>
</Canvas>

#### Monospace

<Canvas withSource={SourceState.OPEN}>
  <Story name="Text Input Monospace Dark" decorators={decorators}>
    <Input
      type="text"
      theme={THEME.BRAND}
      placeholder="Monospace font"
      className="font-mono"
    />
  </Story>
</Canvas>

#### With a tooltip

<Canvas withSource={SourceState.OPEN}>
  <Story name="Text Input Tooltip Dark" decorators={decorators}>
    <Tooltip
      placement="top"
      referenceElement={
        <Input
          type="text"
          theme={THEME.BRAND}
          onFocus={() => console.log("onFocus from input")}
          onBlur={() => console.log("onBlur from input")}
        />
      }
    >
      Please don’t leave me blank
    </Tooltip>
  </Story>
</Canvas>
