@wix/interact 2.1.4 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/react.js +1 -1
- package/dist/cjs/web.js +1 -1
- package/dist/cjs/web.js.map +1 -1
- package/dist/es/index.js +1 -1
- package/dist/es/react.js +2 -2
- package/dist/es/web.js +15 -15
- package/dist/es/web.js.map +1 -1
- package/dist/index-C0nIxDnf.js +18 -0
- package/dist/index-C0nIxDnf.js.map +1 -0
- package/dist/{index-DHqlFmW8.mjs → index-CJl_iRUI.mjs} +495 -487
- package/dist/index-CJl_iRUI.mjs.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types/core/Interact.d.ts +2 -2
- package/dist/types/core/Interact.d.ts.map +1 -1
- package/dist/types/core/InteractionController.d.ts +2 -2
- package/dist/types/core/InteractionController.d.ts.map +1 -1
- package/dist/types/core/add.d.ts.map +1 -1
- package/dist/types/core/css.d.ts.map +1 -1
- package/dist/types/handlers/effectHandlers.d.ts +4 -4
- package/dist/types/handlers/effectHandlers.d.ts.map +1 -1
- package/dist/types/handlers/eventTrigger.d.ts +2 -2
- package/dist/types/handlers/eventTrigger.d.ts.map +1 -1
- package/dist/types/handlers/index.d.ts.map +1 -1
- package/dist/types/handlers/viewEnter.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/react/index.d.ts +1 -1
- package/dist/types/react/index.d.ts.map +1 -1
- package/dist/types/types/config.d.ts +47 -0
- package/dist/types/types/config.d.ts.map +1 -0
- package/dist/types/types/controller.d.ts +34 -0
- package/dist/types/types/controller.d.ts.map +1 -0
- package/dist/types/types/effects.d.ts +75 -0
- package/dist/types/types/effects.d.ts.map +1 -0
- package/dist/types/types/external.d.ts +6 -0
- package/dist/types/types/external.d.ts.map +1 -0
- package/dist/types/types/global.d.ts +11 -0
- package/dist/types/types/global.d.ts.map +1 -0
- package/dist/types/types/handlers.d.ts +41 -0
- package/dist/types/types/handlers.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +8 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/dist/types/types/internal.d.ts +36 -0
- package/dist/types/types/internal.d.ts.map +1 -0
- package/dist/types/types/triggers.d.ts +28 -0
- package/dist/types/types/triggers.d.ts.map +1 -0
- package/dist/types/web/InteractElement.d.ts +2 -2
- package/dist/types/web/InteractElement.d.ts.map +1 -1
- package/dist/types/web/index.d.ts +1 -1
- package/dist/types/web/index.d.ts.map +1 -1
- package/docs/api/README.md +2 -3
- package/docs/api/functions.md +4 -4
- package/docs/api/interact-class.md +2 -3
- package/docs/api/interact-element.md +2 -2
- package/docs/api/interaction-controller.md +4 -4
- package/docs/api/types.md +38 -69
- package/docs/examples/README.md +1 -1
- package/docs/examples/click-interactions.md +0 -7
- package/docs/examples/entrance-animations.md +28 -27
- package/docs/examples/list-patterns.md +17 -16
- package/docs/guides/conditions-and-media-queries.md +2 -3
- package/docs/guides/configuration-structure.md +5 -7
- package/docs/guides/effects-and-animations.md +2 -4
- package/docs/guides/getting-started.md +0 -1
- package/docs/guides/lists-and-dynamic-content.md +10 -9
- package/docs/guides/sequences.md +3 -4
- package/docs/guides/state-management.md +0 -2
- package/docs/guides/understanding-triggers.md +9 -13
- package/package.json +2 -2
- package/rules/click.md +96 -560
- package/rules/full-lean.md +546 -359
- package/rules/hover.md +107 -530
- package/rules/integration.md +222 -261
- package/rules/pointermove.md +154 -1407
- package/rules/viewenter.md +128 -863
- package/rules/viewprogress.md +88 -322
- package/dist/index-DHqlFmW8.mjs.map +0 -1
- package/dist/index-DYEvpIGz.js +0 -18
- package/dist/index-DYEvpIGz.js.map +0 -1
- package/dist/types/types.d.ts +0 -256
- package/dist/types/types.d.ts.map +0 -1
- package/rules/MASTER-CLEANUP-PLAN.md +0 -286
- package/rules/scroll-list.md +0 -748
package/rules/integration.md
CHANGED
|
@@ -1,367 +1,328 @@
|
|
|
1
1
|
# @wix/interact Integration Rules
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Rules for integrating `@wix/interact` into a webpage — binding animations and effects to user-driven triggers via declarative configuration.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Table of Contents
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- [Entry Points](#entry-points)
|
|
8
|
+
- [Web (Custom Elements)](#web-custom-elements)
|
|
9
|
+
- [React](#react)
|
|
10
|
+
- [Vanilla JS](#vanilla-js)
|
|
11
|
+
- [Named Effects & registerEffects](#named-effects--registereffects)
|
|
12
|
+
- [Configuration Schema](#configuration-schema)
|
|
13
|
+
- [InteractConfig](#interactconfig)
|
|
14
|
+
- [Interaction](#interaction)
|
|
15
|
+
- [Element Selection](#element-selection)
|
|
16
|
+
- [Triggers](#triggers)
|
|
17
|
+
- [Sequences](#sequences)
|
|
18
|
+
- [Critical CSS (FOUC Prevention)](#critical-css-fouc-prevention)
|
|
19
|
+
- [Static API](#static-api)
|
|
8
20
|
|
|
9
|
-
|
|
21
|
+
---
|
|
10
22
|
|
|
11
|
-
|
|
23
|
+
## Entry Points
|
|
12
24
|
|
|
13
|
-
|
|
25
|
+
Install with your package manager:
|
|
14
26
|
|
|
15
|
-
|
|
27
|
+
```bash
|
|
28
|
+
npm install @wix/interact @wix/motion-presets
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Web (Custom Elements)
|
|
16
32
|
|
|
17
33
|
```typescript
|
|
18
34
|
import { Interact } from '@wix/interact/web';
|
|
19
35
|
|
|
20
|
-
|
|
21
|
-
const config = {
|
|
22
|
-
interactions: [
|
|
23
|
-
// ...
|
|
24
|
-
],
|
|
25
|
-
effects: {
|
|
26
|
-
// ...
|
|
27
|
-
},
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
// Initialize the interact instance
|
|
31
|
-
const interact = Interact.create(config);
|
|
36
|
+
Interact.create(config);
|
|
32
37
|
```
|
|
33
38
|
|
|
34
|
-
|
|
39
|
+
The `config` object contains `interactions` (trigger-effect bindings), and optionally `effects`, `sequences`, and `conditions`. See [Configuration Schema](#configuration-schema) for full details.
|
|
35
40
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
- MUST have a `data-interact-key` attribute with a value that is unique within the scope.
|
|
39
|
-
- MUST contain at least one child element.
|
|
40
|
-
|
|
41
|
-
**Usage:**
|
|
41
|
+
Wrap target elements with `<interact-element>`:
|
|
42
42
|
|
|
43
43
|
```html
|
|
44
|
-
|
|
45
|
-
<
|
|
46
|
-
<div>This will fade in when it enters the viewport!</div>
|
|
44
|
+
<interact-element data-interact-key="hero">
|
|
45
|
+
<section class="hero">...</section>
|
|
47
46
|
</interact-element>
|
|
48
47
|
```
|
|
49
48
|
|
|
50
|
-
|
|
49
|
+
**Rules:**
|
|
50
|
+
|
|
51
|
+
- MUST set `data-interact-key` to a unique string within the page.
|
|
52
|
+
- MUST contain at least one child element (the library targets `.firstElementChild` by default).
|
|
51
53
|
|
|
52
|
-
|
|
54
|
+
### React
|
|
53
55
|
|
|
54
|
-
|
|
56
|
+
- Wrap the `Interact.create()` call in a `useEffect` hook to prevent it from running on server-side.
|
|
57
|
+
- Store the returned instance, and call its `.destroy()` method on the effect's cleanup function.
|
|
55
58
|
|
|
56
59
|
```typescript
|
|
60
|
+
import { useEffect } from 'react';
|
|
57
61
|
import { Interact } from '@wix/interact/react';
|
|
58
62
|
|
|
59
|
-
|
|
60
|
-
const
|
|
61
|
-
interactions: [
|
|
62
|
-
// ...
|
|
63
|
-
],
|
|
64
|
-
effects: {
|
|
65
|
-
// ...
|
|
66
|
-
},
|
|
67
|
-
};
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
const instance = Interact.create(config);
|
|
68
65
|
|
|
69
|
-
|
|
70
|
-
|
|
66
|
+
return () => {
|
|
67
|
+
instance.destroy();
|
|
68
|
+
};
|
|
69
|
+
}, [config]);
|
|
71
70
|
```
|
|
72
71
|
|
|
73
|
-
|
|
72
|
+
Replace target elements with `<Interaction>`:
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
import { Interaction } from '@wix/interact/react';
|
|
76
|
+
|
|
77
|
+
<Interaction tagName="div" interactKey="hero" className="hero">
|
|
78
|
+
...
|
|
79
|
+
</Interaction>;
|
|
80
|
+
```
|
|
74
81
|
|
|
75
82
|
**Rules:**
|
|
76
83
|
|
|
77
|
-
- MUST
|
|
78
|
-
- MUST set
|
|
79
|
-
- MUST set the `interactKey` prop to a unique string within the scope.
|
|
84
|
+
- MUST set `tagName` to a valid HTML tag string for the element being replaced.
|
|
85
|
+
- MUST set `interactKey` to a unique string within the page.
|
|
80
86
|
|
|
81
|
-
|
|
87
|
+
### Vanilla JS
|
|
82
88
|
|
|
83
|
-
```
|
|
84
|
-
import {
|
|
89
|
+
```typescript
|
|
90
|
+
import { Interact } from '@wix/interact';
|
|
85
91
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
<Interaction tagName="div" interactKey="my-element" className="animated-content">
|
|
89
|
-
Hello, animated world!
|
|
90
|
-
</Interaction>
|
|
91
|
-
);
|
|
92
|
-
}
|
|
92
|
+
const interact = Interact.create(config);
|
|
93
|
+
interact.add(element, 'hero');
|
|
93
94
|
```
|
|
94
95
|
|
|
95
|
-
|
|
96
|
+
**Rules:**
|
|
97
|
+
|
|
98
|
+
- Call `add(element, key)` after elements exist in the DOM.
|
|
99
|
+
- Call `remove(key)` to unregister all interactions for a key.
|
|
100
|
+
|
|
101
|
+
---
|
|
96
102
|
|
|
97
|
-
|
|
103
|
+
## Named Effects & registerEffects
|
|
104
|
+
|
|
105
|
+
To use `namedEffect` presets from `@wix/motion-presets`, register them before calling `Interact.create`. For full effect type syntax (`keyframeEffect`, `customEffect`, `StateEffect`, `ScrubEffect`), see `full-lean.md`.
|
|
106
|
+
|
|
107
|
+
**Install:**
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
> npm install @wix/motion-presets
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Import and register:**
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
import { Interact } from '@wix/interact/web';
|
|
117
|
+
import * as presets from '@wix/motion-presets';
|
|
118
|
+
|
|
119
|
+
Interact.registerEffects(presets);
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Or register selectively:
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
import { FadeIn, ParallaxScroll } from '@wix/motion-presets';
|
|
126
|
+
Interact.registerEffects({ FadeIn, ParallaxScroll });
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Then use in effects:
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
{ namedEffect: { type: 'FadeIn' }, duration: 800, easing: 'ease-out' }
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
For full effect type syntax (`keyframeEffect`, `namedEffect`, `customEffect`, `transition`/`transitionProperties`), see [full-lean.md](./full-lean.md) and the trigger-specific rule files.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Configuration Schema
|
|
140
|
+
|
|
141
|
+
### InteractConfig
|
|
98
142
|
|
|
99
143
|
```typescript
|
|
100
144
|
type InteractConfig = {
|
|
101
|
-
interactions: Interaction[];
|
|
102
|
-
effects?: Record<string, Effect>;
|
|
103
|
-
sequences?: Record<string, SequenceConfig>;
|
|
104
|
-
conditions?: Record<string, Condition>;
|
|
145
|
+
interactions: Interaction[];
|
|
146
|
+
effects?: Record<string, Effect>;
|
|
147
|
+
sequences?: Record<string, SequenceConfig>;
|
|
148
|
+
conditions?: Record<string, Condition>;
|
|
105
149
|
};
|
|
106
150
|
```
|
|
107
151
|
|
|
108
|
-
|
|
152
|
+
| Field | Description |
|
|
153
|
+
| :------------- | :---------------------------------------------------------------------- |
|
|
154
|
+
| `interactions` | Required. Array of interaction definitions binding triggers to effects. |
|
|
155
|
+
| `effects?` | Reusable effects referenced by `effectId` from interactions. |
|
|
156
|
+
| `sequences?` | Reusable sequence definitions, referenced by `sequenceId`. |
|
|
157
|
+
| `conditions?` | Named conditions (media/container/selector queries), referenced by ID. |
|
|
158
|
+
|
|
159
|
+
Each call to `Interact.create(config)` creates a new `Interact` instance. A single config can define multiple interactions.
|
|
160
|
+
|
|
161
|
+
### Interaction
|
|
109
162
|
|
|
110
163
|
```typescript
|
|
111
164
|
{
|
|
112
|
-
key:
|
|
113
|
-
trigger:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
conditions?: [
|
|
119
|
-
effects?: [
|
|
120
|
-
sequences?: [
|
|
165
|
+
key: string; // REQUIRED — matches data-interact-key / interactKey
|
|
166
|
+
trigger: TriggerType; // REQUIRED — trigger type
|
|
167
|
+
params?: TriggerParams; // trigger-specific parameters
|
|
168
|
+
selector?: string; // CSS selector to refine target within the element
|
|
169
|
+
listContainer?: string; // CSS selector for a list container
|
|
170
|
+
listItemSelector?: string; // optional — CSS selector to filter which children of listContainer are selected
|
|
171
|
+
conditions?: string[]; // array of condition IDs; all must pass
|
|
172
|
+
effects?: Effect[]; // effects to apply
|
|
173
|
+
sequences?: SequenceConfig[]; // sequences to apply
|
|
121
174
|
}
|
|
122
175
|
```
|
|
123
176
|
|
|
124
|
-
|
|
177
|
+
At least one of `effects` or `sequences` MUST be provided.
|
|
125
178
|
|
|
126
|
-
|
|
127
|
-
2. **`listContainer` only**: Targets immediate children of the container as list items.
|
|
128
|
-
3. **`selector` only**: Matches all elements within the root element (using `querySelectorAll`).
|
|
129
|
-
4. **Fallback**: If none are provided, targets the **first child** of `<interact-element>` in `web` or the root element in `react`.
|
|
179
|
+
**Multiple effects per interaction:** A single interaction can contain multiple effects in its `effects` array. All effects share the same trigger — they fire together when the trigger activates. Use this to animate different targets from the same trigger event instead of duplicating interactions.
|
|
130
180
|
|
|
131
|
-
|
|
181
|
+
### Element Selection
|
|
132
182
|
|
|
133
|
-
|
|
183
|
+
**Most common**: Omit `selector`/`listContainer`/`listItemSelector` entirely — the element with the matching key is used as both source and target. Use `selector` to target a child element within the keyed element. Use `listContainer` for staggered sequences across list items.
|
|
134
184
|
|
|
135
|
-
|
|
185
|
+
`listItemSelector` is **optional** — only use it when you need to **filter** which children of `listContainer` participate (e.g. select only `.active` items). When omitted, all immediate children of the `listContainer` are selected.
|
|
136
186
|
|
|
137
|
-
|
|
187
|
+
#### Source element resolution (Interaction level)
|
|
138
188
|
|
|
139
|
-
|
|
140
|
-
- MUST set `data-interact-initial="true"` on the `<interact-element>` whose first child should be hidden until the animation plays.
|
|
141
|
-
- Only valid when: trigger is `viewEnter` + `params.type` is `'once'` + source element and target element are the same.
|
|
142
|
-
- Do NOT use for `hover`, `click`, or `viewEnter` with `repeat`/`alternate`/`state` types.
|
|
189
|
+
The source element is what the trigger attaches to. Resolved in priority order:
|
|
143
190
|
|
|
144
|
-
|
|
191
|
+
1. **`listContainer` + `listItemSelector`** — matches only the elements matching `listItemSelector` within the the `listContainer`.
|
|
192
|
+
2. **`listContainer` only** — trigger attaches to all immediate children of the container (common case).
|
|
193
|
+
3. **`listContainer` + `selector`** — matches via `querySelector` within each immediate child of the container.
|
|
194
|
+
4. **`selector` only** — matches via `querySelectorAll` within the root element.
|
|
195
|
+
5. **Fallback** — first child of `<interact-element>` (web) or the root element (react/vanilla).
|
|
145
196
|
|
|
146
|
-
|
|
147
|
-
import { generate } from '@wix/interact/web';
|
|
197
|
+
#### Target element resolution (Effect level)
|
|
148
198
|
|
|
149
|
-
|
|
150
|
-
/*...*/
|
|
151
|
-
};
|
|
199
|
+
The target element is what the effect animates. Resolved in priority order:
|
|
152
200
|
|
|
153
|
-
|
|
154
|
-
|
|
201
|
+
1. **`Effect.key`** — the root with matching `data-interact-key`.
|
|
202
|
+
2. **Registry Effect's `key`** — if the effect is an `EffectRef`, the `key` from the referenced registry entry is used.
|
|
203
|
+
3. **Fallback to `Interaction.key`** — the source element acts as the target's root.
|
|
204
|
+
4. After resolving the target's root, `selector`, `listContainer`, and `listItemSelector` on the effect further refine which child elements within that target are animated (same priority order as source resolution).
|
|
155
205
|
|
|
156
|
-
|
|
157
|
-
const html = `
|
|
158
|
-
<!DOCTYPE html>
|
|
159
|
-
<html>
|
|
160
|
-
<head>
|
|
161
|
-
<style>${css}</style>
|
|
162
|
-
</head>
|
|
163
|
-
<body>
|
|
164
|
-
<interact-element data-interact-key="hero" data-interact-initial="true">
|
|
165
|
-
<section class="hero">
|
|
166
|
-
...
|
|
167
|
-
</section>
|
|
168
|
-
</interact-element>
|
|
169
|
-
<script type="module" src="./main.js"></script>
|
|
170
|
-
</body>
|
|
171
|
-
</html>
|
|
172
|
-
`;
|
|
173
|
-
```
|
|
206
|
+
---
|
|
174
207
|
|
|
175
|
-
##
|
|
208
|
+
## Triggers
|
|
176
209
|
|
|
177
|
-
| Trigger | Description
|
|
178
|
-
| :------------- |
|
|
179
|
-
| `hover` | Mouse enter/leave
|
|
180
|
-
| `click` | Mouse click
|
|
181
|
-
| `
|
|
182
|
-
| `
|
|
183
|
-
| `viewEnter` | Element enters viewport
|
|
184
|
-
| `viewProgress` | Scroll-driven
|
|
185
|
-
| `pointerMove` | Mouse movement
|
|
186
|
-
| `animationEnd` |
|
|
210
|
+
| Trigger | Description | Trigger `params` | Rules |
|
|
211
|
+
| :------------- | :------------------------------------- | :-------------------------------------------------------------------------------------- | :----------------------------------- |
|
|
212
|
+
| `hover` | Mouse enter/leave | No params. Set `triggerType` on TimeEffect or `stateAction` on StateEffect. | [hover.md](./hover.md) |
|
|
213
|
+
| `click` | Mouse click | Same as `hover` | [click.md](./click.md) |
|
|
214
|
+
| `interest` | Accessible hover (hover + focus) | Same as `hover` | [hover.md](./hover.md) |
|
|
215
|
+
| `activate` | Accessible click (click + Enter/Space) | Same as `click` | [click.md](./click.md) |
|
|
216
|
+
| `viewEnter` | Element enters viewport | `threshold?`; `inset?`. Set `triggerType` on TimeEffect or sequence config. | [viewenter.md](./viewenter.md) |
|
|
217
|
+
| `viewProgress` | Scroll-driven (ViewTimeline) | No trigger params. Configure `rangeStart`/`rangeEnd` on the **effect**, not on `params` | [viewprogress.md](./viewprogress.md) |
|
|
218
|
+
| `pointerMove` | Mouse movement | `hitArea?`: `'self'` \| `'root'`; `axis?`: `'x'` \| `'y'` | [pointermove.md](./pointermove.md) |
|
|
219
|
+
| `animationEnd` | Chain after another effect | `effectId`: ID of the preceding effect | — |
|
|
187
220
|
|
|
188
|
-
|
|
221
|
+
For `hover`/`click` (and their accessible variants `interest`/`activate`): set `triggerType` on the effect for keyframe/named/custom effects (TimeEffect), or `stateAction` on the effect for transitions (StateEffect). Do not mix both on the same effect.
|
|
189
222
|
|
|
190
|
-
|
|
223
|
+
---
|
|
191
224
|
|
|
192
|
-
|
|
225
|
+
## Sequences
|
|
226
|
+
|
|
227
|
+
Sequences coordinate multiple effects with staggered timing.
|
|
193
228
|
|
|
194
229
|
```typescript
|
|
195
230
|
{
|
|
196
|
-
offset:
|
|
197
|
-
offsetEasing:
|
|
198
|
-
delay:
|
|
199
|
-
effects: [
|
|
200
|
-
|
|
231
|
+
offset: number, // ms between consecutive items
|
|
232
|
+
offsetEasing: string, // Any valid easing string for stagger distribution curve
|
|
233
|
+
delay: number, // ms base delay before the sequence starts
|
|
234
|
+
effects: [
|
|
235
|
+
/* ... effect definitions */,
|
|
201
236
|
],
|
|
202
237
|
}
|
|
203
238
|
```
|
|
204
239
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
Reusable sequences can be defined in `InteractConfig.sequences` and referenced by `sequenceId`:
|
|
240
|
+
Define reusable sequences in `InteractConfig.sequences` and reference by `sequenceId`:
|
|
208
241
|
|
|
209
242
|
```typescript
|
|
210
243
|
{
|
|
211
244
|
sequences: {
|
|
212
|
-
'stagger-
|
|
245
|
+
'stagger-fade': {
|
|
246
|
+
/* ... sequence definition */
|
|
247
|
+
},
|
|
213
248
|
},
|
|
214
249
|
interactions: [
|
|
215
|
-
{
|
|
250
|
+
{
|
|
251
|
+
key: `'[SOURCE_KEY]'`,
|
|
252
|
+
trigger: `'[TRIGGER]'`,
|
|
253
|
+
params: `[TRIGGER_PARAMS]`,
|
|
254
|
+
sequences: [{ sequenceId: 'stagger-fade' }],
|
|
255
|
+
},
|
|
216
256
|
],
|
|
217
257
|
}
|
|
218
258
|
```
|
|
219
259
|
|
|
220
|
-
|
|
260
|
+
---
|
|
221
261
|
|
|
222
|
-
|
|
262
|
+
## Critical CSS (FOUC Prevention)
|
|
223
263
|
|
|
224
|
-
**
|
|
264
|
+
**Problem:** Elements with entrance animations (e.g. `FadeIn` on `viewEnter`) are initially visible in their final state. Before the animation framework applies the starting keyframe, the content flashes visibly — a flash of un-animated content (FOUC).
|
|
225
265
|
|
|
226
|
-
|
|
227
|
-
> npm install @wix/motion-presets
|
|
228
|
-
```
|
|
266
|
+
**Solution:** Two things are required — both MUST be present:
|
|
229
267
|
|
|
230
|
-
**
|
|
268
|
+
1. **Generate critical CSS** with `generate(config)` — produces CSS that hides entrance-animated elements until the animation plays.
|
|
269
|
+
2. **Mark elements with `initial`** — `data-interact-initial="true"` on `<interact-element>`, or `initial={true}` on `<Interaction>` in React.
|
|
231
270
|
|
|
232
|
-
|
|
233
|
-
import { Interact } from '@wix/interact/web';
|
|
234
|
-
import * as presets from '@wix/motion-presets';
|
|
271
|
+
Using only one of these has no effect — both are required.
|
|
235
272
|
|
|
236
|
-
|
|
237
|
-
```
|
|
273
|
+
See [viewenter.md](./viewenter.md) for full details.
|
|
238
274
|
|
|
239
|
-
**
|
|
275
|
+
**Rules:**
|
|
240
276
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
import { FadeIn, ParallaxScroll } from '@wix/motion-presets';
|
|
277
|
+
- `generate()` should be called server-side or at build time. Can also be called on the client if page content is initially hidden (e.g. behind a loader).
|
|
278
|
+
- Only valid for `viewEnter` + `triggerType: 'once'` (or no `triggerType`, which defaults to `'once'`) where source and target are the same element.
|
|
244
279
|
|
|
245
|
-
|
|
280
|
+
```javascript
|
|
281
|
+
import { generate } from '@wix/interact/web';
|
|
282
|
+
const css = generate(config);
|
|
246
283
|
```
|
|
247
284
|
|
|
248
|
-
|
|
249
|
-
{
|
|
250
|
-
namedEffect: { type: 'FadeIn' },
|
|
251
|
-
duration: 800,
|
|
252
|
-
easing: 'ease-out'
|
|
253
|
-
}
|
|
254
|
-
```
|
|
285
|
+
**Append to `<head>` or beginning of `<body>`:**
|
|
255
286
|
|
|
256
|
-
|
|
287
|
+
```html
|
|
288
|
+
<style>
|
|
289
|
+
${css}
|
|
290
|
+
</style>
|
|
291
|
+
```
|
|
257
292
|
|
|
258
|
-
|
|
293
|
+
**Web:**
|
|
259
294
|
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
transitionProperties: [
|
|
265
|
-
{
|
|
266
|
-
name: 'transform',
|
|
267
|
-
value: 'scale(1.1)',
|
|
268
|
-
duration: 300,
|
|
269
|
-
delay: 100,
|
|
270
|
-
easing: 'cubic-bezier(0.34, 1.56, 0.64, 1)',
|
|
271
|
-
},
|
|
272
|
-
],
|
|
273
|
-
},
|
|
274
|
-
},
|
|
275
|
-
interactions: [
|
|
276
|
-
{
|
|
277
|
-
key: 'btn',
|
|
278
|
-
trigger: 'hover',
|
|
279
|
-
effects: [
|
|
280
|
-
{
|
|
281
|
-
effectId: 'scaleUp',
|
|
282
|
-
},
|
|
283
|
-
],
|
|
284
|
-
},
|
|
285
|
-
],
|
|
286
|
-
};
|
|
295
|
+
```html
|
|
296
|
+
<interact-element data-interact-key="hero" data-interact-initial="true">
|
|
297
|
+
<section id="hero">...</section>
|
|
298
|
+
</interact-element>
|
|
287
299
|
```
|
|
288
300
|
|
|
289
|
-
|
|
301
|
+
**React:**
|
|
290
302
|
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
key: 'hero',
|
|
296
|
-
trigger: 'viewEnter',
|
|
297
|
-
params: { type: 'once', threshold: 0.2 },
|
|
298
|
-
effects: [
|
|
299
|
-
{
|
|
300
|
-
namedEffect: { type: 'FadeIn' },
|
|
301
|
-
duration: 800,
|
|
302
|
-
},
|
|
303
|
-
],
|
|
304
|
-
},
|
|
305
|
-
],
|
|
306
|
-
};
|
|
303
|
+
```tsx
|
|
304
|
+
<Interaction tagName="section" interactKey="hero" initial={true} className="hero">
|
|
305
|
+
...
|
|
306
|
+
</Interaction>
|
|
307
307
|
```
|
|
308
308
|
|
|
309
|
-
|
|
309
|
+
**Vanilla:**
|
|
310
310
|
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
interactions: [
|
|
314
|
-
{
|
|
315
|
-
key: 'card-grid',
|
|
316
|
-
trigger: 'viewEnter',
|
|
317
|
-
params: { type: 'once', threshold: 0.3 },
|
|
318
|
-
sequences: [
|
|
319
|
-
{
|
|
320
|
-
offset: 100,
|
|
321
|
-
offsetEasing: 'quadIn',
|
|
322
|
-
effects: [{ effectId: 'card-entrance', listContainer: '.card-grid' }],
|
|
323
|
-
},
|
|
324
|
-
],
|
|
325
|
-
},
|
|
326
|
-
],
|
|
327
|
-
effects: {
|
|
328
|
-
'card-entrance': {
|
|
329
|
-
duration: 500,
|
|
330
|
-
easing: 'ease-out',
|
|
331
|
-
keyframeEffect: {
|
|
332
|
-
name: 'card-fade-up',
|
|
333
|
-
keyframes: [
|
|
334
|
-
{ transform: 'translateY(40px)', opacity: 0 },
|
|
335
|
-
{ transform: 'translateY(0)', opacity: 1 },
|
|
336
|
-
],
|
|
337
|
-
},
|
|
338
|
-
fill: 'both',
|
|
339
|
-
},
|
|
340
|
-
},
|
|
341
|
-
};
|
|
311
|
+
```html
|
|
312
|
+
<section data-interact-key="hero" data-interact-initial="true" class="hero">...</section>
|
|
342
313
|
```
|
|
343
314
|
|
|
344
|
-
|
|
315
|
+
---
|
|
345
316
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
name: 'slide',
|
|
359
|
-
keyframes: [{ transform: 'translateX(-100%)' }, { transform: 'translateX(0)' }],
|
|
360
|
-
},
|
|
361
|
-
duration: 300,
|
|
362
|
-
},
|
|
363
|
-
],
|
|
364
|
-
},
|
|
365
|
-
],
|
|
366
|
-
};
|
|
367
|
-
```
|
|
317
|
+
## Static API
|
|
318
|
+
|
|
319
|
+
Each `Interact.create(config)` call returns an instance. Keep a reference if you need to add/remove elements dynamically (vanilla JS) or to destroy a specific instance. Call `Interact.destroy()` to tear down all instances at once (e.g. on page navigation).
|
|
320
|
+
|
|
321
|
+
| Method / Property | Description |
|
|
322
|
+
| :---------------------------------- | :------------------------------------------------------------------------------------------- |
|
|
323
|
+
| `Interact.create(config)` | Initialize with a config. Returns the instance. Multiple configs create separate instances. |
|
|
324
|
+
| `Interact.registerEffects(presets)` | Register named effect presets before `create`. Required for `namedEffect` usage. |
|
|
325
|
+
| `Interact.destroy()` | Tear down all instances. |
|
|
326
|
+
| `Interact.forceReducedMotion` | `boolean` — force reduced-motion behavior regardless of OS setting. Default: `false`. |
|
|
327
|
+
| `Interact.allowA11yTriggers` | `boolean` — enable accessibility triggers (`interest`, `activate`). Default: `false`. |
|
|
328
|
+
| `Interact.setup(options)` | Configure global defaults for scroll/pointer/viewEnter trigger params. Call before `create`. |
|