# 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.

## Controlling Spacing in Patchwork Layouts

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

Run storybook and look at the 'Box' story for examples of these spacing levels in action.

## Notes for Patchwork Implementors

To make your component respond to the spacing properties, you need to do two things:

1. Mix the `SpacingProps` type into your components property typedef:

```js
import type { SpacingProps } from '../../theme';

type MyComponentProps = SpacingProps & {
  //... component-specific property types.
};
```

This enables type checking when people use the `spacing` property with your component.

2. Pull in the code that maps between spacing values and low level CSS:

```js
import type { ComponentType } from 'react';
import { getSpacingRules } from '../../theme/theme-utils';

// ...

export const MyComponent: Component<MyComponentProps> = styled.div.attrs(
  props => ({
    style: getSpacingRules(props),
  }),
)`
  // ...
`;
```
