# <motion-underline>

A line that draws itself under a phrase, from left to right. Straight,
dashed and dotted lines follow text that wraps across lines;
`shape="wave"` and `shape="zigzag"` draw a wavy or a zigzag line and keep
the text on one line. It uses the text color unless you set one.

**Use it for:** a word or link that should stand out with a drawn line,
such as a call to action or a term you introduce.

**Avoid it for:** ordinary links in body text, where the browser's own
underline is clearer and always visible. For a highlight behind the text,
use `motion-marker`.

**Accessibility:** the line is a background under the text, which stays
in the page and is read by screen readers unchanged. With `trigger="hover"`
the line follows the pointer only, so give links their own visible focus
style.

**Reduced motion:** the line appears fully drawn at once. With
`trigger="hover"` it appears on enter and disappears on leave, instantly.
With `loop` it stays drawn and never cycles.

**Common mistakes:** leaving the link's own `text-decoration` on, so two
lines show; set `text-decoration: none` on the link. Using `shape="wave"`
or `shape="zigzag"` on a long phrase, which stays on one line and can
overflow a narrow screen.

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

## Install

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

Or without a build step:

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

## Example

```html
<a href="/guide/"><motion-underline trigger="hover">Read the guide</motion-underline></a>
```

## Attributes

| Attribute | Type | Default | Description |
| --- | --- | --- | --- |
| `shape` | `'line' \| 'dashed' \| 'dotted' \| 'wave' \| 'zigzag'` | `'line'` | `'line'`, `'dashed'` or `'dotted'`, which follow wrapping text, or `'wave'` or `'zigzag'`, which keep the text on one line. |
| `trigger` | `'view' \| 'hover' \| 'mount'` | `'view'` | What draws the mark: `'view'` (scrolled into view), `'hover'` (pointer enter, undraws on leave) or `'mount'`. |
| `duration` | `number` | `0.6` | Spring duration of the drawing, in seconds. |
| `delay` | `number` | `0` | Seconds to wait before drawing. |
| `bounce` | `number` | `0` | Spring bounciness. `0` keeps the stroke from overshooting the text. |
| `loop` | `boolean` | `false` | Draw, hold, undraw, draw again on repeat. With `trigger="view"` the cycle runs while the mark is on screen. |
| `hold` | `number` | `1.6` | With `loop`, seconds the mark stays drawn before it undraws. |
| `gap` | `number` | `0.5` | With `loop`, seconds the mark stays undrawn before it draws again. |
| `pause-on-hover` | `boolean` | `false` | Pause the loop while the pointer is over the mark, resuming on leave. |
| `once` | `boolean` | `true` | With `trigger="view"`, draw only the first time. Set `once="false"` to undraw on leave and draw again on every entry. Ignored with `loop`. |
| `threshold` | `number` | `0.6` | Share of the element, from 0 to 1, that must be visible before it draws. |

## 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`. |
| `replay()` | Draws the mark again from the start. |
| `sweep()` | Sweeps a drawn mark across: it erases from its start, so it leaves at its end, then draws in again from the start. Calls while a sweep runs, before the mark is drawn, or under reduced motion do nothing. |

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

## Slots

| Slot | Description |
| --- | --- |
| (default) | The phrase to underline. It may wrap across lines. |

## CSS custom properties

| Property | Description |
| --- | --- |
| `--mc-mark-color` | Color of the line. Default `currentColor`. |
| `--mc-mark-thickness` | Thickness of the line. Default `2px`. |
