import { Story, Preview, Props, Meta } from "@storybook/addon-docs/blocks";
import { EnumTable } from "../../storybook-components/EnumTable";
import { Button } from "../Button";
import { Link } from "../Link";
import { Heading } from "../Heading";
import { Description } from "../Description";
import { ORIENTATION, JUSTIFY } from "../../types";
import { Stack } from "./Stack";

<Meta title="Components/Layout/Stack" component={Stack} />

# Stack

Use `Stack` to space a group of elements of different types (e.g., text, links,
buttons, inputs, etc). The `Stack` will apply equal margin between each item.

Components that often appear in groups may have a `.Group` sub-component. If such
a component is available and all your items are of the same type, use that
sub-component. For example, use `Button.Group` instead of `Stack` to group
`Button`s.

### Tips for ordering items with `Stack`

If dealing with interactive items, the primary action should always be first in
the code (aka source order). This is important for accessbility.

There are times where visually, the primary action appears to come _after_ the
secondary action. In these cases, the primary action should still come first in
the source order and the visual order of the items can be reversed by using
the `reverse` prop. There is an example of this below.

## Do’s and don’ts

- **Do** use any type of component in a `Stack`.
- **Don’t** use the justify prop with a vertically oriented `Stack`, it
  won’t have any effect.

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

export const Item = ({ children }) => (
  <div className="flex items-center justify-center w-10 h-10 rounded-full bg-gray-400">
    {children}
  </div>
);

<Preview>
  <Story name="Stack">
    <Stack>
      <Button>Save</Button>
      <Link as="button">Cancel</Link>
    </Stack>
  </Story>
</Preview>

## Props

These are the custom props that extend `BoxProps`.

<Props of={Stack} />
<EnumTable enums={{ ORIENTATION, JUSTIFY }} />

## Demos

### Orientation

Set the orientation of the child items to horizontal or vertical.

#### Horizontal orientation (default)

<Preview>
  <Story name="Horizontal orientation (default)">
    <Stack>
      <Button>Save</Button>
      <Link as="button">Cancel</Link>
    </Stack>
  </Story>
</Preview>

#### Vertical orientation

<Preview>
  <Story name="Vertical orientation">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Heading.H1>Page title</Heading.H1>
      <Description className="max-w-sm">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer ac
        neque libero. Aliquam diam justo, accumsan eget fermentum vel, molestie
        vel lorem. Aliquam in consequat mi.
      </Description>
      <Link as="button">Read more</Link>
    </Stack>
  </Story>
</Preview>

### Reverse layout

Use the `reverse` prop to flip the layout of the items within `Stack`. This is
useful when you need the items to

There are times where visually, the primary action appears to come _after_ the
secondary action. In these cases, the primary action should still come first in
the source order and the visual order of the items can be reversed by using
the `reverse` prop. There is an example of this below.

#### Horizontal orientation with reverse

<Preview>
  <Story name="Horizontal orientation with reverse">
    <Stack reverse>
      <Button>Save</Button>
      <Link as="button">Cancel</Link>
    </Stack>
  </Story>
</Preview>

#### Vertical orientation with reverse

<Preview>
  <Story name="Vertical orientation with reverse">
    <Stack orientation={ORIENTATION.VERTICAL} reverse>
      <Heading.H1>Page title</Heading.H1>
      <Heading.H4 className="text-gray-600">Subtitle</Heading.H4>
    </Stack>
  </Story>
</Preview>

### Justification

The justification of the child items can be changed.

#### Horizontal orientation, justify start (default)

<Preview>
  <Story name="Horizontal orientation, justify start">
    <Stack justify={JUSTIFY.START}>
      <Button>Save</Button>
      <Link as="button">Cancel</Link>
    </Stack>
  </Story>
</Preview>

#### Horizontal orientation, justify center

<Preview>
  <Story name="Horizontal orientation, justify center">
    <Stack justify={JUSTIFY.CENTER}>
      <Button>Save</Button>
      <Link as="button">Cancel</Link>
    </Stack>
  </Story>
</Preview>

#### Horizontal orientation, justify end

<Preview>
  <Story name="Horizontal orientation, justify end">
    <Stack justify={JUSTIFY.END}>
      <Button>Save</Button>
      <Link as="button">Cancel</Link>
    </Stack>
  </Story>
</Preview>

#### Horizontal orientation, justify around

<Preview>
  <Story name="Horizontal orientation, justify around">
    <Stack justify={JUSTIFY.AROUND}>
      <Button>Save</Button>
      <Link as="button">Cancel</Link>
    </Stack>
  </Story>
</Preview>

#### Horizontal orientation, justify between

<Preview>
  <Story name="Horizontal orientation, justify between">
    <Stack justify={JUSTIFY.BETWEEN}>
      <Button>Save</Button>
      <Link as="button">Cancel</Link>
    </Stack>
  </Story>
</Preview>

### Spacing

Determines how much spacing is placed between the items; the values map to the
padding values in the tailwind.config file, which are a multiple of 4. 2 is the
default value, i.e., 8px of spacing.

See [spacing tokens](/?path=/docs/tokens-spacing--page).

#### Horizontal, justify start

<Preview>
  <Story name="Spacing horizontal justify start">
    <div>
      {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((spacing) => (
        <Stack
          key={spacing}
          className="my-4"
          spacing={spacing}
          justify={JUSTIFY.START}
        >
          <Item>1</Item>
          <Item>2</Item>
          <Item>3</Item>
          <Item>4</Item>
          <Item>5</Item>
        </Stack>
      ))}
    </div>
    <div>
      {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((spacing) => (
        <Stack
          key={spacing}
          className="my-4"
          spacing={spacing}
          justify={JUSTIFY.START}
          reverse
        >
          <Item>1</Item>
          <Item>2</Item>
          <Item>3</Item>
          <Item>4</Item>
          <Item>5</Item>
        </Stack>
      ))}
    </div>
  </Story>
</Preview>

#### Horizontal, justify center

<Preview>
  <Story name="Spacing horizontal justify center">
    <div>
      {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((spacing) => (
        <Stack
          key={spacing}
          className="my-4"
          spacing={spacing}
          justify={JUSTIFY.CENTER}
        >
          <Item>1</Item>
          <Item>2</Item>
          <Item>3</Item>
          <Item>4</Item>
          <Item>5</Item>
        </Stack>
      ))}
    </div>
    <div>
      {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((spacing) => (
        <Stack
          key={spacing}
          className="my-4"
          spacing={spacing}
          justify={JUSTIFY.CENTER}
          reverse
        >
          <Item>1</Item>
          <Item>2</Item>
          <Item>3</Item>
          <Item>4</Item>
          <Item>5</Item>
        </Stack>
      ))}
    </div>
  </Story>
</Preview>

#### Spacing, horizontal, justify end

<Preview>
  <Story name="Spacing horizontal justify end">
    <div>
      {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((spacing) => (
        <Stack
          key={spacing}
          className="my-4"
          spacing={spacing}
          justify={JUSTIFY.END}
        >
          <Item>1</Item>
          <Item>2</Item>
          <Item>3</Item>
          <Item>4</Item>
          <Item>5</Item>
        </Stack>
      ))}
    </div>
    <div>
      {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((spacing) => (
        <Stack
          key={spacing}
          className="my-4"
          spacing={spacing}
          justify={JUSTIFY.END}
          reverse
        >
          <Item>1</Item>
          <Item>2</Item>
          <Item>3</Item>
          <Item>4</Item>
          <Item>5</Item>
        </Stack>
      ))}
    </div>
  </Story>
</Preview>

#### Spacing, horizontal, justify around

<Preview>
  <Story name="Spacing horizontal justify around">
    <div>
      {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((spacing) => (
        <Stack
          key={spacing}
          className="my-4"
          spacing={spacing}
          justify={JUSTIFY.AROUND}
        >
          <Item>1</Item>
          <Item>2</Item>
          <Item>3</Item>
          <Item>4</Item>
          <Item>5</Item>
        </Stack>
      ))}
    </div>
    <div>
      {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((spacing) => (
        <Stack
          key={spacing}
          className="my-4"
          spacing={spacing}
          justify={JUSTIFY.AROUND}
          reverse
        >
          <Item>1</Item>
          <Item>2</Item>
          <Item>3</Item>
          <Item>4</Item>
          <Item>5</Item>
        </Stack>
      ))}
    </div>
  </Story>
</Preview>

#### Spacing, horizontal, justify between

<Preview>
  <Story name="Spacing horizontal justify between">
    <div>
      {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((spacing) => (
        <Stack
          key={spacing}
          className="my-4"
          spacing={spacing}
          justify={JUSTIFY.BETWEEN}
        >
          <Item>1</Item>
          <Item>2</Item>
          <Item>3</Item>
          <Item>4</Item>
          <Item>5</Item>
        </Stack>
      ))}
    </div>
    <div>
      {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((spacing) => (
        <Stack
          key={spacing}
          className="my-4"
          spacing={spacing}
          justify={JUSTIFY.BETWEEN}
          reverse
        >
          <Item>1</Item>
          <Item>2</Item>
          <Item>3</Item>
          <Item>4</Item>
          <Item>5</Item>
        </Stack>
      ))}
    </div>
  </Story>
</Preview>

#### Spacing, vertical

<Preview>
  <Story name="Spacing vertical">
    <Stack>
      {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((spacing) => (
        <Stack
          key={spacing}
          className="my-4"
          spacing={spacing}
          orientation={ORIENTATION.VERTICAL}
        >
          <Item>1</Item>
          <Item>2</Item>
          <Item>3</Item>
          <Item>4</Item>
          <Item>5</Item>
        </Stack>
      ))}
    </Stack>
    <Stack>
      {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((spacing) => (
        <Stack
          key={spacing}
          className="my-4"
          spacing={spacing}
          orientation={ORIENTATION.VERTICAL}
          reverse
        >
          <Item>1</Item>
          <Item>2</Item>
          <Item>3</Item>
          <Item>4</Item>
          <Item>5</Item>
        </Stack>
      ))}
    </Stack>
  </Story>
</Preview>
