@wix/interact 1.74.0 → 1.76.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 +33 -21
- package/dist/cjs/WixInteractElement.js +61 -17
- package/dist/cjs/WixInteractElement.js.map +1 -1
- package/dist/cjs/__tests__/interact.spec.js +761 -109
- package/dist/cjs/__tests__/interact.spec.js.map +1 -1
- package/dist/cjs/core/Interact.js +190 -0
- package/dist/cjs/core/Interact.js.map +1 -0
- package/dist/cjs/core/add.js +231 -0
- package/dist/cjs/core/add.js.map +1 -0
- package/dist/cjs/core/remove.js +37 -0
- package/dist/cjs/core/remove.js.map +1 -0
- package/dist/cjs/handlers/click.js +1 -1
- package/dist/cjs/handlers/click.js.map +1 -1
- package/dist/cjs/handlers/hover.js +1 -1
- package/dist/cjs/handlers/hover.js.map +1 -1
- package/dist/cjs/index.js +6 -4
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/utils.js +12 -10
- package/dist/cjs/utils.js.map +1 -1
- package/dist/esm/WixInteractElement.js +61 -17
- package/dist/esm/WixInteractElement.js.map +1 -1
- package/dist/esm/__tests__/interact.spec.js +743 -91
- package/dist/esm/__tests__/interact.spec.js.map +1 -1
- package/dist/esm/core/Interact.js +186 -0
- package/dist/esm/core/Interact.js.map +1 -0
- package/dist/esm/core/add.js +226 -0
- package/dist/esm/core/add.js.map +1 -0
- package/dist/esm/core/remove.js +32 -0
- package/dist/esm/core/remove.js.map +1 -0
- package/dist/esm/handlers/click.js +1 -1
- package/dist/esm/handlers/click.js.map +1 -1
- package/dist/esm/handlers/hover.js +1 -1
- package/dist/esm/handlers/hover.js.map +1 -1
- package/dist/esm/index.js +3 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/utils.js +12 -10
- package/dist/esm/utils.js.map +1 -1
- package/dist/types/WixInteractElement.d.ts +5 -2
- package/dist/types/core/Interact.d.ts +24 -0
- package/dist/types/core/add.d.ts +6 -0
- package/dist/types/core/remove.d.ts +5 -0
- package/dist/types/index.d.ts +3 -1
- package/dist/types/types.d.ts +22 -9
- package/dist/types/utils.d.ts +1 -1
- package/package.json +7 -6
- package/dist/cjs/interact.js +0 -308
- package/dist/cjs/interact.js.map +0 -1
- package/dist/esm/interact.js +0 -301
- package/dist/esm/interact.js.map +0 -1
- package/dist/types/interact.d.ts +0 -26
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _Interact = require("../core/Interact");
|
|
4
|
+
var _add = require("../core/add");
|
|
5
|
+
var _remove = require("../core/remove");
|
|
4
6
|
var _utilities = require("../handlers/utilities");
|
|
5
7
|
// Mock @wix/motion module
|
|
6
8
|
jest.mock('@wix/motion', () => {
|
|
@@ -41,75 +43,75 @@ describe('interact', () => {
|
|
|
41
43
|
const mockConfig = {
|
|
42
44
|
interactions: [{
|
|
43
45
|
trigger: 'viewEnter',
|
|
44
|
-
|
|
46
|
+
key: 'logo-entrance',
|
|
45
47
|
params: {
|
|
46
48
|
threshold: 0.2
|
|
47
49
|
},
|
|
48
50
|
effects: [{
|
|
49
|
-
|
|
51
|
+
key: 'logo-entrance',
|
|
50
52
|
effectId: 'logo-arc-in'
|
|
51
53
|
}, {
|
|
52
|
-
|
|
54
|
+
key: 'logo-click',
|
|
53
55
|
effectId: 'logo-bounce'
|
|
54
56
|
}]
|
|
55
57
|
}, {
|
|
56
58
|
trigger: 'pageVisible',
|
|
57
|
-
|
|
59
|
+
key: 'logo-loop',
|
|
58
60
|
effects: [{
|
|
59
|
-
|
|
61
|
+
key: 'logo-loop',
|
|
60
62
|
effectId: 'logo-poke'
|
|
61
63
|
}]
|
|
62
64
|
}, {
|
|
63
65
|
trigger: 'animationEnd',
|
|
64
|
-
|
|
66
|
+
key: 'logo-animation-end',
|
|
65
67
|
params: {
|
|
66
68
|
effectId: 'logo-arc-in'
|
|
67
69
|
},
|
|
68
70
|
effects: [{
|
|
69
|
-
|
|
71
|
+
key: 'logo-animation-end',
|
|
70
72
|
effectId: 'logo-poke'
|
|
71
73
|
}]
|
|
72
74
|
}, {
|
|
73
75
|
trigger: 'pointerMove',
|
|
74
|
-
|
|
76
|
+
key: 'logo-mouse',
|
|
75
77
|
params: {
|
|
76
78
|
hitArea: 'root'
|
|
77
79
|
},
|
|
78
80
|
effects: [{
|
|
79
|
-
|
|
81
|
+
key: 'logo-mouse',
|
|
80
82
|
effectId: 'logo-track-mouse'
|
|
81
83
|
}]
|
|
82
84
|
}, {
|
|
83
85
|
trigger: 'click',
|
|
84
|
-
|
|
86
|
+
key: 'logo-click',
|
|
85
87
|
params: {
|
|
86
88
|
type: 'alternate'
|
|
87
89
|
},
|
|
88
90
|
effects: [{
|
|
89
|
-
|
|
91
|
+
key: 'logo-click',
|
|
90
92
|
effectId: 'logo-bounce'
|
|
91
93
|
}]
|
|
92
94
|
}, {
|
|
93
95
|
trigger: 'click',
|
|
94
|
-
|
|
96
|
+
key: 'logo-click',
|
|
95
97
|
params: {
|
|
96
98
|
method: 'toggle'
|
|
97
99
|
},
|
|
98
100
|
effects: [{
|
|
99
|
-
|
|
101
|
+
key: 'logo-click',
|
|
100
102
|
effectId: 'logo-transition-hover'
|
|
101
103
|
}]
|
|
102
104
|
}, {
|
|
103
105
|
trigger: 'hover',
|
|
104
|
-
|
|
106
|
+
key: 'logo-hover',
|
|
105
107
|
params: {
|
|
106
108
|
type: 'alternate'
|
|
107
109
|
},
|
|
108
110
|
effects: [{
|
|
109
|
-
|
|
111
|
+
key: 'logo-hover',
|
|
110
112
|
effectId: 'logo-arc-in'
|
|
111
113
|
}, {
|
|
112
|
-
|
|
114
|
+
key: 'logo-hover',
|
|
113
115
|
effectId: 'logo-arc-in',
|
|
114
116
|
namedEffect: {
|
|
115
117
|
type: 'ArcIn',
|
|
@@ -119,19 +121,49 @@ describe('interact', () => {
|
|
|
119
121
|
}]
|
|
120
122
|
}, {
|
|
121
123
|
trigger: 'hover',
|
|
122
|
-
|
|
124
|
+
key: 'logo-hover',
|
|
123
125
|
params: {
|
|
124
126
|
method: 'toggle'
|
|
125
127
|
},
|
|
126
128
|
effects: [{
|
|
127
|
-
|
|
129
|
+
key: 'logo-hover',
|
|
128
130
|
effectId: 'logo-transition-hover'
|
|
129
131
|
}]
|
|
130
132
|
}, {
|
|
131
133
|
trigger: 'viewProgress',
|
|
132
|
-
|
|
134
|
+
key: 'logo-scroll',
|
|
133
135
|
effects: [{
|
|
134
|
-
|
|
136
|
+
key: 'logo-scroll',
|
|
137
|
+
effectId: 'logo-fade-scroll'
|
|
138
|
+
}]
|
|
139
|
+
}, {
|
|
140
|
+
trigger: 'click',
|
|
141
|
+
key: 'logo-click-container',
|
|
142
|
+
listContainer: '#logo-list',
|
|
143
|
+
effects: [{
|
|
144
|
+
effectId: 'logo-bounce'
|
|
145
|
+
}]
|
|
146
|
+
}, {
|
|
147
|
+
trigger: 'viewEnter',
|
|
148
|
+
key: 'logo-view-container',
|
|
149
|
+
effects: [{
|
|
150
|
+
listContainer: '#logo-list',
|
|
151
|
+
effectId: 'logo-bounce'
|
|
152
|
+
}]
|
|
153
|
+
}, {
|
|
154
|
+
trigger: 'viewProgress',
|
|
155
|
+
key: 'logo-scroll-container',
|
|
156
|
+
listContainer: '#logo-scroll-list',
|
|
157
|
+
effects: [{
|
|
158
|
+
listContainer: '#logo-scroll-list',
|
|
159
|
+
effectId: 'logo-fade-scroll'
|
|
160
|
+
}]
|
|
161
|
+
}, {
|
|
162
|
+
trigger: 'viewProgress',
|
|
163
|
+
key: 'logo-scroll-container',
|
|
164
|
+
effects: [{
|
|
165
|
+
key: 'logo-scroll-items',
|
|
166
|
+
listContainer: '#logo-scroll-list',
|
|
135
167
|
effectId: 'logo-fade-scroll'
|
|
136
168
|
}]
|
|
137
169
|
}],
|
|
@@ -145,7 +177,7 @@ describe('interact', () => {
|
|
|
145
177
|
duration: 1200
|
|
146
178
|
},
|
|
147
179
|
'logo-arc-in-with-target': {
|
|
148
|
-
|
|
180
|
+
key: 'logo-hover',
|
|
149
181
|
namedEffect: {
|
|
150
182
|
type: 'ArcIn',
|
|
151
183
|
direction: 'right',
|
|
@@ -269,7 +301,8 @@ describe('interact', () => {
|
|
|
269
301
|
window.CSSStyleSheet = class CSSStyleSheet {
|
|
270
302
|
constructor(_) {
|
|
271
303
|
return {
|
|
272
|
-
replace: jest.fn()
|
|
304
|
+
replace: jest.fn(),
|
|
305
|
+
insertRule: jest.fn()
|
|
273
306
|
};
|
|
274
307
|
}
|
|
275
308
|
};
|
|
@@ -319,12 +352,12 @@ describe('interact', () => {
|
|
|
319
352
|
},
|
|
320
353
|
interactions: [{
|
|
321
354
|
trigger: 'click',
|
|
322
|
-
|
|
355
|
+
key: 'cascade-source',
|
|
323
356
|
effects: [{
|
|
324
|
-
|
|
357
|
+
key: 'cascade-target',
|
|
325
358
|
effectId: 'default-effect'
|
|
326
359
|
}, {
|
|
327
|
-
|
|
360
|
+
key: 'cascade-target',
|
|
328
361
|
effectId: 'default-effect',
|
|
329
362
|
conditions: ['desktop'],
|
|
330
363
|
namedEffect: {
|
|
@@ -334,7 +367,7 @@ describe('interact', () => {
|
|
|
334
367
|
},
|
|
335
368
|
duration: 800
|
|
336
369
|
}, {
|
|
337
|
-
|
|
370
|
+
key: 'cascade-target',
|
|
338
371
|
effectId: 'default-effect',
|
|
339
372
|
conditions: ['mobile'],
|
|
340
373
|
namedEffect: {
|
|
@@ -358,27 +391,29 @@ describe('interact', () => {
|
|
|
358
391
|
}
|
|
359
392
|
afterEach(() => {
|
|
360
393
|
jest.clearAllMocks();
|
|
361
|
-
(0,
|
|
362
|
-
(0,
|
|
363
|
-
(0,
|
|
364
|
-
(0,
|
|
365
|
-
(0,
|
|
366
|
-
(0,
|
|
367
|
-
(0,
|
|
394
|
+
(0, _remove.remove)('logo-entrance');
|
|
395
|
+
(0, _remove.remove)('logo-loop');
|
|
396
|
+
(0, _remove.remove)('logo-animation-end');
|
|
397
|
+
(0, _remove.remove)('logo-mouse');
|
|
398
|
+
(0, _remove.remove)('logo-click');
|
|
399
|
+
(0, _remove.remove)('logo-hover');
|
|
400
|
+
(0, _remove.remove)('logo-scroll');
|
|
368
401
|
// Clean up cascading test elements
|
|
369
|
-
(0,
|
|
370
|
-
(0,
|
|
371
|
-
(0,
|
|
372
|
-
(0,
|
|
373
|
-
(0,
|
|
374
|
-
(0,
|
|
402
|
+
(0, _remove.remove)('cascade-source');
|
|
403
|
+
(0, _remove.remove)('cascade-target');
|
|
404
|
+
(0, _remove.remove)('cascade-target-1');
|
|
405
|
+
(0, _remove.remove)('cascade-target-2');
|
|
406
|
+
(0, _remove.remove)('multi-source-1');
|
|
407
|
+
(0, _remove.remove)('multi-source-2');
|
|
375
408
|
// Clear Interact instances to ensure test isolation
|
|
376
|
-
|
|
377
|
-
|
|
409
|
+
_Interact.Interact.instances.length = 0;
|
|
410
|
+
_Interact.Interact.elementCache.clear();
|
|
411
|
+
// Reset forceReducedMotion to default
|
|
412
|
+
_Interact.Interact.forceReducedMotion = false;
|
|
378
413
|
});
|
|
379
414
|
describe('init Interact', () => {
|
|
380
415
|
it('should initialize with valid config', () => {
|
|
381
|
-
|
|
416
|
+
_Interact.Interact.create({});
|
|
382
417
|
expect(customElements.get('wix-interact-element')).toBeDefined();
|
|
383
418
|
});
|
|
384
419
|
});
|
|
@@ -387,13 +422,13 @@ describe('interact', () => {
|
|
|
387
422
|
const {
|
|
388
423
|
getWebAnimation
|
|
389
424
|
} = require('@wix/motion');
|
|
390
|
-
|
|
391
|
-
|
|
425
|
+
_Interact.Interact.forceReducedMotion = true;
|
|
426
|
+
_Interact.Interact.create({
|
|
392
427
|
interactions: [{
|
|
393
428
|
trigger: 'hover',
|
|
394
|
-
|
|
429
|
+
key: 'logo-hover',
|
|
395
430
|
effects: [{
|
|
396
|
-
|
|
431
|
+
key: 'logo-hover',
|
|
397
432
|
effectId: 'logo-arc-in'
|
|
398
433
|
}]
|
|
399
434
|
}],
|
|
@@ -411,17 +446,17 @@ describe('interact', () => {
|
|
|
411
446
|
element = document.createElement('wix-interact-element');
|
|
412
447
|
const div = document.createElement('div');
|
|
413
448
|
element.append(div);
|
|
414
|
-
(0,
|
|
449
|
+
(0, _add.add)(element, 'logo-hover');
|
|
415
450
|
expect(getWebAnimation).toHaveBeenCalledWith(div, expect.any(Object), undefined, {
|
|
416
451
|
reducedMotion: true
|
|
417
452
|
});
|
|
418
|
-
|
|
419
|
-
(0,
|
|
453
|
+
_Interact.Interact.forceReducedMotion = false;
|
|
454
|
+
(0, _remove.remove)('logo-hover');
|
|
420
455
|
});
|
|
421
456
|
});
|
|
422
457
|
describe('add interaction', () => {
|
|
423
458
|
beforeEach(() => {
|
|
424
|
-
|
|
459
|
+
_Interact.Interact.create(mockConfig);
|
|
425
460
|
});
|
|
426
461
|
describe('hover', () => {
|
|
427
462
|
it('should add handler for hover trigger with alternate type', () => {
|
|
@@ -432,7 +467,7 @@ describe('interact', () => {
|
|
|
432
467
|
const div = document.createElement('div');
|
|
433
468
|
element.append(div);
|
|
434
469
|
const addEventListenerSpy = jest.spyOn(div, 'addEventListener');
|
|
435
|
-
(0,
|
|
470
|
+
(0, _add.add)(element, 'logo-hover');
|
|
436
471
|
expect(addEventListenerSpy).toHaveBeenCalledTimes(4);
|
|
437
472
|
expect(addEventListenerSpy).toHaveBeenCalledWith('mouseenter', expect.any(Function), expect.objectContaining({
|
|
438
473
|
passive: true
|
|
@@ -458,7 +493,7 @@ describe('interact', () => {
|
|
|
458
493
|
const div = document.createElement('div');
|
|
459
494
|
element.append(div);
|
|
460
495
|
const addEventListenerSpy = jest.spyOn(div, 'addEventListener');
|
|
461
|
-
(0,
|
|
496
|
+
(0, _add.add)(element, 'logo-click');
|
|
462
497
|
expect(addEventListenerSpy).toHaveBeenCalledTimes(2);
|
|
463
498
|
expect(addEventListenerSpy).toHaveBeenCalledWith('click', expect.any(Function), expect.objectContaining({
|
|
464
499
|
passive: true
|
|
@@ -473,7 +508,7 @@ describe('interact', () => {
|
|
|
473
508
|
element = document.createElement('wix-interact-element');
|
|
474
509
|
const div = document.createElement('div');
|
|
475
510
|
element.append(div);
|
|
476
|
-
(0,
|
|
511
|
+
(0, _add.add)(element, 'logo-entrance');
|
|
477
512
|
expect(getWebAnimation).toHaveBeenCalledTimes(1);
|
|
478
513
|
expect(getWebAnimation).toHaveBeenCalledWith(expect.any(HTMLElement), expect.any(Object), undefined, {
|
|
479
514
|
reducedMotion: false
|
|
@@ -485,14 +520,25 @@ describe('interact', () => {
|
|
|
485
520
|
} = require('@wix/motion');
|
|
486
521
|
element = document.createElement('wix-interact-element');
|
|
487
522
|
const div = document.createElement('div');
|
|
523
|
+
div.id = 'logo-entrance';
|
|
488
524
|
element.append(div);
|
|
489
525
|
const elementClick = document.createElement('wix-interact-element');
|
|
490
526
|
const divClick = document.createElement('div');
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
(0,
|
|
494
|
-
|
|
495
|
-
expect(getWebAnimation).
|
|
527
|
+
divClick.id = 'logo-click';
|
|
528
|
+
elementClick.append(divClick);
|
|
529
|
+
(0, _add.add)(elementClick, 'logo-click');
|
|
530
|
+
(0, _add.add)(element, 'logo-entrance');
|
|
531
|
+
expect(getWebAnimation).toHaveBeenCalledTimes(3);
|
|
532
|
+
expect(getWebAnimation.mock.calls[0][0]).toBe(divClick);
|
|
533
|
+
expect(getWebAnimation.mock.calls[1][0]).toBe(div);
|
|
534
|
+
expect(getWebAnimation.mock.calls[2][0]).toBe(divClick);
|
|
535
|
+
expect(getWebAnimation.mock.calls[0][3]).toMatchObject({
|
|
536
|
+
reducedMotion: false
|
|
537
|
+
});
|
|
538
|
+
expect(getWebAnimation.mock.calls[1][3]).toMatchObject({
|
|
539
|
+
reducedMotion: false
|
|
540
|
+
});
|
|
541
|
+
expect(getWebAnimation.mock.calls[2][3]).toMatchObject({
|
|
496
542
|
reducedMotion: false
|
|
497
543
|
});
|
|
498
544
|
});
|
|
@@ -505,7 +551,7 @@ describe('interact', () => {
|
|
|
505
551
|
element = document.createElement('wix-interact-element');
|
|
506
552
|
const div = document.createElement('div');
|
|
507
553
|
element.append(div);
|
|
508
|
-
(0,
|
|
554
|
+
(0, _add.add)(element, 'logo-loop');
|
|
509
555
|
expect(getWebAnimation).toHaveBeenCalledTimes(1);
|
|
510
556
|
expect(getWebAnimation).toHaveBeenCalledWith(expect.any(HTMLElement), expect.any(Object), undefined, {
|
|
511
557
|
reducedMotion: false
|
|
@@ -520,7 +566,7 @@ describe('interact', () => {
|
|
|
520
566
|
element = document.createElement('wix-interact-element');
|
|
521
567
|
const div = document.createElement('div');
|
|
522
568
|
element.append(div);
|
|
523
|
-
(0,
|
|
569
|
+
(0, _add.add)(element, 'logo-animation-end');
|
|
524
570
|
expect(getWebAnimation).toHaveBeenCalledTimes(1);
|
|
525
571
|
expect(getWebAnimation).toHaveBeenCalledWith(expect.any(HTMLElement), expect.any(Object), undefined, {
|
|
526
572
|
reducedMotion: false
|
|
@@ -543,7 +589,7 @@ describe('interact', () => {
|
|
|
543
589
|
element = document.createElement('wix-interact-element');
|
|
544
590
|
const div = document.createElement('div');
|
|
545
591
|
element.append(div);
|
|
546
|
-
(0,
|
|
592
|
+
(0, _add.add)(element, 'logo-mouse');
|
|
547
593
|
expect(getScrubScene).toHaveBeenCalledTimes(1);
|
|
548
594
|
expect(getScrubScene).toHaveBeenCalledWith(expect.any(HTMLElement), expect.objectContaining((0, _utilities.effectToAnimationOptions)(mockConfig.effects['logo-track-mouse'])), expect.objectContaining({
|
|
549
595
|
trigger: 'pointer-move'
|
|
@@ -559,7 +605,7 @@ describe('interact', () => {
|
|
|
559
605
|
element = document.createElement('wix-interact-element');
|
|
560
606
|
const div = document.createElement('div');
|
|
561
607
|
element.append(div);
|
|
562
|
-
(0,
|
|
608
|
+
(0, _add.add)(element, 'logo-scroll');
|
|
563
609
|
expect(getWebAnimation).toHaveBeenCalledTimes(1);
|
|
564
610
|
expect(getWebAnimation).toHaveBeenCalledWith(expect.any(HTMLElement), expect.objectContaining((0, _utilities.effectToAnimationOptions)(mockConfig.effects['logo-fade-scroll'])), expect.objectContaining({
|
|
565
611
|
trigger: 'view-progress'
|
|
@@ -582,7 +628,7 @@ describe('interact', () => {
|
|
|
582
628
|
element = document.createElement('wix-interact-element');
|
|
583
629
|
const div = document.createElement('div');
|
|
584
630
|
element.append(div);
|
|
585
|
-
(0,
|
|
631
|
+
(0, _add.add)(element, 'logo-scroll');
|
|
586
632
|
expect(getScrubScene).toHaveBeenCalledTimes(1);
|
|
587
633
|
expect(getScrubScene).toHaveBeenCalledWith(expect.any(HTMLElement), expect.objectContaining((0, _utilities.effectToAnimationOptions)(mockConfig.effects['logo-fade-scroll'])), expect.objectContaining({
|
|
588
634
|
trigger: 'view-progress'
|
|
@@ -592,23 +638,133 @@ describe('interact', () => {
|
|
|
592
638
|
}, 0);
|
|
593
639
|
});
|
|
594
640
|
});
|
|
641
|
+
describe('listContainer', () => {
|
|
642
|
+
it('should add a handler per list item for click trigger with listContainer', () => {
|
|
643
|
+
element = document.createElement('wix-interact-element');
|
|
644
|
+
const div = document.createElement('div');
|
|
645
|
+
const ul = document.createElement('ul');
|
|
646
|
+
ul.id = 'logo-list';
|
|
647
|
+
div.append(ul);
|
|
648
|
+
const li = document.createElement('li');
|
|
649
|
+
const li2 = li.cloneNode(true);
|
|
650
|
+
ul.append(li);
|
|
651
|
+
ul.append(li2);
|
|
652
|
+
element.append(div);
|
|
653
|
+
const addEventListenerSpy = jest.spyOn(li, 'addEventListener');
|
|
654
|
+
const addEventListenerSpy2 = jest.spyOn(li2, 'addEventListener');
|
|
655
|
+
(0, _add.add)(element, 'logo-click-container');
|
|
656
|
+
expect(addEventListenerSpy).toHaveBeenCalledTimes(1);
|
|
657
|
+
expect(addEventListenerSpy2).toHaveBeenCalledTimes(1);
|
|
658
|
+
expect(addEventListenerSpy).toHaveBeenCalledWith('click', expect.any(Function), expect.objectContaining({
|
|
659
|
+
passive: true
|
|
660
|
+
}));
|
|
661
|
+
expect(addEventListenerSpy2).toHaveBeenCalledWith('click', expect.any(Function), expect.objectContaining({
|
|
662
|
+
passive: true
|
|
663
|
+
}));
|
|
664
|
+
});
|
|
665
|
+
it('should add a handler per list item for viewEnter trigger with listContainer in effect', () => {
|
|
666
|
+
const {
|
|
667
|
+
getWebAnimation
|
|
668
|
+
} = require('@wix/motion');
|
|
669
|
+
element = document.createElement('wix-interact-element');
|
|
670
|
+
const div = document.createElement('div');
|
|
671
|
+
const ul = document.createElement('ul');
|
|
672
|
+
ul.id = 'logo-list';
|
|
673
|
+
div.append(ul);
|
|
674
|
+
const li = document.createElement('li');
|
|
675
|
+
const li2 = li.cloneNode(true);
|
|
676
|
+
ul.append(li);
|
|
677
|
+
ul.append(li2);
|
|
678
|
+
element.append(div);
|
|
679
|
+
(0, _add.add)(element, 'logo-view-container');
|
|
680
|
+
expect(getWebAnimation).toHaveBeenCalledTimes(2);
|
|
681
|
+
expect(getWebAnimation.mock.calls[0][0]).toBe(li);
|
|
682
|
+
expect(getWebAnimation.mock.calls[1][0]).toBe(li2);
|
|
683
|
+
});
|
|
684
|
+
it('should add a handler per newly added list item for click trigger with listContainer', () => {
|
|
685
|
+
element = document.createElement('wix-interact-element');
|
|
686
|
+
const div = document.createElement('div');
|
|
687
|
+
const ul = document.createElement('ul');
|
|
688
|
+
ul.id = 'logo-list';
|
|
689
|
+
div.append(ul);
|
|
690
|
+
const li = document.createElement('li');
|
|
691
|
+
const li2 = li.cloneNode(true);
|
|
692
|
+
ul.append(li);
|
|
693
|
+
ul.append(li2);
|
|
694
|
+
element.append(div);
|
|
695
|
+
const addEventListenerSpy = jest.spyOn(li, 'addEventListener');
|
|
696
|
+
const addEventListenerSpy2 = jest.spyOn(li2, 'addEventListener');
|
|
697
|
+
(0, _add.add)(element, 'logo-click-container');
|
|
698
|
+
expect(addEventListenerSpy).toHaveBeenCalledTimes(1);
|
|
699
|
+
expect(addEventListenerSpy2).toHaveBeenCalledTimes(1);
|
|
700
|
+
expect(addEventListenerSpy).toHaveBeenCalledWith('click', expect.any(Function), expect.objectContaining({
|
|
701
|
+
passive: true
|
|
702
|
+
}));
|
|
703
|
+
expect(addEventListenerSpy2).toHaveBeenCalledWith('click', expect.any(Function), expect.objectContaining({
|
|
704
|
+
passive: true
|
|
705
|
+
}));
|
|
706
|
+
const li3 = document.createElement('li');
|
|
707
|
+
ul.append(li3);
|
|
708
|
+
const addEventListenerSpy3 = jest.spyOn(li3, 'addEventListener');
|
|
709
|
+
(0, _add.addListItems)(element, 'logo-click-container', '#logo-list', [li3]);
|
|
710
|
+
expect(addEventListenerSpy3).toHaveBeenCalledTimes(1);
|
|
711
|
+
expect(addEventListenerSpy3).toHaveBeenCalledWith('click', expect.any(Function), expect.objectContaining({
|
|
712
|
+
passive: true
|
|
713
|
+
}));
|
|
714
|
+
});
|
|
715
|
+
it('should add a handler per newly added list item for viewProgress trigger but not add same interaction twice', () => {
|
|
716
|
+
const {
|
|
717
|
+
getWebAnimation
|
|
718
|
+
} = require('@wix/motion');
|
|
719
|
+
element = document.createElement('wix-interact-element');
|
|
720
|
+
const div = document.createElement('div');
|
|
721
|
+
const targetElement = document.createElement('wix-interact-element');
|
|
722
|
+
const divTarget = document.createElement('div');
|
|
723
|
+
const ul = document.createElement('ul');
|
|
724
|
+
ul.id = 'logo-scroll-list';
|
|
725
|
+
divTarget.append(ul);
|
|
726
|
+
const li = document.createElement('li');
|
|
727
|
+
const li2 = li.cloneNode(true);
|
|
728
|
+
ul.append(li);
|
|
729
|
+
ul.append(li2);
|
|
730
|
+
element.append(div);
|
|
731
|
+
targetElement.append(divTarget);
|
|
732
|
+
(0, _add.add)(element, 'logo-scroll-container');
|
|
733
|
+
expect(getWebAnimation).toHaveBeenCalledTimes(0);
|
|
734
|
+
(0, _add.add)(targetElement, 'logo-scroll-items');
|
|
735
|
+
expect(getWebAnimation).toHaveBeenCalledTimes(2);
|
|
736
|
+
expect(getWebAnimation).toHaveBeenCalledWith(li, expect.objectContaining((0, _utilities.effectToAnimationOptions)(mockConfig.effects['logo-fade-scroll'])), expect.objectContaining({
|
|
737
|
+
trigger: 'view-progress'
|
|
738
|
+
}));
|
|
739
|
+
expect(getWebAnimation).toHaveBeenCalledWith(li2, expect.objectContaining((0, _utilities.effectToAnimationOptions)(mockConfig.effects['logo-fade-scroll'])), expect.objectContaining({
|
|
740
|
+
trigger: 'view-progress'
|
|
741
|
+
}));
|
|
742
|
+
const li3 = document.createElement('li');
|
|
743
|
+
ul.append(li3);
|
|
744
|
+
(0, _add.addListItems)(targetElement, 'logo-scroll-items', '#logo-scroll-list', [li3]);
|
|
745
|
+
expect(getWebAnimation).toHaveBeenCalledTimes(3);
|
|
746
|
+
expect(getWebAnimation).toHaveBeenCalledWith(li3, expect.objectContaining((0, _utilities.effectToAnimationOptions)(mockConfig.effects['logo-fade-scroll'])), expect.objectContaining({
|
|
747
|
+
trigger: 'view-progress'
|
|
748
|
+
}));
|
|
749
|
+
});
|
|
750
|
+
});
|
|
595
751
|
});
|
|
596
752
|
describe('remove interaction', () => {
|
|
597
753
|
beforeEach(() => {
|
|
598
|
-
|
|
754
|
+
_Interact.Interact.create(mockConfig);
|
|
599
755
|
});
|
|
600
756
|
it('should remove event listeners', () => {
|
|
601
757
|
element = document.createElement('wix-interact-element');
|
|
602
758
|
const div = document.createElement('div');
|
|
603
759
|
element.append(div);
|
|
604
760
|
const removeEventListenerSpy = jest.spyOn(div, 'removeEventListener');
|
|
605
|
-
(0,
|
|
606
|
-
(0,
|
|
761
|
+
(0, _add.add)(element, 'logo-click');
|
|
762
|
+
(0, _remove.remove)('logo-click');
|
|
607
763
|
expect(removeEventListenerSpy).toHaveBeenCalledTimes(2);
|
|
608
764
|
expect(removeEventListenerSpy).toHaveBeenCalledWith('click', expect.any(Function));
|
|
609
765
|
});
|
|
610
766
|
it('should do nothing if key does not exist', () => {
|
|
611
|
-
expect(() => (0,
|
|
767
|
+
expect(() => (0, _remove.remove)('non-existent-key')).not.toThrow();
|
|
612
768
|
});
|
|
613
769
|
it('should cleanup pointer effects', () => {
|
|
614
770
|
const {
|
|
@@ -622,8 +778,8 @@ describe('interact', () => {
|
|
|
622
778
|
element = document.createElement('wix-interact-element');
|
|
623
779
|
const div = document.createElement('div');
|
|
624
780
|
element.append(div);
|
|
625
|
-
(0,
|
|
626
|
-
(0,
|
|
781
|
+
(0, _add.add)(element, 'logo-mouse');
|
|
782
|
+
(0, _remove.remove)('logo-mouse');
|
|
627
783
|
expect(pointerInstance.destroy).toHaveBeenCalledTimes(1);
|
|
628
784
|
});
|
|
629
785
|
});
|
|
@@ -634,7 +790,7 @@ describe('interact', () => {
|
|
|
634
790
|
getWebAnimation
|
|
635
791
|
} = require('@wix/motion');
|
|
636
792
|
const config = createCascadingTestConfig({}, ['min-width: 1024px']);
|
|
637
|
-
|
|
793
|
+
_Interact.Interact.create(config);
|
|
638
794
|
const sourceElement = document.createElement('wix-interact-element');
|
|
639
795
|
const sourceDiv = document.createElement('div');
|
|
640
796
|
sourceElement.append(sourceDiv);
|
|
@@ -642,8 +798,8 @@ describe('interact', () => {
|
|
|
642
798
|
const targetDiv = document.createElement('div');
|
|
643
799
|
targetElement.append(targetDiv);
|
|
644
800
|
const addEventListenerSpy = jest.spyOn(sourceDiv, 'addEventListener');
|
|
645
|
-
(0,
|
|
646
|
-
(0,
|
|
801
|
+
(0, _add.add)(sourceElement, 'cascade-source');
|
|
802
|
+
(0, _add.add)(targetElement, 'cascade-target');
|
|
647
803
|
expect(addEventListenerSpy).toHaveBeenCalledTimes(1);
|
|
648
804
|
expect(addEventListenerSpy).toHaveBeenCalledWith('click', expect.any(Function), expect.objectContaining({
|
|
649
805
|
passive: true
|
|
@@ -666,15 +822,15 @@ describe('interact', () => {
|
|
|
666
822
|
} = require('@wix/motion');
|
|
667
823
|
const config = createCascadingTestConfig({}, []); // No matching conditions
|
|
668
824
|
|
|
669
|
-
|
|
825
|
+
_Interact.Interact.create(config);
|
|
670
826
|
const sourceElement = document.createElement('wix-interact-element');
|
|
671
827
|
const sourceDiv = document.createElement('div');
|
|
672
828
|
sourceElement.append(sourceDiv);
|
|
673
829
|
const targetElement = document.createElement('wix-interact-element');
|
|
674
830
|
const targetDiv = document.createElement('div');
|
|
675
831
|
targetElement.append(targetDiv);
|
|
676
|
-
(0,
|
|
677
|
-
(0,
|
|
832
|
+
(0, _add.add)(sourceElement, 'cascade-source');
|
|
833
|
+
(0, _add.add)(targetElement, 'cascade-target');
|
|
678
834
|
|
|
679
835
|
// Should create animation with default effect
|
|
680
836
|
expect(getWebAnimation).toHaveBeenCalledTimes(1);
|
|
@@ -692,15 +848,15 @@ describe('interact', () => {
|
|
|
692
848
|
getWebAnimation
|
|
693
849
|
} = require('@wix/motion');
|
|
694
850
|
const config = createCascadingTestConfig({}, ['max-width: 767px']);
|
|
695
|
-
|
|
851
|
+
_Interact.Interact.create(config);
|
|
696
852
|
const sourceElement = document.createElement('wix-interact-element');
|
|
697
853
|
const sourceDiv = document.createElement('div');
|
|
698
854
|
sourceElement.append(sourceDiv);
|
|
699
855
|
const targetElement = document.createElement('wix-interact-element');
|
|
700
856
|
const targetDiv = document.createElement('div');
|
|
701
857
|
targetElement.append(targetDiv);
|
|
702
|
-
(0,
|
|
703
|
-
(0,
|
|
858
|
+
(0, _add.add)(sourceElement, 'cascade-source');
|
|
859
|
+
(0, _add.add)(targetElement, 'cascade-target');
|
|
704
860
|
|
|
705
861
|
// Should create animation with mobile effect
|
|
706
862
|
expect(getWebAnimation).toHaveBeenCalledTimes(1);
|
|
@@ -720,7 +876,7 @@ describe('interact', () => {
|
|
|
720
876
|
getWebAnimation
|
|
721
877
|
} = require('@wix/motion');
|
|
722
878
|
const config = createCascadingTestConfig({}, ['min-width: 1024px']);
|
|
723
|
-
|
|
879
|
+
_Interact.Interact.create(config);
|
|
724
880
|
const sourceElement = document.createElement('wix-interact-element');
|
|
725
881
|
const sourceDiv = document.createElement('div');
|
|
726
882
|
sourceElement.append(sourceDiv);
|
|
@@ -729,9 +885,9 @@ describe('interact', () => {
|
|
|
729
885
|
targetElement.append(targetDiv);
|
|
730
886
|
|
|
731
887
|
// Add source first
|
|
732
|
-
(0,
|
|
888
|
+
(0, _add.add)(sourceElement, 'cascade-source');
|
|
733
889
|
// Add target second
|
|
734
|
-
(0,
|
|
890
|
+
(0, _add.add)(targetElement, 'cascade-target');
|
|
735
891
|
expect(getWebAnimation).toHaveBeenCalledTimes(1);
|
|
736
892
|
expect(getWebAnimation).toHaveBeenCalledWith(targetElement.firstElementChild, expect.objectContaining({
|
|
737
893
|
namedEffect: expect.objectContaining({
|
|
@@ -746,7 +902,7 @@ describe('interact', () => {
|
|
|
746
902
|
getWebAnimation
|
|
747
903
|
} = require('@wix/motion');
|
|
748
904
|
const config = createCascadingTestConfig({}, ['min-width: 1024px']);
|
|
749
|
-
|
|
905
|
+
_Interact.Interact.create(config);
|
|
750
906
|
const sourceElement = document.createElement('wix-interact-element');
|
|
751
907
|
const sourceDiv = document.createElement('div');
|
|
752
908
|
sourceElement.append(sourceDiv);
|
|
@@ -755,9 +911,9 @@ describe('interact', () => {
|
|
|
755
911
|
targetElement.append(targetDiv);
|
|
756
912
|
|
|
757
913
|
// Add target first
|
|
758
|
-
(0,
|
|
914
|
+
(0, _add.add)(targetElement, 'cascade-target');
|
|
759
915
|
// Add source second
|
|
760
|
-
(0,
|
|
916
|
+
(0, _add.add)(sourceElement, 'cascade-source');
|
|
761
917
|
expect(getWebAnimation).toHaveBeenCalledTimes(1);
|
|
762
918
|
expect(getWebAnimation).toHaveBeenCalledWith(targetElement.firstElementChild, expect.objectContaining({
|
|
763
919
|
namedEffect: expect.objectContaining({
|
|
@@ -786,13 +942,13 @@ describe('interact', () => {
|
|
|
786
942
|
},
|
|
787
943
|
interactions: [{
|
|
788
944
|
trigger: 'click',
|
|
789
|
-
|
|
945
|
+
key: 'multi-source-1',
|
|
790
946
|
effects: [{
|
|
791
|
-
|
|
947
|
+
key: 'cascade-target-1',
|
|
792
948
|
effectId: 'desktop-effect',
|
|
793
949
|
conditions: ['desktop']
|
|
794
950
|
}, {
|
|
795
|
-
|
|
951
|
+
key: 'cascade-target-2',
|
|
796
952
|
effectId: 'mobile-effect',
|
|
797
953
|
conditions: ['mobile']
|
|
798
954
|
}]
|
|
@@ -817,7 +973,7 @@ describe('interact', () => {
|
|
|
817
973
|
}
|
|
818
974
|
};
|
|
819
975
|
mockMatchMedia(['min-width: 1024px']); // Only desktop matches
|
|
820
|
-
|
|
976
|
+
_Interact.Interact.create(complexConfig);
|
|
821
977
|
const sourceElement = document.createElement('wix-interact-element');
|
|
822
978
|
const sourceDiv = document.createElement('div');
|
|
823
979
|
sourceElement.append(sourceDiv);
|
|
@@ -827,9 +983,9 @@ describe('interact', () => {
|
|
|
827
983
|
const target2Element = document.createElement('wix-interact-element');
|
|
828
984
|
const target2Div = document.createElement('div');
|
|
829
985
|
target2Element.append(target2Div);
|
|
830
|
-
(0,
|
|
831
|
-
(0,
|
|
832
|
-
(0,
|
|
986
|
+
(0, _add.add)(sourceElement, 'multi-source-1');
|
|
987
|
+
(0, _add.add)(target1Element, 'cascade-target-1');
|
|
988
|
+
(0, _add.add)(target2Element, 'cascade-target-2');
|
|
833
989
|
|
|
834
990
|
// Only desktop effect should be applied (mobile condition doesn't match)
|
|
835
991
|
expect(getWebAnimation).toHaveBeenCalledTimes(1);
|
|
@@ -867,12 +1023,12 @@ describe('interact', () => {
|
|
|
867
1023
|
},
|
|
868
1024
|
interactions: [{
|
|
869
1025
|
trigger: 'click',
|
|
870
|
-
|
|
1026
|
+
key: 'cascade-source',
|
|
871
1027
|
effects: [{
|
|
872
|
-
|
|
1028
|
+
key: 'cascade-target',
|
|
873
1029
|
effectId: 'premium-effect'
|
|
874
1030
|
}, {
|
|
875
|
-
|
|
1031
|
+
key: 'cascade-target',
|
|
876
1032
|
effectId: 'premium-effect',
|
|
877
1033
|
conditions: ['desktop', 'high-res']
|
|
878
1034
|
}]
|
|
@@ -891,15 +1047,15 @@ describe('interact', () => {
|
|
|
891
1047
|
|
|
892
1048
|
// Both conditions match
|
|
893
1049
|
mockMatchMedia(['min-width: 1024px', 'min-resolution: 2dppx']);
|
|
894
|
-
|
|
1050
|
+
_Interact.Interact.create(multiConditionConfig);
|
|
895
1051
|
const sourceElement = document.createElement('wix-interact-element');
|
|
896
1052
|
const sourceDiv = document.createElement('div');
|
|
897
1053
|
sourceElement.append(sourceDiv);
|
|
898
1054
|
const targetElement = document.createElement('wix-interact-element');
|
|
899
1055
|
const targetDiv = document.createElement('div');
|
|
900
1056
|
targetElement.append(targetDiv);
|
|
901
|
-
(0,
|
|
902
|
-
(0,
|
|
1057
|
+
(0, _add.add)(sourceElement, 'cascade-source');
|
|
1058
|
+
(0, _add.add)(targetElement, 'cascade-target');
|
|
903
1059
|
|
|
904
1060
|
// Premium effect should be applied since both conditions match
|
|
905
1061
|
expect(getWebAnimation).toHaveBeenCalledTimes(1);
|
|
@@ -926,12 +1082,12 @@ describe('interact', () => {
|
|
|
926
1082
|
},
|
|
927
1083
|
interactions: [{
|
|
928
1084
|
trigger: 'click',
|
|
929
|
-
|
|
1085
|
+
key: 'cascade-source',
|
|
930
1086
|
effects: [{
|
|
931
|
-
|
|
1087
|
+
key: 'cascade-target',
|
|
932
1088
|
effectId: 'default-effect'
|
|
933
1089
|
}, {
|
|
934
|
-
|
|
1090
|
+
key: 'cascade-target',
|
|
935
1091
|
effectId: 'default-effect',
|
|
936
1092
|
conditions: ['nonexistent-condition']
|
|
937
1093
|
}]
|
|
@@ -947,15 +1103,15 @@ describe('interact', () => {
|
|
|
947
1103
|
}
|
|
948
1104
|
};
|
|
949
1105
|
mockMatchMedia(['min-width: 1024px']);
|
|
950
|
-
|
|
1106
|
+
_Interact.Interact.create(configWithMissingCondition);
|
|
951
1107
|
const sourceElement = document.createElement('wix-interact-element');
|
|
952
1108
|
const sourceDiv = document.createElement('div');
|
|
953
1109
|
sourceElement.append(sourceDiv);
|
|
954
1110
|
const targetElement = document.createElement('wix-interact-element');
|
|
955
1111
|
const targetDiv = document.createElement('div');
|
|
956
1112
|
targetElement.append(targetDiv);
|
|
957
|
-
(0,
|
|
958
|
-
(0,
|
|
1113
|
+
(0, _add.add)(sourceElement, 'cascade-source');
|
|
1114
|
+
(0, _add.add)(targetElement, 'cascade-target');
|
|
959
1115
|
|
|
960
1116
|
// Should fall back to default effect since condition doesn't exist
|
|
961
1117
|
expect(getWebAnimation).toHaveBeenCalledTimes(1);
|
|
@@ -975,9 +1131,9 @@ describe('interact', () => {
|
|
|
975
1131
|
conditions: {},
|
|
976
1132
|
interactions: [{
|
|
977
1133
|
trigger: 'click',
|
|
978
|
-
|
|
1134
|
+
key: 'cascade-source',
|
|
979
1135
|
effects: [{
|
|
980
|
-
|
|
1136
|
+
key: 'cascade-target',
|
|
981
1137
|
effectId: 'always-applied-effect',
|
|
982
1138
|
conditions: []
|
|
983
1139
|
}]
|
|
@@ -994,15 +1150,15 @@ describe('interact', () => {
|
|
|
994
1150
|
}
|
|
995
1151
|
};
|
|
996
1152
|
mockMatchMedia([]);
|
|
997
|
-
|
|
1153
|
+
_Interact.Interact.create(configWithEmptyConditions);
|
|
998
1154
|
const sourceElement = document.createElement('wix-interact-element');
|
|
999
1155
|
const sourceDiv = document.createElement('div');
|
|
1000
1156
|
sourceElement.append(sourceDiv);
|
|
1001
1157
|
const targetElement = document.createElement('wix-interact-element');
|
|
1002
1158
|
const targetDiv = document.createElement('div');
|
|
1003
1159
|
targetElement.append(targetDiv);
|
|
1004
|
-
(0,
|
|
1005
|
-
(0,
|
|
1160
|
+
(0, _add.add)(sourceElement, 'cascade-source');
|
|
1161
|
+
(0, _add.add)(targetElement, 'cascade-target');
|
|
1006
1162
|
|
|
1007
1163
|
// Effect should be applied since empty conditions array should always match
|
|
1008
1164
|
expect(getWebAnimation).toHaveBeenCalledTimes(1);
|
|
@@ -1016,5 +1172,501 @@ describe('interact', () => {
|
|
|
1016
1172
|
});
|
|
1017
1173
|
});
|
|
1018
1174
|
});
|
|
1175
|
+
describe('selector functionality', () => {
|
|
1176
|
+
let sourceElement;
|
|
1177
|
+
let targetElement;
|
|
1178
|
+
beforeEach(() => {
|
|
1179
|
+
// Create source element with multiple child elements
|
|
1180
|
+
sourceElement = document.createElement('wix-interact-element');
|
|
1181
|
+
sourceElement.innerHTML = `
|
|
1182
|
+
<div class="first-child">First Child</div>
|
|
1183
|
+
<button class="trigger-button">Click Me</button>
|
|
1184
|
+
<div class="other-element">Other</div>
|
|
1185
|
+
<div class="list-container">
|
|
1186
|
+
<div class="list-item">Item 1</div>
|
|
1187
|
+
<div class="list-item">Item 2</div>
|
|
1188
|
+
<div class="list-item">Item 3</div>
|
|
1189
|
+
</div>
|
|
1190
|
+
`;
|
|
1191
|
+
|
|
1192
|
+
// Create target element with multiple child elements
|
|
1193
|
+
targetElement = document.createElement('wix-interact-element');
|
|
1194
|
+
targetElement.innerHTML = `
|
|
1195
|
+
<div class="first-child">Target First</div>
|
|
1196
|
+
<div class="animation-target">Animation Target</div>
|
|
1197
|
+
<div class="overlay">Overlay</div>
|
|
1198
|
+
<div class="nested">
|
|
1199
|
+
<span class="deep-target">Deep Target</span>
|
|
1200
|
+
</div>
|
|
1201
|
+
`;
|
|
1202
|
+
});
|
|
1203
|
+
describe('basic selector functionality', () => {
|
|
1204
|
+
it('should use selector instead of firstElementChild for source', () => {
|
|
1205
|
+
const config = {
|
|
1206
|
+
effects: {
|
|
1207
|
+
'test-effect': {
|
|
1208
|
+
keyframeEffect: {
|
|
1209
|
+
name: 'test',
|
|
1210
|
+
keyframes: [{
|
|
1211
|
+
opacity: '0'
|
|
1212
|
+
}, {
|
|
1213
|
+
opacity: '1'
|
|
1214
|
+
}]
|
|
1215
|
+
},
|
|
1216
|
+
duration: 300
|
|
1217
|
+
}
|
|
1218
|
+
},
|
|
1219
|
+
interactions: [{
|
|
1220
|
+
key: 'selector-source',
|
|
1221
|
+
selector: '.trigger-button',
|
|
1222
|
+
trigger: 'click',
|
|
1223
|
+
effects: [{
|
|
1224
|
+
key: 'selector-target',
|
|
1225
|
+
effectId: 'test-effect'
|
|
1226
|
+
}]
|
|
1227
|
+
}]
|
|
1228
|
+
};
|
|
1229
|
+
_Interact.Interact.create(config);
|
|
1230
|
+
const triggerButton = sourceElement.querySelector('.trigger-button');
|
|
1231
|
+
const firstChild = sourceElement.querySelector('.first-child');
|
|
1232
|
+
const triggerSpy = jest.spyOn(triggerButton, 'addEventListener');
|
|
1233
|
+
const firstChildSpy = jest.spyOn(firstChild, 'addEventListener');
|
|
1234
|
+
(0, _add.add)(sourceElement, 'selector-source');
|
|
1235
|
+
(0, _add.add)(targetElement, 'selector-target');
|
|
1236
|
+
|
|
1237
|
+
// Should add event listener to the selected element, not firstElementChild
|
|
1238
|
+
expect(triggerSpy).toHaveBeenCalledWith('click', expect.any(Function), expect.any(Object));
|
|
1239
|
+
expect(firstChildSpy).not.toHaveBeenCalled();
|
|
1240
|
+
});
|
|
1241
|
+
it('should use selector instead of firstElementChild for target', () => {
|
|
1242
|
+
const {
|
|
1243
|
+
getWebAnimation
|
|
1244
|
+
} = require('@wix/motion');
|
|
1245
|
+
const config = {
|
|
1246
|
+
effects: {
|
|
1247
|
+
'test-effect': {
|
|
1248
|
+
keyframeEffect: {
|
|
1249
|
+
name: 'test',
|
|
1250
|
+
keyframes: [{
|
|
1251
|
+
opacity: '0'
|
|
1252
|
+
}, {
|
|
1253
|
+
opacity: '1'
|
|
1254
|
+
}]
|
|
1255
|
+
},
|
|
1256
|
+
duration: 300
|
|
1257
|
+
}
|
|
1258
|
+
},
|
|
1259
|
+
interactions: [{
|
|
1260
|
+
key: 'selector-source',
|
|
1261
|
+
trigger: 'click',
|
|
1262
|
+
effects: [{
|
|
1263
|
+
key: 'selector-target',
|
|
1264
|
+
selector: '.animation-target',
|
|
1265
|
+
effectId: 'test-effect'
|
|
1266
|
+
}]
|
|
1267
|
+
}]
|
|
1268
|
+
};
|
|
1269
|
+
_Interact.Interact.create(config);
|
|
1270
|
+
(0, _add.add)(sourceElement, 'selector-source');
|
|
1271
|
+
(0, _add.add)(targetElement, 'selector-target');
|
|
1272
|
+
const animationTarget = targetElement.querySelector('.animation-target');
|
|
1273
|
+
|
|
1274
|
+
// Should create animation on the selected element, not firstElementChild
|
|
1275
|
+
expect(getWebAnimation).toHaveBeenCalledWith(animationTarget, expect.any(Object), undefined, {
|
|
1276
|
+
reducedMotion: false
|
|
1277
|
+
});
|
|
1278
|
+
});
|
|
1279
|
+
it('should fall back to firstElementChild when no selector is provided', () => {
|
|
1280
|
+
const config = {
|
|
1281
|
+
effects: {
|
|
1282
|
+
'test-effect': {
|
|
1283
|
+
keyframeEffect: {
|
|
1284
|
+
name: 'test',
|
|
1285
|
+
keyframes: [{
|
|
1286
|
+
opacity: '0'
|
|
1287
|
+
}, {
|
|
1288
|
+
opacity: '1'
|
|
1289
|
+
}]
|
|
1290
|
+
},
|
|
1291
|
+
duration: 300
|
|
1292
|
+
}
|
|
1293
|
+
},
|
|
1294
|
+
interactions: [{
|
|
1295
|
+
key: 'fallback-source',
|
|
1296
|
+
trigger: 'click',
|
|
1297
|
+
effects: [{
|
|
1298
|
+
key: 'fallback-target',
|
|
1299
|
+
effectId: 'test-effect'
|
|
1300
|
+
}]
|
|
1301
|
+
}]
|
|
1302
|
+
};
|
|
1303
|
+
_Interact.Interact.create(config);
|
|
1304
|
+
const firstChild = sourceElement.querySelector('.first-child');
|
|
1305
|
+
const firstChildSpy = jest.spyOn(firstChild, 'addEventListener');
|
|
1306
|
+
(0, _add.add)(sourceElement, 'fallback-source');
|
|
1307
|
+
(0, _add.add)(targetElement, 'fallback-target');
|
|
1308
|
+
|
|
1309
|
+
// Should fall back to firstElementChild
|
|
1310
|
+
expect(firstChildSpy).toHaveBeenCalledWith('click', expect.any(Function), expect.any(Object));
|
|
1311
|
+
});
|
|
1312
|
+
});
|
|
1313
|
+
describe('selector with listContainer', () => {
|
|
1314
|
+
it('should use selector within listContainer items', () => {
|
|
1315
|
+
const config = {
|
|
1316
|
+
effects: {
|
|
1317
|
+
'list-effect': {
|
|
1318
|
+
keyframeEffect: {
|
|
1319
|
+
name: 'list-test',
|
|
1320
|
+
keyframes: [{
|
|
1321
|
+
transform: 'scale(1)'
|
|
1322
|
+
}, {
|
|
1323
|
+
transform: 'scale(1.1)'
|
|
1324
|
+
}]
|
|
1325
|
+
},
|
|
1326
|
+
duration: 200
|
|
1327
|
+
}
|
|
1328
|
+
},
|
|
1329
|
+
interactions: [{
|
|
1330
|
+
key: 'list-source',
|
|
1331
|
+
listContainer: '.list-container',
|
|
1332
|
+
selector: '.list-item',
|
|
1333
|
+
trigger: 'hover',
|
|
1334
|
+
effects: [{
|
|
1335
|
+
listContainer: '.list-container',
|
|
1336
|
+
selector: '.list-item',
|
|
1337
|
+
effectId: 'list-effect'
|
|
1338
|
+
}]
|
|
1339
|
+
}]
|
|
1340
|
+
};
|
|
1341
|
+
_Interact.Interact.create(config);
|
|
1342
|
+
|
|
1343
|
+
// Set up spies before adding interactions
|
|
1344
|
+
const listItems = Array.from(sourceElement.querySelectorAll('.list-item'));
|
|
1345
|
+
const spies = listItems.map(item => jest.spyOn(item, 'addEventListener'));
|
|
1346
|
+
(0, _add.add)(sourceElement, 'list-source');
|
|
1347
|
+
|
|
1348
|
+
// Should add event listeners to each list item
|
|
1349
|
+
spies.forEach(spy => {
|
|
1350
|
+
expect(spy).toHaveBeenCalledWith('mouseenter', expect.any(Function), expect.any(Object));
|
|
1351
|
+
});
|
|
1352
|
+
});
|
|
1353
|
+
it('should handle listContainer without selector (all children)', () => {
|
|
1354
|
+
var _sourceElement$queryS;
|
|
1355
|
+
const config = {
|
|
1356
|
+
effects: {
|
|
1357
|
+
'container-effect': {
|
|
1358
|
+
keyframeEffect: {
|
|
1359
|
+
name: 'container-test',
|
|
1360
|
+
keyframes: [{
|
|
1361
|
+
opacity: '0.5'
|
|
1362
|
+
}, {
|
|
1363
|
+
opacity: '1'
|
|
1364
|
+
}]
|
|
1365
|
+
},
|
|
1366
|
+
duration: 150
|
|
1367
|
+
}
|
|
1368
|
+
},
|
|
1369
|
+
interactions: [{
|
|
1370
|
+
key: 'container-source',
|
|
1371
|
+
listContainer: '.list-container',
|
|
1372
|
+
trigger: 'click',
|
|
1373
|
+
effects: [{
|
|
1374
|
+
listContainer: '.list-container',
|
|
1375
|
+
effectId: 'container-effect'
|
|
1376
|
+
}]
|
|
1377
|
+
}]
|
|
1378
|
+
};
|
|
1379
|
+
_Interact.Interact.create(config);
|
|
1380
|
+
|
|
1381
|
+
// Set up spies before adding interactions
|
|
1382
|
+
const containerChildren = Array.from(((_sourceElement$queryS = sourceElement.querySelector('.list-container')) == null ? void 0 : _sourceElement$queryS.children) || []);
|
|
1383
|
+
const spies = containerChildren.map(child => jest.spyOn(child, 'addEventListener'));
|
|
1384
|
+
(0, _add.add)(sourceElement, 'container-source');
|
|
1385
|
+
|
|
1386
|
+
// Should add event listeners to all children of the container
|
|
1387
|
+
spies.forEach(spy => {
|
|
1388
|
+
expect(spy).toHaveBeenCalledWith('click', expect.any(Function), expect.any(Object));
|
|
1389
|
+
});
|
|
1390
|
+
});
|
|
1391
|
+
});
|
|
1392
|
+
describe('selector error handling', () => {
|
|
1393
|
+
let consoleSpy;
|
|
1394
|
+
beforeEach(() => {
|
|
1395
|
+
consoleSpy = jest.spyOn(console, 'warn').mockImplementation();
|
|
1396
|
+
});
|
|
1397
|
+
afterEach(() => {
|
|
1398
|
+
consoleSpy.mockRestore();
|
|
1399
|
+
});
|
|
1400
|
+
it('should warn when selector does not match any elements', () => {
|
|
1401
|
+
const config = {
|
|
1402
|
+
effects: {
|
|
1403
|
+
'test-effect': {
|
|
1404
|
+
keyframeEffect: {
|
|
1405
|
+
name: 'test',
|
|
1406
|
+
keyframes: [{
|
|
1407
|
+
opacity: '0'
|
|
1408
|
+
}, {
|
|
1409
|
+
opacity: '1'
|
|
1410
|
+
}]
|
|
1411
|
+
},
|
|
1412
|
+
duration: 300
|
|
1413
|
+
}
|
|
1414
|
+
},
|
|
1415
|
+
interactions: [{
|
|
1416
|
+
key: 'invalid-source',
|
|
1417
|
+
selector: '.non-existent-element',
|
|
1418
|
+
trigger: 'click',
|
|
1419
|
+
effects: [{
|
|
1420
|
+
key: 'invalid-target',
|
|
1421
|
+
effectId: 'test-effect'
|
|
1422
|
+
}]
|
|
1423
|
+
}]
|
|
1424
|
+
};
|
|
1425
|
+
_Interact.Interact.create(config);
|
|
1426
|
+
(0, _add.add)(sourceElement, 'invalid-source');
|
|
1427
|
+
(0, _add.add)(targetElement, 'invalid-target');
|
|
1428
|
+
expect(consoleSpy).toHaveBeenCalledWith('WixInteract: No element found for selector ".non-existent-element"');
|
|
1429
|
+
});
|
|
1430
|
+
it('should warn when listContainer selector does not match', () => {
|
|
1431
|
+
const config = {
|
|
1432
|
+
effects: {
|
|
1433
|
+
'test-effect': {
|
|
1434
|
+
keyframeEffect: {
|
|
1435
|
+
name: 'test',
|
|
1436
|
+
keyframes: [{
|
|
1437
|
+
opacity: '0'
|
|
1438
|
+
}, {
|
|
1439
|
+
opacity: '1'
|
|
1440
|
+
}]
|
|
1441
|
+
},
|
|
1442
|
+
duration: 300
|
|
1443
|
+
}
|
|
1444
|
+
},
|
|
1445
|
+
interactions: [{
|
|
1446
|
+
key: 'invalid-container-source',
|
|
1447
|
+
listContainer: '.non-existent-container',
|
|
1448
|
+
trigger: 'click',
|
|
1449
|
+
effects: [{
|
|
1450
|
+
key: 'invalid-container-target',
|
|
1451
|
+
effectId: 'test-effect'
|
|
1452
|
+
}]
|
|
1453
|
+
}]
|
|
1454
|
+
};
|
|
1455
|
+
_Interact.Interact.create(config);
|
|
1456
|
+
(0, _add.add)(sourceElement, 'invalid-container-source');
|
|
1457
|
+
(0, _add.add)(targetElement, 'invalid-container-target');
|
|
1458
|
+
expect(consoleSpy).toHaveBeenCalledWith('WixInteract: No container found for list container ".non-existent-container"');
|
|
1459
|
+
});
|
|
1460
|
+
it('should gracefully handle invalid selectors without breaking interactions', () => {
|
|
1461
|
+
const config = {
|
|
1462
|
+
effects: {
|
|
1463
|
+
'valid-effect': {
|
|
1464
|
+
keyframeEffect: {
|
|
1465
|
+
name: 'valid',
|
|
1466
|
+
keyframes: [{
|
|
1467
|
+
opacity: '0'
|
|
1468
|
+
}, {
|
|
1469
|
+
opacity: '1'
|
|
1470
|
+
}]
|
|
1471
|
+
},
|
|
1472
|
+
duration: 300
|
|
1473
|
+
}
|
|
1474
|
+
},
|
|
1475
|
+
interactions: [{
|
|
1476
|
+
key: 'mixed-source',
|
|
1477
|
+
selector: '.non-existent',
|
|
1478
|
+
trigger: 'click',
|
|
1479
|
+
effects: [{
|
|
1480
|
+
key: 'mixed-target',
|
|
1481
|
+
effectId: 'valid-effect'
|
|
1482
|
+
}]
|
|
1483
|
+
}, {
|
|
1484
|
+
key: 'valid-source',
|
|
1485
|
+
selector: '.trigger-button',
|
|
1486
|
+
trigger: 'click',
|
|
1487
|
+
effects: [{
|
|
1488
|
+
key: 'valid-target',
|
|
1489
|
+
effectId: 'valid-effect'
|
|
1490
|
+
}]
|
|
1491
|
+
}]
|
|
1492
|
+
};
|
|
1493
|
+
_Interact.Interact.create(config);
|
|
1494
|
+
|
|
1495
|
+
// Set up spy before adding interactions
|
|
1496
|
+
const triggerButton = sourceElement.querySelector('.trigger-button');
|
|
1497
|
+
const spy = jest.spyOn(triggerButton, 'addEventListener');
|
|
1498
|
+
|
|
1499
|
+
// This should not throw and should allow other interactions to work
|
|
1500
|
+
expect(() => {
|
|
1501
|
+
(0, _add.add)(sourceElement, 'mixed-source');
|
|
1502
|
+
(0, _add.add)(sourceElement, 'valid-source');
|
|
1503
|
+
(0, _add.add)(targetElement, 'mixed-target');
|
|
1504
|
+
(0, _add.add)(targetElement, 'valid-target');
|
|
1505
|
+
}).not.toThrow();
|
|
1506
|
+
|
|
1507
|
+
// Valid interaction should still work
|
|
1508
|
+
expect(spy).toHaveBeenCalled();
|
|
1509
|
+
});
|
|
1510
|
+
});
|
|
1511
|
+
describe('complex selector scenarios', () => {
|
|
1512
|
+
it('should handle nested selectors', () => {
|
|
1513
|
+
const {
|
|
1514
|
+
getWebAnimation
|
|
1515
|
+
} = require('@wix/motion');
|
|
1516
|
+
const config = {
|
|
1517
|
+
effects: {
|
|
1518
|
+
'nested-effect': {
|
|
1519
|
+
keyframeEffect: {
|
|
1520
|
+
name: 'nested',
|
|
1521
|
+
keyframes: [{
|
|
1522
|
+
color: 'black'
|
|
1523
|
+
}, {
|
|
1524
|
+
color: 'blue'
|
|
1525
|
+
}]
|
|
1526
|
+
},
|
|
1527
|
+
duration: 200
|
|
1528
|
+
}
|
|
1529
|
+
},
|
|
1530
|
+
interactions: [{
|
|
1531
|
+
key: 'nested-source',
|
|
1532
|
+
selector: '.other-element',
|
|
1533
|
+
trigger: 'click',
|
|
1534
|
+
effects: [{
|
|
1535
|
+
key: 'nested-target',
|
|
1536
|
+
selector: '.nested .deep-target',
|
|
1537
|
+
effectId: 'nested-effect'
|
|
1538
|
+
}]
|
|
1539
|
+
}]
|
|
1540
|
+
};
|
|
1541
|
+
_Interact.Interact.create(config);
|
|
1542
|
+
const addEventListenerSpy = jest.spyOn(sourceElement.querySelector('.other-element'), 'addEventListener');
|
|
1543
|
+
(0, _add.add)(sourceElement, 'nested-source');
|
|
1544
|
+
(0, _add.add)(targetElement, 'nested-target');
|
|
1545
|
+
const deepTarget = targetElement.querySelector('.nested .deep-target');
|
|
1546
|
+
expect(addEventListenerSpy).toHaveBeenCalledWith('click', expect.any(Function), expect.any(Object));
|
|
1547
|
+
expect(getWebAnimation).toHaveBeenCalledWith(deepTarget, expect.any(Object), undefined, {
|
|
1548
|
+
reducedMotion: false
|
|
1549
|
+
});
|
|
1550
|
+
});
|
|
1551
|
+
it('should handle attribute selectors', () => {
|
|
1552
|
+
// Add data attributes to test elements
|
|
1553
|
+
const buttonWithData = sourceElement.querySelector('.trigger-button');
|
|
1554
|
+
buttonWithData.setAttribute('data-interactive', 'true');
|
|
1555
|
+
buttonWithData.setAttribute('data-category', 'primary');
|
|
1556
|
+
const config = {
|
|
1557
|
+
effects: {
|
|
1558
|
+
'attr-effect': {
|
|
1559
|
+
keyframeEffect: {
|
|
1560
|
+
name: 'attr',
|
|
1561
|
+
keyframes: [{
|
|
1562
|
+
backgroundColor: 'white'
|
|
1563
|
+
}, {
|
|
1564
|
+
backgroundColor: 'lightblue'
|
|
1565
|
+
}]
|
|
1566
|
+
},
|
|
1567
|
+
duration: 300
|
|
1568
|
+
}
|
|
1569
|
+
},
|
|
1570
|
+
interactions: [{
|
|
1571
|
+
key: 'attr-source',
|
|
1572
|
+
selector: '[data-interactive="true"][data-category="primary"]',
|
|
1573
|
+
trigger: 'click',
|
|
1574
|
+
effects: [{
|
|
1575
|
+
key: 'attr-target',
|
|
1576
|
+
selector: '[class*="animation"]',
|
|
1577
|
+
effectId: 'attr-effect'
|
|
1578
|
+
}]
|
|
1579
|
+
}]
|
|
1580
|
+
};
|
|
1581
|
+
_Interact.Interact.create(config);
|
|
1582
|
+
|
|
1583
|
+
// Set up spy before adding interactions
|
|
1584
|
+
const spy = jest.spyOn(buttonWithData, 'addEventListener');
|
|
1585
|
+
(0, _add.add)(sourceElement, 'attr-source');
|
|
1586
|
+
(0, _add.add)(targetElement, 'attr-target');
|
|
1587
|
+
expect(spy).toHaveBeenCalledWith('click', expect.any(Function), expect.any(Object));
|
|
1588
|
+
});
|
|
1589
|
+
});
|
|
1590
|
+
describe('selector inheritance and priority', () => {
|
|
1591
|
+
it('should not inherit selector from interaction to effect', () => {
|
|
1592
|
+
const {
|
|
1593
|
+
getWebAnimation
|
|
1594
|
+
} = require('@wix/motion');
|
|
1595
|
+
const config = {
|
|
1596
|
+
effects: {
|
|
1597
|
+
'inherit-effect': {
|
|
1598
|
+
keyframeEffect: {
|
|
1599
|
+
name: 'inherit',
|
|
1600
|
+
keyframes: [{
|
|
1601
|
+
opacity: '0'
|
|
1602
|
+
}, {
|
|
1603
|
+
opacity: '1'
|
|
1604
|
+
}]
|
|
1605
|
+
},
|
|
1606
|
+
duration: 300
|
|
1607
|
+
}
|
|
1608
|
+
},
|
|
1609
|
+
interactions: [{
|
|
1610
|
+
key: 'inherit-source',
|
|
1611
|
+
selector: '.trigger-button',
|
|
1612
|
+
// Interaction has selector
|
|
1613
|
+
trigger: 'click',
|
|
1614
|
+
effects: [{
|
|
1615
|
+
key: 'inherit-target',
|
|
1616
|
+
// Effect has no selector - should use firstElementChild, not inherit
|
|
1617
|
+
effectId: 'inherit-effect'
|
|
1618
|
+
}]
|
|
1619
|
+
}]
|
|
1620
|
+
};
|
|
1621
|
+
_Interact.Interact.create(config);
|
|
1622
|
+
(0, _add.add)(sourceElement, 'inherit-source');
|
|
1623
|
+
(0, _add.add)(targetElement, 'inherit-target');
|
|
1624
|
+
|
|
1625
|
+
// Effect should target firstElementChild, not the interaction's selector
|
|
1626
|
+
const targetFirstChild = targetElement.firstElementChild;
|
|
1627
|
+
expect(getWebAnimation).toHaveBeenCalledWith(targetFirstChild, expect.any(Object), undefined, {
|
|
1628
|
+
reducedMotion: false
|
|
1629
|
+
});
|
|
1630
|
+
});
|
|
1631
|
+
});
|
|
1632
|
+
describe('selector cleanup', () => {
|
|
1633
|
+
it('should clean up selector-based interactions on remove', () => {
|
|
1634
|
+
const config = {
|
|
1635
|
+
effects: {
|
|
1636
|
+
'cleanup-effect': {
|
|
1637
|
+
keyframeEffect: {
|
|
1638
|
+
name: 'cleanup',
|
|
1639
|
+
keyframes: [{
|
|
1640
|
+
opacity: '0'
|
|
1641
|
+
}, {
|
|
1642
|
+
opacity: '1'
|
|
1643
|
+
}]
|
|
1644
|
+
},
|
|
1645
|
+
duration: 300
|
|
1646
|
+
}
|
|
1647
|
+
},
|
|
1648
|
+
interactions: [{
|
|
1649
|
+
key: 'cleanup-source',
|
|
1650
|
+
selector: '.trigger-button',
|
|
1651
|
+
trigger: 'click',
|
|
1652
|
+
effects: [{
|
|
1653
|
+
key: 'cleanup-target',
|
|
1654
|
+
selector: '.animation-target',
|
|
1655
|
+
effectId: 'cleanup-effect'
|
|
1656
|
+
}]
|
|
1657
|
+
}]
|
|
1658
|
+
};
|
|
1659
|
+
_Interact.Interact.create(config);
|
|
1660
|
+
const triggerButton = sourceElement.querySelector('.trigger-button');
|
|
1661
|
+
const removeEventListenerSpy = jest.spyOn(triggerButton, 'removeEventListener');
|
|
1662
|
+
(0, _add.add)(sourceElement, 'cleanup-source');
|
|
1663
|
+
(0, _add.add)(targetElement, 'cleanup-target');
|
|
1664
|
+
(0, _remove.remove)('cleanup-source');
|
|
1665
|
+
|
|
1666
|
+
// Should remove event listeners from the selected element
|
|
1667
|
+
expect(removeEventListenerSpy).toHaveBeenCalledWith('click', expect.any(Function));
|
|
1668
|
+
});
|
|
1669
|
+
});
|
|
1670
|
+
});
|
|
1019
1671
|
});
|
|
1020
1672
|
//# sourceMappingURL=interact.spec.js.map
|