@wix/interact 2.1.4 → 2.2.0
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-DHqlFmW8.mjs → index-ByLXasWO.mjs} +491 -485
- package/dist/index-ByLXasWO.mjs.map +1 -0
- package/dist/index-CzRuJxn8.js +18 -0
- package/dist/index-CzRuJxn8.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types/core/Interact.d.ts +2 -2
- 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 +536 -360
- package/rules/hover.md +107 -530
- package/rules/integration.md +212 -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,318 @@
|
|
|
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:**
|
|
51
50
|
|
|
52
|
-
|
|
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).
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
### React
|
|
55
55
|
|
|
56
56
|
```typescript
|
|
57
57
|
import { Interact } from '@wix/interact/react';
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
interactions: [
|
|
62
|
-
// ...
|
|
63
|
-
],
|
|
64
|
-
effects: {
|
|
65
|
-
// ...
|
|
66
|
-
},
|
|
67
|
-
};
|
|
59
|
+
Interact.create(config);
|
|
60
|
+
```
|
|
68
61
|
|
|
69
|
-
|
|
70
|
-
|
|
62
|
+
Replace target elements with `<Interaction>`:
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
import { Interaction } from '@wix/interact/react';
|
|
66
|
+
|
|
67
|
+
<Interaction tagName="div" interactKey="hero" className="hero">
|
|
68
|
+
...
|
|
69
|
+
</Interaction>;
|
|
71
70
|
```
|
|
72
71
|
|
|
73
|
-
|
|
72
|
+
**Rules:**
|
|
73
|
+
|
|
74
|
+
- MUST set `tagName` to a valid HTML tag string for the element being replaced.
|
|
75
|
+
- MUST set `interactKey` to a unique string within the page.
|
|
76
|
+
|
|
77
|
+
### Vanilla JS
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
import { Interact } from '@wix/interact';
|
|
81
|
+
|
|
82
|
+
const interact = Interact.create(config);
|
|
83
|
+
interact.add(element, 'hero');
|
|
84
|
+
```
|
|
74
85
|
|
|
75
86
|
**Rules:**
|
|
76
87
|
|
|
77
|
-
-
|
|
78
|
-
-
|
|
79
|
-
- MUST set the `interactKey` prop to a unique string within the scope.
|
|
88
|
+
- Call `add(element, key)` after elements exist in the DOM.
|
|
89
|
+
- Call `remove(key)` to unregister all interactions for a key.
|
|
80
90
|
|
|
81
|
-
|
|
91
|
+
---
|
|
82
92
|
|
|
83
|
-
|
|
84
|
-
import { Interaction } from '@wix/interact/react';
|
|
93
|
+
## Named Effects & registerEffects
|
|
85
94
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
95
|
+
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`.
|
|
96
|
+
|
|
97
|
+
**Install:**
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
> npm install @wix/motion-presets
|
|
93
101
|
```
|
|
94
102
|
|
|
95
|
-
|
|
103
|
+
**Import and register:**
|
|
96
104
|
|
|
97
|
-
|
|
105
|
+
```typescript
|
|
106
|
+
import { Interact } from '@wix/interact/web';
|
|
107
|
+
import * as presets from '@wix/motion-presets';
|
|
108
|
+
|
|
109
|
+
Interact.registerEffects(presets);
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Or register selectively:
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
import { FadeIn, ParallaxScroll } from '@wix/motion-presets';
|
|
116
|
+
Interact.registerEffects({ FadeIn, ParallaxScroll });
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Then use in effects:
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
{ namedEffect: { type: 'FadeIn' }, duration: 800, easing: 'ease-out' }
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
For full effect type syntax (`keyframeEffect`, `namedEffect`, `customEffect`, `transition`/`transitionProperties`), see [full-lean.md](./full-lean.md) and the trigger-specific rule files.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Configuration Schema
|
|
130
|
+
|
|
131
|
+
### InteractConfig
|
|
98
132
|
|
|
99
133
|
```typescript
|
|
100
134
|
type InteractConfig = {
|
|
101
|
-
interactions: Interaction[];
|
|
102
|
-
effects?: Record<string, Effect>;
|
|
103
|
-
sequences?: Record<string, SequenceConfig>;
|
|
104
|
-
conditions?: Record<string, Condition>;
|
|
135
|
+
interactions: Interaction[];
|
|
136
|
+
effects?: Record<string, Effect>;
|
|
137
|
+
sequences?: Record<string, SequenceConfig>;
|
|
138
|
+
conditions?: Record<string, Condition>;
|
|
105
139
|
};
|
|
106
140
|
```
|
|
107
141
|
|
|
108
|
-
|
|
142
|
+
| Field | Description |
|
|
143
|
+
| :------------- | :---------------------------------------------------------------------- |
|
|
144
|
+
| `interactions` | Required. Array of interaction definitions binding triggers to effects. |
|
|
145
|
+
| `effects?` | Reusable effects referenced by `effectId` from interactions. |
|
|
146
|
+
| `sequences?` | Reusable sequence definitions, referenced by `sequenceId`. |
|
|
147
|
+
| `conditions?` | Named conditions (media/container/selector queries), referenced by ID. |
|
|
148
|
+
|
|
149
|
+
Each call to `Interact.create(config)` creates a new `Interact` instance. A single config can define multiple interactions.
|
|
150
|
+
|
|
151
|
+
### Interaction
|
|
109
152
|
|
|
110
153
|
```typescript
|
|
111
154
|
{
|
|
112
|
-
key:
|
|
113
|
-
trigger:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
conditions?: [
|
|
119
|
-
effects?: [
|
|
120
|
-
sequences?: [
|
|
155
|
+
key: string; // REQUIRED — matches data-interact-key / interactKey
|
|
156
|
+
trigger: TriggerType; // REQUIRED — trigger type
|
|
157
|
+
params?: TriggerParams; // trigger-specific parameters
|
|
158
|
+
selector?: string; // CSS selector to refine target within the element
|
|
159
|
+
listContainer?: string; // CSS selector for a list container
|
|
160
|
+
listItemSelector?: string; // optional — CSS selector to filter which children of listContainer are selected
|
|
161
|
+
conditions?: string[]; // array of condition IDs; all must pass
|
|
162
|
+
effects?: Effect[]; // effects to apply
|
|
163
|
+
sequences?: SequenceConfig[]; // sequences to apply
|
|
121
164
|
}
|
|
122
165
|
```
|
|
123
166
|
|
|
124
|
-
|
|
167
|
+
At least one of `effects` or `sequences` MUST be provided.
|
|
125
168
|
|
|
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`.
|
|
169
|
+
**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
170
|
|
|
131
|
-
|
|
171
|
+
### Element Selection
|
|
132
172
|
|
|
133
|
-
|
|
173
|
+
**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
174
|
|
|
135
|
-
|
|
175
|
+
`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
176
|
|
|
137
|
-
|
|
177
|
+
#### Source element resolution (Interaction level)
|
|
138
178
|
|
|
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.
|
|
179
|
+
The source element is what the trigger attaches to. Resolved in priority order:
|
|
143
180
|
|
|
144
|
-
|
|
181
|
+
1. **`listContainer` + `listItemSelector`** — matches only the elements matching `listItemSelector` within the the `listContainer`.
|
|
182
|
+
2. **`listContainer` only** — trigger attaches to all immediate children of the container (common case).
|
|
183
|
+
3. **`listContainer` + `selector`** — matches via `querySelector` within each immediate child of the container.
|
|
184
|
+
4. **`selector` only** — matches via `querySelectorAll` within the root element.
|
|
185
|
+
5. **Fallback** — first child of `<interact-element>` (web) or the root element (react/vanilla).
|
|
145
186
|
|
|
146
|
-
|
|
147
|
-
import { generate } from '@wix/interact/web';
|
|
187
|
+
#### Target element resolution (Effect level)
|
|
148
188
|
|
|
149
|
-
|
|
150
|
-
/*...*/
|
|
151
|
-
};
|
|
189
|
+
The target element is what the effect animates. Resolved in priority order:
|
|
152
190
|
|
|
153
|
-
|
|
154
|
-
|
|
191
|
+
1. **`Effect.key`** — the root with matching `data-interact-key`.
|
|
192
|
+
2. **Registry Effect's `key`** — if the effect is an `EffectRef`, the `key` from the referenced registry entry is used.
|
|
193
|
+
3. **Fallback to `Interaction.key`** — the source element acts as the target's root.
|
|
194
|
+
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
195
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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
|
-
```
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Triggers
|
|
174
199
|
|
|
175
|
-
|
|
200
|
+
| Trigger | Description | Trigger `params` | Rules |
|
|
201
|
+
| :------------- | :------------------------------------- | :-------------------------------------------------------------------------------------- | :----------------------------------- |
|
|
202
|
+
| `hover` | Mouse enter/leave | No params. Set `triggerType` on TimeEffect or `stateAction` on StateEffect. | [hover.md](./hover.md) |
|
|
203
|
+
| `click` | Mouse click | Same as `hover` | [click.md](./click.md) |
|
|
204
|
+
| `interest` | Accessible hover (hover + focus) | Same as `hover` | [hover.md](./hover.md) |
|
|
205
|
+
| `activate` | Accessible click (click + Enter/Space) | Same as `click` | [click.md](./click.md) |
|
|
206
|
+
| `viewEnter` | Element enters viewport | `threshold?`; `inset?`. Set `triggerType` on TimeEffect or sequence config. | [viewenter.md](./viewenter.md) |
|
|
207
|
+
| `viewProgress` | Scroll-driven (ViewTimeline) | No trigger params. Configure `rangeStart`/`rangeEnd` on the **effect**, not on `params` | [viewprogress.md](./viewprogress.md) |
|
|
208
|
+
| `pointerMove` | Mouse movement | `hitArea?`: `'self'` \| `'root'`; `axis?`: `'x'` \| `'y'` | [pointermove.md](./pointermove.md) |
|
|
209
|
+
| `animationEnd` | Chain after another effect | `effectId`: ID of the preceding effect | — |
|
|
176
210
|
|
|
177
|
-
|
|
178
|
-
| :------------- | :---------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------ | :------------------ |
|
|
179
|
-
| `hover` | Mouse enter/leave | `type`: 'once', 'alternate', 'repeat', 'state' for animations, or `method`: 'add', 'remove', 'toggle', 'clear' for states | `./hover.md` |
|
|
180
|
-
| `click` | Mouse click | `type`: 'once', 'alternate', 'repeat', 'state' for animations, or `method`: 'add', 'remove', 'toggle', 'clear' for states | `./click.md` |
|
|
181
|
-
| `activate` | Accessible click (click + keyboard Space/Enter) | Same as `click` with keyboard support | `./click.md` |
|
|
182
|
-
| `interest` | Accessible hover (hover + focus) | Same as `hover` with focus support | `./hover.md` |
|
|
183
|
-
| `viewEnter` | Element enters viewport | `type`: 'once', 'alternate', 'repeat', 'state'; `threshold` (0-1) | `./viewenter.md` |
|
|
184
|
-
| `viewProgress` | Scroll-driven using ViewTimeline | (No specific params, uses effect ranges) | `./viewprogress.md` |
|
|
185
|
-
| `pointerMove` | Mouse movement | `hitArea`: 'self' (default) or 'root'; `axis`: 'x' or 'y' for keyframeEffect | `./pointermove.md` |
|
|
186
|
-
| `animationEnd` | Chaining animations | `effectId`: ID of the previous effect | -- |
|
|
211
|
+
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.
|
|
187
212
|
|
|
188
|
-
|
|
213
|
+
---
|
|
189
214
|
|
|
190
|
-
Sequences
|
|
215
|
+
## Sequences
|
|
191
216
|
|
|
192
|
-
|
|
217
|
+
Sequences coordinate multiple effects with staggered timing.
|
|
193
218
|
|
|
194
219
|
```typescript
|
|
195
220
|
{
|
|
196
|
-
offset:
|
|
197
|
-
offsetEasing:
|
|
198
|
-
delay:
|
|
199
|
-
effects: [
|
|
200
|
-
|
|
221
|
+
offset: number, // ms between consecutive items
|
|
222
|
+
offsetEasing: string, // Any valid easing string for stagger distribution curve
|
|
223
|
+
delay: number, // ms base delay before the sequence starts
|
|
224
|
+
effects: [
|
|
225
|
+
/* ... effect definitions */,
|
|
201
226
|
],
|
|
202
227
|
}
|
|
203
228
|
```
|
|
204
229
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
Reusable sequences can be defined in `InteractConfig.sequences` and referenced by `sequenceId`:
|
|
230
|
+
Define reusable sequences in `InteractConfig.sequences` and reference by `sequenceId`:
|
|
208
231
|
|
|
209
232
|
```typescript
|
|
210
233
|
{
|
|
211
234
|
sequences: {
|
|
212
|
-
'stagger-
|
|
235
|
+
'stagger-fade': {
|
|
236
|
+
/* ... sequence definition */
|
|
237
|
+
},
|
|
213
238
|
},
|
|
214
239
|
interactions: [
|
|
215
|
-
{
|
|
240
|
+
{
|
|
241
|
+
key: `'[SOURCE_KEY]'`,
|
|
242
|
+
trigger: `'[TRIGGER]'`,
|
|
243
|
+
params: `[TRIGGER_PARAMS]`,
|
|
244
|
+
sequences: [{ sequenceId: 'stagger-fade' }],
|
|
245
|
+
},
|
|
216
246
|
],
|
|
217
247
|
}
|
|
218
248
|
```
|
|
219
249
|
|
|
220
|
-
|
|
250
|
+
---
|
|
221
251
|
|
|
222
|
-
|
|
252
|
+
## Critical CSS (FOUC Prevention)
|
|
223
253
|
|
|
224
|
-
**
|
|
254
|
+
**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
255
|
|
|
226
|
-
|
|
227
|
-
> npm install @wix/motion-presets
|
|
228
|
-
```
|
|
256
|
+
**Solution:** Two things are required — both MUST be present:
|
|
229
257
|
|
|
230
|
-
**
|
|
258
|
+
1. **Generate critical CSS** with `generate(config)` — produces CSS that hides entrance-animated elements until the animation plays.
|
|
259
|
+
2. **Mark elements with `initial`** — `data-interact-initial="true"` on `<interact-element>`, or `initial={true}` on `<Interaction>` in React.
|
|
231
260
|
|
|
232
|
-
|
|
233
|
-
import { Interact } from '@wix/interact/web';
|
|
234
|
-
import * as presets from '@wix/motion-presets';
|
|
261
|
+
Using only one of these has no effect — both are required.
|
|
235
262
|
|
|
236
|
-
|
|
237
|
-
```
|
|
263
|
+
See [viewenter.md](./viewenter.md) for full details.
|
|
238
264
|
|
|
239
|
-
**
|
|
265
|
+
**Rules:**
|
|
240
266
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
import { FadeIn, ParallaxScroll } from '@wix/motion-presets';
|
|
267
|
+
- `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).
|
|
268
|
+
- Only valid for `viewEnter` + `triggerType: 'once'` (or no `triggerType`, which defaults to `'once'`) where source and target are the same element.
|
|
244
269
|
|
|
245
|
-
|
|
270
|
+
```javascript
|
|
271
|
+
import { generate } from '@wix/interact/web';
|
|
272
|
+
const css = generate(config);
|
|
246
273
|
```
|
|
247
274
|
|
|
248
|
-
|
|
249
|
-
{
|
|
250
|
-
namedEffect: { type: 'FadeIn' },
|
|
251
|
-
duration: 800,
|
|
252
|
-
easing: 'ease-out'
|
|
253
|
-
}
|
|
254
|
-
```
|
|
275
|
+
**Append to `<head>` or beginning of `<body>`:**
|
|
255
276
|
|
|
256
|
-
|
|
277
|
+
```html
|
|
278
|
+
<style>
|
|
279
|
+
${css}
|
|
280
|
+
</style>
|
|
281
|
+
```
|
|
257
282
|
|
|
258
|
-
|
|
283
|
+
**Web:**
|
|
259
284
|
|
|
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
|
-
};
|
|
285
|
+
```html
|
|
286
|
+
<interact-element data-interact-key="hero" data-interact-initial="true">
|
|
287
|
+
<section id="hero">...</section>
|
|
288
|
+
</interact-element>
|
|
287
289
|
```
|
|
288
290
|
|
|
289
|
-
|
|
291
|
+
**React:**
|
|
290
292
|
|
|
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
|
-
};
|
|
293
|
+
```tsx
|
|
294
|
+
<Interaction tagName="section" interactKey="hero" initial={true} className="hero">
|
|
295
|
+
...
|
|
296
|
+
</Interaction>
|
|
307
297
|
```
|
|
308
298
|
|
|
309
|
-
|
|
299
|
+
**Vanilla:**
|
|
310
300
|
|
|
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
|
-
};
|
|
301
|
+
```html
|
|
302
|
+
<section data-interact-key="hero" data-interact-initial="true" class="hero">...</section>
|
|
342
303
|
```
|
|
343
304
|
|
|
344
|
-
|
|
305
|
+
---
|
|
345
306
|
|
|
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
|
-
```
|
|
307
|
+
## Static API
|
|
308
|
+
|
|
309
|
+
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).
|
|
310
|
+
|
|
311
|
+
| Method / Property | Description |
|
|
312
|
+
| :---------------------------------- | :------------------------------------------------------------------------------------------- |
|
|
313
|
+
| `Interact.create(config)` | Initialize with a config. Returns the instance. Multiple configs create separate instances. |
|
|
314
|
+
| `Interact.registerEffects(presets)` | Register named effect presets before `create`. Required for `namedEffect` usage. |
|
|
315
|
+
| `Interact.destroy()` | Tear down all instances. |
|
|
316
|
+
| `Interact.forceReducedMotion` | `boolean` — force reduced-motion behavior regardless of OS setting. Default: `false`. |
|
|
317
|
+
| `Interact.allowA11yTriggers` | `boolean` — enable accessibility triggers (`interest`, `activate`). Default: `false`. |
|
|
318
|
+
| `Interact.setup(options)` | Configure global defaults for scroll/pointer/viewEnter trigger params. Call before `create`. |
|