@wix/interact 1.91.0 → 1.93.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/InteractElement.js +1 -0
- package/dist/cjs/InteractElement.js.map +1 -1
- package/dist/cjs/__tests__/interact.spec.js +294 -1
- package/dist/cjs/__tests__/interact.spec.js.map +1 -1
- package/dist/cjs/core/Interact.js +4 -0
- package/dist/cjs/core/Interact.js.map +1 -1
- package/dist/cjs/core/add.js +15 -8
- package/dist/cjs/core/add.js.map +1 -1
- package/dist/cjs/handlers/animationEnd.js +6 -2
- package/dist/cjs/handlers/animationEnd.js.map +1 -1
- package/dist/cjs/handlers/click.js +37 -9
- package/dist/cjs/handlers/click.js.map +1 -1
- package/dist/cjs/handlers/hover.js +41 -10
- package/dist/cjs/handlers/hover.js.map +1 -1
- package/dist/cjs/handlers/index.js +12 -1
- package/dist/cjs/handlers/index.js.map +1 -1
- package/dist/cjs/handlers/pointerMove.js +2 -2
- package/dist/cjs/handlers/pointerMove.js.map +1 -1
- package/dist/cjs/handlers/viewEnter.js +6 -2
- package/dist/cjs/handlers/viewEnter.js.map +1 -1
- package/dist/cjs/handlers/viewProgress.js +24 -10
- package/dist/cjs/handlers/viewProgress.js.map +1 -1
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/utils.js +34 -4
- package/dist/cjs/utils.js.map +1 -1
- package/dist/esm/InteractElement.js +1 -0
- package/dist/esm/InteractElement.js.map +1 -1
- package/dist/esm/__tests__/interact.spec.js +295 -1
- package/dist/esm/__tests__/interact.spec.js.map +1 -1
- package/dist/esm/core/Interact.js +4 -0
- package/dist/esm/core/Interact.js.map +1 -1
- package/dist/esm/core/add.js +16 -9
- package/dist/esm/core/add.js.map +1 -1
- package/dist/esm/handlers/animationEnd.js +6 -5
- package/dist/esm/handlers/animationEnd.js.map +1 -1
- package/dist/esm/handlers/click.js +37 -15
- package/dist/esm/handlers/click.js.map +1 -1
- package/dist/esm/handlers/hover.js +41 -16
- package/dist/esm/handlers/hover.js.map +1 -1
- package/dist/esm/handlers/index.js +12 -1
- package/dist/esm/handlers/index.js.map +1 -1
- package/dist/esm/handlers/pointerMove.js +2 -5
- package/dist/esm/handlers/pointerMove.js.map +1 -1
- package/dist/esm/handlers/viewEnter.js +6 -5
- package/dist/esm/handlers/viewEnter.js.map +1 -1
- package/dist/esm/handlers/viewProgress.js +24 -13
- package/dist/esm/handlers/viewProgress.js.map +1 -1
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/utils.js +33 -4
- package/dist/esm/utils.js.map +1 -1
- package/dist/types/core/Interact.d.ts +2 -0
- package/dist/types/handlers/animationEnd.d.ts +2 -2
- package/dist/types/handlers/click.d.ts +2 -2
- package/dist/types/handlers/hover.d.ts +2 -2
- package/dist/types/handlers/pointerMove.d.ts +2 -2
- package/dist/types/handlers/viewEnter.d.ts +2 -2
- package/dist/types/handlers/viewProgress.d.ts +2 -2
- package/dist/types/types.d.ts +11 -3
- package/dist/types/utils.d.ts +2 -1
- package/package.json +2 -2
|
@@ -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 = [];
|
|
@@ -403,8 +416,9 @@ describe('interact', () => {
|
|
|
403
416
|
jest.clearAllMocks();
|
|
404
417
|
// Clear Interact instances to ensure test isolation
|
|
405
418
|
Interact.destroy();
|
|
406
|
-
// Reset
|
|
419
|
+
// Reset static flags to default
|
|
407
420
|
Interact.forceReducedMotion = false;
|
|
421
|
+
Interact.allowA11yTriggers = false;
|
|
408
422
|
});
|
|
409
423
|
describe('init Interact instance', () => {
|
|
410
424
|
it('should initialize with valid config', () => {
|
|
@@ -1804,5 +1818,285 @@ describe('interact', () => {
|
|
|
1804
1818
|
expect(spy).toHaveBeenCalledWith(pointerOptionsGetter);
|
|
1805
1819
|
});
|
|
1806
1820
|
});
|
|
1821
|
+
describe('a11y - accessible triggers', () => {
|
|
1822
|
+
let a11yElement;
|
|
1823
|
+
function getA11yConfig(trigger, key) {
|
|
1824
|
+
return {
|
|
1825
|
+
interactions: [{
|
|
1826
|
+
trigger,
|
|
1827
|
+
key,
|
|
1828
|
+
effects: [{
|
|
1829
|
+
effectId: 'test-effect'
|
|
1830
|
+
}]
|
|
1831
|
+
}],
|
|
1832
|
+
effects: {
|
|
1833
|
+
'test-effect': {
|
|
1834
|
+
namedEffect: {
|
|
1835
|
+
type: 'BounceIn',
|
|
1836
|
+
power: 'medium'
|
|
1837
|
+
},
|
|
1838
|
+
duration: 500
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
};
|
|
1842
|
+
}
|
|
1843
|
+
afterEach(() => {
|
|
1844
|
+
Interact.destroy();
|
|
1845
|
+
});
|
|
1846
|
+
describe('activate trigger', () => {
|
|
1847
|
+
it('should add both click and keydown listeners', () => {
|
|
1848
|
+
Interact.create(getA11yConfig('activate', 'activate-div'));
|
|
1849
|
+
a11yElement = document.createElement('interact-element');
|
|
1850
|
+
const div = document.createElement('div');
|
|
1851
|
+
a11yElement.append(div);
|
|
1852
|
+
const addEventListenerSpy = jest.spyOn(div, 'addEventListener');
|
|
1853
|
+
add(a11yElement, 'activate-div');
|
|
1854
|
+
expect(addEventListenerSpy).toHaveBeenCalledWith('click', expect.any(Function), expect.any(Object));
|
|
1855
|
+
expect(addEventListenerSpy).toHaveBeenCalledWith('keydown', expect.any(Function), expect.any(Object));
|
|
1856
|
+
});
|
|
1857
|
+
it('should not double-invoke handler when Enter triggers both keydown and click', () => {
|
|
1858
|
+
const {
|
|
1859
|
+
getWebAnimation
|
|
1860
|
+
} = require('@wix/motion');
|
|
1861
|
+
const mockPlay = getWebAnimation().play;
|
|
1862
|
+
mockPlay.mockClear();
|
|
1863
|
+
Interact.create(getA11yConfig('activate', 'activate-handler-test'));
|
|
1864
|
+
a11yElement = document.createElement('interact-element');
|
|
1865
|
+
const button = document.createElement('button');
|
|
1866
|
+
a11yElement.append(button);
|
|
1867
|
+
add(a11yElement, 'activate-handler-test');
|
|
1868
|
+
|
|
1869
|
+
// Simulate browser behavior: Enter key triggers keydown AND synthesized click with no pointerType
|
|
1870
|
+
button.dispatchEvent(new KeyboardEvent('keydown', {
|
|
1871
|
+
code: 'Enter',
|
|
1872
|
+
bubbles: true
|
|
1873
|
+
}));
|
|
1874
|
+
button.dispatchEvent(new MouseEvent('click', {
|
|
1875
|
+
bubbles: true
|
|
1876
|
+
}));
|
|
1877
|
+
expect(mockPlay).toHaveBeenCalledTimes(1);
|
|
1878
|
+
});
|
|
1879
|
+
});
|
|
1880
|
+
describe('interest trigger', () => {
|
|
1881
|
+
it('should add focusin listener alongside mouseenter', () => {
|
|
1882
|
+
Interact.create(getA11yConfig('interest', 'interest-test'));
|
|
1883
|
+
a11yElement = document.createElement('interact-element');
|
|
1884
|
+
const div = document.createElement('div');
|
|
1885
|
+
a11yElement.append(div);
|
|
1886
|
+
const addEventListenerSpy = jest.spyOn(div, 'addEventListener');
|
|
1887
|
+
add(a11yElement, 'interest-test');
|
|
1888
|
+
expect(addEventListenerSpy).toHaveBeenCalledWith('mouseenter', expect.any(Function), expect.any(Object));
|
|
1889
|
+
expect(addEventListenerSpy).toHaveBeenCalledWith('focusin', expect.any(Function), expect.any(Object));
|
|
1890
|
+
});
|
|
1891
|
+
});
|
|
1892
|
+
describe('click trigger with allowA11yTriggers flag', () => {
|
|
1893
|
+
it('should NOT add keydown listener when flag is false', () => {
|
|
1894
|
+
Interact.create(getA11yConfig('click', 'click-no-flag'));
|
|
1895
|
+
Interact.setup({
|
|
1896
|
+
allowA11yTriggers: false
|
|
1897
|
+
});
|
|
1898
|
+
a11yElement = document.createElement('interact-element');
|
|
1899
|
+
const div = document.createElement('div');
|
|
1900
|
+
a11yElement.append(div);
|
|
1901
|
+
const addEventListenerSpy = jest.spyOn(div, 'addEventListener');
|
|
1902
|
+
add(a11yElement, 'click-no-flag');
|
|
1903
|
+
expect(addEventListenerSpy).toHaveBeenCalledWith('click', expect.any(Function), expect.any(Object));
|
|
1904
|
+
expect(addEventListenerSpy).not.toHaveBeenCalledWith('keydown', expect.any(Function), expect.any(Object));
|
|
1905
|
+
});
|
|
1906
|
+
it('should add keydown listener when flag is true', () => {
|
|
1907
|
+
Interact.setup({
|
|
1908
|
+
allowA11yTriggers: true
|
|
1909
|
+
});
|
|
1910
|
+
Interact.create(getA11yConfig('click', 'click-with-flag'));
|
|
1911
|
+
a11yElement = document.createElement('interact-element');
|
|
1912
|
+
const div = document.createElement('div');
|
|
1913
|
+
a11yElement.append(div);
|
|
1914
|
+
const addEventListenerSpy = jest.spyOn(div, 'addEventListener');
|
|
1915
|
+
add(a11yElement, 'click-with-flag');
|
|
1916
|
+
expect(addEventListenerSpy).toHaveBeenCalledWith('click', expect.any(Function), expect.any(Object));
|
|
1917
|
+
expect(addEventListenerSpy).toHaveBeenCalledWith('keydown', expect.any(Function), expect.any(Object));
|
|
1918
|
+
});
|
|
1919
|
+
});
|
|
1920
|
+
describe('hover trigger with allowA11yTriggers flag', () => {
|
|
1921
|
+
it('should NOT add focusin listener when flag is false', () => {
|
|
1922
|
+
Interact.setup({
|
|
1923
|
+
allowA11yTriggers: false
|
|
1924
|
+
});
|
|
1925
|
+
Interact.create(getA11yConfig('hover', 'hover-no-flag'));
|
|
1926
|
+
a11yElement = document.createElement('interact-element');
|
|
1927
|
+
const div = document.createElement('div');
|
|
1928
|
+
a11yElement.append(div);
|
|
1929
|
+
const addEventListenerSpy = jest.spyOn(div, 'addEventListener');
|
|
1930
|
+
add(a11yElement, 'hover-no-flag');
|
|
1931
|
+
expect(addEventListenerSpy).toHaveBeenCalledWith('mouseenter', expect.any(Function), expect.any(Object));
|
|
1932
|
+
expect(addEventListenerSpy).not.toHaveBeenCalledWith('focusin', expect.any(Function), expect.any(Object));
|
|
1933
|
+
});
|
|
1934
|
+
it('should add focusin listener when flag is true', () => {
|
|
1935
|
+
Interact.setup({
|
|
1936
|
+
allowA11yTriggers: true
|
|
1937
|
+
});
|
|
1938
|
+
Interact.create(getA11yConfig('hover', 'hover-with-flag'));
|
|
1939
|
+
a11yElement = document.createElement('interact-element');
|
|
1940
|
+
const div = document.createElement('div');
|
|
1941
|
+
a11yElement.append(div);
|
|
1942
|
+
const addEventListenerSpy = jest.spyOn(div, 'addEventListener');
|
|
1943
|
+
add(a11yElement, 'hover-with-flag');
|
|
1944
|
+
expect(addEventListenerSpy).toHaveBeenCalledWith('mouseenter', expect.any(Function), expect.any(Object));
|
|
1945
|
+
expect(addEventListenerSpy).toHaveBeenCalledWith('focusin', expect.any(Function), expect.any(Object));
|
|
1946
|
+
});
|
|
1947
|
+
});
|
|
1948
|
+
});
|
|
1949
|
+
describe('selector condition type', () => {
|
|
1950
|
+
it('should pass selectorCondition to handler when condition type is selector', async () => {
|
|
1951
|
+
const config = {
|
|
1952
|
+
conditions: {
|
|
1953
|
+
active: {
|
|
1954
|
+
type: 'selector',
|
|
1955
|
+
predicate: '.active'
|
|
1956
|
+
}
|
|
1957
|
+
},
|
|
1958
|
+
interactions: [{
|
|
1959
|
+
trigger: 'click',
|
|
1960
|
+
key: 'selector-test',
|
|
1961
|
+
effects: [{
|
|
1962
|
+
key: 'selector-test',
|
|
1963
|
+
effectId: 'test-effect',
|
|
1964
|
+
conditions: ['active']
|
|
1965
|
+
}]
|
|
1966
|
+
}],
|
|
1967
|
+
effects: {
|
|
1968
|
+
'test-effect': {
|
|
1969
|
+
namedEffect: {
|
|
1970
|
+
type: 'FadeIn',
|
|
1971
|
+
power: 'medium'
|
|
1972
|
+
},
|
|
1973
|
+
duration: 500
|
|
1974
|
+
}
|
|
1975
|
+
}
|
|
1976
|
+
};
|
|
1977
|
+
Interact.create(config);
|
|
1978
|
+
const testElement = document.createElement('interact-element');
|
|
1979
|
+
const div = document.createElement('div');
|
|
1980
|
+
testElement.append(div);
|
|
1981
|
+
add(testElement, 'selector-test');
|
|
1982
|
+
|
|
1983
|
+
// The handler should have received selectorCondition
|
|
1984
|
+
// We verify by checking the animation is created (condition doesn't block setup)
|
|
1985
|
+
const {
|
|
1986
|
+
getWebAnimation
|
|
1987
|
+
} = await import('@wix/motion');
|
|
1988
|
+
expect(getWebAnimation).toHaveBeenCalled();
|
|
1989
|
+
});
|
|
1990
|
+
it('should skip handler execution when element does not match selector condition', async () => {
|
|
1991
|
+
const {
|
|
1992
|
+
getWebAnimation
|
|
1993
|
+
} = await import('@wix/motion');
|
|
1994
|
+
const mockAnimation = {
|
|
1995
|
+
play: jest.fn(),
|
|
1996
|
+
cancel: jest.fn(),
|
|
1997
|
+
onFinish: jest.fn(),
|
|
1998
|
+
reverse: jest.fn(),
|
|
1999
|
+
progress: jest.fn(),
|
|
2000
|
+
playState: 'idle',
|
|
2001
|
+
isCSS: false
|
|
2002
|
+
};
|
|
2003
|
+
getWebAnimation.mockReturnValue(mockAnimation);
|
|
2004
|
+
const config = {
|
|
2005
|
+
conditions: {
|
|
2006
|
+
active: {
|
|
2007
|
+
type: 'selector',
|
|
2008
|
+
predicate: '.active'
|
|
2009
|
+
}
|
|
2010
|
+
},
|
|
2011
|
+
interactions: [{
|
|
2012
|
+
trigger: 'click',
|
|
2013
|
+
key: 'selector-skip-test',
|
|
2014
|
+
effects: [{
|
|
2015
|
+
key: 'selector-skip-test',
|
|
2016
|
+
effectId: 'skip-effect',
|
|
2017
|
+
conditions: ['active']
|
|
2018
|
+
}]
|
|
2019
|
+
}],
|
|
2020
|
+
effects: {
|
|
2021
|
+
'skip-effect': {
|
|
2022
|
+
namedEffect: {
|
|
2023
|
+
type: 'FadeIn',
|
|
2024
|
+
power: 'medium'
|
|
2025
|
+
},
|
|
2026
|
+
duration: 500
|
|
2027
|
+
}
|
|
2028
|
+
}
|
|
2029
|
+
};
|
|
2030
|
+
Interact.create(config);
|
|
2031
|
+
const testElement = document.createElement('interact-element');
|
|
2032
|
+
const div = document.createElement('div');
|
|
2033
|
+
// div does NOT have .active class
|
|
2034
|
+
testElement.append(div);
|
|
2035
|
+
add(testElement, 'selector-skip-test');
|
|
2036
|
+
|
|
2037
|
+
// Simulate click - animation should NOT play because element doesn't match .active
|
|
2038
|
+
// Must use PointerEvent with pointerType because click handler filters by pointerType
|
|
2039
|
+
div.dispatchEvent(new PointerEvent('click', {
|
|
2040
|
+
bubbles: true,
|
|
2041
|
+
pointerType: 'mouse'
|
|
2042
|
+
}));
|
|
2043
|
+
expect(mockAnimation.play).not.toHaveBeenCalled();
|
|
2044
|
+
});
|
|
2045
|
+
it('should execute handler when element matches selector condition', async () => {
|
|
2046
|
+
const {
|
|
2047
|
+
getWebAnimation
|
|
2048
|
+
} = await import('@wix/motion');
|
|
2049
|
+
const mockAnimation = {
|
|
2050
|
+
play: jest.fn(),
|
|
2051
|
+
cancel: jest.fn(),
|
|
2052
|
+
onFinish: jest.fn(),
|
|
2053
|
+
reverse: jest.fn(),
|
|
2054
|
+
progress: jest.fn(),
|
|
2055
|
+
playState: 'idle',
|
|
2056
|
+
isCSS: false
|
|
2057
|
+
};
|
|
2058
|
+
getWebAnimation.mockReturnValue(mockAnimation);
|
|
2059
|
+
const config = {
|
|
2060
|
+
conditions: {
|
|
2061
|
+
active: {
|
|
2062
|
+
type: 'selector',
|
|
2063
|
+
predicate: '.active'
|
|
2064
|
+
}
|
|
2065
|
+
},
|
|
2066
|
+
interactions: [{
|
|
2067
|
+
trigger: 'click',
|
|
2068
|
+
key: 'selector-match-test',
|
|
2069
|
+
effects: [{
|
|
2070
|
+
key: 'selector-match-test',
|
|
2071
|
+
effectId: 'match-effect',
|
|
2072
|
+
conditions: ['active']
|
|
2073
|
+
}]
|
|
2074
|
+
}],
|
|
2075
|
+
effects: {
|
|
2076
|
+
'match-effect': {
|
|
2077
|
+
namedEffect: {
|
|
2078
|
+
type: 'FadeIn',
|
|
2079
|
+
power: 'medium'
|
|
2080
|
+
},
|
|
2081
|
+
duration: 500
|
|
2082
|
+
}
|
|
2083
|
+
}
|
|
2084
|
+
};
|
|
2085
|
+
Interact.create(config);
|
|
2086
|
+
const testElement = document.createElement('interact-element');
|
|
2087
|
+
const div = document.createElement('div');
|
|
2088
|
+
div.classList.add('active'); // div HAS .active class
|
|
2089
|
+
testElement.append(div);
|
|
2090
|
+
add(testElement, 'selector-match-test');
|
|
2091
|
+
|
|
2092
|
+
// Simulate click - animation SHOULD play because element matches .active
|
|
2093
|
+
// Must use PointerEvent with pointerType because click handler filters by pointerType
|
|
2094
|
+
div.dispatchEvent(new PointerEvent('click', {
|
|
2095
|
+
bubbles: true,
|
|
2096
|
+
pointerType: 'mouse'
|
|
2097
|
+
}));
|
|
2098
|
+
expect(mockAnimation.play).toHaveBeenCalled();
|
|
2099
|
+
});
|
|
2100
|
+
});
|
|
1807
2101
|
});
|
|
1808
2102
|
//# sourceMappingURL=interact.spec.js.map
|