# Bleed (/components/layout/bleed)

`Bleed` lets content extend beyond the space provided by its parent. Use it when a child should
reach farther on one or more edges without changing the parent's spacing.

apps/docs/src/examples/bleed/basic.tsx

```tsx
import { Bleed } from '@luke-ui/react/bleed';
import { Box } from '@luke-ui/react/box';
import { Stack } from '@luke-ui/react/stack';
import { ExampleItem } from '#docs';

export default () => {
	return (
		<Box
			backgroundColor="surface.subdued"
			borderColor="decorative"
			borderStyle="solid"
			borderWidth="thin"
			padding="space.24"
		>
			<Stack gap="space.16">
				<ExampleItem>Inset within the padding</ExampleItem>
				<Bleed inline="space.24">
					<ExampleItem>Extends to both inline edges</ExampleItem>
				</Bleed>
			</Stack>
		</Box>
	);
};
```

## Choose how far to extend [#choose-how-far-to-extend]

Pass a spacing token for the distance to extend. The value does not need to match the parent's
padding. When it does, the content reaches the parent's edge.

Use `all` to extend both axes by the same amount.

Bleed accepts the same responsive spacing values as other layout props. Read
[Responsive values](/docs/layout#responsive-values) for breakpoint behaviour.

## Choose the edges [#choose-the-edges]

Use `inline` to extend both inline edges and `block` to extend both block edges. Use `inlineStart`,
`inlineEnd`, `blockStart`, or `blockEnd` when only one edge should extend.

At the same breakpoint, an axis prop overrides `all`, and an edge prop overrides its axis prop. A
value continues to larger breakpoints until any of these props has a value at a later breakpoint.
For example, `inline="space.16" inlineStart={{ bp768: 'space.8' }}` extends the inline-start edge by
`space.16` below `bp768` and by `space.8` from `bp768`.

apps/docs/src/examples/bleed/edges.tsx

```tsx
import { Bleed } from '@luke-ui/react/bleed';
import { Box } from '@luke-ui/react/box';
import { ExampleItem } from '#docs';

export default () => {
	return (
		<Box
			backgroundColor="surface.subdued"
			borderColor="decorative"
			borderStyle="solid"
			borderWidth="thin"
			padding="space.16"
		>
			<Bleed inlineStart="space.16">
				<ExampleItem>Inline start edge</ExampleItem>
			</Bleed>
		</Box>
	);
};
```

Use `'0'` at a breakpoint to stop bleeding. Here, `inline` matches the parent's padding on narrow
viewports, so the item reaches both edges. Resize the preview: at `bp640`, `inline` is `'0'` and the
parent's padding keeps the item inset.

apps/docs/src/examples/bleed/responsive.tsx

```tsx
import { Bleed } from '@luke-ui/react/bleed';
import { Box } from '@luke-ui/react/box';
import { Stack } from '@luke-ui/react/stack';
import { ExampleItem } from '#docs';

export default () => {
	return (
		<Box
			backgroundColor="surface.subdued"
			borderColor="decorative"
			borderStyle="solid"
			borderWidth="thin"
			paddingBlock="space.16"
			paddingInline="space.16"
		>
			<Stack gap="space.16">
				<ExampleItem>Inset within the padding</ExampleItem>
				<Bleed inline={{ initial: 'space.16', bp640: '0' }}>
					<ExampleItem>Full bleed on narrow viewports, inset from bp640</ExampleItem>
				</Bleed>
			</Stack>
		</Box>
	);
};
```

## Overlap adjacent items [#overlap-adjacent-items]

In a `Stack`, a block bleed larger than the gap extends into the space around adjacent items.

apps/docs/src/examples/bleed/stack-overlap.tsx

```tsx
import { Bleed } from '@luke-ui/react/bleed';
import { Stack } from '@luke-ui/react/stack';
import { Comparison, ComparisonItem, ExampleItem } from '#docs';

export default () => {
	return (
		<Comparison>
			<ComparisonItem label="Without bleed">
				<Stack gap="space.16">
					<ExampleItem>First item</ExampleItem>
					<ExampleItem backgroundColor="info.subtle">Middle item</ExampleItem>
					<ExampleItem>Last item</ExampleItem>
				</Stack>
			</ComparisonItem>
			<ComparisonItem label="With block bleed">
				<Stack gap="space.16">
					<ExampleItem>First item</ExampleItem>
					<Bleed block="space.24" position="relative">
						<ExampleItem backgroundColor="info.subtle">Middle item</ExampleItem>
					</Bleed>
					<ExampleItem>Last item</ExampleItem>
				</Stack>
			</ComparisonItem>
		</Comparison>
	);
};
```

In a `Grid`, use `all` to extend a cell into the gaps on every side.

apps/docs/src/examples/bleed/grid-overlap.tsx

```tsx
import { Bleed } from '@luke-ui/react/bleed';
import { Box } from '@luke-ui/react/box';
import { Grid } from '@luke-ui/react/grid';
import { ExampleItem } from '#docs';

export default () => {
	return (
		<Box
			backgroundColor="surface.subdued"
			borderColor="decorative"
			borderStyle="solid"
			borderWidth="thin"
			padding="space.24"
		>
			<Grid columns={3} gap="space.8">
				<ExampleItem>1</ExampleItem>
				<ExampleItem>2</ExampleItem>
				<ExampleItem>3</ExampleItem>
				<ExampleItem>4</ExampleItem>
				<Bleed all="space.12" position="relative">
					<ExampleItem backgroundColor="info.subtle" blockSize="100%">
						5
					</ExampleItem>
				</Bleed>
				<ExampleItem>6</ExampleItem>
				<ExampleItem>7</ExampleItem>
				<ExampleItem>8</ExampleItem>
				<ExampleItem>9</ExampleItem>
			</Grid>
		</Box>
	);
};
```

## Choose the rendered element [#choose-the-rendered-element]

Bleed uses
[Box's `elementType` and `renderRoot` contract](/components/layout/box#choose-the-rendered-element).

## API [#api]

### BleedProps

Props for `Bleed`.

`BleedProps` also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.

| Prop                      | Type                                                                                                                                                                                                        | Description                                                                                                                                                                                                                                                        |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `children?`               | `ReactNode \| undefined`                                                                                                                                                                                    |                                                                                                                                                                                                                                                                    |
| `className?`              | `string \| undefined`                                                                                                                                                                                       |                                                                                                                                                                                                                                                                    |
| `style?`                  | `CSSProperties \| undefined`                                                                                                                                                                                |                                                                                                                                                                                                                                                                    |
| `alignSelf?`              | `ResponsiveValue<"auto" \| "baseline" \| "center" \| "flex-end" \| "flex-start" \| "normal" \| "stretch"> \| undefined`                                                                                     |                                                                                                                                                                                                                                                                    |
| `blockSize?`              | `ResponsiveValue<"0" \| "100%" \| "auto" \| "fit-content" \| "max-content" \| "min-content"> \| undefined`                                                                                                  |                                                                                                                                                                                                                                                                    |
| `flexBasis?`              | `ResponsiveValue<"0" \| "100%" \| "auto" \| "content" \| "fit-content" \| "max-content" \| "min-content"> \| undefined`                                                                                     |                                                                                                                                                                                                                                                                    |
| `flexGrow?`               | `ResponsiveValue<"0" \| "1"> \| undefined`                                                                                                                                                                  |                                                                                                                                                                                                                                                                    |
| `flexShrink?`             | `ResponsiveValue<"0" \| "1"> \| undefined`                                                                                                                                                                  |                                                                                                                                                                                                                                                                    |
| `inlineSize?`             | `ResponsiveValue<"0" \| "100%" \| "auto" \| "fit-content" \| "max-content" \| "min-content"> \| undefined`                                                                                                  |                                                                                                                                                                                                                                                                    |
| `inset?`                  | `ResponsiveValue<"0" \| "auto" \| "space.4" \| "space.8" \| "space.12" \| "space.16" \| "space.24" \| "space.32" \| "space.40" \| "space.48" \| "space.64" \| "space.96"> \| undefined`                     |                                                                                                                                                                                                                                                                    |
| `insetBlock?`             | `ResponsiveValue<"0" \| "auto" \| "space.4" \| "space.8" \| "space.12" \| "space.16" \| "space.24" \| "space.32" \| "space.40" \| "space.48" \| "space.64" \| "space.96"> \| undefined`                     |                                                                                                                                                                                                                                                                    |
| `insetBlockEnd?`          | `ResponsiveValue<"0" \| "auto" \| "space.4" \| "space.8" \| "space.12" \| "space.16" \| "space.24" \| "space.32" \| "space.40" \| "space.48" \| "space.64" \| "space.96"> \| undefined`                     |                                                                                                                                                                                                                                                                    |
| `insetBlockStart?`        | `ResponsiveValue<"0" \| "auto" \| "space.4" \| "space.8" \| "space.12" \| "space.16" \| "space.24" \| "space.32" \| "space.40" \| "space.48" \| "space.64" \| "space.96"> \| undefined`                     |                                                                                                                                                                                                                                                                    |
| `insetInline?`            | `ResponsiveValue<"0" \| "auto" \| "space.4" \| "space.8" \| "space.12" \| "space.16" \| "space.24" \| "space.32" \| "space.40" \| "space.48" \| "space.64" \| "space.96"> \| undefined`                     |                                                                                                                                                                                                                                                                    |
| `insetInlineEnd?`         | `ResponsiveValue<"0" \| "auto" \| "space.4" \| "space.8" \| "space.12" \| "space.16" \| "space.24" \| "space.32" \| "space.40" \| "space.48" \| "space.64" \| "space.96"> \| undefined`                     |                                                                                                                                                                                                                                                                    |
| `insetInlineStart?`       | `ResponsiveValue<"0" \| "auto" \| "space.4" \| "space.8" \| "space.12" \| "space.16" \| "space.24" \| "space.32" \| "space.40" \| "space.48" \| "space.64" \| "space.96"> \| undefined`                     |                                                                                                                                                                                                                                                                    |
| `justifySelf?`            | `ResponsiveValue<"auto" \| "center" \| "end" \| "normal" \| "start" \| "stretch"> \| undefined`                                                                                                             |                                                                                                                                                                                                                                                                    |
| `maxBlockSize?`           | `ResponsiveValue<"0" \| "100%" \| "fit-content" \| "max-content" \| "min-content" \| "none"> \| undefined`                                                                                                  |                                                                                                                                                                                                                                                                    |
| `maxInlineSize?`          | `ResponsiveValue<"0" \| "100%" \| "container.448" \| "container.672" \| "container.896" \| "container.1152" \| "container.1280" \| "fit-content" \| "max-content" \| "min-content" \| "none"> \| undefined` |                                                                                                                                                                                                                                                                    |
| `minBlockSize?`           | `ResponsiveValue<"0" \| "100%" \| "auto" \| "fit-content" \| "max-content" \| "min-content"> \| undefined`                                                                                                  |                                                                                                                                                                                                                                                                    |
| `minInlineSize?`          | `ResponsiveValue<"0" \| "100%" \| "auto" \| "fit-content" \| "max-content" \| "min-content"> \| undefined`                                                                                                  |                                                                                                                                                                                                                                                                    |
| `order?`                  | `ResponsiveValue<number> \| undefined`                                                                                                                                                                      |                                                                                                                                                                                                                                                                    |
| `overflow?`               | `ResponsiveValue<"auto" \| "clip" \| "hidden" \| "scroll" \| "visible"> \| undefined`                                                                                                                       |                                                                                                                                                                                                                                                                    |
| `overflowX?`              | `ResponsiveValue<"auto" \| "clip" \| "hidden" \| "scroll" \| "visible"> \| undefined`                                                                                                                       |                                                                                                                                                                                                                                                                    |
| `overflowY?`              | `ResponsiveValue<"auto" \| "clip" \| "hidden" \| "scroll" \| "visible"> \| undefined`                                                                                                                       |                                                                                                                                                                                                                                                                    |
| `overscrollBehavior?`     | `ResponsiveValue<"auto" \| "contain"> \| undefined`                                                                                                                                                         |                                                                                                                                                                                                                                                                    |
| `padding?`                | `ResponsiveValue<"0" \| "space.4" \| "space.8" \| "space.12" \| "space.16" \| "space.24" \| "space.32" \| "space.40" \| "space.48" \| "space.64" \| "space.96"> \| undefined`                               |                                                                                                                                                                                                                                                                    |
| `paddingBlock?`           | `ResponsiveValue<"0" \| "space.4" \| "space.8" \| "space.12" \| "space.16" \| "space.24" \| "space.32" \| "space.40" \| "space.48" \| "space.64" \| "space.96"> \| undefined`                               |                                                                                                                                                                                                                                                                    |
| `paddingBlockEnd?`        | `ResponsiveValue<"0" \| "space.4" \| "space.8" \| "space.12" \| "space.16" \| "space.24" \| "space.32" \| "space.40" \| "space.48" \| "space.64" \| "space.96"> \| undefined`                               |                                                                                                                                                                                                                                                                    |
| `paddingBlockStart?`      | `ResponsiveValue<"0" \| "space.4" \| "space.8" \| "space.12" \| "space.16" \| "space.24" \| "space.32" \| "space.40" \| "space.48" \| "space.64" \| "space.96"> \| undefined`                               |                                                                                                                                                                                                                                                                    |
| `paddingInline?`          | `ResponsiveValue<"0" \| "space.4" \| "space.8" \| "space.12" \| "space.16" \| "space.24" \| "space.32" \| "space.40" \| "space.48" \| "space.64" \| "space.96"> \| undefined`                               |                                                                                                                                                                                                                                                                    |
| `paddingInlineEnd?`       | `ResponsiveValue<"0" \| "space.4" \| "space.8" \| "space.12" \| "space.16" \| "space.24" \| "space.32" \| "space.40" \| "space.48" \| "space.64" \| "space.96"> \| undefined`                               |                                                                                                                                                                                                                                                                    |
| `paddingInlineStart?`     | `ResponsiveValue<"0" \| "space.4" \| "space.8" \| "space.12" \| "space.16" \| "space.24" \| "space.32" \| "space.40" \| "space.48" \| "space.64" \| "space.96"> \| undefined`                               |                                                                                                                                                                                                                                                                    |
| `placeSelf?`              | `ResponsiveValue<"auto" \| "center" \| "end" \| "normal" \| "start" \| "stretch"> \| undefined`                                                                                                             |                                                                                                                                                                                                                                                                    |
| `position?`               | `ResponsiveValue<"absolute" \| "fixed" \| "relative" \| "static" \| "sticky"> \| undefined`                                                                                                                 |                                                                                                                                                                                                                                                                    |
| `borderBlockStartWidth?`  | `ResponsiveValue<"none" \| "thick" \| "thin"> \| undefined`                                                                                                                                                 |                                                                                                                                                                                                                                                                    |
| `borderBlockEndWidth?`    | `ResponsiveValue<"none" \| "thick" \| "thin"> \| undefined`                                                                                                                                                 |                                                                                                                                                                                                                                                                    |
| `borderInlineStartWidth?` | `ResponsiveValue<"none" \| "thick" \| "thin"> \| undefined`                                                                                                                                                 |                                                                                                                                                                                                                                                                    |
| `borderInlineEndWidth?`   | `ResponsiveValue<"none" \| "thick" \| "thin"> \| undefined`                                                                                                                                                 |                                                                                                                                                                                                                                                                    |
| `elementType?`            | `BoxLikeElementType`                                                                                                                                                                                        | Chooses a supported structural element. Use `elementType` instead of `renderRoot` for a supported structural element. Default: `div`                                                                                                                               |
| `ref?`                    | `Ref<HTMLElement>`                                                                                                                                                                                          | Ref to the rendered element.                                                                                                                                                                                                                                       |
| `renderRoot?`             | `(domProps: { [K in "children" \| "className" \| "ref" \| "style"]: BoxLikeResolvedRenderProps[K]; }, state: Record<string, never>) => React.ReactElement`                                                  | Use `renderRoot` instead of `elementType` to own the rendered element. Passes resolved `children`, `className`, `style`, and a callback `ref` as `domProps`. The second argument is an empty state object. Put DOM attributes on the element the callback returns. |
| `all?`                    | `BleedSpaceProp`                                                                                                                                                                                            | Amount to extend from all four edges. Axis and edge props override this at the same breakpoint.                                                                                                                                                                    |
| `block?`                  | `BleedSpaceProp`                                                                                                                                                                                            | Amount to extend from both block edges. Overrides `all` at the same breakpoint.                                                                                                                                                                                    |
| `blockEnd?`               | `BleedSpaceProp`                                                                                                                                                                                            | Amount to extend from the block-end edge. Overrides `block` at the same breakpoint.                                                                                                                                                                                |
| `blockStart?`             | `BleedSpaceProp`                                                                                                                                                                                            | Amount to extend from the block-start edge. Overrides `block` at the same breakpoint.                                                                                                                                                                              |
| `inline?`                 | `BleedSpaceProp`                                                                                                                                                                                            | Amount to extend from both inline edges. Overrides `all` at the same breakpoint.                                                                                                                                                                                   |
| `inlineEnd?`              | `BleedSpaceProp`                                                                                                                                                                                            | Amount to extend from the inline-end edge. Overrides `inline` at the same breakpoint.                                                                                                                                                                              |
| `inlineStart?`            | `BleedSpaceProp`                                                                                                                                                                                            | Amount to extend from the inline-start edge. Overrides `inline` at the same breakpoint.                                                                                                                                                                            |

#### Type definitions

These are the types that this table's signatures and the definitions below name. TypeScript's built-in types, such as `Omit` and `ReadonlyArray`, are not listed.

##### `ResponsiveValue`

```ts
type ResponsiveValue<Value> = Value
  | null
  | {
    [Condition in BreakpointName]?: Value | null;
  };
```

Refers to `BreakpointName`.

##### `BreakpointName`

```ts
type BreakpointName = keyof typeof responsiveConditions;
```

Which resolves to:

```ts
"bp640"
  | "bp768"
  | "bp1024"
  | "bp1280"
  | "bp1536"
  | "initial"
```

##### `BoxLikeElementType`

```ts
type BoxLikeElementType = keyof Pick<JSX.IntrinsicElements, 'article'
  | 'aside'
  | 'dd'
  | 'div'
  | 'dl'
  | 'dt'
  | 'figcaption'
  | 'figure'
  | 'footer'
  | 'header'
  | 'li'
  | 'main'
  | 'nav'
  | 'ol'
  | 'section'
  | 'span'
  | 'ul'>;
```

Which resolves to:

```ts
"article"
  | "aside"
  | "dd"
  | "div"
  | "dl"
  | "dt"
  | "figcaption"
  | "figure"
  | "footer"
  | "header"
  | "li"
  | "main"
  | "nav"
  | "ol"
  | "section"
  | "span"
  | "ul"
```

Refers to `IntrinsicElements`.

##### `BoxLikeResolvedRenderProps`

```ts
type BoxLikeResolvedRenderProps = DistributiveOmit<BoxLikePresentationProps, 'ref'> & {
  ref: UseRenderRef;
};
```

Refers to `DistributiveOmit`, `BoxLikePresentationProps`, and `UseRenderRef`.

##### `DistributiveOmit`

```ts
type DistributiveOmit<T, K extends KeysOfUnion<T>> = T extends any ? Omit<T, Extract<K, keyof T>> : never;
```

Refers to `KeysOfUnion`.

##### `KeysOfUnion`

```ts
type KeysOfUnion<T> = T extends T ? keyof T : never;
```

##### `BoxLikePresentationProps`

```ts
interface BoxLikePresentationProps extends Pick<HTMLAttributes<HTMLElement>, 'children'
  | 'className'
  | 'style'> {
  ref?: Ref<HTMLElement>;
}
```

Refers to `HTMLAttributes` and `Ref`.

##### `UseRenderRef`

```ts
type UseRenderRef = NonNullable<Exclude<Ref<HTMLElement>, RefObject<HTMLElement | null>>>;
```

Refers to `Ref` and `RefObject`.

##### `BleedSpaceProp`

```ts
type BleedSpaceProp = ResponsivePropValue<'0' | SpaceToken>;
```

Refers to `ResponsivePropValue` and `SpaceToken`.

##### `ResponsivePropValue`

```ts
type ResponsivePropValue<Value> = Value | {
  [Condition in ResponsiveCondition]?: Value | null;
};
```

Refers to `ResponsiveCondition`.

##### `ResponsiveCondition`

```ts
type ResponsiveCondition = keyof typeof responsiveConditions;
```

Which resolves to:

```ts
"bp640"
  | "bp768"
  | "bp1024"
  | "bp1280"
  | "bp1536"
  | "initial"
```

##### `SpaceToken`

```ts
type SpaceToken = `space.${SpaceStep}`;
```

Refers to `SpaceStep`.

##### `SpaceStep`

```ts
type SpaceStep = keyof typeof spaceScale;
```

Which resolves to:

```ts
"4"
  | "8"
  | "12"
  | "16"
  | "24"
  | "32"
  | "40"
  | "48"
  | "64"
  | "96"
```

##### `ReactNode`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

```ts
type ReactNode = ReactElement
  | string
  | number
  | bigint
  | Iterable<ReactNode>
  | ReactPortal
  | boolean
  | null
  | undefined
  | DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES[keyof DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES]
  | Promise<AwaitedReactNode>;
```

Refers to `ReactElement`, `ReactPortal`, `DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES`, and `AwaitedReactNode`.

##### `ReactElement`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `ReactPortal`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `AwaitedReactNode`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `CSSProperties`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `IntrinsicElements`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `Ref`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

```ts
type Ref<T> = RefCallback<T>
  | RefObject<T | null>
  | null;
```

Refers to `RefCallback` and `RefObject`.

##### `RefCallback`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `RefObject`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `HTMLAttributes`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).
