@wix/interact 2.0.3 → 2.1.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.
Files changed (43) hide show
  1. package/dist/cjs/index.js +1 -1
  2. package/dist/cjs/react.js +1 -1
  3. package/dist/cjs/web.js +1 -1
  4. package/dist/es/index.js +1 -1
  5. package/dist/es/react.js +2 -2
  6. package/dist/es/web.js +2 -2
  7. package/dist/{index-BfcN_rkn.mjs → index-BP07b-Y1.mjs} +1202 -751
  8. package/dist/index-BP07b-Y1.mjs.map +1 -0
  9. package/dist/index-D4orAyUu.js +18 -0
  10. package/dist/index-D4orAyUu.js.map +1 -0
  11. package/dist/tsconfig.build.tsbuildinfo +1 -1
  12. package/dist/types/core/Interact.d.ts +12 -1
  13. package/dist/types/core/Interact.d.ts.map +1 -1
  14. package/dist/types/core/add.d.ts.map +1 -1
  15. package/dist/types/core/remove.d.ts.map +1 -1
  16. package/dist/types/handlers/animationEnd.d.ts +1 -1
  17. package/dist/types/handlers/animationEnd.d.ts.map +1 -1
  18. package/dist/types/handlers/effectHandlers.d.ts +2 -1
  19. package/dist/types/handlers/effectHandlers.d.ts.map +1 -1
  20. package/dist/types/handlers/eventTrigger.d.ts +1 -1
  21. package/dist/types/handlers/eventTrigger.d.ts.map +1 -1
  22. package/dist/types/handlers/viewEnter.d.ts +1 -1
  23. package/dist/types/handlers/viewEnter.d.ts.map +1 -1
  24. package/dist/types/types.d.ts +29 -2
  25. package/dist/types/types.d.ts.map +1 -1
  26. package/docs/api/types.md +114 -0
  27. package/docs/examples/README.md +10 -1
  28. package/docs/examples/list-patterns.md +148 -0
  29. package/docs/guides/README.md +5 -0
  30. package/docs/guides/sequences.md +421 -0
  31. package/package.json +2 -2
  32. package/rules/MASTER-CLEANUP-PLAN.md +286 -0
  33. package/rules/click.md +124 -32
  34. package/rules/full-lean.md +93 -7
  35. package/rules/hover.md +142 -153
  36. package/rules/integration.md +83 -82
  37. package/rules/pointermove.md +32 -57
  38. package/rules/scroll-list.md +82 -280
  39. package/rules/viewenter.md +158 -253
  40. package/rules/viewprogress.md +139 -845
  41. package/dist/index-BfcN_rkn.mjs.map +0 -1
  42. package/dist/index-HXLBEIjG.js +0 -18
  43. package/dist/index-HXLBEIjG.js.map +0 -1
@@ -30,6 +30,25 @@ const config: InteractConfig = {
30
30
  Interact.create(config);
31
31
  ```
32
32
 
33
+ ### Using `namedEffect` presets (`registerEffects`)
34
+
35
+ Before using `namedEffect`, you must register the presets with the `Interact` instance. Without this, `namedEffect` types will not resolve.
36
+
37
+ ```ts
38
+ import { Interact } from '@wix/interact/web'; // or /react
39
+ import * as presets from '@wix/motion-presets';
40
+
41
+ Interact.registerEffects(presets);
42
+ Interact.create(config);
43
+ ```
44
+
45
+ Or register only what you need:
46
+
47
+ ```ts
48
+ import { FadeIn, ParallaxScroll } from '@wix/motion-presets';
49
+ Interact.registerEffects({ FadeIn, ParallaxScroll });
50
+ ```
51
+
33
52
  - Without Node/build tools: add a `<script type="module">` and import from the CDN.
34
53
 
35
54
  ```html
@@ -97,7 +116,7 @@ This configuration declares what user/system triggers occur on which source elem
97
116
 
98
117
  ### Global rules
99
118
 
100
- - **Required/Optional**: You MUST provide an `interactions` array. You SHOULD provide an `effects` registry when you want to reference reusable effects by id. `conditions` are OPTIONAL.
119
+ - **Required/Optional**: You MUST provide an `interactions` array. You SHOULD provide an `effects` registry when you want to reference reusable effects by id. `conditions` and `sequences` are OPTIONAL.
101
120
  - **Cross-references**: All cross-references (by id) MUST point to existing entries (e.g., an `EffectRef.effectId` MUST exist in `effects`).
102
121
  - **Element keys**: All element keys (`key` fields) refer to the element path string (e.g., the value used in `data-interact-key`) and MUST be stable for the lifetime of the configuration.
103
122
  - **List context**: Where both a list container and list item selector are provided, they MUST describe the same list context across an interaction and its effects. Mismatched list contexts will be ignored by the system.
@@ -111,6 +130,11 @@ This configuration declares what user/system triggers occur on which source elem
111
130
  - **Key (string)**: The effect id. MUST be unique across the registry.
112
131
  - **Value (Effect)**: A full effect definition. See Effect rules below.
113
132
 
133
+ - **sequences?: Record<string, SequenceConfig>**
134
+ - **Purpose**: A registry of reusable sequence definitions that can be referenced from interactions via `SequenceConfigRef`.
135
+ - **Key (string)**: The sequence id. MUST be unique across the registry.
136
+ - **Value (SequenceConfig)**: A full sequence definition. See Sequences section below.
137
+
114
138
  - **conditions?: Record<string, Condition>**
115
139
  - **Purpose**: Named predicates that gate interactions/effects by runtime context.
116
140
  - **Key (string)**: The condition id. MUST be unique across the registry.
@@ -195,8 +219,67 @@ This configuration declares what user/system triggers occur on which source elem
195
219
  - OPTIONAL. Additional CSS selector to refine element selection:
196
220
  - Without `listContainer`: Uses `querySelectorAll` to match all elements within the root element as separate items.
197
221
  - With `listContainer`: Uses `querySelectorAll` within the container to find matching elements as list items. For dynamically added list items, uses `querySelector` within each item to find a single matching element.
198
- - **effects: Array<Effect | EffectRef>**
199
- - REQUIRED. The effects to apply when the trigger fires. Ordering is significant: the first array entry is applied first. The system may reverse internal storage to preserve this application order.
222
+ - **effects?: Array<Effect | EffectRef>**
223
+ - The effects to apply when the trigger fires. Ordering is significant: the first array entry is applied first. The system may reverse internal storage to preserve this application order.
224
+ - At least one of `effects` or `sequences` MUST be provided.
225
+ - **sequences?: Array<SequenceConfig | SequenceConfigRef>**
226
+ - OPTIONAL. Sequences to play when the trigger fires. Each sequence coordinates multiple effects with staggered timing. See Sequences section below.
227
+
228
+ ### Sequences (coordinated multi-effect stagger)
229
+
230
+ Sequences let you group multiple effects into a single coordinated timeline with staggered delays. Instead of manually setting `delay` on each effect, you define `offset` (ms between items) and `offsetEasing` (how that offset is distributed).
231
+
232
+ **Prefer sequences over manual delay stagger** for any multi-element entrance or orchestration pattern.
233
+
234
+ - **SequenceConfig** type:
235
+ - `effects: (Effect | EffectRef)[]` — REQUIRED. The effects in this sequence, applied in array order.
236
+ - `delay?: number` — Base delay (ms) before the entire sequence starts. Default `0`.
237
+ - `offset?: number` — Stagger offset (ms) between consecutive effects. Default `0`.
238
+ - `offsetEasing?: string | ((p: number) => number)` — Easing function for stagger distribution. Named easings: `'linear'`, `'quadIn'`, `'quadOut'`, `'sineOut'`, `'cubicIn'`, `'cubicOut'`, `'cubicInOut'`. Also accepts `'cubic-bezier(...)'` strings or a JS function `(p: number) => number`. Default `'linear'`.
239
+ - `sequenceId?: string` — Id for caching and referencing. Auto-generated if omitted.
240
+ - `conditions?: string[]` — Condition ids that MUST all pass for this sequence to be active.
241
+
242
+ - **SequenceConfigRef** type (referencing a reusable sequence):
243
+ - `sequenceId: string` — REQUIRED. MUST match a key in `InteractConfig.sequences`.
244
+ - `delay?`, `offset?`, `offsetEasing?`, `conditions?` — OPTIONAL overrides merged on top of the referenced sequence.
245
+
246
+ - Effects within a sequence follow the same rules as standalone effects. Each effect can:
247
+ - Target a different element via `key` (cross-element sequences).
248
+ - Use `listContainer` to target list children (each child becomes a separate effect in the sequence).
249
+ - Reference the effects registry via `effectId`.
250
+
251
+ - A sequence is treated as a single animation unit by the trigger handler—it plays, reverses, and alternates as one.
252
+
253
+ **Example — viewEnter staggered list using `listContainer`**:
254
+
255
+ ```typescript
256
+ {
257
+ interactions: [
258
+ {
259
+ key: 'card-grid',
260
+ trigger: 'viewEnter',
261
+ params: { type: 'once', threshold: 0.3 },
262
+ sequences: [
263
+ {
264
+ offset: 100,
265
+ offsetEasing: 'quadIn',
266
+ effects: [
267
+ {
268
+ effectId: 'card-entrance',
269
+ listContainer: '.card-grid',
270
+ },
271
+ ],
272
+ },
273
+ ],
274
+ },
275
+ ],
276
+ effects: {
277
+ 'card-entrance': {
278
+ // ...
279
+ },
280
+ },
281
+ }
282
+ ```
200
283
 
201
284
  ### Working with elements
202
285
 
@@ -363,7 +446,7 @@ The config remains the same for both integrations—only the HTML/JSX setup diff
363
446
  - `transitionDelay?`: number
364
447
  - `transitionEasing?`: `ScrubTransitionEasing`
365
448
  - One of `keyframeEffect | namedEffect | customEffect` (see above)
366
- - For mouse-effects driven by the `pointerMove` trigger, do NOT use `keyframeEffect` (pointer progress is two‑dimensional and cannot be mapped to linear keyframes). Use `namedEffect` mouse presets instead, or `customEffect` for custom‑made animations.
449
+ - For mouse-effects driven by the `pointerMove` trigger, avoid `keyframeEffect` unless using `params: { axis: 'x' | 'y' }` to map a single pointer axis to linear 0–1 progress. For 2D effects, use `namedEffect` mouse presets or `customEffect` instead.
367
450
  - For scroll `namedEffect` presets (e.g., `*Scroll`) used with a `viewProgress` trigger, include `range: 'in' | 'out' | 'continuous'` in the `namedEffect` options; prefer `'continuous'` for simplicity.
368
451
  - RangeOffset (used by `rangeStart`/`rangeEnd`):
369
452
  - Type: `{ name: 'entry' | 'exit' | 'contain' | 'cover' | 'entry-crossing' | 'exit-crossing'; offset: LengthPercentage }`
@@ -396,11 +479,14 @@ The config remains the same for both integrations—only the HTML/JSX setup diff
396
479
 
397
480
  - **namedEffect (Preferred)**: Use first for best performance. These are pre-built presets from `@wix/motion-presets` that are GPU-friendly and tuned.
398
481
  - Structure: `namedEffect: { type: '<PresetName>', /* optional preset options like direction (bottom|top|left|right), etc. do not use those without having proper documentation of which options exist and of what types. */ }`
399
- - Short list of common preset names: - Entrance: `FadeIn`, `BounceIn`, `SlideIn`, `F
400
- lipIn`, `ArcIn` - Ongoing: `Pulse`, `Spin`, `Wiggle`, `Bounce` - Scroll: `ParallaxScroll`, `FadeScroll`, `RevealScroll`, `TiltScroll` - For scroll-effects used with the `viewProgress` trigger, the `namedEffect` options MUST include `range: 'in' | 'out' | 'continuous'`. Prefer `range: 'continuous'` for simplicity. - Mouse: For `pointerMove` (mouse-effects), prefer `namedEffect` presets (e.g., `TrackMouse`, `Tilt3DMouse`, `ScaleMouse`, `BlurMouse`); avoid `keyframeEffect` with `pointerMove` since progress is two‑dimensional. - Mouse: `TrackMouse`, `Tilt3DMouse`, `ScaleMouse`, `BlurMouse`
482
+ - Short list of common preset names:
483
+ - Entrance: `FadeIn`, `BounceIn`, `SlideIn`, `FlipIn`, `ArcIn`
484
+ - Ongoing: `Pulse`, `Spin`, `Wiggle`, `Bounce`
485
+ - Scroll: `ParallaxScroll`, `FadeScroll`, `RevealScroll`, `TiltScroll` — for `viewProgress`, `namedEffect` options MUST include `range: 'in' | 'out' | 'continuous'`; prefer `'continuous'`
486
+ - Mouse: `TrackMouse`, `Tilt3DMouse`, `ScaleMouse`, `BlurMouse` — for `pointerMove`; prefer over `keyframeEffect` for 2D pointer effects
401
487
  - **keyframeEffect (Default for custom animations)**: Prefer this when you need a custom-made animation.
402
488
  - Structure: `keyframeEffect: { name: string; keyframes: Keyframe[] }` (keyframes use standard CSS/WAAPI properties).
403
- - Not compatible with `pointerMove` (mouse-effects) because pointer progress is twodimensional; use `customEffect` for custom pointer‑driven animations.
489
+ - When used with `pointerMove`, requires `params: { axis: 'x' | 'y' }` to select which pointer coordinate maps to linear progress. Without `axis`, pointer progress is two-dimensional and cannot drive keyframe animations. For 2D pointer effects, use `namedEffect` or `customEffect`.
404
490
  - **customEffect (Last resort)**: Use only when you must perform DOM manipulation or produce randomized/non-deterministic visuals that cannot be expressed as keyframes or presets.
405
491
  - Structure: `customEffect: (element: Element, progress: any) => void`
406
492
 
package/rules/hover.md CHANGED
@@ -1,4 +1,4 @@
1
- # Hover Trigger Rules
1
+ # Hover Trigger Rules for @wix/interact
2
2
 
3
3
  This document contains rules for generating hover trigger interactions in `@wix/interact`. These rules cover all hover behavior patterns and common use cases.
4
4
 
@@ -10,11 +10,11 @@ This document contains rules for generating hover trigger interactions in `@wix/
10
10
 
11
11
  ```typescript
12
12
  {
13
- key: '[SOURCE_IDENTIFIER]',
13
+ key: '[SOURCE_KEY]',
14
14
  trigger: 'hover',
15
15
  effects: [
16
16
  {
17
- key: '[TARGET_IDENTIFIER]',
17
+ key: '[TARGET_KEY]',
18
18
  [EFFECT_TYPE]: [EFFECT_DEFINITION],
19
19
  fill: 'both',
20
20
  duration: [DURATION_MS],
@@ -26,8 +26,8 @@ This document contains rules for generating hover trigger interactions in `@wix/
26
26
 
27
27
  **Variables**:
28
28
 
29
- - `[SOURCE_IDENTIFIER]`: Unique identifier for hoverable element (e.g., '#menu-button', '#accordion-header'). Should equal the value of the data-interact-key attribute on the wrapping interact-element.
30
- - `[TARGET_IDENTIFIER]`: Unique identifier for animated element (can be same as trigger or different). Should equal the value of the data-interact-key attribute on the wrapping interact-element.
29
+ - `[SOURCE_KEY]`: Unique identifier for hoverable element. Should equal the value of the `data-interact-key` attribute on the wrapping `<interact-element>`.
30
+ - `[TARGET_KEY]`: Unique identifier for animated element (can be same as `[SOURCE_KEY]` for self-targeting, or different for cross-targeting).
31
31
  - `[EFFECT_TYPE]`: Either `namedEffect` or `keyframeEffect`
32
32
  - `[EFFECT_DEFINITION]`: Named effect object (e.g., { type: 'SlideIn', ...params }, { type: 'FadeIn', ...params }) or keyframe object (e.g., { name: 'custom-fade', keyframes: [{ opacity: 0 }, { opacity: 1 }] }, { name: 'custom-slide', keyframes: [{ transform: 'translateX(-100%)' }, { transform: 'translateX(0)' }] })
33
33
  - `[DURATION_MS]`: Animation duration in milliseconds (typically 200-500ms for micro-interactions)
@@ -38,7 +38,7 @@ This document contains rules for generating hover trigger interactions in `@wix/
38
38
 
39
39
  - `DURATION_MS`: 300 (for micro-interactions)
40
40
  - `EASING_FUNCTION`: 'ease-out' (for smooth feel)
41
- - `TARGET_IDENTIFIER`: Same as source key (self-targeting)
41
+ - `[TARGET_KEY]`: Same as `[SOURCE_KEY]` for self-targeting
42
42
 
43
43
  **Common Use Cases**:
44
44
 
@@ -93,26 +93,25 @@ This document contains rules for generating hover trigger interactions in `@wix/
93
93
  }
94
94
  ```
95
95
 
96
- ## Rule 2: Hover Enter/Leave Animations with Named Effects
96
+ ## Rule 2: Hover Alternate Animations (namedEffect / keyframeEffect)
97
97
 
98
- **Purpose**: Generate hover interactions using pre-built named effects from @wix/motion-presets
98
+ **Purpose**: Hover interactions that play forward on mouse enter and reverse on mouse leave (`type: 'alternate'`).
99
99
 
100
100
  **Pattern**:
101
101
 
102
102
  ```typescript
103
103
  {
104
- key: '[SOURCE_IDENTIFIER]',
104
+ key: '[SOURCE_KEY]',
105
105
  trigger: 'hover',
106
106
  params: {
107
107
  type: 'alternate'
108
108
  },
109
109
  effects: [
110
110
  {
111
- key: '[TARGET_IDENTIFIER]',
112
- namedEffect: {
113
- type: '[NAMED_EFFECT_TYPE]',
114
- [EFFECT_PROPERTIES]
115
- },
111
+ key: '[TARGET_KEY]',
112
+ // Use namedEffect OR keyframeEffect:
113
+ namedEffect: { type: '[NAMED_EFFECT_TYPE]' },
114
+ // keyframeEffect: { name: '[EFFECT_NAME]', keyframes: [{ ... }, { ... }] },
116
115
  fill: 'both',
117
116
  reversed: [REVERSED_BOOL],
118
117
  duration: [DURATION_MS],
@@ -124,143 +123,56 @@ This document contains rules for generating hover trigger interactions in `@wix/
124
123
 
125
124
  **Variables**:
126
125
 
127
- - `[REVERSED_BOOL]`: Optional boolean value indicating whether the mouse enter animation is reversed (and mouse leave is forwards).
128
- - `[NAMED_EFFECT_TYPE]`: Name of the pre-built named effect from @wix/motion-presets to use.
129
- - `[EFFECT_PROPERTIES]`: Named effect specific properties (distance, angle, perspective, etc.)
126
+ - `[REVERSED_BOOL]`: Optional. `true` to reverse the enter direction (mouse enter plays backwards, leave plays forwards).
127
+ - `[NAMED_EFFECT_TYPE]`: Pre-built effect from `@wix/motion-presets`. Available hover presets:
128
+ - Size: `ExpandIn`, `Pulse`, `GrowIn`
129
+ - Fade/Blur: `FadeIn`, `Flash`, `BlurIn`
130
+ - Translate: `SlideIn`, `GlideIn`, `FloatIn`, `BounceIn`, `GlitchIn`
131
+ - Rotate: `SpinIn`, `TiltIn`, `ArcIn`, `TurnIn`, `FlipIn`, `Spin`, `Swing`
132
+ - Attention: `Bounce`, `DropIn`, `Rubber`, `Jello`, `Cross`, `Wiggle`, `Poke`
130
133
  - Other variables same as Rule 1
131
134
 
132
- **Available Named Effects for Hover**:
133
-
134
- - **Size Changes**: `ExpandIn`, `Pulse`, `GrowIn`
135
- - **Opacity/Blur Changes**: `FadeIn`, `Flash`, `BlurIn`
136
- - **Translation Effects**: `SlideIn`, `GlideIn`, `FloatIn`, `BounceIn`, `GlitchIn`
137
- - **Rotation Effects**: `SpinIn`, `TiltIn`, `ArcIn`, `TurnIn`, `FlipIn`, `Spin`, `Swing`
138
- - **Special Attention Effects**: `Bounce`, `DropIn`, `Rubber`, `Jello`, `Cross`, `Wiggle`, `Poke`
139
-
140
- **Important**: Spatial effects that change the hit-area considerably (translation, rotation) should use different source and target keys to avoid unwanted flickering on hover enter/leave.
135
+ **Important**: Spatial effects (translation, rotation) that change the hit-area considerably should use different source and target keys to avoid flickering on enter/leave.
141
136
 
142
137
  **Default Values**:
143
138
 
144
- - `type`: 'alternate' (plays forward on enter, reverses on leave)
145
- - `DURATION_MS`: 250
139
+ - `DURATION_MS`: 250–300
146
140
  - `EASING_FUNCTION`: 'ease-out'
147
141
 
148
- **Example Generations**:
142
+ **Example — namedEffect (card scale)**:
149
143
 
150
144
  ```typescript
151
- // Card scale effect
152
145
  {
153
146
  key: 'feature-card',
154
147
  trigger: 'hover',
155
- params: {
156
- type: 'alternate'
157
- },
148
+ params: { type: 'alternate' },
158
149
  effects: [
159
150
  {
160
151
  key: 'feature-card',
161
- namedEffect: {
162
- type: 'Pulse'
163
- },
152
+ namedEffect: { type: 'Pulse' },
164
153
  fill: 'both',
165
154
  duration: 250,
166
155
  easing: 'ease-out'
167
156
  }
168
157
  ]
169
158
  }
170
-
171
- // Icon rotation effect (different source/target to avoid flickering)
172
- {
173
- key: 'button',
174
- trigger: 'hover',
175
- params: {
176
- type: 'alternate'
177
- },
178
- effects: [
179
- {
180
- key: 'button-icon',
181
- namedEffect: {
182
- type: 'SpinIn',
183
- direction: 'clockwise'
184
- },
185
- fill: 'both',
186
- duration: 200,
187
- easing: 'ease-out'
188
- }
189
- ]
190
- }
191
159
  ```
192
160
 
193
- ## Rule 3: Hover Interactions with Alternate Pattern
194
-
195
- **Purpose**: Generate hover interactions that play forward on mouse enter and reverse on mouse leave
196
-
197
- **Pattern**:
161
+ **Example keyframeEffect (card lift)**:
198
162
 
199
163
  ```typescript
200
- {
201
- key: '[SOURCE_IDENTIFIER]',
202
- trigger: 'hover',
203
- params: {
204
- type: 'alternate'
205
- },
206
- effects: [
207
- {
208
- key: '[TARGET_IDENTIFIER]',
209
- keyframeEffect: {
210
- name: '[UNIQUE_KEYFRAME_EFFECT_NAME]',
211
- keyframes: [
212
- { [PROPERTY_1]: '[START_VALUE]', [PROPERTY_2]: '[START_VALUE]' },
213
- { [PROPERTY_1]: '[END_VALUE]', [PROPERTY_2]: '[END_VALUE]' }
214
- ]
215
- },
216
- fill: 'both',
217
- duration: [DURATION_MS],
218
- easing: '[EASING_FUNCTION]'
219
- }
220
- ]
221
- }
222
- ```
223
-
224
- **Variables**:
225
-
226
- - `[UNIQUE_KEYFRAME_EFFECT_NAME]`: unique name for the keyframeEffect.
227
- - `[PROPERTY_N]`: animatable CSS property.
228
- - `[START/END_VALUE]`: values for the animated CSS properties in the start/end frame.
229
- - Other variables same as Rule 1
230
-
231
- **Best Properties for Hover Effects**:
232
-
233
- - `transform`: scale, translate, rotate transformations
234
- - `opacity`: fade effects
235
- - `box-shadow`: elevation changes
236
- - `filter`: blur, brightness, hue-rotate
237
- - `background-color`: color transitions
238
- - Spatial effects that change the hit-area of the animated element considerably (e.g. Translation effects, Rotation effects, etc.) should have different source and target to avoid unwanted flickering.
239
-
240
- **Default Values**:
241
-
242
- - `type`: 'alternate'
243
- - `DURATION_MS`: 300
244
- - `EASING_FUNCTION`: 'ease-out'
245
-
246
- **Example Generations**:
247
-
248
- ```typescript
249
- // Card hover with multiple properties
250
164
  {
251
165
  key: 'portfolio-item',
252
166
  trigger: 'hover',
253
- params: {
254
- type: 'alternate'
255
- },
167
+ params: { type: 'alternate' },
256
168
  effects: [
257
169
  {
258
170
  key: 'portfolio-item',
259
171
  keyframeEffect: {
260
- name: 'portfolio',
172
+ name: 'portfolio-lift',
261
173
  keyframes: [
262
- { transform: 'translateY(0)', boxShadow: '0 4px 6px rgba(0,0,0,0.1)', filter: 'brightness(1)' },
263
- { transform: 'translateY(-8px)', boxShadow: '0 20px 25px rgba(0,0,0,0.15)', filter: 'brightness(1.1)' }
174
+ { transform: 'translateY(0)', boxShadow: '0 4px 6px rgba(0,0,0,0.1)' },
175
+ { transform: 'translateY(-8px)', boxShadow: '0 20px 25px rgba(0,0,0,0.15)' }
264
176
  ]
265
177
  },
266
178
  fill: 'both',
@@ -269,33 +181,9 @@ This document contains rules for generating hover trigger interactions in `@wix/
269
181
  }
270
182
  ]
271
183
  }
272
-
273
- // Image overlay reveal
274
- {
275
- key: 'gallery-image',
276
- trigger: 'hover',
277
- params: {
278
- type: 'alternate'
279
- },
280
- effects: [
281
- {
282
- key: 'image-overlay',
283
- keyframeEffect: {
284
- name: 'image-overlay-slide',
285
- keyframes: [
286
- { opacity: '0', transform: 'translateY(100%)' },
287
- { opacity: '1', transform: 'translateY(0)' }
288
- ]
289
- },
290
- fill: 'both',
291
- duration: 250,
292
- easing: 'ease-out'
293
- }
294
- ]
295
- }
296
184
  ```
297
185
 
298
- ## Rule 4: Hover Interactions with Repeat Pattern
186
+ ## Rule 3: Hover Interactions with Repeat Pattern
299
187
 
300
188
  **Purpose**: Generate hover interactions that restart animation each time mouse enters
301
189
 
@@ -303,14 +191,14 @@ This document contains rules for generating hover trigger interactions in `@wix/
303
191
 
304
192
  ```typescript
305
193
  {
306
- key: '[SOURCE_IDENTIFIER]',
194
+ key: '[SOURCE_KEY]',
307
195
  trigger: 'hover',
308
196
  params: {
309
197
  type: 'repeat'
310
198
  },
311
199
  effects: [
312
200
  {
313
- key: '[TARGET_IDENTIFIER]',
201
+ key: '[TARGET_KEY]',
314
202
  [EFFECT_TYPE]: [EFFECT_DEFINITION],
315
203
  duration: [DURATION_MS],
316
204
  easing: '[EASING_FUNCTION]'
@@ -384,7 +272,7 @@ This document contains rules for generating hover trigger interactions in `@wix/
384
272
  }
385
273
  ```
386
274
 
387
- ## Rule 5: Hover Interactions with Play/Pause Pattern
275
+ ## Rule 4: Hover Interactions with Play/Pause Pattern
388
276
 
389
277
  **Purpose**: Generate hover interactions that pause/resume on hover (state-based control)
390
278
 
@@ -392,14 +280,14 @@ This document contains rules for generating hover trigger interactions in `@wix/
392
280
 
393
281
  ```typescript
394
282
  {
395
- key: '[SOURCE_IDENTIFIER]',
283
+ key: '[SOURCE_KEY]',
396
284
  trigger: 'hover',
397
285
  params: {
398
286
  type: 'state'
399
287
  },
400
288
  effects: [
401
289
  {
402
- key: '[TARGET_IDENTIFIER]',
290
+ key: '[TARGET_KEY]',
403
291
  [EFFECT_TYPE]: [EFFECT_DEFINITION],
404
292
  duration: [DURATION_MS],
405
293
  iterations: Infinity,
@@ -475,7 +363,7 @@ This document contains rules for generating hover trigger interactions in `@wix/
475
363
  }
476
364
  ```
477
365
 
478
- ## Rule 6: Multi-Target Hover Effects
366
+ ## Rule 5: Multi-Target Hover Effects
479
367
 
480
368
  **Purpose**: Generate hover interactions that affect multiple elements from a single source
481
369
 
@@ -483,7 +371,7 @@ This document contains rules for generating hover trigger interactions in `@wix/
483
371
 
484
372
  ```typescript
485
373
  {
486
- key: '[SOURCE_IDENTIFIER]',
374
+ key: '[SOURCE_KEY]',
487
375
  trigger: 'hover',
488
376
  params: {
489
377
  type: '[BEHAVIOR_TYPE]'
@@ -512,7 +400,7 @@ This document contains rules for generating hover trigger interactions in `@wix/
512
400
  **Variables**:
513
401
 
514
402
  - `[BEHAVIOR_TYPE]`: type of behavior for the effect. use `alternate`, `repeat`, or `state` according to the previous rules.
515
- - `[FILL_N]`: Optional fill value for the Nth effect - same ass CSS animation-fill-mode (e.g. 'both', 'forwards', 'backwards').
403
+ - `[FILL_N]`: Optional fill value for the Nth effect - same as CSS animation-fill-mode (e.g. 'both', 'forwards', 'backwards').
516
404
  - `[REVERSED_BOOL_N]`: Same as `[REVERSED_BOOL]` from Rule 2 only for the Nth effect.
517
405
  - `[DURATION_N]`: Same as `[DURATION_MS]` from Rule 1 only for the Nth effect.
518
406
  - `[DELAY_N]`: Delay in milliseconds of the Nth effect.
@@ -596,12 +484,85 @@ This document contains rules for generating hover trigger interactions in `@wix/
596
484
  }
597
485
  ```
598
486
 
487
+ ## Rule 6: Hover with Sequence (Staggered Multi-Target)
488
+
489
+ **Purpose**: Hover interactions that stagger animations across multiple targets using a sequence instead of manual delays.
490
+
491
+ **When to Apply**:
492
+
493
+ - When hovering a container should stagger-animate its children
494
+ - For list item hover effects with coordinated timing
495
+ - When you want easing-controlled stagger on hover
496
+
497
+ **Pattern**:
498
+
499
+ ```typescript
500
+ {
501
+ key: '[SOURCE_KEY]',
502
+ trigger: 'hover',
503
+ params: {
504
+ type: 'repeat'
505
+ },
506
+ sequences: [
507
+ {
508
+ offset: [OFFSET_MS],
509
+ offsetEasing: '[OFFSET_EASING]',
510
+ effects: [
511
+ {
512
+ effectId: '[EFFECT_ID]',
513
+ listContainer: '[LIST_CONTAINER_SELECTOR]'
514
+ }
515
+ ]
516
+ }
517
+ ]
518
+ }
519
+ ```
520
+
521
+ **Example - Hover Card Grid Stagger**:
522
+
523
+ ```typescript
524
+ {
525
+ key: 'card-grid',
526
+ trigger: 'hover',
527
+ params: { type: 'repeat' },
528
+ sequences: [
529
+ {
530
+ offset: 80,
531
+ offsetEasing: 'sineOut',
532
+ effects: [
533
+ {
534
+ effectId: 'item-pop',
535
+ listContainer: '.card-grid-items'
536
+ }
537
+ ]
538
+ }
539
+ ]
540
+ }
541
+ ```
542
+
543
+ ```typescript
544
+ effects: {
545
+ 'item-pop': {
546
+ duration: 400,
547
+ easing: 'cubic-bezier(0.4, 0, 0.2, 1)',
548
+ keyframeEffect: {
549
+ name: 'item-pop',
550
+ keyframes: [
551
+ { transform: 'translateY(16px) scale(0.95)', opacity: 0 },
552
+ { transform: 'translateY(0) scale(1)', opacity: 1 }
553
+ ]
554
+ }
555
+ }
556
+ }
557
+ ```
558
+
559
+ ---
560
+
599
561
  ## Best Practices for Hover Rules
600
562
 
601
- ### Performance Guidelines
563
+ ### Timing and Pattern Guidelines
602
564
 
603
565
  1. **Keep durations short** (100-400ms) for responsiveness
604
- 2. **Avoid animating layout properties**: width, height, margin, padding
605
566
 
606
567
  ### User Experience Guidelines
607
568
 
@@ -623,3 +584,31 @@ This document contains rules for generating hover trigger interactions in `@wix/
623
584
  - **Interactive elements**: 'ease-in-out' (smooth both ways)
624
585
  - **Attention effects**: 'ease-in-out' (natural feel)
625
586
  - **Continuous motion**: 'linear' (consistent speed)
587
+
588
+ ## Accessibility
589
+
590
+ Use `@wix/interact`'s `conditions` API to skip hover animations for users who prefer reduced motion. Define a `prefers-motion` condition and reference it on any interaction that should be suppressed:
591
+
592
+ ```typescript
593
+ {
594
+ conditions: {
595
+ 'prefers-motion': { type: 'media', predicate: '(prefers-reduced-motion: no-preference)' }
596
+ },
597
+ interactions: [
598
+ {
599
+ key: 'card',
600
+ trigger: 'hover',
601
+ conditions: ['prefers-motion'], // skipped when reduced-motion is preferred
602
+ effects: [/* ... */]
603
+ }
604
+ ]
605
+ }
606
+ ```
607
+
608
+ For pointer-primary devices only, also consider adding a `hover-capable` condition:
609
+
610
+ ```typescript
611
+ 'hover-capable': { type: 'media', predicate: '(hover: hover)' }
612
+ ```
613
+
614
+ Use `trigger: 'interest'` instead of `'hover'` to also handle keyboard focus, which is the accessible equivalent of hover.