@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.
- 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-BfcN_rkn.mjs → index-BP07b-Y1.mjs} +1202 -751
- package/dist/index-BP07b-Y1.mjs.map +1 -0
- package/dist/index-D4orAyUu.js +18 -0
- package/dist/index-D4orAyUu.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types/core/Interact.d.ts +12 -1
- package/dist/types/core/Interact.d.ts.map +1 -1
- package/dist/types/core/add.d.ts.map +1 -1
- package/dist/types/core/remove.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/effectHandlers.d.ts +2 -1
- package/dist/types/handlers/effectHandlers.d.ts.map +1 -1
- package/dist/types/handlers/eventTrigger.d.ts +1 -1
- package/dist/types/handlers/eventTrigger.d.ts.map +1 -1
- package/dist/types/handlers/viewEnter.d.ts +1 -1
- package/dist/types/handlers/viewEnter.d.ts.map +1 -1
- package/dist/types/types.d.ts +29 -2
- package/dist/types/types.d.ts.map +1 -1
- package/docs/api/types.md +114 -0
- package/docs/examples/README.md +10 -1
- package/docs/examples/list-patterns.md +148 -0
- package/docs/guides/README.md +5 -0
- package/docs/guides/sequences.md +421 -0
- package/package.json +2 -2
- package/rules/MASTER-CLEANUP-PLAN.md +286 -0
- package/rules/click.md +124 -32
- package/rules/full-lean.md +93 -7
- package/rules/hover.md +142 -153
- package/rules/integration.md +83 -82
- package/rules/pointermove.md +32 -57
- package/rules/scroll-list.md +82 -280
- package/rules/viewenter.md +158 -253
- package/rules/viewprogress.md +139 -845
- package/dist/index-BfcN_rkn.mjs.map +0 -1
- package/dist/index-HXLBEIjG.js +0 -18
- package/dist/index-HXLBEIjG.js.map +0 -1
|
@@ -12,6 +12,7 @@ Comprehensive examples of list and grid animations using `@wix/interact`. All ex
|
|
|
12
12
|
- [Filtering & Sorting](#filtering--sorting)
|
|
13
13
|
- [Grid Layouts](#grid-layouts)
|
|
14
14
|
- [Real-World Examples](#real-world-examples)
|
|
15
|
+
- [Sequence-Based Staggering](#sequence-based-staggering)
|
|
15
16
|
|
|
16
17
|
## Entrance Animations
|
|
17
18
|
|
|
@@ -799,8 +800,155 @@ const config = {
|
|
|
799
800
|
</interact-element>
|
|
800
801
|
```
|
|
801
802
|
|
|
803
|
+
## Sequence-Based Staggering
|
|
804
|
+
|
|
805
|
+
The `sequences` config provides built-in stagger support with easing-driven delay distribution — no CSS `animation-delay` hacks needed.
|
|
806
|
+
|
|
807
|
+
### 17. Staggered List Entrance with Sequences
|
|
808
|
+
|
|
809
|
+
```typescript
|
|
810
|
+
const config = {
|
|
811
|
+
interactions: [
|
|
812
|
+
{
|
|
813
|
+
key: 'cards',
|
|
814
|
+
trigger: 'viewEnter',
|
|
815
|
+
listContainer: '.card-grid',
|
|
816
|
+
params: { type: 'once', threshold: 0.1 },
|
|
817
|
+
sequences: [
|
|
818
|
+
{
|
|
819
|
+
offset: 80,
|
|
820
|
+
offsetEasing: 'quadIn',
|
|
821
|
+
effects: [
|
|
822
|
+
{
|
|
823
|
+
key: 'cards',
|
|
824
|
+
listContainer: '.card-grid',
|
|
825
|
+
effectId: 'card-entrance',
|
|
826
|
+
},
|
|
827
|
+
],
|
|
828
|
+
},
|
|
829
|
+
],
|
|
830
|
+
},
|
|
831
|
+
],
|
|
832
|
+
effects: {
|
|
833
|
+
'card-entrance': {
|
|
834
|
+
duration: 600,
|
|
835
|
+
easing: 'cubic-bezier(0.16, 1, 0.3, 1)',
|
|
836
|
+
keyframeEffect: {
|
|
837
|
+
name: 'card-entrance',
|
|
838
|
+
keyframes: [
|
|
839
|
+
{ opacity: '0', transform: 'translateY(40px) scale(0.95)' },
|
|
840
|
+
{ opacity: '1', transform: 'translateY(0) scale(1)' },
|
|
841
|
+
],
|
|
842
|
+
},
|
|
843
|
+
},
|
|
844
|
+
},
|
|
845
|
+
};
|
|
846
|
+
|
|
847
|
+
Interact.create(config);
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
### 18. Dynamic List Items with Sequences
|
|
851
|
+
|
|
852
|
+
New items added to the DOM automatically join the Sequence with recalculated stagger offsets:
|
|
853
|
+
|
|
854
|
+
```typescript
|
|
855
|
+
const config = {
|
|
856
|
+
interactions: [
|
|
857
|
+
{
|
|
858
|
+
key: 'feed',
|
|
859
|
+
trigger: 'viewEnter',
|
|
860
|
+
listContainer: '.feed-items',
|
|
861
|
+
params: { type: 'repeat' },
|
|
862
|
+
sequences: [
|
|
863
|
+
{
|
|
864
|
+
offset: 60,
|
|
865
|
+
offsetEasing: 'sineOut',
|
|
866
|
+
effects: [
|
|
867
|
+
{
|
|
868
|
+
key: 'feed',
|
|
869
|
+
listContainer: '.feed-items',
|
|
870
|
+
keyframeEffect: {
|
|
871
|
+
name: 'feed-entrance',
|
|
872
|
+
keyframes: [
|
|
873
|
+
{ opacity: '0', transform: 'translateY(20px)' },
|
|
874
|
+
{ opacity: '1', transform: 'translateY(0)' },
|
|
875
|
+
],
|
|
876
|
+
},
|
|
877
|
+
duration: 400,
|
|
878
|
+
easing: 'ease-out',
|
|
879
|
+
},
|
|
880
|
+
],
|
|
881
|
+
},
|
|
882
|
+
],
|
|
883
|
+
},
|
|
884
|
+
],
|
|
885
|
+
effects: {},
|
|
886
|
+
};
|
|
887
|
+
|
|
888
|
+
Interact.create(config);
|
|
889
|
+
```
|
|
890
|
+
|
|
891
|
+
### 19. Easing Comparison for List Stagger
|
|
892
|
+
|
|
893
|
+
Different `offsetEasing` values produce distinct stagger patterns:
|
|
894
|
+
|
|
895
|
+
```typescript
|
|
896
|
+
// Linear: even spacing (0, 80, 160, 240, 320ms)
|
|
897
|
+
{ offset: 80, offsetEasing: 'linear' }
|
|
898
|
+
|
|
899
|
+
// quadIn: slow start then rapid (0, 20, 80, 180, 320ms)
|
|
900
|
+
{ offset: 80, offsetEasing: 'quadIn' }
|
|
901
|
+
|
|
902
|
+
// sineOut: fast start then gradual (0, 125, 227, 302, 320ms)
|
|
903
|
+
{ offset: 80, offsetEasing: 'sineOut' }
|
|
904
|
+
```
|
|
905
|
+
|
|
906
|
+
### 20. Reusable Sequences with `sequenceId`
|
|
907
|
+
|
|
908
|
+
Define a sequence once, reference it from multiple interactions:
|
|
909
|
+
|
|
910
|
+
```typescript
|
|
911
|
+
const config = {
|
|
912
|
+
sequences: {
|
|
913
|
+
'list-stagger': {
|
|
914
|
+
offset: 100,
|
|
915
|
+
offsetEasing: 'quadIn',
|
|
916
|
+
effects: [{ effectId: 'fade-up' }],
|
|
917
|
+
},
|
|
918
|
+
},
|
|
919
|
+
interactions: [
|
|
920
|
+
{
|
|
921
|
+
key: 'section-a',
|
|
922
|
+
trigger: 'viewEnter',
|
|
923
|
+
listContainer: '.list-a',
|
|
924
|
+
sequences: [{ sequenceId: 'list-stagger' }],
|
|
925
|
+
},
|
|
926
|
+
{
|
|
927
|
+
key: 'section-b',
|
|
928
|
+
trigger: 'viewEnter',
|
|
929
|
+
listContainer: '.list-b',
|
|
930
|
+
sequences: [{ sequenceId: 'list-stagger', offset: 150 }], // Override offset
|
|
931
|
+
},
|
|
932
|
+
],
|
|
933
|
+
effects: {
|
|
934
|
+
'fade-up': {
|
|
935
|
+
duration: 500,
|
|
936
|
+
easing: 'ease-out',
|
|
937
|
+
keyframeEffect: {
|
|
938
|
+
name: 'fade-up',
|
|
939
|
+
keyframes: [
|
|
940
|
+
{ opacity: '0', transform: 'translateY(20px)' },
|
|
941
|
+
{ opacity: '1', transform: 'translateY(0)' },
|
|
942
|
+
],
|
|
943
|
+
},
|
|
944
|
+
},
|
|
945
|
+
},
|
|
946
|
+
};
|
|
947
|
+
```
|
|
948
|
+
|
|
802
949
|
## See Also
|
|
803
950
|
|
|
951
|
+
- [Sequences & Staggering Guide](../guides/sequences.md)
|
|
804
952
|
- [Lists and Dynamic Content Guide](../guides/lists-and-dynamic-content.md)
|
|
805
953
|
- [Element Selection](../api/element-selection.md)
|
|
806
954
|
- [Performance Guide](../guides/performance.md)
|
package/docs/guides/README.md
CHANGED
|
@@ -36,6 +36,10 @@ Creating responsive interactions that adapt to different screen sizes and condit
|
|
|
36
36
|
|
|
37
37
|
Working with dynamic lists, list containers, staggered animations, and automatic mutation tracking.
|
|
38
38
|
|
|
39
|
+
### 🎼 [Sequences & Staggering](./sequences.md)
|
|
40
|
+
|
|
41
|
+
Coordinate multiple effects with staggered timing using easing-driven delay offsets. Covers inline and reusable sequences, cross-element orchestration, `listContainer` integration, dynamic add/remove, and conditional sequences.
|
|
42
|
+
|
|
39
43
|
## Learning Path
|
|
40
44
|
|
|
41
45
|
If you're new to `@wix/interact`, we recommend following the guides in this order:
|
|
@@ -48,6 +52,7 @@ If you're new to `@wix/interact`, we recommend following the guides in this orde
|
|
|
48
52
|
6. **Lists and Dynamic Content** - Work with repeating elements
|
|
49
53
|
7. **State Management** - Advanced state handling
|
|
50
54
|
8. **Conditions and Media Queries** - Responsive design
|
|
55
|
+
9. **Sequences & Staggering** - Coordinated multi-effect timing
|
|
51
56
|
|
|
52
57
|
## Prerequisites
|
|
53
58
|
|
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
# Sequences & Staggering
|
|
2
|
+
|
|
3
|
+
Sequences let you coordinate multiple effects as a single timeline with staggered delay offsets. Built on the `@wix/motion` `Sequence` class, they provide easing-driven timing distribution across effects — ideal for list entrances, multi-element orchestrations, and any pattern requiring coordinated animation timing.
|
|
4
|
+
|
|
5
|
+
## What is a Sequence?
|
|
6
|
+
|
|
7
|
+
A Sequence groups multiple effects and applies calculated delay offsets to each one, so they play back in a staggered pattern. The stagger timing is shaped by an easing function, producing natural-feeling cascades rather than uniform delays.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
offset[i] = easing(i / last) * last * offsetMs
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
For example, with 5 effects and `offset: 200`:
|
|
14
|
+
|
|
15
|
+
| Easing | Computed delays | Feel |
|
|
16
|
+
| --------- | --------------------- | ------------------------ |
|
|
17
|
+
| `linear` | 0, 200, 400, 600, 800 | Even spacing |
|
|
18
|
+
| `quadIn` | 0, 50, 200, 450, 800 | Slow start, then rapid |
|
|
19
|
+
| `sineOut` | 0, 306, 565, 739, 800 | Fast start, then gradual |
|
|
20
|
+
|
|
21
|
+
## Config Structure
|
|
22
|
+
|
|
23
|
+
Sequences can be defined at two levels:
|
|
24
|
+
|
|
25
|
+
### Reusable Sequences (`InteractConfig.sequences`)
|
|
26
|
+
|
|
27
|
+
Define named sequences in the top-level `sequences` map, then reference them by ID from any interaction:
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
const config: InteractConfig = {
|
|
31
|
+
sequences: {
|
|
32
|
+
'card-stagger': {
|
|
33
|
+
offset: 150,
|
|
34
|
+
offsetEasing: 'quadIn',
|
|
35
|
+
effects: [{ effectId: 'fade-up' }],
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
interactions: [
|
|
39
|
+
{
|
|
40
|
+
key: 'cards',
|
|
41
|
+
trigger: 'viewEnter',
|
|
42
|
+
listContainer: '.card-grid',
|
|
43
|
+
sequences: [{ sequenceId: 'card-stagger' }],
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
effects: {
|
|
47
|
+
'fade-up': {
|
|
48
|
+
duration: 600,
|
|
49
|
+
easing: 'ease-out',
|
|
50
|
+
keyframeEffect: {
|
|
51
|
+
name: 'fade-up',
|
|
52
|
+
keyframes: [
|
|
53
|
+
{ opacity: 0, transform: 'translateY(20px)' },
|
|
54
|
+
{ opacity: 1, transform: 'translateY(0)' },
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Inline Sequences (`Interaction.sequences`)
|
|
63
|
+
|
|
64
|
+
Define sequences directly on an interaction:
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
const config: InteractConfig = {
|
|
68
|
+
interactions: [
|
|
69
|
+
{
|
|
70
|
+
key: 'items',
|
|
71
|
+
trigger: 'viewEnter',
|
|
72
|
+
listContainer: '.item-list',
|
|
73
|
+
sequences: [
|
|
74
|
+
{
|
|
75
|
+
offset: 100,
|
|
76
|
+
offsetEasing: 'sineOut',
|
|
77
|
+
effects: [
|
|
78
|
+
{
|
|
79
|
+
duration: 500,
|
|
80
|
+
keyframeEffect: {
|
|
81
|
+
name: 'slide-in',
|
|
82
|
+
keyframes: [
|
|
83
|
+
{ opacity: 0, transform: 'translateX(-30px)' },
|
|
84
|
+
{ opacity: 1, transform: 'translateX(0)' },
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
effects: {},
|
|
94
|
+
};
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Combining Effects and Sequences
|
|
98
|
+
|
|
99
|
+
An interaction can have both `effects` and `sequences`:
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
{
|
|
103
|
+
key: 'hero',
|
|
104
|
+
trigger: 'viewEnter',
|
|
105
|
+
effects: [{ effectId: 'background-fade' }],
|
|
106
|
+
sequences: [{
|
|
107
|
+
offset: 200,
|
|
108
|
+
effects: [
|
|
109
|
+
{ key: 'hero-title', effectId: 'slide-down' },
|
|
110
|
+
{ key: 'hero-subtitle', effectId: 'fade-in' },
|
|
111
|
+
],
|
|
112
|
+
}],
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Types Reference
|
|
117
|
+
|
|
118
|
+
### `SequenceOptionsConfig`
|
|
119
|
+
|
|
120
|
+
Shared options for sequence timing and identity:
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
type SequenceOptionsConfig = {
|
|
124
|
+
delay?: number; // Base delay (ms). Default: 0
|
|
125
|
+
offset?: number; // Stagger interval (ms). Default: 0
|
|
126
|
+
offsetEasing?: string | ((p: number) => number); // Easing for offset distribution
|
|
127
|
+
sequenceId?: string; // ID for reusable sequence reference
|
|
128
|
+
conditions?: string[]; // Media query condition IDs
|
|
129
|
+
};
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### `SequenceConfig`
|
|
133
|
+
|
|
134
|
+
Inline sequence definition (extends `SequenceOptionsConfig`):
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
type SequenceConfig = SequenceOptionsConfig & {
|
|
138
|
+
effects: (Effect | EffectRef)[];
|
|
139
|
+
};
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### `SequenceConfigRef`
|
|
143
|
+
|
|
144
|
+
Reference to a reusable sequence with optional overrides:
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
type SequenceConfigRef = {
|
|
148
|
+
sequenceId: string;
|
|
149
|
+
delay?: number;
|
|
150
|
+
offset?: number;
|
|
151
|
+
offsetEasing?: string | ((p: number) => number);
|
|
152
|
+
conditions?: string[];
|
|
153
|
+
};
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Overrides in the ref merge on top of the referenced sequence's values.
|
|
157
|
+
|
|
158
|
+
## Cross-Element Sequences
|
|
159
|
+
|
|
160
|
+
Effects within a sequence can target different elements using the `key` property:
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
{
|
|
164
|
+
key: 'trigger-element',
|
|
165
|
+
trigger: 'click',
|
|
166
|
+
params: { type: 'alternate' },
|
|
167
|
+
sequences: [{
|
|
168
|
+
offset: 150,
|
|
169
|
+
offsetEasing: 'sineOut',
|
|
170
|
+
effects: [
|
|
171
|
+
{ key: 'heading', effectId: 'slide-down' },
|
|
172
|
+
{ key: 'body-text', effectId: 'fade-in' },
|
|
173
|
+
{ key: 'hero-image', effectId: 'scale-in' },
|
|
174
|
+
],
|
|
175
|
+
}],
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Cross-element sequences are resolved at add-time. When a sequence effect targets a `key` different from the source interaction, Interact waits for both elements to be registered before creating the Sequence. The effects are processed via `addEffectsForTarget()` when the target controller connects.
|
|
180
|
+
|
|
181
|
+
## Sequences with `listContainer`
|
|
182
|
+
|
|
183
|
+
The most common use case: staggering list item animations.
|
|
184
|
+
|
|
185
|
+
### Initial Load
|
|
186
|
+
|
|
187
|
+
When the source element connects, all existing list items are gathered and a Sequence is created with one `AnimationGroup` per item:
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
{
|
|
191
|
+
key: 'product-grid',
|
|
192
|
+
trigger: 'viewEnter',
|
|
193
|
+
listContainer: '.products',
|
|
194
|
+
params: { type: 'once' },
|
|
195
|
+
sequences: [{
|
|
196
|
+
offset: 80,
|
|
197
|
+
offsetEasing: 'quadIn',
|
|
198
|
+
effects: [{
|
|
199
|
+
key: 'product-grid',
|
|
200
|
+
listContainer: '.products',
|
|
201
|
+
effectId: 'card-entrance',
|
|
202
|
+
}],
|
|
203
|
+
}],
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Dynamic Additions (`addListItems`)
|
|
208
|
+
|
|
209
|
+
When new items are appended to the DOM (detected by MutationObserver), `addListItems` is called. For sequences, this calls `Interact.addToSequence()` with `IndexedGroup` entries at the correct indices, triggering automatic offset recalculation across the entire Sequence.
|
|
210
|
+
|
|
211
|
+
Each `addListItems` invocation uses a unique cache key to manage its Sequence independently.
|
|
212
|
+
|
|
213
|
+
### Dynamic Removals (`removeListItems`)
|
|
214
|
+
|
|
215
|
+
When items are removed from the DOM, `removeListItems` automatically calls `Interact.removeFromSequences(elements)`. This:
|
|
216
|
+
|
|
217
|
+
1. Looks up associated Sequences via the `elementSequenceMap` WeakMap (O(1) per element)
|
|
218
|
+
2. Calls `sequence.removeGroups()` to cancel and remove the matching groups
|
|
219
|
+
3. Recalculates offsets for remaining groups
|
|
220
|
+
4. Cleans up the element from the map
|
|
221
|
+
|
|
222
|
+
No manual cleanup is needed — MutationObserver handles it automatically.
|
|
223
|
+
|
|
224
|
+
## Conditions on Sequences
|
|
225
|
+
|
|
226
|
+
### Sequence-Level Conditions
|
|
227
|
+
|
|
228
|
+
Gate an entire sequence with media query conditions:
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
{
|
|
232
|
+
key: 'hero',
|
|
233
|
+
trigger: 'viewEnter',
|
|
234
|
+
sequences: [{
|
|
235
|
+
conditions: ['desktop-only'],
|
|
236
|
+
offset: 200,
|
|
237
|
+
effects: [
|
|
238
|
+
{ key: 'hero-title', effectId: 'slide-down' },
|
|
239
|
+
{ key: 'hero-body', effectId: 'fade-in' },
|
|
240
|
+
],
|
|
241
|
+
}],
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
When the condition doesn't match, the entire sequence is skipped. Interact sets up `matchMedia` listeners so the sequence is added/removed dynamically when the condition changes.
|
|
246
|
+
|
|
247
|
+
### Effect-Level Conditions
|
|
248
|
+
|
|
249
|
+
Individual effects within a sequence can have their own conditions:
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
sequences: [
|
|
253
|
+
{
|
|
254
|
+
offset: 150,
|
|
255
|
+
effects: [
|
|
256
|
+
{ effectId: 'base-entrance' },
|
|
257
|
+
{ effectId: 'fancy-entrance', conditions: ['desktop-only'] },
|
|
258
|
+
],
|
|
259
|
+
},
|
|
260
|
+
];
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
When an effect-level condition doesn't match, that effect is excluded from the Sequence's animation groups, and offsets are calculated for the remaining effects only.
|
|
264
|
+
|
|
265
|
+
## Sequence Caching
|
|
266
|
+
|
|
267
|
+
Interact caches Sequences to avoid recreating them:
|
|
268
|
+
|
|
269
|
+
- **`Interact.sequenceCache`** (`Map<string, Sequence>`) — maps cache keys to Sequence instances
|
|
270
|
+
- **`Interact.elementSequenceMap`** (`WeakMap<HTMLElement, Set<Sequence>>`) — maps elements to their Sequences for efficient removal
|
|
271
|
+
|
|
272
|
+
Cache keys are derived from the interaction key, sequence index, and context. Cleanup happens automatically:
|
|
273
|
+
|
|
274
|
+
- `Interact.destroy()` clears both `sequenceCache` and `elementSequenceMap`
|
|
275
|
+
- `clearInteractionStateForKey()` removes cache entries by key prefix
|
|
276
|
+
- Element removal cleans up `elementSequenceMap` entries via the WeakMap
|
|
277
|
+
|
|
278
|
+
## Examples
|
|
279
|
+
|
|
280
|
+
### Staggered Card Grid Entrance
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
const config: InteractConfig = {
|
|
284
|
+
interactions: [
|
|
285
|
+
{
|
|
286
|
+
key: 'cards',
|
|
287
|
+
trigger: 'viewEnter',
|
|
288
|
+
listContainer: '.card-grid',
|
|
289
|
+
params: { type: 'once', threshold: 0.1 },
|
|
290
|
+
sequences: [
|
|
291
|
+
{
|
|
292
|
+
offset: 80,
|
|
293
|
+
offsetEasing: 'quadIn',
|
|
294
|
+
effects: [
|
|
295
|
+
{
|
|
296
|
+
key: 'cards',
|
|
297
|
+
listContainer: '.card-grid',
|
|
298
|
+
effectId: 'card-entrance',
|
|
299
|
+
},
|
|
300
|
+
],
|
|
301
|
+
},
|
|
302
|
+
],
|
|
303
|
+
},
|
|
304
|
+
],
|
|
305
|
+
effects: {
|
|
306
|
+
'card-entrance': {
|
|
307
|
+
duration: 600,
|
|
308
|
+
easing: 'cubic-bezier(0.16, 1, 0.3, 1)',
|
|
309
|
+
keyframeEffect: {
|
|
310
|
+
name: 'card-entrance',
|
|
311
|
+
keyframes: [
|
|
312
|
+
{ opacity: 0, transform: 'translateY(40px) scale(0.95)' },
|
|
313
|
+
{ opacity: 1, transform: 'translateY(0) scale(1)' },
|
|
314
|
+
],
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
},
|
|
318
|
+
};
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### Click-Triggered Multi-Element Orchestration
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
const config: InteractConfig = {
|
|
325
|
+
interactions: [
|
|
326
|
+
{
|
|
327
|
+
key: 'reveal-btn',
|
|
328
|
+
trigger: 'click',
|
|
329
|
+
params: { type: 'alternate' },
|
|
330
|
+
sequences: [
|
|
331
|
+
{
|
|
332
|
+
offset: 150,
|
|
333
|
+
offsetEasing: 'sineOut',
|
|
334
|
+
effects: [
|
|
335
|
+
{ key: 'section-heading', effectId: 'slide-down' },
|
|
336
|
+
{ key: 'section-body', effectId: 'fade-in' },
|
|
337
|
+
{ key: 'section-image', effectId: 'scale-in' },
|
|
338
|
+
],
|
|
339
|
+
},
|
|
340
|
+
],
|
|
341
|
+
},
|
|
342
|
+
],
|
|
343
|
+
effects: {
|
|
344
|
+
'slide-down': {
|
|
345
|
+
duration: 400,
|
|
346
|
+
keyframeEffect: {
|
|
347
|
+
name: 'slide-down',
|
|
348
|
+
keyframes: [
|
|
349
|
+
{ transform: 'translateY(-20px)', opacity: 0 },
|
|
350
|
+
{ transform: 'translateY(0)', opacity: 1 },
|
|
351
|
+
],
|
|
352
|
+
},
|
|
353
|
+
},
|
|
354
|
+
'fade-in': {
|
|
355
|
+
duration: 500,
|
|
356
|
+
keyframeEffect: {
|
|
357
|
+
name: 'fade-in',
|
|
358
|
+
keyframes: [{ opacity: 0 }, { opacity: 1 }],
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
'scale-in': {
|
|
362
|
+
duration: 600,
|
|
363
|
+
keyframeEffect: {
|
|
364
|
+
name: 'scale-in',
|
|
365
|
+
keyframes: [
|
|
366
|
+
{ transform: 'scale(0.9)', opacity: 0 },
|
|
367
|
+
{ transform: 'scale(1)', opacity: 1 },
|
|
368
|
+
],
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
},
|
|
372
|
+
};
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### Sequence with Media-Query Conditions
|
|
376
|
+
|
|
377
|
+
```typescript
|
|
378
|
+
const config: InteractConfig = {
|
|
379
|
+
conditions: {
|
|
380
|
+
'desktop-only': { type: 'media', predicate: '(min-width: 1024px)' },
|
|
381
|
+
'no-reduced-motion': { type: 'media', predicate: '(prefers-reduced-motion: no-preference)' },
|
|
382
|
+
},
|
|
383
|
+
interactions: [
|
|
384
|
+
{
|
|
385
|
+
key: 'features',
|
|
386
|
+
trigger: 'viewEnter',
|
|
387
|
+
listContainer: '.feature-list',
|
|
388
|
+
conditions: ['no-reduced-motion'],
|
|
389
|
+
sequences: [
|
|
390
|
+
{
|
|
391
|
+
conditions: ['desktop-only'],
|
|
392
|
+
offset: 120,
|
|
393
|
+
offsetEasing: 'quadIn',
|
|
394
|
+
effects: [{ effectId: 'feature-entrance' }],
|
|
395
|
+
},
|
|
396
|
+
],
|
|
397
|
+
},
|
|
398
|
+
],
|
|
399
|
+
effects: {
|
|
400
|
+
'feature-entrance': {
|
|
401
|
+
duration: 700,
|
|
402
|
+
easing: 'ease-out',
|
|
403
|
+
keyframeEffect: {
|
|
404
|
+
name: 'feature-entrance',
|
|
405
|
+
keyframes: [
|
|
406
|
+
{ opacity: 0, transform: 'translateY(30px)' },
|
|
407
|
+
{ opacity: 1, transform: 'translateY(0)' },
|
|
408
|
+
],
|
|
409
|
+
},
|
|
410
|
+
},
|
|
411
|
+
},
|
|
412
|
+
};
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
## See Also
|
|
416
|
+
|
|
417
|
+
- [Lists and Dynamic Content](./lists-and-dynamic-content.md) — `listContainer`, `addListItems`, mutation tracking
|
|
418
|
+
- [Conditions and Media Queries](./conditions-and-media-queries.md) — conditional interactions
|
|
419
|
+
- [Effects and Animations](./effects-and-animations.md) — effect types and properties
|
|
420
|
+
- [Interact Class API](../api/interact-class.md) — `getSequence()`, `addToSequence()`, `removeFromSequences()`
|
|
421
|
+
- [Type Definitions](../api/types.md) — `SequenceConfig`, `SequenceConfigRef`, `SequenceOptionsConfig`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/interact",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "A powerful, declarative interaction library for creating engaging web apps.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/cjs/index.js",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"url": "https://github.com/wix/interact/issues"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@wix/motion": "^2.
|
|
58
|
+
"@wix/motion": "^2.1.0",
|
|
59
59
|
"fastdom": "^1.0.12",
|
|
60
60
|
"fizban": "^0.7.2",
|
|
61
61
|
"kuliso": "^0.4.13"
|