import { Meta, ArgTypes, Story } from "@storybook/addon-docs/blocks";
import { Grid } from ".";
import { Box } from "../Box";
import { Flex } from "../Flex";
import * as GridStories from "./Grid.stories";

<Meta of={GridStories} />

# Grid

Grid helps create layouts based on a vertical grid of columns. It uses Flexbox to position the elements in the grid.

- A grid is made of a container and several items
- The space between the items is fixed and can be configured with the `gap`, `columnGap` or `rowGap` props
- The width of each item is determined by the number of columns it spans across, which can be configured with the `span` prop

## Install

```bash
yarn add @simplybusiness/mobius
```

## Usage

```js
import { Grid } from "@simplybusiness/mobius";
```

## Playground

export const Card = ({ children, ...props }) => (
  <Box
    style={{
      borderRadius: "4px",
      padding: "8px",
      backgroundColor: "#dddddd",
      width: "80%",
    }}
    {...props}
  >
    {children}
  </Box>
);

Different items can have different widths. This is especially useful when creating layouts with sidebars.

<Grid gap="size-xs">
  <Grid.Item span={12}>
    <Card>span=12</Card>
  </Grid.Item>
  <Grid.Item span={11}>
    <Card>span=11</Card>
  </Grid.Item>
  <Grid.Item span={1}>
    <Card>span=1</Card>
  </Grid.Item>
  <Grid.Item span={10}>
    <Card>span=10</Card>
  </Grid.Item>
  <Grid.Item span={2}>
    <Card>span=2</Card>
  </Grid.Item>
  <Grid.Item span={9}>
    <Card>span=9</Card>
  </Grid.Item>
  <Grid.Item span={3}>
    <Card>span=3</Card>
  </Grid.Item>
  <Grid.Item span={8}>
    <Card>span=8</Card>
  </Grid.Item>
  <Grid.Item span={4}>
    <Card>span=4</Card>
  </Grid.Item>
  <Grid.Item span={7}>
    <Card>span=7</Card>
  </Grid.Item>
  <Grid.Item span={5}>
    <Card>span=5</Card>
  </Grid.Item>
  <Grid.Item span={6}>
    <Card>span=6</Card>
  </Grid.Item>
  <Grid.Item span={6}>
    <Card>span=6</Card>
  </Grid.Item>
</Grid>

```jsx
import { Grid } from "@simplybusiness/mobius";

// Card component is here only for demonstration purposes
const Card = ({ children, ...props }) => (
  <Box
    style={{
      borderRadius: "4px",
      padding: "8px",
      backgroundColor: "#dddddd",
      width: "100%",
    }}
    {...props}
  >
    {children}
  </Box>
);

<Grid gap="size-xs">
  <Grid.Item span={12}>
    <Card>span=12</Card>
  </Grid.Item>
  <Grid.Item span={11}>
    <Card>span=11</Card>
  </Grid.Item>
  <Grid.Item span={1}>
    <Card>span=1</Card>
  </Grid.Item>
  <Grid.Item span={10}>
    <Card>span=10</Card>
  </Grid.Item>
  <Grid.Item span={2}>
    <Card>span=2</Card>
  </Grid.Item>
  <Grid.Item span={9}>
    <Card>span=9</Card>
  </Grid.Item>
  <Grid.Item span={3}>
    <Card>span=3</Card>
  </Grid.Item>
  <Grid.Item span={8}>
    <Card>span=8</Card>
  </Grid.Item>
  <Grid.Item span={4}>
    <Card>span=4</Card>
  </Grid.Item>
  <Grid.Item span={7}>
    <Card>span=7</Card>
  </Grid.Item>
  <Grid.Item span={5}>
    <Card>span=5</Card>
  </Grid.Item>
  <Grid.Item span={6}>
    <Card>span=6</Card>
  </Grid.Item>
  <Grid.Item span={6}>
    <Card>span=6</Card>
  </Grid.Item>
</Grid>;
```

### Alignment

Grid items can be aligned using the standard grid alignment properties:

- `align-content`
- `justify-content`
- `align-items`
- `justify-items`

export const Square = ({ children, ...props }) => (
  <Flex
    alignItems="center"
    justifyContent="center"
    style={{ height: "100%" }}
    {...props}
  >
    {children}
  </Flex>
);

<Story of={GridStories.AlignmentProperties} />

```jsx
import { Grid } from "@simplybusiness/mobius";

<Grid gap="size-xs">
  <Grid.Item span={4}>
    <Square>1</Square>
  </Grid.Item>
  <Grid.Item span={4}>
    <Square>2</Square>
  </Grid.Item>
  <Grid.Item span={4}>
    <Square>3</Square>
  </Grid.Item>
  <Grid.Item span={4}>
    <Square>4</Square>
  </Grid.Item>
  <Grid.Item span={4}>
    <Square>5</Square>
  </Grid.Item>
  <Grid.Item span={4}>
    <Square>6</Square>
  </Grid.Item>
  <Grid.Item span={4}>
    <Square>7</Square>
  </Grid.Item>
  <Grid.Item span={4}>
    <Square>8</Square>
  </Grid.Item>
  <Grid.Item span={4}>
    <Square>9</Square>
  </Grid.Item>
</Grid>;
```

## Examples

### Default

<Story of={GridStories.Default} />

```jsx
import { Grid } from "@simplybusiness/mobius";

// Card component is here only for demonstration purposes
const Card = ({ children, ...props }) => (
  <Box
    style={{
      borderRadius: "4px",
      padding: "8px",
      backgroundColor: "#dddddd",
      width: "100%",
    }}
    {...props}
  >
    {children}
  </Box>
);

<Grid gap="size-xs">
  <Grid.Item span={12}>
    <Card>span=12</Card>
  </Grid.Item>
  <Grid.Item span={11}>
    <Card>span=11</Card>
  </Grid.Item>
  <Grid.Item span={1}>
    <Card>span=1</Card>
  </Grid.Item>
  <Grid.Item span={10}>
    <Card>span=10</Card>
  </Grid.Item>
  <Grid.Item span={2}>
    <Card>span=2</Card>
  </Grid.Item>
  <Grid.Item span={9}>
    <Card>span=9</Card>
  </Grid.Item>
  <Grid.Item span={3}>
    <Card>span=3</Card>
  </Grid.Item>
  <Grid.Item span={8}>
    <Card>span=8</Card>
  </Grid.Item>
  <Grid.Item span={4}>
    <Card>span=4</Card>
  </Grid.Item>
  <Grid.Item span={7}>
    <Card>span=7</Card>
  </Grid.Item>
  <Grid.Item span={5}>
    <Card>span=5</Card>
  </Grid.Item>
  <Grid.Item span={6}>
    <Card>span=6</Card>
  </Grid.Item>
  <Grid.Item span={6}>
    <Card>span=6</Card>
  </Grid.Item>
</Grid>;
```

### Eight Columns

<Story of={GridStories.EightColumns} />

```jsx
import { Grid } from "@simplybusiness/mobius";

// Card component is here only for demonstration purposes
const Card = ({ children, ...props }) => (
  <Box
    style={{
      borderRadius: "4px",
      padding: "8px",
      backgroundColor: "#dddddd",
      width: "100%",
    }}
    {...props}
  >
    {children}
  </Box>
);

<Grid columns={8} gap="size-xs">
  <Card columns={8}>span=1</Card>
  <Card columns={8}>span=1</Card>
  <Card columns={8}>span=1</Card>
  <Card columns={8}>span=1</Card>
  <Card columns={8}>span=1</Card>
  <Card columns={8}>span=1</Card>
  <Card columns={8}>span=1</Card>
  <Card columns={8}>span=1</Card>
</Grid>;
```

### Responsive

<Story of={GridStories.Responsive} />

{/* prettier-ignore */}
```jsx
import { Grid } from "@simplybusiness/mobius";

// Card component is here only for demonstration purposes
const Card = ({ children, ...props }) => (
  <Box
    style={{
      borderRadius: "4px",
      padding: "8px",
      backgroundColor: "#dddddd",
      width: "100%",
    }}
    {...props}
  >
    {children}
  </Box>
);

<Grid gap="size-xs">
  <Grid.Item xs={12} sm={6} md={2} lg={8} xl={12} xxl={4}>
    <Card>xs=12 sm=6 md=2 lg=8 xl=12 xxl=4</Card>
  </Grid.Item>
  <Grid.Item lg={4}>
    <Card>lg=4</Card>
  </Grid.Item>
  <Grid.Item xs={5}>
    <Card>xs=5</Card>
  </Grid.Item>
  <Grid.Item span={5}>
    <Card>span=5</Card>
  </Grid.Item>
</Grid>
```

## Item positioning

Individual grid items may be positioned separately to the rest of the grid items using the following properties:

- `alignSelf` - aligns the grid item along the block (column) axis
- `justifySelf` - aligns the grid item along the inline (row) axis

The example demonstrates the positioning of the first block. Using `alignSelf="center"` and `justifySelf="end"` places the item in vertical centre (1) and horizontal end (2)

export const AlignSquare = ({ children, ...props }) => (
  <Box style={{}} {...props}>
    {children}
  </Box>
);

<Story of={GridStories.ItemPositioning} />

{/* prettier-ignore */}
```jsx
import { Grid } from "@simplybusiness/mobius";

// AlignSquareItem component is here only for demonstration purposes
const AlignSquareItem = styled(Grid.Item)`
  background-color: #dddddd;
`;

// AlignSquare component is here only for demonstration purposes
const AlignSquare = ({ children, ...props }) => (
  <Box {...props}>
    {children}
  </Box>
);
<Grid gap="size-xs">
  <AlignSquareItem span={4} alignSelf="center" justifySelf="end">
    <AlignSquare>1</AlignSquare>
  </AlignSquareItem>
  <AlignSquareItem span={4}>
    <AlignSquare>2</AlignSquare>
  </AlignSquareItem>
  <AlignSquareItem span={4}>
    <AlignSquare>3</AlignSquare>
  </AlignSquareItem>
  <AlignSquareItem span={4}>
    <AlignSquare>4</AlignSquare>
  </AlignSquareItem>
</Grid>
```

## Props

<ArgTypes of={Grid} />
