import { Meta, Story, ArgsTable, Canvas } from '@storybook/addon-docs/blocks';
import { Box } from '../..';

<Meta title="2 - System/Layout/Spacing" />

# Spacing

Patchwork exposes spacing in a way that is intended to strike a balance between consistency and themeability.

The approach is based around the concept of a space scale, as used in popular CSS frameworks like BassCSS or Tachyons. The specific values for the space scale are a property of the currently active `theme`.

Our space scale defines 7 levels that increase according to a set of ratios defined by the design team. By limiting all margin and padding measures to these 7 discrete amounts, we can achieve a level of consistency in the application design that looks clean and professional while allowing for a variety of UI component compositions.

The actual pixel size of each level varies by theme, since different consumers of patchwork have different needs around information density, etc. in their layouts.

The value for the currently-selected theme are as follows; select a different theme in the storybook theme selector (`Canvas` -> `Patchwork Theme`) to see these values in a different theme.

| Spacing Level | Pixel Amount |
| ------------- | ------------ |
| s1            | 10px         |
| s2            | 20px         |
| s3            | 30px         |
| s4            | 40px         |
| s5            | 50px         |
| s6            | 60px         |
| s7            | 70px         |

## Controlling Spacing in Patchwork Layouts

Most Patchwork container elements such as `<Box>` and `<Text>` expose a `spacing` attribute. This attribute can be a string, or a list of strings, consisting of one of the following values:

### Margin Selectors

- `m0`: no margin in all four dimensions.
- `m1` .. `m7`: level 1 to 7 margin in all four dimensions.
- `ml0` .. `ml7`: level 0 (none) to 7 left margin
- `mr0` .. `mr7`: level 0 (none) to 7 right margin
- `mt0` .. `mt7`: level 0 (none) to 7 top margin
- `mb0` .. `mb7`: level 0 (none) to 7 bottom margin
- `mh0` .. `mh7`: level 0 (none) to 7 horizontal (left and right) margins
- `mv0` .. `mv7`: level 0 (none) to 7 vertical (top and bottom) margins.
- `mhauto`: left and right 'auto' margins: useful for horizontally centering a fixed-width block inside its parent.

### Padding Selectors

- `p0`: no padding in all four dimensions.
- `p1` .. `p7`: level 1 to 7 padding in all four dimensions.
- `pl0` .. `pl7`: level 0 (none) to 7 left padding
- `pr0` .. `pr7`: level 0 (none) to 7 right padding
- `pt0` .. `pt7`: level 0 (none) to 7 top padding
- `pb0` .. `pb7`: level 0 (none) to 7 bottom padding
- `ph0` .. `ph7`: level 0 (none) to 7 horizontal (left and right) padding
- `pv0` .. `pv7`: level 0 (none) to 7 vertical (top and bottom) padding.

## Examples

### Margin

<Canvas>
  <Story id="2-system-layout-spacing--margin-left" />
  <Story id="2-system-layout-spacing--margin-right" />
  <Story id="2-system-layout-spacing--margin-horizontal" />
  <Story id="2-system-layout-spacing--margin-top" />
  <Story id="2-system-layout-spacing--margin-bottom" />
  <Story id="2-system-layout-spacing--margin-vertical" />
</Canvas>

### Padding

<Canvas>
  <Story id="2-system-layout-spacing--padding-left" />
  <Story id="2-system-layout-spacing--padding-right" />
  <Story id="2-system-layout-spacing--padding-horizontal" />
  <Story id="2-system-layout-spacing--padding-top" />
  <Story id="2-system-layout-spacing--padding-bottom" />
  <Story id="2-system-layout-spacing--padding-vertical" />
</Canvas>

### Different Values for Different Sides

You can also control one or more side's padding and margin independently, using the array version of the prop:

```jsx
<Box spacing={[
  'mt1', 'mr2', 'mb3', 'ml4',
  'st4', 'sr3', 'sb3', 'sl1',
]}
```

### Different Values for Different Breakpoints

Finally, this mixin is able to support different values for different breakpoints:

```jsx
<Box
  spacing={{
    sm: ['m1', 'p1'],
    md: ['m2', 'p2'],
    lg: ['m4', 'p4'],
    xl: ['m7', 'p7'],
  }}
/>
```

<Canvas>
  <Story id="2-system-spacing--responsive" />
</Canvas>
