@wix/interact 1.92.0 → 1.94.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 (46) hide show
  1. package/dist/cjs/InteractElement.js +1 -0
  2. package/dist/cjs/InteractElement.js.map +1 -1
  3. package/dist/cjs/__tests__/interact.spec.js +334 -0
  4. package/dist/cjs/__tests__/interact.spec.js.map +1 -1
  5. package/dist/cjs/__tests__/viewEnter.spec.js +23 -6
  6. package/dist/cjs/__tests__/viewEnter.spec.js.map +1 -1
  7. package/dist/cjs/core/add.js +12 -8
  8. package/dist/cjs/core/add.js.map +1 -1
  9. package/dist/cjs/handlers/animationEnd.js +9 -0
  10. package/dist/cjs/handlers/animationEnd.js.map +1 -1
  11. package/dist/cjs/handlers/click.js +19 -3
  12. package/dist/cjs/handlers/click.js.map +1 -1
  13. package/dist/cjs/handlers/hover.js +19 -3
  14. package/dist/cjs/handlers/hover.js.map +1 -1
  15. package/dist/cjs/handlers/viewEnter.js +10 -1
  16. package/dist/cjs/handlers/viewEnter.js.map +1 -1
  17. package/dist/cjs/handlers/viewProgress.js +24 -8
  18. package/dist/cjs/handlers/viewProgress.js.map +1 -1
  19. package/dist/cjs/types.js.map +1 -1
  20. package/dist/cjs/utils.js +34 -4
  21. package/dist/cjs/utils.js.map +1 -1
  22. package/dist/esm/InteractElement.js +1 -0
  23. package/dist/esm/InteractElement.js.map +1 -1
  24. package/dist/esm/__tests__/interact.spec.js +335 -0
  25. package/dist/esm/__tests__/interact.spec.js.map +1 -1
  26. package/dist/esm/__tests__/viewEnter.spec.js +23 -6
  27. package/dist/esm/__tests__/viewEnter.spec.js.map +1 -1
  28. package/dist/esm/core/add.js +13 -9
  29. package/dist/esm/core/add.js.map +1 -1
  30. package/dist/esm/handlers/animationEnd.js +9 -0
  31. package/dist/esm/handlers/animationEnd.js.map +1 -1
  32. package/dist/esm/handlers/click.js +19 -3
  33. package/dist/esm/handlers/click.js.map +1 -1
  34. package/dist/esm/handlers/hover.js +19 -3
  35. package/dist/esm/handlers/hover.js.map +1 -1
  36. package/dist/esm/handlers/viewEnter.js +10 -1
  37. package/dist/esm/handlers/viewEnter.js.map +1 -1
  38. package/dist/esm/handlers/viewProgress.js +24 -8
  39. package/dist/esm/handlers/viewProgress.js.map +1 -1
  40. package/dist/esm/types.js.map +1 -1
  41. package/dist/esm/utils.js +33 -4
  42. package/dist/esm/utils.js.map +1 -1
  43. package/dist/types/__tests__/viewEnter.spec.d.ts +7 -0
  44. package/dist/types/types.d.ts +3 -1
  45. package/dist/types/utils.d.ts +2 -1
  46. package/package.json +3 -3
@@ -1,3 +1,4 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
1
2
  import { Interact } from '../core/Interact';
2
3
  import { add, addListItems } from '../core/add';
3
4
  import { remove } from '../core/remove';
@@ -308,6 +309,18 @@ describe('interact', () => {
308
309
  }
309
310
  };
310
311
 
312
+ // Mock PointerEvent (not available in JSDOM)
313
+ window.PointerEvent = class PointerEvent extends MouseEvent {
314
+ constructor(type, params) {
315
+ if (params === void 0) {
316
+ params = {};
317
+ }
318
+ super(type, params);
319
+ _defineProperty(this, "pointerType", void 0);
320
+ this.pointerType = params.pointerType || '';
321
+ }
322
+ };
323
+
311
324
  // Mock adoptedStyleSheets
312
325
  if (!document.adoptedStyleSheets) {
313
326
  document.adoptedStyleSheets = [];
@@ -675,6 +688,176 @@ describe('interact', () => {
675
688
  });
676
689
  });
677
690
  });
691
+ describe('null animation handling', () => {
692
+ it('should not add click handler when getAnimation returns null', () => {
693
+ Interact.destroy();
694
+ const {
695
+ getWebAnimation
696
+ } = require('@wix/motion');
697
+ Interact.create({
698
+ interactions: [{
699
+ trigger: 'click',
700
+ key: 'null-click-test',
701
+ effects: [{
702
+ effectId: 'null-test-effect'
703
+ }]
704
+ }],
705
+ effects: {
706
+ 'null-test-effect': {
707
+ namedEffect: {
708
+ type: 'FadeIn'
709
+ },
710
+ duration: 500
711
+ }
712
+ }
713
+ });
714
+ getWebAnimation.mockReturnValueOnce(null);
715
+ element = document.createElement('interact-element');
716
+ const div = document.createElement('div');
717
+ element.append(div);
718
+ const addEventListenerSpy = jest.spyOn(div, 'addEventListener');
719
+ add(element, 'null-click-test');
720
+ expect(addEventListenerSpy).not.toHaveBeenCalled();
721
+ });
722
+ it('should not add hover handler when getAnimation returns null', () => {
723
+ Interact.destroy();
724
+ const {
725
+ getWebAnimation
726
+ } = require('@wix/motion');
727
+ Interact.create({
728
+ interactions: [{
729
+ trigger: 'hover',
730
+ key: 'null-hover-test',
731
+ effects: [{
732
+ effectId: 'null-test-effect'
733
+ }]
734
+ }],
735
+ effects: {
736
+ 'null-test-effect': {
737
+ namedEffect: {
738
+ type: 'FadeIn'
739
+ },
740
+ duration: 500
741
+ }
742
+ }
743
+ });
744
+ getWebAnimation.mockReturnValueOnce(null);
745
+ element = document.createElement('interact-element');
746
+ const div = document.createElement('div');
747
+ element.append(div);
748
+ const addEventListenerSpy = jest.spyOn(div, 'addEventListener');
749
+ add(element, 'null-hover-test');
750
+ expect(addEventListenerSpy).not.toHaveBeenCalled();
751
+ });
752
+ it('should not add animationEnd handler when getAnimation returns null', () => {
753
+ Interact.destroy();
754
+ const {
755
+ getWebAnimation
756
+ } = require('@wix/motion');
757
+ Interact.create({
758
+ interactions: [{
759
+ trigger: 'animationEnd',
760
+ key: 'null-animationend-test',
761
+ params: {
762
+ effectId: 'trigger-effect'
763
+ },
764
+ effects: [{
765
+ effectId: 'null-test-effect'
766
+ }]
767
+ }],
768
+ effects: {
769
+ 'null-test-effect': {
770
+ namedEffect: {
771
+ type: 'FadeIn'
772
+ },
773
+ duration: 500
774
+ }
775
+ }
776
+ });
777
+ getWebAnimation.mockReturnValueOnce(null);
778
+ element = document.createElement('interact-element');
779
+ const div = document.createElement('div');
780
+ element.append(div);
781
+ const addEventListenerSpy = jest.spyOn(div, 'addEventListener');
782
+ add(element, 'null-animationend-test');
783
+ expect(addEventListenerSpy).not.toHaveBeenCalled();
784
+ });
785
+ it('should not add viewProgress handler when getWebAnimation returns null (ViewTimeline)', () => {
786
+ Interact.destroy();
787
+ const {
788
+ getWebAnimation
789
+ } = require('@wix/motion');
790
+ Interact.create({
791
+ interactions: [{
792
+ trigger: 'viewProgress',
793
+ key: 'null-viewprogress-test',
794
+ effects: [{
795
+ effectId: 'null-scroll-effect'
796
+ }]
797
+ }],
798
+ effects: {
799
+ 'null-scroll-effect': {
800
+ namedEffect: {
801
+ type: 'FadeScroll',
802
+ range: 'in',
803
+ opacity: 0
804
+ }
805
+ }
806
+ }
807
+ });
808
+ getWebAnimation.mockReturnValueOnce(null);
809
+ element = document.createElement('interact-element');
810
+ const div = document.createElement('div');
811
+ element.append(div);
812
+ add(element, 'null-viewprogress-test');
813
+
814
+ // getWebAnimation should have been called
815
+ expect(getWebAnimation).toHaveBeenCalled();
816
+ });
817
+ it('should not add viewProgress handler when getScrubScene returns null (polyfill)', () => {
818
+ // Remove ViewTimeline support to use polyfill path
819
+ delete window.ViewTimeline;
820
+ Interact.destroy();
821
+ const {
822
+ getScrubScene
823
+ } = require('@wix/motion');
824
+ Interact.create({
825
+ interactions: [{
826
+ trigger: 'viewProgress',
827
+ key: 'null-viewprogress-polyfill-test',
828
+ effects: [{
829
+ effectId: 'null-scroll-effect'
830
+ }]
831
+ }],
832
+ effects: {
833
+ 'null-scroll-effect': {
834
+ namedEffect: {
835
+ type: 'FadeScroll',
836
+ range: 'in',
837
+ opacity: 0
838
+ }
839
+ }
840
+ }
841
+ });
842
+ getScrubScene.mockReturnValueOnce(null);
843
+ element = document.createElement('interact-element');
844
+ const div = document.createElement('div');
845
+ element.append(div);
846
+ add(element, 'null-viewprogress-polyfill-test');
847
+
848
+ // getScrubScene should have been called
849
+ expect(getScrubScene).toHaveBeenCalled();
850
+
851
+ // Restore ViewTimeline
852
+ window.ViewTimeline = class ViewTimeline {
853
+ constructor(options) {
854
+ return {
855
+ ...options
856
+ };
857
+ }
858
+ };
859
+ });
860
+ });
678
861
  describe('pointerMove', () => {
679
862
  it('should add handler for pointerMove trigger', () => {
680
863
  const {
@@ -1933,5 +2116,157 @@ describe('interact', () => {
1933
2116
  });
1934
2117
  });
1935
2118
  });
2119
+ describe('selector condition type', () => {
2120
+ it('should pass selectorCondition to handler when condition type is selector', async () => {
2121
+ const config = {
2122
+ conditions: {
2123
+ active: {
2124
+ type: 'selector',
2125
+ predicate: '.active'
2126
+ }
2127
+ },
2128
+ interactions: [{
2129
+ trigger: 'click',
2130
+ key: 'selector-test',
2131
+ effects: [{
2132
+ key: 'selector-test',
2133
+ effectId: 'test-effect',
2134
+ conditions: ['active']
2135
+ }]
2136
+ }],
2137
+ effects: {
2138
+ 'test-effect': {
2139
+ namedEffect: {
2140
+ type: 'FadeIn',
2141
+ power: 'medium'
2142
+ },
2143
+ duration: 500
2144
+ }
2145
+ }
2146
+ };
2147
+ Interact.create(config);
2148
+ const testElement = document.createElement('interact-element');
2149
+ const div = document.createElement('div');
2150
+ testElement.append(div);
2151
+ add(testElement, 'selector-test');
2152
+
2153
+ // The handler should have received selectorCondition
2154
+ // We verify by checking the animation is created (condition doesn't block setup)
2155
+ const {
2156
+ getWebAnimation
2157
+ } = await import('@wix/motion');
2158
+ expect(getWebAnimation).toHaveBeenCalled();
2159
+ });
2160
+ it('should skip handler execution when element does not match selector condition', async () => {
2161
+ const {
2162
+ getWebAnimation
2163
+ } = await import('@wix/motion');
2164
+ const mockAnimation = {
2165
+ play: jest.fn(),
2166
+ cancel: jest.fn(),
2167
+ onFinish: jest.fn(),
2168
+ reverse: jest.fn(),
2169
+ progress: jest.fn(),
2170
+ playState: 'idle',
2171
+ isCSS: false
2172
+ };
2173
+ getWebAnimation.mockReturnValue(mockAnimation);
2174
+ const config = {
2175
+ conditions: {
2176
+ active: {
2177
+ type: 'selector',
2178
+ predicate: '.active'
2179
+ }
2180
+ },
2181
+ interactions: [{
2182
+ trigger: 'click',
2183
+ key: 'selector-skip-test',
2184
+ effects: [{
2185
+ key: 'selector-skip-test',
2186
+ effectId: 'skip-effect',
2187
+ conditions: ['active']
2188
+ }]
2189
+ }],
2190
+ effects: {
2191
+ 'skip-effect': {
2192
+ namedEffect: {
2193
+ type: 'FadeIn',
2194
+ power: 'medium'
2195
+ },
2196
+ duration: 500
2197
+ }
2198
+ }
2199
+ };
2200
+ Interact.create(config);
2201
+ const testElement = document.createElement('interact-element');
2202
+ const div = document.createElement('div');
2203
+ // div does NOT have .active class
2204
+ testElement.append(div);
2205
+ add(testElement, 'selector-skip-test');
2206
+
2207
+ // Simulate click - animation should NOT play because element doesn't match .active
2208
+ // Must use PointerEvent with pointerType because click handler filters by pointerType
2209
+ div.dispatchEvent(new PointerEvent('click', {
2210
+ bubbles: true,
2211
+ pointerType: 'mouse'
2212
+ }));
2213
+ expect(mockAnimation.play).not.toHaveBeenCalled();
2214
+ });
2215
+ it('should execute handler when element matches selector condition', async () => {
2216
+ const {
2217
+ getWebAnimation
2218
+ } = await import('@wix/motion');
2219
+ const mockAnimation = {
2220
+ play: jest.fn(),
2221
+ cancel: jest.fn(),
2222
+ onFinish: jest.fn(),
2223
+ reverse: jest.fn(),
2224
+ progress: jest.fn(),
2225
+ playState: 'idle',
2226
+ isCSS: false
2227
+ };
2228
+ getWebAnimation.mockReturnValue(mockAnimation);
2229
+ const config = {
2230
+ conditions: {
2231
+ active: {
2232
+ type: 'selector',
2233
+ predicate: '.active'
2234
+ }
2235
+ },
2236
+ interactions: [{
2237
+ trigger: 'click',
2238
+ key: 'selector-match-test',
2239
+ effects: [{
2240
+ key: 'selector-match-test',
2241
+ effectId: 'match-effect',
2242
+ conditions: ['active']
2243
+ }]
2244
+ }],
2245
+ effects: {
2246
+ 'match-effect': {
2247
+ namedEffect: {
2248
+ type: 'FadeIn',
2249
+ power: 'medium'
2250
+ },
2251
+ duration: 500
2252
+ }
2253
+ }
2254
+ };
2255
+ Interact.create(config);
2256
+ const testElement = document.createElement('interact-element');
2257
+ const div = document.createElement('div');
2258
+ div.classList.add('active'); // div HAS .active class
2259
+ testElement.append(div);
2260
+ add(testElement, 'selector-match-test');
2261
+
2262
+ // Simulate click - animation SHOULD play because element matches .active
2263
+ // Must use PointerEvent with pointerType because click handler filters by pointerType
2264
+ div.dispatchEvent(new PointerEvent('click', {
2265
+ bubbles: true,
2266
+ pointerType: 'mouse'
2267
+ }));
2268
+ expect(mockAnimation.play).toHaveBeenCalled();
2269
+ });
2270
+ });
1936
2271
  });
1937
2272
  //# sourceMappingURL=interact.spec.js.map