# System props

All of the components in Blockstack UI are built with `styled-components` and implement `styled-system`. With this, you can pass css attributes to any component as props. Check out the page [further reading](/further-reading) to dig deeper.

## System props reference

See below for the various props and aliases you can pass for styling components. You can see the full spec on the [Styled System docs](https://styled-system.com/api).

### Margin & padding

```jsx live=false
import { Box } from "@blockstack/ui";

// m={2} refers to the value of `theme.space[2]`
<Box m={2}>Tomato</Box>;

// You can also use custom values
<Box maxW="960px" mx="auto" />;

// sets margin `8px` on all viewports and `16px` from the first breakpoint and up
<Box m={[2, 3]} />;
```

| Prop                  | CSS Property                       | Theme Key |
| --------------------- | ---------------------------------- | --------- |
| `m`, `margin`         | `margin`                           | `space`   |
| `mt`, `marginTop`     | `margin-top`                       | `space`   |
| `mr`, `marginRight`   | `margin-right`                     | `space`   |
| `mb`, `marginBottom`  | `margin-bottom`                    | `space`   |
| `ml`, `marginLeft`    | `margin-left`                      | `space`   |
| `mx`                  | `margin-left` and `margin-right`   | `space`   |
| `my`                  | `margin-top` and `margin-bottom`   | `space`   |
| `p`, `padding`        | `padding`                          | `space`   |
| `pt`, `paddingTop`    | `padding-top`                      | `space`   |
| `pr`, `paddingRight`  | `padding-right`                    | `space`   |
| `pb`, `paddingBottom` | `padding-bottom`                   | `space`   |
| `pl`, `paddingLeft`   | `padding-left`                     | `space`   |
| `px`                  | `padding-left` and `padding-right` | `space`   |
| `py`                  | `padding-top` and `padding-bottom` | `space`   |

### Color & background color

```jsx live=false
import { Box } from "@blockstack/ui";

// picks up a nested color value using dot notation
// => `theme.colors.ink[50]`
<Box color='ink.50' />

// raw CSS color value
<Box color='#f00' />

// background colors
<Box bg='tomato' />

// verbose prop
<Box backgroundColor='tomato' />
```

| Prop                    | CSS Property       | Theme Key |
| ----------------------- | ------------------ | --------- |
| `color`                 | `color`            | `colors`  |
| `bg`, `backgroundColor` | `background-color` | `colors`  |
| `opacity`               | `opacity`          | none      |

### Typography

```jsx live=false
import { Text } from "@blockstack/ui";

// font-size of `theme.textStyle.display.large
<Text textStyle="display.large" />

// font-size `32px`
<Text fontSize={32} />

// font-size `'2em'`
<Text fontSize='2em' />

// text-align `left` on all viewports and `center` from the first breakpoint and up
<Text textAlign={[ 'left', 'center' ]} />
```

| Prop             | CSS Property      | Theme Key        |
| ---------------- | ----------------- | ---------------- |
| `fontFamily`     | `font-family`     | `fonts`          |
| `fontSize`       | `font-size`       | `fontSizes`      |
| `fontWeight`     | `font-weight`     | `fontWeights`    |
| `lineHeight`     | `line-height`     | `lineHeights`    |
| `letterSpacing`  | `letter-spacing`  | `letterSpacings` |
| `textAlign`      | `text-align`      | none             |
| `fontStyle`      | `font-style`      | none             |
| `textTransform`  | `text-transform`  | none             |
| `textDecoration` | `text-decoration` | none             |

### Layout, width and height

```jsx live=false
import { Box } from "@blockstack/ui";

// verbose
<Box width="100%" height={32} />;

// shorthand
<Box w="100%" h="32px" />;

// width `50%`
<Box w={1/2} />

// width `256px`
<Box w={256} />

// width `'40px'`
<Box w='40px' />

```

| Prop                | CSS Property     | Theme Key |
| ------------------- | ---------------- | --------- |
| `w`, `width`        | `width`          | `sizes`   |
| `h`, `height`       | `height`         | `sizes`   |
| `minW`, `minWidth`  | `min-width`      | `sizes`   |
| `maxW`, `maxWidth`  | `max-width`      | `sizes`   |
| `minH`, `minHeight` | `min-height`     | `sizes`   |
| `maxH`, `maxHeight` | `max-height`     | `sizes`   |
| `d`, `display`      | `display`        | none      |
| `size`              | `width` `height` | `sizes`   |
| `verticalAlign`     | `vertical-align` | none      |
| `overflow`          | `overflow`       | none      |
| `overflowX`         | `overflowX`      | none      |
| `overflowY`         | `overflowY`      | none      |

### Flexbox

```jsx live=false
import { Box, Flex } from "@blockstack/ui";

// verbose
<Box display="flex" alignItems="center" justifyContent="space-between">
  Box with Flex props
</Box>;

// shorthand using the `Flex` component
<Flex align="center" justify="center">
  Flex Container
</Flex>;
```

> Note: Props in `*` will only work if you use the `Flex` component.

| Prop                                      | CSS Property       | Theme Key |
| ----------------------------------------- | ------------------ | --------- |
| `alignItems`, \*`align`                   | `align-items`      | none      |
| `alignContent`                            | `align-content`    | none      |
| `justifyItems`                            | `justify-items`    | none      |
| `justifyContent`, \*`justify`             | `justify-content`  | none      |
| `flexWrap`, \*`wrap`                      | `flex-wrap`        | none      |
| `flexDirection`, `flexDir`, \*`direction` | `flex-direction`   | none      |
| `flex`                                    | `flex` (shorthand) | none      |
| `flexGrow`                                | `flex-grow`        | none      |
| `flexShrink`                              | `flex-shrink`      | none      |
| `flexBasis`                               | `flex-basis`       | none      |
| `justifySelf`                             | `justify-self`     | none      |
| `alignSelf`                               | `align-self`       | none      |
| `order`                                   | `order`            | none      |

### Grid Layout

```jsx live=false
import { Box, Grid } from "@blockstack/ui";

// verbose
<Box display="grid" gridGap={2} gridAutoFlow="row dense">
  Grid
</Box>;

// shorthand using the `Grid` component
<Grid gap={2} autoFlow="row dense">
  Grid
</Grid>;
```

> Note: Props in `*` will only work if you use the `Grid` component.

| Prop                                       | CSS Property            | Theme Key |
| ------------------------------------------ | ----------------------- | --------- |
| `gridGap`, \*`gap`                         | `grid-gap`              | `space`   |
| `gridRowGap`, \*`rowGap`                   | `grid-row-gap`          | `space`   |
| `gridColumnGap`, \*`columnGap`             | `grid-column-gap`       | `space`   |
| `gridColumn`, \*`column`                   | `grid-column`           | none      |
| `gridRow`, \*`row`                         | `grid-row`              | none      |
| `gridArea`, \*`area`                       | `grid-area`             | none      |
| `gridAutoFlow`, \*`autoFlow`               | `grid-auto-flow`        | none      |
| `gridAutoRows`, \*`autoRows`               | `grid-auto-rows`        | none      |
| `gridAutoColumns`, \*`autoColumns`         | `grid-auto-columns`     | none      |
| `gridTemplateRows`, \*`templateRows`       | `grid-template-rows`    | none      |
| `gridTemplateColumns`, \*`templateColumns` | `grid-template-columns` | none      |
| `gridTemplateAreas`, \*`templateAreas`     | `grid-template-areas`   | none      |

### Background

```jsx live=false
import { Box } from "@blockstack/ui";

// verbose
<Box
  backgroundImage="url('/images/kitten.png')"
  backgroundPosition="center"
  backgroundRepeat="no-repeat"
/>;

// shorthand
<Box bgImage="url('/images/puppy.png')" bgPos="center" bgRepeat="no-repeat" />;
```

| Prop                                  | CSS Property            | Theme Key |
| ------------------------------------- | ----------------------- | --------- |
| `background`                          | `background`            | none      |
| `bgImg`, `backgroundImage`            | `background-image`      | none      |
| `bgSize`, `backgroundSize`            | `background-size`       | none      |
| `bgPos`,`backgroundPosition`          | `background-position`   | none      |
| `bgRepeat`,`backgroundRepeat`         | `background-repeat`     | none      |
| `bgAttachment`,`backgroundAttachment` | `background-attachment` | none      |

### Borders

```jsx live=false
import { Box } from "@blockstack/ui";

<Box border="1px" borderRadius="6px" borderColor="ink.i00">
  Card
</Box>;
```

| Prop                | CSS Property                   | Theme Field    |
| ------------------- | ------------------------------ | -------------- |
| `border`            | `border`                       | `borders`      |
| `borderWidth`       | `border-width`                 | `borderWidths` |
| `borderStyle`       | `border-style`                 | `borderStyles` |
| `borderColor`       | `border-color`                 | `colors`       |
| `borderTop`         | `border-top`                   | `borders`      |
| `borderTopWidth`    | `border-top-width`             | `borderWidths` |
| `borderTopStyle`    | `border-top-style`             | `borderStyles` |
| `borderTopColor`    | `border-top-color`             | `colors`       |
| `borderRight`       | `border-right`                 | `borders`      |
| `borderRightWidth`  | `border-right-width`           | `borderWidths` |
| `borderRightStyle`  | `border-right-style`           | `borderStyles` |
| `borderRightColor`  | `border-right-color`           | `colors`       |
| `borderBottom`      | `border-bottom`                | `borders`      |
| `borderBottomWidth` | `border-bottom-width`          | `borderWidths` |
| `borderBottomStyle` | `border-bottom-style`          | `borderStyles` |
| `borderBottomColor` | `border-bottom-color`          | `colors`       |
| `borderLeft`        | `border-left`                  | `borders`      |
| `borderLeftWidth`   | `border-left-width`            | `borderWidths` |
| `borderLeftStyle`   | `border-left-style`            | `borderStyles` |
| `borderLeftColor`   | `border-left-color`            | `colors`       |
| `borderX`           | `border-left` & `border-right` | `borders`      |
| `borderY`           | `border-top` & `border-bottom` | `borders`      |

### Border Radius

```jsx live=false
import { Button } from "@blockstack/ui";

// This button will have no right borderRadius
<Button roundedRight="0">Button 1</Button>;

// This button will have no left borderRadius*/
<Button roundedLeft="0">Button 2</Button>;

// top left and top right radius will be `theme.radii.md` => 4px
<Button roundedTop="md">Button 2</Button>;
```

| Prop                                            | CSS Property                                               | Theme Field |
| ----------------------------------------------- | ---------------------------------------------------------- | ----------- |
| `rounded`, `borderRadius`                       | `border-radius`                                            | `radii`     |
| `roundedTopLeft`, `borderTopLeftRadius`         | `border-top-left-radius`                                   | `radii`     |
| `roundedTopRight`, `borderTopRightRadius`       | `border-top-right-radius`                                  | `radii`     |
| `roundedBottomRight`, `borderBottomRightRadius` | `border-bottom-right-radius`                               | `radii`     |
| `roundedBottomLeft`, `borderBottomLeftRadius`   | `border-bottom-left-radius`                                | `radii`     |
| `roundedTop`                                    | `border-top-left-radius` & `border-top-right-radius`       | `radii`     |
| `roundedRight`                                  | `border-top-right-radius` & `border-bottom-right-radius`   | `radii`     |
| `roundedBottom`                                 | `border-bottom-left-radius` & `border-bottom-right-radius` | `radii`     |
| `roundedLeft`                                   | `border-top-left-radius` & `border-bottom-left-radius`     | `radii`     |

### Position

```jsx live=false
import { Box } from "@blockstack/ui";

// verbose
<Box position="absolute">Cover</Box>;

// shorthand
<Box pos="absolute">Cover</Box>;

<Box pos="absolute" top="0" left="0">
  Absolute with top and left
</Box>;

<Box pos="fixed" w="100%" zIndex={2}>
  Fixed with zIndex
</Box>;
```

| Prop             | CSS Property | Theme Field |
| ---------------- | ------------ | ----------- |
| `pos`,`position` | `position`   | none        |
| `zIndex`         | `z-index`    | `zIndices`  |
| `top`            | `top`        | `space`     |
| `right`          | `right`      | `space`     |
| `bottom`         | `bottom`     | `space`     |
| `left`           | `left`       | `space`     |

### Shadow

```jsx live=false
import { Box, Text } from "@blockstack/ui";

// text-shadow will be `theme.shadows.low`
// box-shadow will be `theme.shadows.high`
<Box textShadow="low" boxShadow="high" />;

// raw CSS values
<Text
  textShadow="0px 1px 2px rgba(0, 0, 0, 0.04)"
  boxShadow="0px 8px 16px rgba(27, 39, 51, 0.08)"
>
  Text with shadows
</Text>;
```

| Prop                 | CSS Property  | Theme Field |
| -------------------- | ------------- | ----------- |
| `textShadow`         | `text-shadow` | `shadows`   |
| `shadow`,`boxShadow` | `box-shadow`  | `shadows`   |

### Other Props

Asides all the common system props listed above, all component will accept the
following props:

| Prop              | CSS Property       | Theme Field |
| ----------------- | ------------------ | ----------- |
| `animation`       | `animation`        | none        |
| `appearance`      | `appearance`       | none        |
| `transform`       | `transform`        | none        |
| `transformOrigin` | `transform-origin` | none        |
| `visibility`      | `visibility`       | none        |
| `whiteSpace`      | `white-space`      | none        |
| `userSelect`      | `user-select`      | none        |
| `pointerEvents`   | `pointer-events`   | none        |
| `wordBreak`       | `word-break`       | none        |
| `overflowWrap`    | `overflow-wrap`    | none        |
| `textOverflow`    | `text-overflow`    | none        |
| `boxSizing`       | `box-sizing`       | none        |
| `cursor`          | `cursor`           | none        |
| `resize`          | `resize`           | none        |
| `transition`      | `transition`       | none        |
| `objectFit`       | `object-fit`       | none        |
| `objectPosition`  | `object-position`  | none        |
| `objectPosition`  | `object-position`  | none        |
| `fill`            | `fill`             | `colors`    |
| `stroke`          | `stroke`           | `colors`    |
| `outline`         | `outline`          | none        |

## The as prop

The `as` prop is a feature that all of our components get from
[`styled-components`](https://www.styled-components.com/docs/api#as-polymorphic-prop). It allows you to pass a HTML tag or another component to a
Blockstack UI component to be rendered as the base tag of that component along with all
it's styles and props.

For example, say you are using a Button component, and you need to make it a
link instead. You can compose `a` and Button like this:

```jsx
<Button as="a" target="_blank" variant="link" href="https://blockstack.org">
  This is now a link
</Button>
```

This allows you to use all of the `Button` props and all of the `<a>` props
without having to wrap the Button in an `a` component.

> Note: this does have some limitations.

Let's say you wanted the button to take styles from a `Flex` primitive. You'd do the following:

```jsx
<Button as={Flex} onClick={() => console.log("button")}>
  This is now using a Flex as the primary wrapper component.
</Button>
```

The issue with this, though, is the Button no long renders as a `button` DOM element. It will be rendered as a `div` because `Flex` by default renders as a `div`.

For these reasons, it's recommended only to use the as prop when you cannot achieve the same result by nesting components. The Flex / Button example could be done like so:

```jsx
<Flex>
  <Button onClick={() => console.log("button")}>Some Button</Button>
</Flex>
```

or

```jsx
<Button
  as={p => <Flex as="button" {...p} />}
  onClick={() => console.log("button")}
>
  Button with flex, but as a button html element.
</Button>
```
