Skip to main content

interactor

Use when user asks to add/edit motion without specific library, or with @wix/interact - hover, click, view/scroll triggered, scroll-driven, and pointer-driven animations for web. Wire animations to user interactions; install or set up @wix/interact; or edit an existing interact config. Do NOT use for other animation libraries.

Source facts

Repository
wix/interact
Last source activity
October 25, 2026 at 13:11
Detected SKILL.md language
English
Stars
4
Forks
3

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
100 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
interactor
description
Use when user asks to add/edit motion without specific library, or with @wix/interact - hover, click, view/scroll triggered, scroll-driven, and pointer-driven animations for web. Wire animations to user interactions; install or set up @wix/interact; or edit an existing interact config. Do NOT use for other animation libraries.
# Interactor — build interactions with @wix/interact This skill installs, wires up, and configures motion interactions so you can add or edit interactions on any webpage or web app. It is **interact-first**: you describe _what should animate and when_ as a declarative JSON config, and the library does the DOM wiring. You almost never call the motion engine directly. ## Mental model — packages and one config | Package | Role | You touch it… | | :----------------------- | :--------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------- | | `@wix/interact` | Declarative layer. Binds **triggers → effects** via an `InteractConfig`. Ships vanilla / React / Web-Component entry points. | Always. This is the API. | | `@wix/motion-presets` | Ready-made named effects (entrance, scroll, ongoing, mouse). Referenced as `namedEffect: { type: 'FadeIn' }`. | When you want a prebuilt effect (the common case). | | `@wix/motion` | The engine (WAAPI, CSS, ViewTimeline, fastdom). Bundled inside interact. | Rarely — only for programmatic/escape-hatch animation. See `references/motion-engine.md`. | | `@wix/interact-validate` | Static validator for `InteractConfig` shape (schema + referential checks). No DOM. | Agent-side validation always; optional dev/CI guard in user projects. See `references/validate.md`. | | `@wix/splittext` | Splits text into per-char/word/line spans. Ships an Interact adapter at `@wix/splittext/plugin`. | When animating text per character, word, or line. See `references/plugins.md`. | The whole job is: **pick a trigger, pick an effect, bind it to an element with a key.** Everything else is detail. ``` ┌── trigger (when) ──┐ ┌── effect (what) ────────────────┐ │ viewEnter, hover, │ ───► │ namedEffect: { type: 'FadeIn' } │ ──► applied to │ click, viewProgress│ │ duration, easing, triggerType │ element with │ pointerMove, … │ │ (or keyframeEffect/customEffect)│ matching key └────────────────────┘ └─────────────────────────────────┘ ``` ## Workflow Follow four steps in order: **Install → Integrate → Add/Edit interactions → Validate.** If the project already uses interact (a config and the package exist), skip to _Add/Edit_. Read the linked reference files as you reach each step — they hold the full schema, the preset catalog, and per-trigger rules. Don't try to hold it all in your head; the references are the source of truth. For static or pre-rendered output (agent-authored HTML, SSG, static export), follow the canonical CSS generation policy in `references/integration-recipes.md`. --- ### Step 1 — Install Both packages, one command. `@wix/motion` comes transitively inside `@wix/interact` — **do not install it separately** on this path. ```bash npm install @wix/interact @wix/motion-presets # (yarn add / pnpm add work too — match the project's package manager) npm install @wix/splittext # only for per-char/word/line text animation; not transitive npm install -D @wix/interact-validate # optional — permanent dev/CI config guard only ``` A no-build / plain-HTML site can skip npm and import Interact from a CDN for runtime wiring — see the CDN recipe in `references/integration-recipes.md`. CDN pages skip the validate package install; the agent validates configs without shipping the validator. --- ### Step 2 — Integrate **First, detect the stack and pick the entry point** (this determines every import and a couple of flags). Decision procedure: 1. **React / Next / any JSX project** (a `package.json` with `react`, `.jsx`/`.tsx` files) → use `@wix/interact/react` with the `<Interaction>` component. 2. **Static / pre-rendered HTML** (agent-generated `.html`, SSG export, Astro/Eleventy/Hugo output) → use `@wix/interact/web` with `<interact-element>` and follow the canonical CSS policy in `references/integration-recipes.md`. 3. **Plain HTML, no bundler** (hand-edited static `.html`, CDN runtime) → same as (2), using the CDN recipe for runtime wiring. 4. **Bundled vanilla JS / other framework** (Vite/Webpack but no React, or Vue/Svelte/Angular) → use `@wix/interact/web` (Web Components are framework-agnostic) **or** the base `@wix/interact` vanilla API. Prefer `/web` unless the user wants to control binding manually. If you can't tell, ask the user which framework the page uses. The full copy-paste setup for each entry point — including SSR, cleanup, and a verification snippet — is in **`references/integration-recipes.md`**. Read it now for the entry point you chose. Prefer two phases — **generation/build** (all CSS possible) and **runtime** (trigger wiring plus any runtime-dependent CSS): ```ts // Generation/build script (Node, SSG, agent scratch) import { Interact, generate } from '@wix/interact/web'; // or /react, or '@wix/interact' import { FadeIn } from '@wix/motion-presets'; Interact.registerEffects({ FadeIn }); // BEFORE generate() — see invariants const css = generate(config, true); // true=web, false=react/vanilla // Deliver css according to the canonical policy in integration-recipes.md ``` ```ts // Runtime (browser bundle / CDN module) import { Interact } from '@wix/interact/web'; const instance = Interact.create(config); // wire triggers ``` For CSS delivery and runtime-only configs, follow the canonical policy in `references/integration-recipes.md`. If the config carries a `$`-prefixed plugin field (e.g. `$splitText` for text effects), each phase gains one line — `plugins: { … }` in `generate()`'s options bag above, `Interact.use(…)` before `create()` below. Both, or neither; see `references/plugins.md`. (For CDN/quick-start, `import * as presets` + `registerEffects(presets)` is fine at generation time — selective imports just keep bundled apps lean. See `references/presets.md`.) Mark up target elements with a **key** that matches the config: ```html <!-- web --> <interact-element data-interact-key="hero"><section>…</section></interact-element> <!-- react --> <Interaction tagName="section" interactKey="hero">…</Interaction> <!-- vanilla --> <section data-interact-key="hero">…</section> ``` ```js // for vanilla - add the following import { add } from '@wix/interact'; const el = document.querySelector('[data-interact-key="hero"]'); add(el); ``` --- ### Step 3 — Add / edit interactions **Before designing the config, draw on the example library for inspiration and reference patterns:** 1. Read `examples/index.md` (this file is the table of contents — it lists every demo with its summary and tags). 2. Based on the user's request, identify 2–4 demos whose trigger type, layout, motion properties, or overall feel best match what's being built. Match on tags such as `viewProgress`, `pointerMove`, `sticky`, `stagger`, `3d`, or `clip-path`. 3. Read those demo files from `examples/examples/<category>/<name>.md`. Use the index rather than guessing paths; the categories are `gallery`, `carousel`, `image-background`, `text-animations`, `text-image`, and `ui-components`. 4. Treat each demo as a cohesive unit — the interact config, HTML structure, and CSS layout are designed to work together. Adapt all three parts to the user's context rather than lifting any single piece in isolation. This step is especially useful for: picking the right trigger/effect combination, handling complex layered compositions, and producing configs that feel polished rather than generic. --- This is where most work happens. An `InteractConfig` is: ```ts { interactions: [ // REQUIRED — each binds one source+trigger to effect(s) { key, trigger, params?, effects?, sequences?, conditions?, selector?, listContainer?, listItemSelector? } ], effects?: { [effectId]: Effect }, // reusable effects, referenced by effectId sequences?: { [sequenceId]: SequenceConfig }, conditions?:{ [conditionId]: Condition }, // media/selector gates } ``` To **add** an interaction: 1. Choose the **trigger** (see decision table below). 2. Choose the **effect**: prefer a `namedEffect` preset (browse `references/presets.md`); fall back to inline `keyframeEffect` for custom keyframes, or `customEffect` for non-CSS (SVG/canvas/text). 3. Set the **playback field** the trigger needs: `triggerType` for time effects on hover/click/viewEnter; `stateAction` for CSS-state (transition) effects; `rangeStart`/`rangeEnd` for `viewProgress`. Never set both `triggerType` and `stateAction` on one effect. 4. Bind it: give the target element the matching `key` in the markup. If the thing you're animating is a stack of layers that should move together (hero background + overlay + content, card image + text), key the **one container** that wraps them and put a single effect on it — don't repeat the effect on each layer (invariant 11). 5. **Text per char/word/line:** add `$splitText` on the interaction rather than hand-rolling spans, then stagger the generated `.split-c` / `.split-w` / `.split-l` / `.split-s` spans with `selector` on the **effect** inside a sequence. Read `references/plugins.md` for the wiring, and note that on character-sized targets a `keyframeEffect` usually beats a preset. To **edit** an existing config: read the current config first, find the interaction/effect by its `key`/`effectId`, and change _only_ what's asked. Preserve the rest (other interactions, ids, markup keys). After editing, re-run validation (Step 4) — a changed `namedEffect.type` or a new `viewProgress` effect can silently break if you skip it. If the effect catalog or trigger semantics are involved, open `references/presets.md` / `references/triggers.md`. For multi-target staggering (cards, lists, nav items), use **sequences**, not manual per-item delays — see `references/triggers.md` and the sequences section of `references/config-schema.md`. --- ### Step 4 — Validate the config No `InteractConfig` reaches `generate()` / `Interact.create()` unvalidated, and **no `@wix/interact-validate` reference ships in the code you deliver** — on any entry point, CDN included. How you run validation depends on whether you can construct the config statically: - **Static config** (you authored a literal you can read in full): validate **before emit** in a scratch script — never add validator imports to user files. See `references/validate.md` for per-environment run mechanics. Validate (and serialize) **before** calling `generate()`/`create()`, never after: both rewrite the config in place, leaving it invalid — see `config-schema.md`. - **Dynamic config** (built at runtime from data/props/fetch/loops — you cannot construct it by reading): temporarily inject `assertValidInteractConfig(config)` immediately before `generate()`/`create()`, run so that code path executes, fix every `severity: 'error'`, then **remove** the call, import, any `esm.sh` import, and any temp devDep. Prefer a dev-only validation script when the config builder module is importable in isolation (no removal step). Full loop in `references/validate.md`. For static site output, follow the canonical CSS generation policy in `references/integration-recipes.md`. - **Permanent guard (opt-in, separate):** leaving `assertValidInteractConfig` in shipped code as a devDependency CI gate is only when scaffolding a new project or the user explicitly asks — do not conflate with the temporary injection above. Fix every issue with `severity: 'error'` before proceeding; prefer fixing warnings too. `valid: false` blocks emit. **Before declaring done**, grep the files you're shipping: ```bash grep -REn 'interact-validate|validateInteractConfig|assertValidInteractConfig|InteractValidationError' <shipped files> # expect: no matches (unless the user asked for a permanent CI guard) ``` Then run the semantic checklist below. --- ## Trigger → use-case quick reference | Trigger | Use for | Effect type & key field | | :------------------- | :-------------------------------------------------------------- | :-------------------------------------------------------------- | | `viewEnter` | Entrance animations when an element scrolls into view | Time effect; `triggerType` (default `'once'`) | | `viewProgress` | Scroll-driven (parallax, reveal, scrub tied to scroll position) | Scrub effect; `rangeStart`/`rangeEnd` | | `hover` / `interest` | Hover effects (`interest` = hover+focus, accessible) | Time effect (`triggerType`) **or** State effect (`stateAction`) | | `click` / `activate` | Click toggles (`activate` = click+keyboard, accessible) | Time effect (`triggerType`) **or** State effect (`stateAction`) | | `pointerMove` | Cursor-following / tilt / parallax-on-mouse | Scrub effect; `params.hitArea`, `params.axis` |
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub