@wix/interact 2.2.2 → 2.4.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/README.md +322 -246
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/react.js +1 -1
- package/dist/cjs/web.js +1 -1
- package/dist/es/index.js +1 -1
- package/dist/es/react.js +2 -2
- package/dist/es/web.js +2 -2
- package/dist/index-C6u4q815.mjs +3291 -0
- package/dist/index-C6u4q815.mjs.map +1 -0
- package/dist/index-Qg46rn0Y.js +21 -0
- package/dist/index-Qg46rn0Y.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types/core/add.d.ts.map +1 -1
- package/dist/types/core/css.d.ts +17 -2
- package/dist/types/core/css.d.ts.map +1 -1
- package/dist/types/core/cssUtils.d.ts +8 -0
- package/dist/types/core/cssUtils.d.ts.map +1 -0
- package/dist/types/core/resolvers.d.ts +4 -0
- package/dist/types/core/resolvers.d.ts.map +1 -0
- package/dist/types/core/utilities.d.ts +6 -0
- package/dist/types/core/utilities.d.ts.map +1 -1
- package/dist/types/handlers/animationEnd.d.ts +1 -1
- package/dist/types/handlers/animationEnd.d.ts.map +1 -1
- package/dist/types/handlers/viewProgress.d.ts.map +1 -1
- package/dist/types/types/config.d.ts +23 -2
- package/dist/types/types/config.d.ts.map +1 -1
- package/dist/types/types/css.d.ts +26 -0
- package/dist/types/types/css.d.ts.map +1 -0
- package/dist/types/types/effects.d.ts +12 -0
- package/dist/types/types/effects.d.ts.map +1 -1
- package/dist/types/types/external.d.ts +3 -3
- package/dist/types/types/external.d.ts.map +1 -1
- package/dist/types/types/handlers.d.ts +2 -1
- package/dist/types/types/handlers.d.ts.map +1 -1
- package/dist/types/types/index.d.ts +1 -0
- package/dist/types/types/index.d.ts.map +1 -1
- package/dist/types/types/internal.d.ts +1 -1
- package/dist/types/types/internal.d.ts.map +1 -1
- package/dist/types/utils.d.ts +11 -2
- package/dist/types/utils.d.ts.map +1 -1
- package/docs/README.md +1 -1
- package/docs/api/README.md +4 -4
- package/docs/api/functions.md +157 -42
- package/docs/examples/entrance-animations.md +7 -5
- package/docs/guides/getting-started.md +1 -1
- package/docs/integration/react.md +8 -8
- package/package.json +6 -3
- package/rules/full-lean.md +24 -15
- package/rules/integration.md +23 -17
- package/rules/viewenter.md +4 -2
- package/rules/viewprogress.md +52 -0
- package/dist/index-A2Q0e94t.js +0 -18
- package/dist/index-A2Q0e94t.js.map +0 -1
- package/dist/index-HeFaJMEX.mjs +0 -2839
- package/dist/index-HeFaJMEX.mjs.map +0 -1
package/docs/api/functions.md
CHANGED
|
@@ -12,11 +12,11 @@ import { add, remove, generate } from '@wix/interact';
|
|
|
12
12
|
|
|
13
13
|
## Functions Overview
|
|
14
14
|
|
|
15
|
-
| Function | Purpose
|
|
16
|
-
| ------------ |
|
|
17
|
-
| `add()` | Add interactions to an element
|
|
18
|
-
| `remove()` | Remove interactions from an element
|
|
19
|
-
| `generate()` | Generate CSS for
|
|
15
|
+
| Function | Purpose | Parameters | Returns |
|
|
16
|
+
| ------------ | -------------------------------------------------------------------------------- | -------------------------- | -------- |
|
|
17
|
+
| `add()` | Add interactions to an element | `element`, `key?` | `void` |
|
|
18
|
+
| `remove()` | Remove interactions from an element | `key` | `void` |
|
|
19
|
+
| `generate()` | Generate complete CSS for all animations, transitions, and scroll-driven effects | `config`, `useFirstChild?` | `string` |
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
@@ -198,7 +198,7 @@ console.log('Interactions removed for hero');
|
|
|
198
198
|
|
|
199
199
|
## `generate(config, useFirstChild?)`
|
|
200
200
|
|
|
201
|
-
Generates CSS
|
|
201
|
+
Generates a complete CSS string from an `InteractConfig`. The output includes `@keyframes`, animation and transition custom properties, view-timeline declarations, state-selector rules, coordinated-list aggregation, and FOUC-prevention initial rules — everything the browser needs to run the configured animations and transitions natively, without waiting for JavaScript.
|
|
202
202
|
|
|
203
203
|
### Signature
|
|
204
204
|
|
|
@@ -208,53 +208,85 @@ function generate(config: InteractConfig, useFirstChild?: boolean): string;
|
|
|
208
208
|
|
|
209
209
|
### Parameters
|
|
210
210
|
|
|
211
|
-
**`config: InteractConfig`** - The interaction configuration
|
|
211
|
+
**`config: InteractConfig`** - The full interaction configuration. Every interaction in the config is processed — not just `viewEnter`.
|
|
212
212
|
|
|
213
|
-
**`useFirstChild?: boolean`** - When `true
|
|
213
|
+
**`useFirstChild?: boolean`** - When `true` (the default), generated selectors target the first child of each keyed element (e.g. `[data-interact-key="hero"] > :first-child`). This is the correct mode for `<interact-element>` custom elements. Pass `false` when the keyed element itself is the animation target (vanilla JS or React `<Interaction>`).
|
|
214
214
|
|
|
215
215
|
### Returns
|
|
216
216
|
|
|
217
|
-
**`string`** - A CSS string to inject into a `<style>` tag or
|
|
217
|
+
**`string`** - A CSS string to inject into a `<style>` tag, adopted stylesheet, or inline `<style>` in the document `<head>`.
|
|
218
218
|
|
|
219
|
-
###
|
|
219
|
+
### What it generates
|
|
220
220
|
|
|
221
|
-
The
|
|
221
|
+
The output covers every CSS-expressible aspect of the configuration:
|
|
222
222
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
223
|
+
- **`@keyframes`** for every `namedEffect` and `keyframeEffect` across all interactions.
|
|
224
|
+
- **Animation custom properties** (`--animation-*`, `--animation-composition-*`, `--animation-timeline-*`, `--animation-range-*`) that wire each effect to its target.
|
|
225
|
+
- **`view-timeline` declarations** for `viewProgress` triggers, enabling native scroll-driven animations.
|
|
226
|
+
- **Transition custom properties** for `StateEffect` CSS transitions.
|
|
227
|
+
- **State selector rules** using `:state()`, `:--`, and `[data-interact-effect~=]` for state-driven style overrides.
|
|
228
|
+
- **Coordinated-list aggregation rules** that combine animation/transition properties from multiple interactions targeting the same element, using CSS custom properties so they compose rather than override.
|
|
229
|
+
- **FOUC-prevention initial rules** for `viewEnter` + `triggerType: 'once'` effects where source and target are the same element — these hide the target with `visibility: hidden` and neutral transform values until the animation starts (gated by `:not([data-interact-enter])`).
|
|
230
|
+
- **Condition-gated rules** — `@media` wrappers for media-type conditions, and selector-based conditions appended to the element selector.
|
|
226
231
|
|
|
227
|
-
|
|
232
|
+
### Benefits
|
|
233
|
+
|
|
234
|
+
- **No DOM element references needed.** The generated CSS uses attribute selectors (`[data-interact-key="..."]`, `:state()`, `[data-interact-effect~="..."]`) rather than JS-managed DOM references. Animations bind reactively as elements appear in the DOM — no `querySelector`, no cached element references, no observer wiring, no cleanup on unmount. This removes entire categories of error-prone JS: stale references, race conditions between element mount and JS initialization, and manual lifecycle management. The browser's style engine handles the binding.
|
|
235
|
+
- **Reduced runtime JS.** CSS-expressible animations and transitions run natively on the compositor thread, freeing the main thread. Scroll-driven animations via `view-timeline` are especially beneficial — they run entirely in CSS without any JS scroll listeners.
|
|
236
|
+
- **Instant first paint.** When injected in `<head>`, animations are ready before the page content is painted. No waiting for JS to load, parse, and execute.
|
|
237
|
+
|
|
238
|
+
### Use cases
|
|
239
|
+
|
|
240
|
+
1. **FOUC prevention** — hide entrance-animated elements (`viewEnter` + `triggerType: 'once'`) until their animation starts.
|
|
241
|
+
2. **Pre-rendering scroll-driven animations** — `viewProgress` effects produce `view-timeline` + `animation-timeline` CSS that works before (or without) JS.
|
|
242
|
+
3. **Reducing runtime JS overhead** — all CSS-expressible animations run natively; the runtime only handles `customEffect` callbacks and event-trigger wiring.
|
|
243
|
+
4. **SSR / static-site generation** — generate CSS at build time or on the server and embed it in the HTML.
|
|
244
|
+
5. **Declarative, reference-free animation binding** — no element queries, no reference caching; elements animate simply by having the right `data-interact-key` attribute in the DOM.
|
|
245
|
+
|
|
246
|
+
### FOUC prevention (viewEnter)
|
|
247
|
+
|
|
248
|
+
For entrance animations where the source and target are the same element, `generate()` emits an initial rule that hides the element until its animation starts. Two things are required:
|
|
249
|
+
|
|
250
|
+
1. **Inject the generated CSS** into `<head>` (preferred) or the beginning of `<body>`.
|
|
251
|
+
2. **Mark elements with `initial`** — set `data-interact-initial="true"` on the element, or use `initial={true}` on the React `<Interaction>` component.
|
|
252
|
+
|
|
253
|
+
The initial rule uses `:not([data-interact-enter])` so the element becomes visible once the animation begins. This only applies to `viewEnter` interactions with `triggerType: 'once'` (the default for `viewEnter`).
|
|
254
|
+
|
|
255
|
+
For `triggerType: 'repeat'`/`'alternate'`/`'state'`, do NOT use `initial`. Instead, manually apply the starting keyframe as inline styles on the target element and use `fill: 'both'`.
|
|
256
|
+
|
|
257
|
+
**Generated FOUC CSS with `useFirstChild: false`:**
|
|
228
258
|
|
|
229
259
|
```css
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
rotate: none;
|
|
237
|
-
}
|
|
260
|
+
[data-interact-key='hero']:not([data-interact-enter]) {
|
|
261
|
+
visibility: hidden;
|
|
262
|
+
transform: none;
|
|
263
|
+
translate: none;
|
|
264
|
+
scale: none;
|
|
265
|
+
rotate: none;
|
|
238
266
|
}
|
|
239
267
|
```
|
|
240
268
|
|
|
241
|
-
**
|
|
269
|
+
**Generated FOUC CSS with `useFirstChild: true`:**
|
|
242
270
|
|
|
243
271
|
```css
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
rotate: none;
|
|
251
|
-
}
|
|
272
|
+
[data-interact-key='hero'] > :first-child:not([data-interact-enter]) {
|
|
273
|
+
visibility: hidden;
|
|
274
|
+
transform: none;
|
|
275
|
+
translate: none;
|
|
276
|
+
scale: none;
|
|
277
|
+
rotate: none;
|
|
252
278
|
}
|
|
253
279
|
```
|
|
254
280
|
|
|
281
|
+
### Scroll-driven CSS (viewProgress)
|
|
282
|
+
|
|
283
|
+
For `viewProgress` interactions, `generate()` emits `view-timeline` declarations and `animation-timeline`/`animation-range` custom properties. This produces fully native scroll-driven animations that work before JavaScript loads — the browser drives the animation based on the element's scroll position, with zero JS overhead.
|
|
284
|
+
|
|
285
|
+
No `initial` attribute is needed for scroll-driven animations.
|
|
286
|
+
|
|
255
287
|
### Examples
|
|
256
288
|
|
|
257
|
-
####
|
|
289
|
+
#### Entrance animation (viewEnter)
|
|
258
290
|
|
|
259
291
|
```typescript
|
|
260
292
|
import { Interact, generate } from '@wix/interact';
|
|
@@ -282,21 +314,101 @@ const config = {
|
|
|
282
314
|
effects: {},
|
|
283
315
|
};
|
|
284
316
|
|
|
285
|
-
// Generate the CSS (pass true when using custom elements so first child is targeted)
|
|
286
317
|
const css = generate(config, false);
|
|
287
318
|
|
|
288
|
-
// Inject into page
|
|
289
319
|
const styleElement = document.createElement('style');
|
|
290
320
|
styleElement.textContent = css;
|
|
291
321
|
document.head.appendChild(styleElement);
|
|
292
322
|
|
|
293
|
-
// Create the Interact instance
|
|
294
323
|
Interact.create(config);
|
|
295
324
|
```
|
|
296
325
|
|
|
297
|
-
####
|
|
326
|
+
#### Scroll-driven animation (viewProgress)
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
import { generate } from '@wix/interact';
|
|
330
|
+
|
|
331
|
+
const config = {
|
|
332
|
+
interactions: [
|
|
333
|
+
{
|
|
334
|
+
key: 'parallax-section',
|
|
335
|
+
trigger: 'viewProgress',
|
|
336
|
+
effects: [
|
|
337
|
+
{
|
|
338
|
+
keyframeEffect: {
|
|
339
|
+
name: 'parallax',
|
|
340
|
+
keyframes: [{ transform: 'translateY(50px)' }, { transform: 'translateY(-50px)' }],
|
|
341
|
+
},
|
|
342
|
+
rangeStart: { name: 'cover', offset: { unit: 'percentage', value: 0 } },
|
|
343
|
+
rangeEnd: { name: 'cover', offset: { unit: 'percentage', value: 100 } },
|
|
344
|
+
fill: 'both',
|
|
345
|
+
},
|
|
346
|
+
],
|
|
347
|
+
},
|
|
348
|
+
],
|
|
349
|
+
effects: {},
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
const css = generate(config, false);
|
|
353
|
+
// Produces @keyframes, view-timeline, animation-timeline, and animation-range CSS
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
#### Mixed config (multiple trigger types)
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
const config = {
|
|
360
|
+
interactions: [
|
|
361
|
+
{
|
|
362
|
+
key: 'hero',
|
|
363
|
+
trigger: 'viewEnter',
|
|
364
|
+
effects: [
|
|
365
|
+
{
|
|
366
|
+
keyframeEffect: {
|
|
367
|
+
name: 'fade-in',
|
|
368
|
+
keyframes: [{ opacity: 0 }, { opacity: 1 }],
|
|
369
|
+
},
|
|
370
|
+
duration: 800,
|
|
371
|
+
},
|
|
372
|
+
],
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
key: 'card',
|
|
376
|
+
trigger: 'hover',
|
|
377
|
+
effects: [
|
|
378
|
+
{
|
|
379
|
+
keyframeEffect: {
|
|
380
|
+
name: 'lift',
|
|
381
|
+
keyframes: [{ transform: 'translateY(-4px)' }],
|
|
382
|
+
},
|
|
383
|
+
duration: 200,
|
|
384
|
+
fill: 'both',
|
|
385
|
+
},
|
|
386
|
+
],
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
key: 'progress-bar',
|
|
390
|
+
trigger: 'viewProgress',
|
|
391
|
+
effects: [
|
|
392
|
+
{
|
|
393
|
+
keyframeEffect: {
|
|
394
|
+
name: 'fill-bar',
|
|
395
|
+
keyframes: [{ width: '0%' }, { width: '100%' }],
|
|
396
|
+
},
|
|
397
|
+
rangeStart: { name: 'entry', offset: { unit: 'percentage', value: 0 } },
|
|
398
|
+
rangeEnd: { name: 'exit', offset: { unit: 'percentage', value: 100 } },
|
|
399
|
+
fill: 'both',
|
|
400
|
+
},
|
|
401
|
+
],
|
|
402
|
+
},
|
|
403
|
+
],
|
|
404
|
+
effects: {},
|
|
405
|
+
};
|
|
298
406
|
|
|
299
|
-
|
|
407
|
+
// generate() processes ALL interactions — viewEnter, hover, AND viewProgress
|
|
408
|
+
const css = generate(config, false);
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
#### Server-Side Rendering (SSR)
|
|
300
412
|
|
|
301
413
|
```typescript
|
|
302
414
|
// server.ts
|
|
@@ -304,14 +416,13 @@ import { generate, InteractConfig } from '@wix/interact';
|
|
|
304
416
|
|
|
305
417
|
const config: InteractConfig = {
|
|
306
418
|
interactions: [
|
|
307
|
-
/* your interactions */
|
|
419
|
+
/* all your interactions */
|
|
308
420
|
],
|
|
309
421
|
effects: {},
|
|
310
422
|
};
|
|
311
423
|
|
|
312
424
|
const css = generate(config);
|
|
313
425
|
|
|
314
|
-
// Include in your HTML template
|
|
315
426
|
const html = `
|
|
316
427
|
<!DOCTYPE html>
|
|
317
428
|
<html>
|
|
@@ -319,7 +430,7 @@ const html = `
|
|
|
319
430
|
<style>${css}</style>
|
|
320
431
|
</head>
|
|
321
432
|
<body>
|
|
322
|
-
<!--
|
|
433
|
+
<!-- Animations are ready before JS loads -->
|
|
323
434
|
</body>
|
|
324
435
|
</html>
|
|
325
436
|
`;
|
|
@@ -327,7 +438,11 @@ const html = `
|
|
|
327
438
|
|
|
328
439
|
### HTML Setup
|
|
329
440
|
|
|
330
|
-
Elements must have `data-interact-key` matching the interaction key in your config.
|
|
441
|
+
Elements must have `data-interact-key` matching the interaction key in your config.
|
|
442
|
+
|
|
443
|
+
- **Custom elements (`<interact-element>`)**: use `generate(config, true)` (the default) so selectors target the first child.
|
|
444
|
+
- **Vanilla JS / React**: use `generate(config, false)` so selectors target the keyed element directly.
|
|
445
|
+
- **FOUC prevention**: for `viewEnter` + `triggerType: 'once'`, also set `data-interact-initial="true"` on the element (or `initial={true}` on the React `<Interaction>` component).
|
|
331
446
|
|
|
332
447
|
---
|
|
333
448
|
|
|
@@ -851,7 +851,9 @@ const testimonialConfig = {
|
|
|
851
851
|
|
|
852
852
|
## Preventing Flash of Unstyled Content (FOUC)
|
|
853
853
|
|
|
854
|
-
When using entrance animations, elements may briefly appear before their animation starts (a "flash").
|
|
854
|
+
When using entrance animations, elements may briefly appear before their animation starts (a "flash"). The `generate()` function produces complete CSS for all interactions in your config — including `@keyframes`, animation properties, scroll-driven timelines, and more. For `viewEnter` + `triggerType: 'once'` effects where source and target are the same element, it also emits FOUC-prevention rules that hide the element until its animation starts.
|
|
855
|
+
|
|
856
|
+
> **Note**: `generate()` is not limited to FOUC prevention — it generates CSS for every interaction in the config. See the [generate() function documentation](../api/functions.md#generate) for the full scope.
|
|
855
857
|
|
|
856
858
|
### Server-Side Setup
|
|
857
859
|
|
|
@@ -909,7 +911,7 @@ const html = `
|
|
|
909
911
|
|
|
910
912
|
### HTML Markup
|
|
911
913
|
|
|
912
|
-
Add `data-interact-initial="true"` to the `<interact-element>` that has a child that should be hidden until its entrance animation:
|
|
914
|
+
Add `data-interact-initial="true"` to the `<interact-element>` that has a child that should be hidden until its entrance animation starts:
|
|
913
915
|
|
|
914
916
|
```html
|
|
915
917
|
<interact-element data-interact-key="hero" data-interact-initial="true">
|
|
@@ -920,11 +922,11 @@ Add `data-interact-initial="true"` to the `<interact-element>` that has a child
|
|
|
920
922
|
</interact-element>
|
|
921
923
|
```
|
|
922
924
|
|
|
923
|
-
###
|
|
925
|
+
### Why generate()?
|
|
924
926
|
|
|
925
|
-
|
|
927
|
+
Beyond FOUC prevention, `generate()` produces all CSS needed for your animations — `@keyframes`, animation custom properties, scroll-driven timelines, state-effect rules, and more. Because the CSS uses attribute selectors (`[data-interact-key="..."]`), animations bind reactively as elements appear in the DOM. No DOM element references, no lifecycle management, no stale-reference bugs.
|
|
926
928
|
|
|
927
|
-
See the [generate() function documentation](../api/functions.md#generate) for
|
|
929
|
+
See the [generate() function documentation](../api/functions.md#generate) for the full scope, benefits, and examples.
|
|
928
930
|
|
|
929
931
|
---
|
|
930
932
|
|
|
@@ -305,7 +305,7 @@ Each effect defines:
|
|
|
305
305
|
|
|
306
306
|
> **Note**: Using `namedEffect` requires registering effects first with `Interact.registerEffects(...)` (presets from `@wix/motion-presets` or your own custom-made effects). See [Installation](#optional-animation-presets).
|
|
307
307
|
|
|
308
|
-
> **Tip**:
|
|
308
|
+
> **Tip**: Call `generate(config)` to produce complete CSS for all interactions — `@keyframes`, animation properties, scroll-driven timelines, state effects, and FOUC-prevention rules. The generated CSS uses attribute selectors, so animations bind reactively as elements appear in the DOM without needing JS-managed DOM references. See [generate() documentation](../api/functions.md#generate) for details.
|
|
309
309
|
|
|
310
310
|
---
|
|
311
311
|
|
|
@@ -64,14 +64,14 @@ The `Interaction` component is a wrapper that automatically manages interaction
|
|
|
64
64
|
|
|
65
65
|
### Props
|
|
66
66
|
|
|
67
|
-
| Prop | Type | Required | Description
|
|
68
|
-
| ------------- | ----------------------------- | -------- |
|
|
69
|
-
| `tagName` | `keyof JSX.IntrinsicElements` | Yes | The HTML element to render (e.g., `'div'`, `'button'`, `'span'`)
|
|
70
|
-
| `interactKey` | `string` | Yes | Unique identifier matching the interaction configuration
|
|
71
|
-
| `initial` | `boolean` | No | When `true`, sets `data-interact-initial="true"` for FOUC prevention
|
|
72
|
-
| `children` | `React.ReactNode` | No | Child elements to render
|
|
73
|
-
| `ref` | `React.Ref<any>` | No | Forwarded ref to the underlying DOM element
|
|
74
|
-
| `...rest` | `JSX.IntrinsicElements[T]` | No | Any valid props for the specified `tagName`
|
|
67
|
+
| Prop | Type | Required | Description |
|
|
68
|
+
| ------------- | ----------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
69
|
+
| `tagName` | `keyof JSX.IntrinsicElements` | Yes | The HTML element to render (e.g., `'div'`, `'button'`, `'span'`) |
|
|
70
|
+
| `interactKey` | `string` | Yes | Unique identifier matching the interaction configuration |
|
|
71
|
+
| `initial` | `boolean` | No | When `true`, sets `data-interact-initial="true"` for FOUC prevention. Only relevant for `viewEnter` + `triggerType: 'once'` interactions where source and target are the same element. |
|
|
72
|
+
| `children` | `React.ReactNode` | No | Child elements to render |
|
|
73
|
+
| `ref` | `React.Ref<any>` | No | Forwarded ref to the underlying DOM element |
|
|
74
|
+
| `...rest` | `JSX.IntrinsicElements[T]` | No | Any valid props for the specified `tagName` |
|
|
75
75
|
|
|
76
76
|
### Basic Usage
|
|
77
77
|
|
package/package.json
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/interact",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "Declarative, configuration-driven interaction library — web-native, AI-ready, and framework-agnostic.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/cjs/index.js",
|
|
7
7
|
"module": "dist/es/index.js",
|
|
8
8
|
"types": "dist/types/index.d.ts",
|
|
9
|
+
"llms": "https://wix.github.io/interact/llms.txt",
|
|
10
|
+
"llmsFull": "https://wix.github.io/interact/llms-full.txt",
|
|
9
11
|
"exports": {
|
|
10
12
|
".": {
|
|
11
13
|
"types": "./dist/types/index.d.ts",
|
|
@@ -26,7 +28,8 @@
|
|
|
26
28
|
"files": [
|
|
27
29
|
"dist",
|
|
28
30
|
"rules",
|
|
29
|
-
"docs"
|
|
31
|
+
"docs",
|
|
32
|
+
"llms.txt"
|
|
30
33
|
],
|
|
31
34
|
"sideEffects": false,
|
|
32
35
|
"scripts": {
|
|
@@ -65,7 +68,7 @@
|
|
|
65
68
|
"url": "https://github.com/wix/interact/issues"
|
|
66
69
|
},
|
|
67
70
|
"dependencies": {
|
|
68
|
-
"@wix/motion": "^2.1.
|
|
71
|
+
"@wix/motion": "^2.1.7",
|
|
69
72
|
"fastdom": "^1.0.12",
|
|
70
73
|
"fizban": "^0.7.2",
|
|
71
74
|
"kuliso": "^0.4.13"
|
package/rules/full-lean.md
CHANGED
|
@@ -22,7 +22,7 @@ Declarative configuration-driven interaction library. Binds animations to trigge
|
|
|
22
22
|
- [Animation Payloads](#animation-payloads)
|
|
23
23
|
- [Sequences](#sequences)
|
|
24
24
|
- [Conditions](#conditions)
|
|
25
|
-
- [FOUC Prevention](#fouc-prevention)
|
|
25
|
+
- [CSS Generation & FOUC Prevention](#css-generation--fouc-prevention)
|
|
26
26
|
- [Element Resolution](#element-resolution)
|
|
27
27
|
- [Static API](#static-api)
|
|
28
28
|
|
|
@@ -582,25 +582,19 @@ conditions: {
|
|
|
582
582
|
|
|
583
583
|
---
|
|
584
584
|
|
|
585
|
-
## FOUC Prevention
|
|
585
|
+
## CSS Generation & FOUC Prevention
|
|
586
586
|
|
|
587
|
-
|
|
587
|
+
### Generating CSS
|
|
588
588
|
|
|
589
|
-
**
|
|
590
|
-
|
|
591
|
-
1. **Generate critical CSS** using `generate(config)` — produces CSS rules that hide entrance-animated elements from the moment the page renders.
|
|
592
|
-
2. **Mark elements with `initial`** — tells the runtime which elements have critical CSS applied so it can coordinate with the generated styles.
|
|
593
|
-
|
|
594
|
-
### Step 1: Generate CSS
|
|
595
|
-
|
|
596
|
-
Call `generate(config)` server-side or at build time and inject the result into the `<head>` (preferred), or insert to beginning of `<body>`, so it loads before the page content is painted:
|
|
589
|
+
Call `generate(config, useFirstChild)` server-side or at build time to produce complete CSS for **all** interactions in the config — including initial state for entrance effects triggered by `viewEnter`. The output includes `@keyframes`, animation/transition custom properties, `view-timeline` declarations, state-selector rules, coordinated-list aggregation, and FOUC-prevention initial rules.
|
|
590
|
+
The `useFirstChild` argument is a boolean flag which tells Interact whether to render `:first-child` selectors when using custom element (`web`) integration.
|
|
597
591
|
|
|
598
592
|
```ts
|
|
599
593
|
import { generate } from '@wix/interact/web';
|
|
600
594
|
const css = generate(config);
|
|
601
595
|
```
|
|
602
596
|
|
|
603
|
-
|
|
597
|
+
Inject the result into the `<head>` (preferred), or beginning of `<body>`, so it loads before the page content is painted:
|
|
604
598
|
|
|
605
599
|
```html
|
|
606
600
|
<style>
|
|
@@ -608,7 +602,18 @@ const css = generate(config);
|
|
|
608
602
|
</style>
|
|
609
603
|
```
|
|
610
604
|
|
|
611
|
-
###
|
|
605
|
+
### FOUC Prevention (viewEnter + once)
|
|
606
|
+
|
|
607
|
+
**Problem:** Elements with entrance animations (e.g. `viewEnter` + `triggerType: 'once'` with `FadeIn`) start in their final visible state. Before the animation framework initializes and applies the starting keyframe (e.g. `opacity: 0`), the element is briefly visible at full opacity — causing a flash of unstyled/un-animated content (FOUC).
|
|
608
|
+
|
|
609
|
+
**Solution:** Two things are required — both MUST be present:
|
|
610
|
+
|
|
611
|
+
1. **Generate CSS** using `generate(config, useFirstChild)` — among all the rules it produces, it includes initial rules that hide entrance-animated elements from the moment the page renders.
|
|
612
|
+
2. **Mark elements with `initial`** — tells the runtime which elements have critical CSS applied so it can coordinate with the generated styles.
|
|
613
|
+
|
|
614
|
+
**Step 1: Generate CSS** — see above.
|
|
615
|
+
|
|
616
|
+
**Step 2: Mark elements**
|
|
612
617
|
|
|
613
618
|
**Web (Custom Elements):**
|
|
614
619
|
|
|
@@ -632,11 +637,15 @@ const css = generate(config);
|
|
|
632
637
|
<section data-interact-key="hero" data-interact-initial="true" class="hero">...</section>
|
|
633
638
|
```
|
|
634
639
|
|
|
640
|
+
### Scroll-driven CSS (viewProgress)
|
|
641
|
+
|
|
642
|
+
For `viewProgress` interactions, `generate()` emits `view-timeline` declarations and `animation-timeline`/`animation-range` properties.
|
|
643
|
+
No `initial` attribute is needed for scroll-driven animations.
|
|
644
|
+
|
|
635
645
|
### Rules
|
|
636
646
|
|
|
637
647
|
- `generate()` should be called server-side or at build time. Can also be called on client-side if page content is initially hidden (e.g. behind a loader/splash screen).
|
|
638
|
-
-
|
|
639
|
-
- `initial` is only valid for `viewEnter` + `type: 'once'` where source and target are the same element.
|
|
648
|
+
- `initial` is only valid for `viewEnter` + `triggerType: 'once'` where source and target are the same element.
|
|
640
649
|
- For `repeat`/`alternate`/`state`, do NOT use `initial`. Instead, manually apply the initial keyframe as inline styles on the target element and use `fill: 'both'`.
|
|
641
650
|
|
|
642
651
|
---
|
package/rules/integration.md
CHANGED
|
@@ -15,7 +15,7 @@ Rules for integrating `@wix/interact` into a webpage — binding animations and
|
|
|
15
15
|
- [Element Selection](#element-selection)
|
|
16
16
|
- [Triggers](#triggers)
|
|
17
17
|
- [Sequences](#sequences)
|
|
18
|
-
- [
|
|
18
|
+
- [CSS Generation & FOUC Prevention](#css-generation--fouc-prevention)
|
|
19
19
|
- [Static API](#static-api)
|
|
20
20
|
|
|
21
21
|
---
|
|
@@ -259,23 +259,10 @@ Define reusable sequences in `InteractConfig.sequences` and reference by `sequen
|
|
|
259
259
|
|
|
260
260
|
---
|
|
261
261
|
|
|
262
|
-
##
|
|
262
|
+
## CSS Generation & FOUC Prevention
|
|
263
263
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
**Solution:** Two things are required — both MUST be present:
|
|
267
|
-
|
|
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.
|
|
270
|
-
|
|
271
|
-
Using only one of these has no effect — both are required.
|
|
272
|
-
|
|
273
|
-
See [viewenter.md](./viewenter.md) for full details.
|
|
274
|
-
|
|
275
|
-
**Rules:**
|
|
276
|
-
|
|
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.
|
|
264
|
+
`generate(config, useFirstChild)` produces complete CSS for **all** interactions in the config — `@keyframes`, animation/transition custom properties, `view-timeline` declarations, state-selector rules, coordinated-list aggregation, and FOUC-prevention initial rules. Call it server-side or at build time and inject the result into `<head>`.
|
|
265
|
+
The `useFirstChild` argument is a boolean flag which tells Interact whether to render `:first-child` selectors when using custom element (`web`) integration.
|
|
279
266
|
|
|
280
267
|
```javascript
|
|
281
268
|
import { generate } from '@wix/interact/web';
|
|
@@ -290,6 +277,25 @@ const css = generate(config);
|
|
|
290
277
|
</style>
|
|
291
278
|
```
|
|
292
279
|
|
|
280
|
+
### FOUC Prevention (viewEnter + once)
|
|
281
|
+
|
|
282
|
+
**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).
|
|
283
|
+
|
|
284
|
+
**Solution:** Two things are required — both MUST be present:
|
|
285
|
+
|
|
286
|
+
1. **Generate CSS** with `generate(config, useFirstChild)` — among all the rules it produces, it includes initial rules that hide entrance-animated elements until the animation starts.
|
|
287
|
+
2. **Mark elements with `initial`** — `data-interact-initial="true"` on `<interact-element>`, or `initial={true}` on `<Interaction>` in React.
|
|
288
|
+
|
|
289
|
+
Using only one of these has no effect — both are required.
|
|
290
|
+
|
|
291
|
+
See [viewenter.md](./viewenter.md) for full details.
|
|
292
|
+
|
|
293
|
+
**Rules:**
|
|
294
|
+
|
|
295
|
+
- `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).
|
|
296
|
+
- `generate()` processes all interactions, not just `viewEnter`.
|
|
297
|
+
- `initial` is only valid for `viewEnter` + `triggerType: 'once'` (or no `triggerType`, which defaults to `'once'`) where source and target are the same element.
|
|
298
|
+
|
|
293
299
|
**Web:**
|
|
294
300
|
|
|
295
301
|
```html
|
package/rules/viewenter.md
CHANGED
|
@@ -17,11 +17,13 @@ This document contains rules for generating interactions that respond to element
|
|
|
17
17
|
|
|
18
18
|
## Preventing Flash of Unstyled Content (FOUC)
|
|
19
19
|
|
|
20
|
+
> **Note:** `generate(config)` produces complete CSS for **all** interactions in the config — `@keyframes`, animation/transition properties, scroll-driven timelines, state effects, and more — not only the FOUC-prevention rules described here. The generated CSS uses attribute selectors, so animations bind reactively as elements appear in the DOM without JS-managed DOM references. See the [generate() documentation](../docs/api/functions.md#generate) for the full scope.
|
|
21
|
+
|
|
20
22
|
**Problem:** Elements with entrance animations (e.g. `FadeIn`) start in their final visible state (e.g. `opacity: 1`). Before the animation framework initializes and applies the starting keyframe (e.g. `opacity: 0`), the element is briefly visible at full opacity — a flash of un-animated content.
|
|
21
23
|
|
|
22
24
|
**Solution:** Two things are required — **both** MUST be present for FOUC prevention to work:
|
|
23
25
|
|
|
24
|
-
1. **Generate
|
|
26
|
+
1. **Generate CSS** using `generate(config)` — among all the CSS it produces, it includes initial rules that hide entrance-animated elements from the moment the page renders, before JavaScript runs.
|
|
25
27
|
2. **Mark elements with `initial`** — set `data-interact-initial="true"` on `<interact-element>`, or `initial={true}` on the `<Interaction>` React component. This tells the runtime which elements have critical CSS applied.
|
|
26
28
|
|
|
27
29
|
If only one of these is present, FOUC prevention will **not** work. Both the CSS and the `initial` attribute are required.
|
|
@@ -89,7 +91,7 @@ const css = generate(config);
|
|
|
89
91
|
- `generate()` should be called server-side or at build time. Can also be called on the client if the page content is initially hidden (e.g. behind a loader/splash screen).
|
|
90
92
|
- `initial` is only valid for `viewEnter` + `triggerType: 'once'` (or no `triggerType`, which defaults to `'once'`) where source and target are the same element.
|
|
91
93
|
- Do NOT use `initial` for `viewEnter` with `triggerType: 'repeat'`/`'alternate'`/`'state'`. For those, manually apply the initial keyframe as inline styles on the target element and use `fill: 'both'`.
|
|
92
|
-
-
|
|
94
|
+
- `generate(config)` processes all interactions in the config, not just `viewEnter`. Set `initial` only on the relevant `viewEnter` + `triggerType: 'once'` elements.
|
|
93
95
|
|
|
94
96
|
## Rule 1: keyframeEffect / namedEffect (TimeEffect)
|
|
95
97
|
|
package/rules/viewprogress.md
CHANGED
|
@@ -11,6 +11,7 @@ These rules help generate scroll-driven interactions using `@wix/interact`. View
|
|
|
11
11
|
- [Rule 1: ViewProgress with keyframeEffect or namedEffect](#rule-1-viewprogress-with-keyframeeffect-or-namedeffect)
|
|
12
12
|
- [Rule 2: ViewProgress with customEffect](#rule-2-viewprogress-with-customeffect)
|
|
13
13
|
- [Rule 3: ViewProgress with Tall Wrapper + Sticky Container (contain range)](#rule-3-viewprogress-with-tall-wrapper--sticky-container-contain-range)
|
|
14
|
+
- [Pre-rendering Scroll-driven CSS with generate()](#pre-rendering-scroll-driven-css-with-generate)
|
|
14
15
|
|
|
15
16
|
---
|
|
16
17
|
|
|
@@ -142,3 +143,54 @@ These rules help generate scroll-driven interactions using `@wix/interact`. View
|
|
|
142
143
|
- `[END_PERCENTAGE]` — 0–100, end point within the `contain` range.
|
|
143
144
|
- `[UNIQUE_EFFECT_ID]` — same as Rule 1.
|
|
144
145
|
- `[EASING_FUNCTION]` — CSS easing string or named easing from `@wix/motion`. Typically `'linear'` for scrolling effects.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Pre-rendering Scroll-driven CSS with generate()
|
|
150
|
+
|
|
151
|
+
Call `generate(config)` server-side or at build time to produce native scroll-driven CSS for `viewProgress` interactions. The generated output includes `view-timeline` declarations, `animation-timeline`/`animation-range` custom properties, and `@keyframes` — everything the browser needs to run scroll-driven animations without any JavaScript.
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
import { generate } from '@wix/interact';
|
|
155
|
+
|
|
156
|
+
const config = {
|
|
157
|
+
interactions: [
|
|
158
|
+
{
|
|
159
|
+
key: 'parallax-hero',
|
|
160
|
+
trigger: 'viewProgress',
|
|
161
|
+
effects: [
|
|
162
|
+
{
|
|
163
|
+
keyframeEffect: {
|
|
164
|
+
name: 'parallax',
|
|
165
|
+
keyframes: [{ transform: 'translateY(50px)' }, { transform: 'translateY(-50px)' }],
|
|
166
|
+
},
|
|
167
|
+
rangeStart: { name: 'cover', offset: { unit: 'percentage', value: 0 } },
|
|
168
|
+
rangeEnd: { name: 'cover', offset: { unit: 'percentage', value: 100 } },
|
|
169
|
+
fill: 'both',
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
},
|
|
173
|
+
],
|
|
174
|
+
effects: {},
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
const css = generate(config, false);
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Inject the resulting CSS into `<head>` so scroll-driven animations are ready before JS loads:
|
|
181
|
+
|
|
182
|
+
```html
|
|
183
|
+
<style>
|
|
184
|
+
${css}
|
|
185
|
+
</style>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**Benefits:**
|
|
189
|
+
|
|
190
|
+
- **Zero JS scroll overhead.** The browser drives animations based on scroll position natively via CSS `view-timeline` — no JS scroll listeners, no `requestAnimationFrame` polling.
|
|
191
|
+
- **No DOM references needed.** CSS attribute selectors (`[data-interact-key]`) bind to elements reactively as they appear in the DOM. No `querySelector`, no cached references, no lifecycle management.
|
|
192
|
+
- **Instant first paint.** Animations work as soon as CSS is parsed, before JS loads or hydrates.
|
|
193
|
+
|
|
194
|
+
No `initial` attribute is needed for scroll-driven animations — unlike `viewEnter` FOUC prevention, there is no flash-of-content concern since the animation is continuously driven by scroll position.
|
|
195
|
+
|
|
196
|
+
> **Note:** `generate()` processes all interactions in the config, not just `viewProgress`. If your config also includes `viewEnter`, `hover`, `click`, or other triggers, CSS for those is generated too.
|