# Page Builder Actions

URL: https://zerodev.ca/docs/prism/developer-documentation/page-builder-actions

> Triggers, property changes, motion and easing curves on Page Builder elements.



Every Page Builder element has an `actions` array. Each action pairs a trigger (`When`) with something to do (`Then`). Actions are stored with the page in the `LANDING` and `PAGES` settings and normalized by `normalizePage()` in `src/web/lib/page.ts`.

```json
{
  "id": "a1b2c3d4",
  "trigger": "hover",
  "kind": "move",
  "property": "text",
  "value": "",
  "x": 0,
  "y": -8,
  "amount": 110,
  "preset": "bounce",
  "duration": 400,
  "delay": 0,
  "every": 3000,
  "curve": [0.25, 0.1, 0.25, 1],
  "entrance": false
}
```

## Triggers

| Trigger           | Fires                                                    |
| ----------------- | -------------------------------------------------------- |
| `user.signed.in`  | Once on render when a customer is signed in.             |
| `user.signed.out` | Once on render when nobody is signed in.                 |
| `user.staff`      | Once on render when the visitor is a team member.        |
| `load`            | When the page loads.                                     |
| `view`            | The first time 20% of the element scrolls into view.     |
| `hover`           | On mouse enter, and reverses on mouse leave.             |
| `click`           | Toggles on each click. Animations replay on every click. |
| `interval`        | Every `every` milliseconds.                              |

User triggers are resolved by `applyActions()` before render. `set` and `hide` actions apply directly, matching motion actions are turned into `load` actions, and actions that do not match are dropped. Older pages that stored `condition` instead of `trigger` still load.

## Kinds

| Kind      | Fields              | Effect                                                                                                                          |
| --------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `set`     | `property`, `value` | Changes `text`, `href`, `body`, `src`, `icon` or `variant`. `{user.name}`, `{user.email}` and `{name}` are replaced in `value`. |
| `hide`    |                     | Hides the element. With a user trigger it is removed from the layout, otherwise it fades out.                                   |
| `move`    | `x`, `y`            | Translates by pixels.                                                                                                           |
| `rotate`  | `amount`            | Rotates by degrees.                                                                                                             |
| `scale`   | `amount`            | Scales by percent, `100` is the original size.                                                                                  |
| `fade`    | `amount`            | Fades to an opacity percent.                                                                                                    |
| `animate` | `preset`            | Plays `bounce`, `shake`, `pulse`, `spin`, `wobble`, `pop`, `float`, `flash`, `jello` or `heartbeat`.                            |

With an event trigger, `set` and `hide` stay active while the trigger is: while hovered, until clicked again, or every other interval tick, so an interval `set` swaps between two texts.

## Motion

Motion kinds run on the Web Animations API through `src/web/lib/motion.ts`. Transforms use `composite: "add"`, so several actions on one element stack. Motion is skipped when the visitor prefers reduced motion.

| Field      | Meaning                                                                                                                                                  |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `duration` | Length in milliseconds.                                                                                                                                  |
| `delay`    | Wait before playing, in milliseconds. Also delays `set` and `hide` on `load`, `view` and `interval`.                                                     |
| `every`    | Interval length in milliseconds, used by `interval`.                                                                                                     |
| `entrance` | Plays from the target back to the resting state, so the element starts moved, rotated, scaled or faded and settles in. Not used with `hover` or `click`. |
| `curve`    | Cubic bezier control points `[x1, y1, x2, y2]`. `x` is clamped to `0..1`, `y` may overshoot for spring and anticipation effects.                         |

`hover` and `click` hold the target pose and reverse back to rest. `interval` plays rest, target, rest on each tick.

## Easing Curves

The builder edits `curve` with a draggable graph (`src/web/components/ui/curveEditor.tsx`) and offers these presets from `CURVES`:

| Preset       | Curve                    |
| ------------ | ------------------------ |
| `linear`     | `[0, 0, 1, 1]`           |
| `ease`       | `[0.25, 0.1, 0.25, 1]`   |
| `easeIn`     | `[0.42, 0, 1, 1]`        |
| `easeOut`    | `[0, 0, 0.58, 1]`        |
| `easeInOut`  | `[0.42, 0, 0.58, 1]`     |
| `back`       | `[0.34, 1.56, 0.64, 1]`  |
| `anticipate` | `[0.36, 0, 0.66, -0.56]` |
| `snappy`     | `[0.2, 0.9, 0.1, 1]`     |

Dragging a handle switches the preset to Custom. The Play button on a motion action previews it on the builder canvas.

## Rendering

`PageView` wraps every element in two boxes. The outer box takes the grid span and receives hover and click events, and the inner box (`data-motion="<element id>"`) is what moves, so an element moving away from the cursor does not cancel its own hover.
