@lumx/core 3.20.1-alpha.3 → 3.20.1-alpha.30
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/CONTRIBUTING.md +1 -5
- package/js/constants/design-tokens.js +5389 -2294
- package/js/constants/index.js +107 -134
- package/js/constants/keycodes.js +9 -13
- package/js/custom-colors.js +17 -22
- package/js/types/Callback.js +0 -1
- package/js/types/Falsy.js +0 -1
- package/js/types/GenericProps.js +0 -1
- package/js/types/HasAriaLabelOrLabelledBy.js +0 -1
- package/js/types/HasClassName.js +0 -1
- package/js/types/HasCloseMode.js +0 -1
- package/js/types/HasTheme.js +0 -1
- package/js/types/HeadingElement.js +0 -1
- package/js/types/Point.js +0 -1
- package/js/types/Predicate.js +0 -1
- package/js/types/RectSize.js +0 -1
- package/js/types/TextElement.js +0 -1
- package/js/types/ValueOf.js +0 -1
- package/js/types/index.js +0 -1
- package/js/utils/className/fontColorClass.js +7 -12
- package/js/utils/className/fontColorClass.test.js +14 -16
- package/js/utils/className/getBasicClass.js +18 -24
- package/js/utils/className/getBasicClass.test.js +54 -19
- package/js/utils/className/getBasicClass.ts +2 -3
- package/js/utils/className/getRootClassName.js +10 -17
- package/js/utils/className/getRootClassName.test.js +11 -13
- package/js/utils/className/getRootClassName.ts +1 -2
- package/js/utils/className/getTypographyClassName.js +3 -7
- package/js/utils/className/getTypographyClassName.test.js +5 -7
- package/js/utils/className/handleBasicClasses.js +26 -31
- package/js/utils/className/handleBasicClasses.test.js +29 -32
- package/js/utils/className/handleBasicClasses.ts +3 -5
- package/js/utils/className/index.js +11 -25
- package/js/utils/className/resolveColorWithVariants.js +4 -9
- package/js/utils/className/resolveColorWithVariants.test.js +26 -28
- package/js/utils/collection/castArray.js +4 -0
- package/js/utils/collection/castArray.test.js +15 -0
- package/js/utils/collection/castArray.test.ts +15 -0
- package/js/utils/collection/castArray.ts +3 -0
- package/js/utils/collection/chunk.js +13 -0
- package/js/utils/collection/chunk.test.js +28 -0
- package/js/utils/collection/chunk.test.ts +38 -0
- package/js/utils/collection/chunk.ts +11 -0
- package/js/utils/collection/isEmpty.js +4 -0
- package/js/utils/collection/isEmpty.test.js +21 -0
- package/js/utils/collection/isEmpty.test.ts +21 -0
- package/js/utils/collection/isEmpty.ts +4 -0
- package/js/utils/collection/last.js +4 -0
- package/js/utils/collection/last.test.js +19 -0
- package/js/utils/collection/last.test.ts +21 -0
- package/js/utils/collection/last.ts +2 -0
- package/js/utils/collection/partitionMulti.js +28 -0
- package/js/utils/collection/partitionMulti.test.js +26 -0
- package/js/utils/collection/partitionMulti.test.ts +35 -0
- package/js/utils/collection/partitionMulti.ts +29 -0
- package/js/utils/collection/range.js +6 -0
- package/js/utils/collection/range.test.js +10 -0
- package/js/utils/collection/range.test.ts +10 -0
- package/js/utils/collection/range.ts +2 -0
- package/js/utils/index.js +159 -174
- package/js/utils/index.ts +4 -6
- package/js/utils/string/kebabCase.js +28 -0
- package/js/utils/string/kebabCase.test.js +41 -0
- package/js/utils/string/kebabCase.test.ts +50 -0
- package/js/utils/string/kebabCase.ts +28 -0
- package/package.json +13 -11
- package/js/components/Icon/index.tsx +0 -133
- package/js/constants/design-tokens.min.js +0 -1
- package/js/constants/index.min.js +0 -1
- package/js/constants/keycodes.min.js +0 -1
- package/js/custom-colors.min.js +0 -1
- package/js/date-picker.js +0 -71
- package/js/date-picker.min.js +0 -1
- package/js/date-picker.ts +0 -77
- package/js/types/Callback.min.js +0 -1
- package/js/types/Falsy.min.js +0 -1
- package/js/types/GenericProps.min.js +0 -1
- package/js/types/HasAriaLabelOrLabelledBy.min.js +0 -1
- package/js/types/HasClassName.min.js +0 -1
- package/js/types/HasCloseMode.min.js +0 -1
- package/js/types/HasTheme.min.js +0 -1
- package/js/types/HeadingElement.min.js +0 -1
- package/js/types/Point.min.js +0 -1
- package/js/types/Predicate.min.js +0 -1
- package/js/types/RectSize.min.js +0 -1
- package/js/types/TextElement.min.js +0 -1
- package/js/types/ValueOf.min.js +0 -1
- package/js/types/index.min.js +0 -1
- package/js/utils/className/fontColorClass.min.js +0 -1
- package/js/utils/className/fontColorClass.test.min.js +0 -1
- package/js/utils/className/getBasicClass.min.js +0 -1
- package/js/utils/className/getBasicClass.test.min.js +0 -1
- package/js/utils/className/getRootClassName.min.js +0 -1
- package/js/utils/className/getRootClassName.test.min.js +0 -1
- package/js/utils/className/getTypographyClassName.min.js +0 -1
- package/js/utils/className/getTypographyClassName.test.min.js +0 -1
- package/js/utils/className/handleBasicClasses.min.js +0 -1
- package/js/utils/className/handleBasicClasses.test.min.js +0 -1
- package/js/utils/className/index.min.js +0 -1
- package/js/utils/className/resolveColorWithVariants.min.js +0 -1
- package/js/utils/className/resolveColorWithVariants.test.min.js +0 -1
- package/js/utils/index.min.js +0 -1
- package/lumx.min.css +0 -1
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { isEmpty } from './isEmpty.js';
|
|
2
|
+
|
|
3
|
+
describe(isEmpty, () => {
|
|
4
|
+
it('should return true for falsy values', () => {
|
|
5
|
+
expect(isEmpty(undefined)).toBe(true);
|
|
6
|
+
expect(isEmpty(null)).toBe(true);
|
|
7
|
+
expect(isEmpty(0)).toBe(true);
|
|
8
|
+
expect(isEmpty('')).toBe(true);
|
|
9
|
+
expect(isEmpty(false)).toBe(true);
|
|
10
|
+
});
|
|
11
|
+
it('should return true for empty object or array', () => {
|
|
12
|
+
expect(isEmpty([])).toBe(true);
|
|
13
|
+
expect(isEmpty({})).toBe(true);
|
|
14
|
+
});
|
|
15
|
+
it('should return false for non empty object or array', () => {
|
|
16
|
+
expect(isEmpty([''])).toBe(false);
|
|
17
|
+
expect(isEmpty({
|
|
18
|
+
foo: false
|
|
19
|
+
})).toBe(false);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { isEmpty } from './isEmpty';
|
|
2
|
+
|
|
3
|
+
describe(isEmpty, () => {
|
|
4
|
+
it('should return true for falsy values', () => {
|
|
5
|
+
expect(isEmpty(undefined)).toBe(true);
|
|
6
|
+
expect(isEmpty(null)).toBe(true);
|
|
7
|
+
expect(isEmpty(0)).toBe(true);
|
|
8
|
+
expect(isEmpty('')).toBe(true);
|
|
9
|
+
expect(isEmpty(false)).toBe(true);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('should return true for empty object or array', () => {
|
|
13
|
+
expect(isEmpty([])).toBe(true);
|
|
14
|
+
expect(isEmpty({})).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('should return false for non empty object or array', () => {
|
|
18
|
+
expect(isEmpty([''])).toBe(false);
|
|
19
|
+
expect(isEmpty({ foo: false })).toBe(false);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { last } from '@lumx/core/js/utils/collection/last';
|
|
2
|
+
|
|
3
|
+
describe(last, () => {
|
|
4
|
+
it('should return undefined for empty array', () => {
|
|
5
|
+
const input = [];
|
|
6
|
+
const output = last(input);
|
|
7
|
+
expect(output).toBeUndefined();
|
|
8
|
+
});
|
|
9
|
+
it('should return last element from array with single element', () => {
|
|
10
|
+
const input = [42];
|
|
11
|
+
const output = last(input);
|
|
12
|
+
expect(output).toBe(42);
|
|
13
|
+
});
|
|
14
|
+
it('should return last element from array with multiple elements', () => {
|
|
15
|
+
const input = [1, 2, 3, 4, 5];
|
|
16
|
+
const output = last(input);
|
|
17
|
+
expect(output).toBe(5);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { last } from '@lumx/core/js/utils/collection/last';
|
|
2
|
+
|
|
3
|
+
describe(last, () => {
|
|
4
|
+
it('should return undefined for empty array', () => {
|
|
5
|
+
const input: number[] = [];
|
|
6
|
+
const output = last(input);
|
|
7
|
+
expect(output).toBeUndefined();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('should return last element from array with single element', () => {
|
|
11
|
+
const input = [42];
|
|
12
|
+
const output = last(input);
|
|
13
|
+
expect(output).toBe(42);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('should return last element from array with multiple elements', () => {
|
|
17
|
+
const input = [1, 2, 3, 4, 5];
|
|
18
|
+
const output = last(input);
|
|
19
|
+
expect(output).toBe(5);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Similar to lodash `partition` function but working with multiple predicates.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* const isString = (s) => typeof s === 'string'
|
|
6
|
+
* const isNumber = (s) => typeof s === 'number'
|
|
7
|
+
* const [strings, numbers, others] = partitionMulti(['a', 1, 'b', false], [isString, isNumber])
|
|
8
|
+
* //=> [['a', 'b'], [1], [false]]
|
|
9
|
+
*
|
|
10
|
+
* @param elements array of elements
|
|
11
|
+
* @param predicates array of predicates to apply on elements
|
|
12
|
+
* @return partitioned elements by the given predicates
|
|
13
|
+
*/
|
|
14
|
+
function partitionMulti(elements, predicates) {
|
|
15
|
+
const others = [];
|
|
16
|
+
const groups = predicates.map(() => []);
|
|
17
|
+
for (const element of elements) {
|
|
18
|
+
const index = predicates.findIndex(predicate => predicate(element));
|
|
19
|
+
if (index !== -1) {
|
|
20
|
+
groups[index].push(element);
|
|
21
|
+
} else {
|
|
22
|
+
others.push(element);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return [...groups, others];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { partitionMulti };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { partitionMulti } from './partitionMulti.js';
|
|
2
|
+
|
|
3
|
+
describe('partitionMulti', () => {
|
|
4
|
+
it('should partition with single predicate', () => {
|
|
5
|
+
const data = [0, 1, 2, 3, 4, 5];
|
|
6
|
+
const isEven = n => n % 2 === 0;
|
|
7
|
+
const actual = partitionMulti(data, [isEven]);
|
|
8
|
+
expect(actual).toEqual([[0, 2, 4], [1, 3, 5]]);
|
|
9
|
+
});
|
|
10
|
+
it('should partition on multiple predicates', () => {
|
|
11
|
+
const data = ['a', 1, 'b', false, true];
|
|
12
|
+
const isString = s => typeof s === 'string';
|
|
13
|
+
const isNumber = s => typeof s === 'number';
|
|
14
|
+
const isNull = s => s === null;
|
|
15
|
+
const partitions = partitionMulti(data, [isString, isNumber, isNull]);
|
|
16
|
+
expect(partitions).toEqual([
|
|
17
|
+
// strings
|
|
18
|
+
['a', 'b'],
|
|
19
|
+
// numbers
|
|
20
|
+
[1],
|
|
21
|
+
// nulls
|
|
22
|
+
[],
|
|
23
|
+
// others
|
|
24
|
+
[false, true]]);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { partitionMulti } from './partitionMulti';
|
|
2
|
+
|
|
3
|
+
describe('partitionMulti', () => {
|
|
4
|
+
it('should partition with single predicate', () => {
|
|
5
|
+
const data = [0, 1, 2, 3, 4, 5];
|
|
6
|
+
const isEven = (n: number): boolean => n % 2 === 0;
|
|
7
|
+
|
|
8
|
+
const actual = partitionMulti(data, [isEven]);
|
|
9
|
+
|
|
10
|
+
expect(actual).toEqual([
|
|
11
|
+
[0, 2, 4],
|
|
12
|
+
[1, 3, 5],
|
|
13
|
+
]);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('should partition on multiple predicates', () => {
|
|
17
|
+
type T = string | number | boolean;
|
|
18
|
+
const data: T[] = ['a', 1, 'b', false, true];
|
|
19
|
+
const isString = (s: T): boolean => typeof s === 'string';
|
|
20
|
+
const isNumber = (s: T): boolean => typeof s === 'number';
|
|
21
|
+
const isNull = (s: T): boolean => s === null;
|
|
22
|
+
|
|
23
|
+
const partitions = partitionMulti(data, [isString, isNumber, isNull]);
|
|
24
|
+
expect(partitions).toEqual([
|
|
25
|
+
// strings
|
|
26
|
+
['a', 'b'],
|
|
27
|
+
// numbers
|
|
28
|
+
[1],
|
|
29
|
+
// nulls
|
|
30
|
+
[],
|
|
31
|
+
// others
|
|
32
|
+
[false, true],
|
|
33
|
+
]);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Predicate } from '@lumx/core/js/types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Similar to lodash `partition` function but working with multiple predicates.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const isString = (s) => typeof s === 'string'
|
|
8
|
+
* const isNumber = (s) => typeof s === 'number'
|
|
9
|
+
* const [strings, numbers, others] = partitionMulti(['a', 1, 'b', false], [isString, isNumber])
|
|
10
|
+
* //=> [['a', 'b'], [1], [false]]
|
|
11
|
+
*
|
|
12
|
+
* @param elements array of elements
|
|
13
|
+
* @param predicates array of predicates to apply on elements
|
|
14
|
+
* @return partitioned elements by the given predicates
|
|
15
|
+
*/
|
|
16
|
+
export function partitionMulti<T>(elements: T[], predicates: Array<Predicate<T>>): T[][] {
|
|
17
|
+
const others = [] as T[];
|
|
18
|
+
const groups = predicates.map(() => []) as T[][];
|
|
19
|
+
|
|
20
|
+
for (const element of elements) {
|
|
21
|
+
const index = predicates.findIndex((predicate) => predicate(element));
|
|
22
|
+
if (index !== -1) {
|
|
23
|
+
groups[index].push(element);
|
|
24
|
+
} else {
|
|
25
|
+
others.push(element);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return [...groups, others];
|
|
29
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { range } from './range.js';
|
|
2
|
+
|
|
3
|
+
describe(range, () => {
|
|
4
|
+
it('should generate a number range', () => {
|
|
5
|
+
expect(range(-2)).toEqual([]);
|
|
6
|
+
expect(range(0)).toEqual([]);
|
|
7
|
+
expect(range(1)).toEqual([0]);
|
|
8
|
+
expect(range(5)).toEqual([0, 1, 2, 3, 4]);
|
|
9
|
+
});
|
|
10
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { range } from './range';
|
|
2
|
+
|
|
3
|
+
describe(range, () => {
|
|
4
|
+
it('should generate a number range', () => {
|
|
5
|
+
expect(range(-2)).toEqual([]);
|
|
6
|
+
expect(range(0)).toEqual([]);
|
|
7
|
+
expect(range(1)).toEqual([0]);
|
|
8
|
+
expect(range(5)).toEqual([0, 1, 2, 3, 4]);
|
|
9
|
+
});
|
|
10
|
+
});
|
package/js/utils/index.js
CHANGED
|
@@ -1,24 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
require('classnames');
|
|
13
|
-
require('lodash/isBoolean');
|
|
14
|
-
require('lodash/isEmpty');
|
|
15
|
-
require('lodash/kebabCase');
|
|
16
|
-
require('../constants/index.js');
|
|
17
|
-
require('../constants/keycodes.js');
|
|
18
|
-
|
|
19
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
20
|
-
|
|
21
|
-
var noop__default = /*#__PURE__*/_interopDefaultLegacy(noop);
|
|
1
|
+
export { handleBasicClasses } from './className/handleBasicClasses.js';
|
|
2
|
+
export { getBasicClass } from './className/getBasicClass.js';
|
|
3
|
+
export { getRootClassName } from './className/getRootClassName.js';
|
|
4
|
+
export { getTypographyClassName } from './className/getTypographyClassName.js';
|
|
5
|
+
export { fontColorClass } from './className/fontColorClass.js';
|
|
6
|
+
export { resolveColorWithVariants } from './className/resolveColorWithVariants.js';
|
|
7
|
+
import 'classnames';
|
|
8
|
+
import '@lumx/core/js/utils/collection/isEmpty';
|
|
9
|
+
import './string/kebabCase.js';
|
|
10
|
+
import '../constants/index.js';
|
|
11
|
+
import '../constants/keycodes.js';
|
|
22
12
|
|
|
23
13
|
/**
|
|
24
14
|
* Make sure the pressed key is the enter key before calling the callback.
|
|
@@ -27,13 +17,14 @@ var noop__default = /*#__PURE__*/_interopDefaultLegacy(noop);
|
|
|
27
17
|
* @return The decorated function.
|
|
28
18
|
*/
|
|
29
19
|
function onEnterPressed(handler) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
20
|
+
return evt => {
|
|
21
|
+
if (evt.key !== 'Enter') {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
handler(evt);
|
|
25
|
+
};
|
|
36
26
|
}
|
|
27
|
+
|
|
37
28
|
/**
|
|
38
29
|
* Make sure the pressed key is the escape key before calling the callback.
|
|
39
30
|
*
|
|
@@ -41,13 +32,14 @@ function onEnterPressed(handler) {
|
|
|
41
32
|
* @return The decorated function.
|
|
42
33
|
*/
|
|
43
34
|
function onEscapePressed(handler) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
35
|
+
return evt => {
|
|
36
|
+
if (evt.key !== 'Escape') {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
handler(evt);
|
|
40
|
+
};
|
|
50
41
|
}
|
|
42
|
+
|
|
51
43
|
/**
|
|
52
44
|
* Handle button key pressed (Enter + Space).
|
|
53
45
|
*
|
|
@@ -55,12 +47,12 @@ function onEscapePressed(handler) {
|
|
|
55
47
|
* @return The decorated function.
|
|
56
48
|
*/
|
|
57
49
|
function onButtonPressed(handler) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
50
|
+
return evt => {
|
|
51
|
+
if (evt.key !== 'Enter' && evt.key !== ' ') {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
handler(evt);
|
|
55
|
+
};
|
|
64
56
|
}
|
|
65
57
|
/**
|
|
66
58
|
* Detects swipe direction.
|
|
@@ -71,153 +63,146 @@ function onButtonPressed(handler) {
|
|
|
71
63
|
* @param handleSwipe Callback function.
|
|
72
64
|
* @return Function to remove listeners.
|
|
73
65
|
*/
|
|
74
|
-
function detectSwipe(touchSurface, handleSwipe
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
};
|
|
66
|
+
function detectSwipe(touchSurface, handleSwipe) {
|
|
67
|
+
let distX;
|
|
68
|
+
let distY;
|
|
69
|
+
let startX;
|
|
70
|
+
let startY;
|
|
71
|
+
let direction;
|
|
72
|
+
// Required min distance traveled to be considered swipe.
|
|
73
|
+
const threshold = 150;
|
|
74
|
+
// Maximum distance allowed at the same time in perpendicular direction.
|
|
75
|
+
const restraint = 100;
|
|
76
|
+
// Maximum time allowed to travel that distance.
|
|
77
|
+
const allowedTime = 300;
|
|
78
|
+
let elapsedTime;
|
|
79
|
+
let startTime;
|
|
80
|
+
const onTouchStart = evt => {
|
|
81
|
+
const [touch] = Array.from(evt.changedTouches);
|
|
82
|
+
direction = 'none';
|
|
83
|
+
// Const dist = 0;
|
|
84
|
+
startX = touch.pageX;
|
|
85
|
+
startY = touch.pageY;
|
|
86
|
+
// Record time when finger first makes contact with surface.
|
|
87
|
+
startTime = new Date().getTime();
|
|
88
|
+
evt.preventDefault();
|
|
89
|
+
};
|
|
90
|
+
const onTouchMove = evt => {
|
|
91
|
+
// Prevent scrolling when inside DIV.
|
|
92
|
+
evt.preventDefault();
|
|
93
|
+
};
|
|
94
|
+
const onTouchEnd = evt => {
|
|
95
|
+
const [touch] = Array.from(evt.changedTouches);
|
|
96
|
+
// Get horizontal dist traveled by finger while in contact with surface.
|
|
97
|
+
distX = touch.pageX - startX;
|
|
98
|
+
// Get vertical dist traveled by finger while in contact with surface.
|
|
99
|
+
distY = touch.pageY - startY;
|
|
100
|
+
// Get time elapsed.
|
|
101
|
+
elapsedTime = new Date().getTime() - startTime;
|
|
102
|
+
if (elapsedTime <= allowedTime) {
|
|
103
|
+
// First condition for awipe met.
|
|
104
|
+
if (Math.abs(distX) >= threshold && Math.abs(distY) <= restraint) {
|
|
105
|
+
// 2nd condition for horizontal swipe met.
|
|
106
|
+
// If dist traveled is negative, it indicates left swipe.
|
|
107
|
+
direction = distX < 0 ? 'left' : 'right';
|
|
108
|
+
} else if (Math.abs(distY) >= threshold && Math.abs(distX) <= restraint) {
|
|
109
|
+
// 2nd condition for vertical swipe met.
|
|
110
|
+
// If dist traveled is negative, it indicates up swipe.
|
|
111
|
+
direction = distY < 0 ? 'up' : 'down';
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
handleSwipe?.(direction);
|
|
115
|
+
evt.preventDefault();
|
|
116
|
+
};
|
|
117
|
+
touchSurface.addEventListener('touchstart', onTouchStart, false);
|
|
118
|
+
touchSurface.addEventListener('touchmove', onTouchMove, false);
|
|
119
|
+
touchSurface.addEventListener('touchend', onTouchEnd, false);
|
|
120
|
+
return () => {
|
|
121
|
+
touchSurface.removeEventListener('touchstart', onTouchStart, false);
|
|
122
|
+
touchSurface.removeEventListener('touchmove', onTouchMove, false);
|
|
123
|
+
touchSurface.removeEventListener('touchend', onTouchEnd, false);
|
|
124
|
+
};
|
|
134
125
|
}
|
|
126
|
+
|
|
135
127
|
/**
|
|
136
128
|
* Checks whether or not the browser support passive events.
|
|
137
129
|
* @see https://github.com/Modernizr/Modernizr/blob/6d56d814b9682843313b16060adb25a58d83a317/feature-detects/dom/passiveeventlisteners.js
|
|
138
130
|
*/
|
|
139
131
|
function isPassiveEventAvailable() {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
return supportsPassiveOption;
|
|
132
|
+
let supportsPassiveOption = false;
|
|
133
|
+
try {
|
|
134
|
+
const opts = Object.defineProperty({}, 'passive', {
|
|
135
|
+
get() {
|
|
136
|
+
supportsPassiveOption = true;
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
window.addEventListener('testPassiveEventSupport', () => {}, opts);
|
|
140
|
+
window.removeEventListener('testPassiveEventSupport', () => {}, opts);
|
|
141
|
+
} catch (e) {
|
|
142
|
+
// ignored
|
|
143
|
+
}
|
|
144
|
+
return supportsPassiveOption;
|
|
154
145
|
}
|
|
146
|
+
|
|
155
147
|
/**
|
|
156
148
|
* Detects horizontal swipe direction without blocking the browser scroll using passive event.
|
|
157
149
|
* @see http://javascriptkit.com/javatutors/touchevents2.shtml
|
|
158
150
|
* @see https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md
|
|
159
151
|
*/
|
|
160
152
|
function detectHorizontalSwipe(touchSurface, handleSwipe) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
153
|
+
let startX;
|
|
154
|
+
let startY;
|
|
155
|
+
// Required min distance traveled to be considered swipe.
|
|
156
|
+
const threshold = 150;
|
|
157
|
+
// Maximum distance allowed at the same time in perpendicular direction.
|
|
158
|
+
const restraint = 150;
|
|
159
|
+
// Maximum time allowed to travel that distance.
|
|
160
|
+
const allowedTime = 300;
|
|
161
|
+
let elapsedTime;
|
|
162
|
+
let startTime;
|
|
163
|
+
let finished;
|
|
164
|
+
const onTouchStart = evt => {
|
|
165
|
+
const [touch] = Array.from(evt.changedTouches);
|
|
166
|
+
startX = touch.pageX;
|
|
167
|
+
startY = touch.pageY;
|
|
168
|
+
// Record time when finger first makes contact with surface.
|
|
169
|
+
startTime = new Date().getTime();
|
|
170
|
+
finished = false;
|
|
171
|
+
};
|
|
172
|
+
const onTouchMove = evt => {
|
|
173
|
+
if (finished) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
elapsedTime = new Date().getTime() - startTime;
|
|
177
|
+
if (elapsedTime > allowedTime) {
|
|
178
|
+
// Touch swipe too long to be considered.
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const [touch] = Array.from(evt.changedTouches);
|
|
182
|
+
// Get horizontal dist traveled by finger while in contact with surface.
|
|
183
|
+
const distX = touch.pageX - startX;
|
|
184
|
+
// Get vertical dist traveled by finger while in contact with surface.
|
|
185
|
+
const distY = touch.pageY - startY;
|
|
186
|
+
if (!(Math.abs(distX) >= threshold && Math.abs(distY) <= restraint)) {
|
|
187
|
+
// Swipe is not horizontal.
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
// Swipe direction.
|
|
191
|
+
const direction = distX < 0 ? 'left' : 'right';
|
|
192
|
+
handleSwipe(direction);
|
|
193
|
+
finished = true;
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
// Activate passive event if possible for better scrolling performance.
|
|
197
|
+
const eventOptions = isPassiveEventAvailable() ? {
|
|
198
|
+
passive: true
|
|
199
|
+
} : false;
|
|
200
|
+
touchSurface.addEventListener('touchstart', onTouchStart, eventOptions);
|
|
201
|
+
touchSurface.addEventListener('touchmove', onTouchMove, eventOptions);
|
|
202
|
+
return () => {
|
|
203
|
+
touchSurface.removeEventListener('touchstart', onTouchStart, eventOptions);
|
|
204
|
+
touchSurface.removeEventListener('touchmove', onTouchMove, eventOptions);
|
|
205
|
+
};
|
|
211
206
|
}
|
|
212
207
|
|
|
213
|
-
|
|
214
|
-
exports.getBasicClass = js_utils_className_getBasicClass.getBasicClass;
|
|
215
|
-
exports.getRootClassName = js_utils_className_getRootClassName.getRootClassName;
|
|
216
|
-
exports.getTypographyClassName = js_utils_className_getTypographyClassName.getTypographyClassName;
|
|
217
|
-
exports.fontColorClass = js_utils_className_fontColorClass.fontColorClass;
|
|
218
|
-
exports.resolveColorWithVariants = js_utils_className_resolveColorWithVariants.resolveColorWithVariants;
|
|
219
|
-
exports.detectHorizontalSwipe = detectHorizontalSwipe;
|
|
220
|
-
exports.detectSwipe = detectSwipe;
|
|
221
|
-
exports.onButtonPressed = onButtonPressed;
|
|
222
|
-
exports.onEnterPressed = onEnterPressed;
|
|
223
|
-
exports.onEscapePressed = onEscapePressed;
|
|
208
|
+
export { detectHorizontalSwipe, detectSwipe, onButtonPressed, onEnterPressed, onEscapePressed };
|