# animationHost

> Emits the host `animation-*` declarations alone, taking every AnimationConfig key but `keyframes`.

```ts
import { animationHost } from "@sdxc/u/animation";
```

Emits the host `animation-*` declarations alone, taking every
AnimationConfig key but `keyframes`. Pair it with a sibling
`u.keyframes` call, since `@keyframes` only hoists from a mixin's top level.

## Quick reference

Every documented call, beside the CSS it emits.

| Call | CSS |
| --- | --- |
| `<div mix={[ u.keyframes("ui-spin-rotate", { from: { transform: "rotate(0deg)" }, to: { transform: "rotate(360deg)" } }), u.when("&[data-busy]", u.animationHost("ui-spin-rotate", { duration: "1s", iterationCount: "infinite" })), ]} />` | `css({ "@keyframes ui-spin-rotate": { from: { transform: "rotate(0deg)" }, to: { transform: "rotate(360deg)" } }, "&[data-busy]": { animationName: "ui-spin-rotate", animationDuration: "1s", animationIterationCount: "infinite" }, })` |

## Examples

### Basic example

Use `animationHost(name, config)` to run a `@keyframes` rule declared elsewhere, like one from `keyframes()`:

```tsx
<div mix={[...]}>
	<div
		mix={[
			keyframes("spin", { from: { rotate: "0deg" }, to: { rotate: "360deg" } }),
			animationHost("spin", { duration: "1s", easing: "linear", iterationCount: "infinite" }),
			...,
		]}
	>
		spin
	</div>
</div>
```

### Running in a state

Wrap it in a state like `hover()` to run the animation only while that state holds. Hover the tile to try it:

```tsx
<div mix={[...]}>
	<div
		mix={[
			keyframes("wiggle", {
				"0%, 100%": { rotate: "-6deg" },
				"50%": { rotate: "6deg" },
			}),
			hover(animationHost("wiggle", { duration: "300ms", iterationCount: "infinite" })),
			...,
		]}
	>
		hover me
	</div>
</div>
```

### Sharing keyframes

Declare the keyframes once and point several `animationHost()` calls at them, each with its own timing:

```tsx
<div
	mix={[
		keyframes("spin", { from: { rotate: "0deg" }, to: { rotate: "360deg" } }),
		...,
	]}
>
	{["3s", "1.5s", "750ms"].map((duration) => (
		<div
			mix={[
				animationHost("spin", { duration, easing: "linear", iterationCount: "infinite" }),
				...,
			]}
		>
			{duration}
		</div>
	))}
</div>
```

## Applying on a state

Wrap the call in a state utility to scope it to one selector.

```ts
u.hover(<div
  mix={[
    u.keyframes("ui-spin-rotate", { from: { transform: "rotate(0deg)" }, to: { transform: "rotate(360deg)" } }),
    u.when("&[data-busy]", u.animationHost("ui-spin-rotate", { duration: "1s", iterationCount: "infinite" })),
  ]}
/>)
```

## Responsive design

Wrap the call in a container query to scope it to one width.

```ts
u.at("md", <div
  mix={[
    u.keyframes("ui-spin-rotate", { from: { transform: "rotate(0deg)" }, to: { transform: "rotate(360deg)" } }),
    u.when("&[data-busy]", u.animationHost("ui-spin-rotate", { duration: "1s", iterationCount: "infinite" })),
  ]}
/>)
```

## Signature

```ts
u.animationHost(name: string, config: Omit<AnimationConfig, "keyframes">)
```
