> For the complete documentation index, see [llms.txt](https://analog.groupthought.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://analog.groupthought.com/reference/alpine/scroll-motion-internals.md).

# Gesture & motion internals

The gesture primitives behind the interactive plugins: hover, press, hold, pan, and the animated number wheel.

The gesture primitives the interactive plugins build on. These modules are internal and can change between versions.

## x-hover

Tracks pointer hover on an element and exposes it as `$isHovering`. Touch input is ignored, so `$isHovering` never sticks on after a tap.

| Directive / magic            | What it does                                                             |
| ---------------------------- | ------------------------------------------------------------------------ |
| `x-hover`                    | Makes `$isHovering` available on the element and its children            |
| `x-hover="expression"`       | Runs the expression on enter and on leave                                |
| `x-hover:start="expression"` | Runs on pointer enter                                                    |
| `x-hover:end="expression"`   | Runs on pointer leave                                                    |
| `x-hover:start.delay.300ms`  | Waits before firing, for tooltip-style reveals                           |
| `$isHovering`                | True while the pointer is over the element or nearest `x-hover` ancestor |

## x-press

Tracks pressed state from pointer and keyboard (Enter/Space) and exposes it as `$isPressing`. Only the primary pointer counts; release is detected on `window` so a press that ends outside the element still ends. Non-focusable elements get `tabindex="0"` so they can be pressed from the keyboard.

| Directive / magic            | What it does                                                                                                    |
| ---------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `x-press`                    | Makes `$isPressing` available on the element and its children                                                   |
| `x-press="expression"`       | Runs the expression on press start and end                                                                      |
| `x-press:start="expression"` | Runs when the press starts                                                                                      |
| `x-press:end="expression"`   | Runs when the press ends. `$success` is true when released over the element, false on cancel or release outside |
| `$isPressing`                | True while the element or nearest `x-press` ancestor is pressed                                                 |

## x-hold

Repeats an expression while the element is held down. The stepper's plus and minus buttons use it to keep counting.

| Directive                   | What it does                                                                  |
| --------------------------- | ----------------------------------------------------------------------------- |
| `x-hold.250ms="expression"` | Runs the expression every 250ms while held (default 25ms)                     |
| `x-hold.250ms.max.3000ms`   | Stops repeating after 3000ms even if the pointer never lifts (default 1500ms) |

## x-pan

Recognizes a pan gesture (pointer down, move past a 5px threshold, release) and dispatches DOM events on the element. Listen with normal Alpine event syntax.

| Directive / event | What it does                             |
| ----------------- | ---------------------------------------- |
| `x-pan`           | Attaches the gesture recognizer          |
| `@panstart`       | Fires when movement passes the threshold |
| `@panmove`        | Fires on each move while panning         |
| `@panend`         | Fires on release                         |

## x-animated-wheel

Animates a sliding track of numbers over an input, so a quantity change spins like a wheel instead of swapping text. The stepper and countdown use it.

| Directive                  | What it does                                                            |
| -------------------------- | ----------------------------------------------------------------------- |
| `x-animated-wheel`         | The root. Reads min/max/step from the input and builds the track        |
| `x-animated-wheel.pad`     | Pads values to equal digits (09, 10, 11)                                |
| `x-animated-wheel.reverse` | Runs the track in descending order, for countdowns                      |
| `x-animated-wheel:input`   | The input or element holding the value                                  |
| `x-animated-wheel:track`   | The overlay that shows the sliding values. Visible only while animating |
