# Click Sparks

> A ring of short spark strokes bursts out from the point a button or link is clicked, flies a short way, shrinks and fades, all within half a second. The click itself is never touched: a `routerLink` or a plain `href` navigates as it did.

Source: https://ngwr.dev/animations/click-sparks  
Kind: Animation, Directive, CSS  
Added in v15.7

## Installation

Import the class, and `@use` the entry point in your global styles. Nothing warns you when the `@use` is missing.

```typescript
import { Component } from '@angular/core';
import { WrClickSparks } from 'ngwr/animations/click-sparks';

@Component({ imports: [WrClickSparks] })
export class MyComponent {}
```

```scss
@use 'ngwr/animations/click-sparks';
```

## Basic

Put `wrClickSparks` on the element that takes the click. A burst is one `aria-hidden` layer of zero size in `document.body`, fixed at the click's client coordinates, so no ancestor clips it and a button inside a transformed hero measures from the viewport all the same. Several quick clicks make several bursts; at most four are alive at once, and the ring turns a golden angle from one burst to the next, so no two consecutive bursts put a stroke in the same place.

```angular-html
<a wr-btn outlined size="lg" routerLink="/docs" wrClickSparks>Get started</a>
```

## Strokes

The directive's own value is how many strokes a burst has, spread evenly round the ring. Unset, eight. The strokes scale with the host's font size: a large hero button throws longer, farther sparks than a small one.

```angular-html
<button wr-btn outlined type="button" wrClickSparks="12">Twelve strokes</button>
```

## Colour

The strokes paint in the host's own text colour, read at the click. On a filled button that colour is the fill's `-contrast`, unreadable off the button: set `--wr-click-sparks-color` on the host to a role instead, and the layer takes it. The length, distance and width of a stroke are the layer's own hooks, in `em` of the host.

```angular-html
<button wr-btn type="button" wrClickSparks style="--wr-click-sparks-color: var(--wr-color-primary)">
  Filled
</button>
```

## Accessibility

| Part | Behaviour |
| --- | --- |
| Keyboard | An activation from Enter or Space is a `click` with `detail === 0`: the burst comes from the host's centre. The listener is passive and prevents nothing. |
| Screen readers | Each burst's layer is `aria-hidden`, holds no text and takes no pointer. |
| Reduced motion | Under `prefers-reduced-motion: reduce` nothing plays; under `forced-colors: active` nothing listens, since the stylesheet paints no stroke. A preference that flips mid-burst leaves an invisible layer, which a timer takes out. |
| Server | Nothing runs: the listener is added after the first render, in the browser only. |

## API

| Name | Description | Type | Default |
| --- | --- | --- | --- |
| `wrClickSparks` | How many strokes one burst has. Written as the directive's own value: `wrClickSparks="10"`. Unset or empty, {@link CLICK_SPARKS_COUNT}. | `number` | `CLICK_SPARKS_COUNT` |

## CSS variables

Set these on the element itself, with a rule more specific than its Declared on selector. In a global stylesheet, put a class of yours on an ancestor it really has: `<body>` for an overlay panel, which renders outside your markup. In a component stylesheet the selector alone works, but only for an element in that component's own template. A value on a wrapper or `:root` is shadowed, because `ngwr/animations/click-sparks` declares each default on its own element.

| Variable | Default | Declared on |
| --- | --- | --- |
| `--wr-click-sparks-duration` | `480ms` | `.wr-click-sparks` and inline on the element, written by the component from its inputs or its state — a rule holds only until the component writes |
| `--wr-click-sparks-ease` | `var(--wr-ease-out)` | `.wr-click-sparks` |
| `--wr-click-sparks-from` | `0.3em` | `.wr-click-sparks` |
| `--wr-click-sparks-length` | `0.55em` | `.wr-click-sparks` |
| `--wr-click-sparks-to` | `1.7em` | `.wr-click-sparks` |
| `--wr-click-sparks-width` | `max(2px, 0.12em)` | `.wr-click-sparks` |
| `--wr-click-sparks-x` | `0px` | `.wr-click-sparks` and inline on the element, written by the component from its inputs or its state — a rule holds only until the component writes |
| `--wr-click-sparks-y` | `0px` | `.wr-click-sparks` and inline on the element, written by the component from its inputs or its state — a rule holds only until the component writes |

## See also

- [Confetti](https://ngwr.dev/animations/confetti) — A one-shot celebration: small paper pieces burst up and out from an element, flutter, tumble and fall under gravity, and are gone inside two and a half seconds.
- [Button](https://ngwr.dev/reference/components/button) — A button for an action or a link.
- [Motion](https://ngwr.dev/guides/tokens/motion) — Easing and duration tokens for your transitions and animations.
