# <motion-words>

Rotating word swap. Cycles through a comma-separated list of `words`,
springing the host width between values and crossfading each word with
a translate + blur transition. Optional per-word `colors` list.

**Use it for:** one word inside a heading or sentence that should change
on a timer, such as a verb that takes turns with other verbs.

**Avoid it for:** information people must read in full, because only one
word shows at a time, and long phrases, which do not wrap. To type a
phrase out letter by letter, use `motion-typewriter`.

**Accessibility:** only the current word is in the page, and changes are
not announced (there is no live region), so a screen reader reads the word
that shows at that moment. Make sure the sentence makes sense with every
word. The words change without end, and the component gives users no way
to stop them. Check that every color in `colors` has enough contrast with
the background.

**Reduced motion:** the words still change every `interval` seconds, but
each change is instant, with no slide, blur or width animation. `pause()`,
`play()` and `cancel()` control the cycle as usual.

**Common mistakes:** putting the words as child text: the component only
reads the `words` attribute and does not show its children. A `words` list
with fewer than two entries never changes.

Docs: https://www.motion-components.dev/docs/text/motion-words/

## Install

```js
import 'motion-components/motion-words'
```

Or without a build step:

```html
<script type="module" src="https://cdn.jsdelivr.net/npm/motion-components@1/dist/motion-words.js/+esm"></script>
```

## Example

```html
<motion-words
  words="ship, design, animate"
  colors="#2563eb, #db2777, #16a34a"
  interval="2">
</motion-words>
```

## Attributes

| Attribute | Type | Default | Description |
| --- | --- | --- | --- |
| `words` | `string` | `''` | Comma-separated list of words to cycle through. |
| `colors` | `string` | `''` | Comma-separated list of CSS colors, one per word. Optional. |
| `interval` | `number` | `2` | Time each word stays visible, in seconds. |

## Properties

| Property | Type | Description |
| --- | --- | --- |
| `playState` | `'idle' \| 'running' \| 'paused' \| 'finished'` | Current state: `'idle'`, `'running'`, `'paused'` or `'finished'`. |
| `finished` | `Promise<void>` | Resolves when the current run settles. A new run replaces the promise. |

## Methods

| Method | Description |
| --- | --- |
| `play()` | Starts the animation, or resumes it when paused. Resolves once the run settles. Under `prefers-reduced-motion: reduce` the final state is applied immediately without animating. |
| `pause()` | Holds the animation at its current position. No-op unless running. |
| `finish()` | Jumps to the final state and settles. Fires `motion-finish`. |
| `cancel()` | Reverts to the initial state and returns to idle. Fires `motion-cancel`. |

## Events

The `motion-*` events bubble and are composed.

| Event | Description |
| --- | --- |
| `motion-start` | When a run starts. |
| `motion-finish` | When a run finishes, or `finish()` jumps to the end. |
| `motion-cancel` | When `cancel()` stops a run and resets it. |
