@agnos-ui/core 0.0.1-alpha.0 → 0.0.1-alpha.10
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 +4 -4
- package/{dist/lib → components/accordion}/accordion.d.ts +29 -25
- package/{dist/lib → components/accordion}/accordion.js +81 -77
- package/components/accordion/index.d.ts +1 -0
- package/components/accordion/index.js +1 -0
- package/components/alert/alert.d.ts +31 -0
- package/components/alert/alert.js +22 -0
- package/{dist/lib/alert.d.ts → components/alert/common.d.ts} +17 -20
- package/{dist/lib/alert.js → components/alert/common.js} +22 -19
- package/components/alert/index.d.ts +2 -0
- package/components/alert/index.js +2 -0
- package/components/commonProps.d.ts +6 -0
- package/components/commonProps.js +1 -0
- package/components/modal/index.d.ts +1 -0
- package/components/modal/index.js +1 -0
- package/{dist/lib → components}/modal/modal.d.ts +30 -29
- package/{dist/lib → components}/modal/modal.js +59 -29
- package/components/pagination/index.d.ts +2 -0
- package/components/pagination/index.js +2 -0
- package/{dist/lib → components/pagination}/pagination.d.ts +5 -14
- package/{dist/lib → components/pagination}/pagination.js +6 -5
- package/components/progressbar/index.d.ts +1 -0
- package/components/progressbar/index.js +1 -0
- package/components/progressbar/progressbar.d.ts +86 -0
- package/components/progressbar/progressbar.js +78 -0
- package/components/rating/index.d.ts +1 -0
- package/components/rating/index.js +1 -0
- package/{dist/lib → components/rating}/rating.d.ts +6 -13
- package/{dist/lib → components/rating}/rating.js +6 -9
- package/components/select/index.d.ts +1 -0
- package/components/select/index.js +1 -0
- package/components/select/select.d.ts +337 -0
- package/components/select/select.js +266 -0
- package/components/slider/index.d.ts +1 -0
- package/components/slider/index.js +1 -0
- package/components/slider/slider.d.ts +245 -0
- package/components/slider/slider.js +413 -0
- package/{dist/lib/config.d.ts → config.d.ts} +17 -7
- package/{dist/lib/config.js → config.js} +3 -3
- package/index.d.ts +25 -0
- package/index.js +31 -0
- package/package.json +42 -28
- package/services/extendWidget.d.ts +23 -0
- package/services/extendWidget.js +35 -0
- package/services/floatingUI.d.ts +56 -0
- package/services/floatingUI.js +105 -0
- package/{dist/lib/services → services}/focustrack.js +5 -5
- package/services/intersection.d.ts +34 -0
- package/services/intersection.js +55 -0
- package/services/navManager.d.ts +93 -0
- package/services/navManager.js +172 -0
- package/{dist/lib/services → services}/portal.d.ts +7 -0
- package/services/portal.js +44 -0
- package/{dist/lib/services → services}/siblingsInert.d.ts +2 -1
- package/{dist/lib/services → services}/siblingsInert.js +2 -2
- package/{dist/lib → services}/transitions/baseTransitions.d.ts +15 -2
- package/{dist/lib → services}/transitions/baseTransitions.js +21 -10
- package/services/transitions/bootstrap/collapse.d.ts +2 -0
- package/services/transitions/bootstrap/fade.d.ts +1 -0
- package/services/transitions/bootstrap.d.ts +2 -0
- package/services/transitions/bootstrap.js +2 -0
- package/services/transitions/collapse.d.ts +43 -0
- package/{dist/lib → services}/transitions/collapse.js +15 -2
- package/{dist/lib → services}/transitions/cssTransitions.d.ts +6 -0
- package/{dist/lib → services}/transitions/cssTransitions.js +8 -4
- package/{dist/lib → services}/transitions/simpleClassTransition.d.ts +12 -1
- package/services/transitions/simpleClassTransition.js +42 -0
- package/{dist/lib/types.d.ts → types.d.ts} +43 -4
- package/types.js +14 -0
- package/{dist/lib/services/directiveUtils.js → utils/directive.js} +1 -1
- package/utils/internal/checks.d.ts +49 -0
- package/utils/internal/checks.js +60 -0
- package/utils/internal/dom.d.ts +25 -0
- package/utils/internal/dom.js +61 -0
- package/utils/internal/func.d.ts +11 -0
- package/utils/internal/func.js +11 -0
- package/utils/internal/isFocusable.d.ts +9 -0
- package/utils/internal/isFocusable.js +35 -0
- package/utils/internal/math.d.ts +5 -0
- package/utils/internal/math.js +13 -0
- package/utils/internal/promise.d.ts +87 -0
- package/utils/internal/promise.js +169 -0
- package/utils/internal/scrollbars.d.ts +8 -0
- package/{dist/lib/modal → utils/internal}/scrollbars.js +7 -1
- package/utils/internal/sort.d.ts +16 -0
- package/utils/internal/sort.js +28 -0
- package/utils/internal/textDirection.d.ts +7 -0
- package/utils/internal/textDirection.js +7 -0
- package/utils/internal/traversal.d.ts +54 -0
- package/utils/internal/traversal.js +105 -0
- package/{dist/lib/services → utils}/stores.d.ts +67 -33
- package/{dist/lib/services → utils}/stores.js +121 -59
- package/utils/writables.d.ts +32 -0
- package/utils/writables.js +72 -0
- package/dist/lib/index.d.ts +0 -11
- package/dist/lib/index.js +0 -11
- package/dist/lib/modal/scrollbars.d.ts +0 -2
- package/dist/lib/select.d.ts +0 -199
- package/dist/lib/select.js +0 -240
- package/dist/lib/services/checks.d.ts +0 -32
- package/dist/lib/services/checks.js +0 -43
- package/dist/lib/services/index.d.ts +0 -6
- package/dist/lib/services/index.js +0 -6
- package/dist/lib/services/portal.js +0 -33
- package/dist/lib/services/writables.d.ts +0 -7
- package/dist/lib/services/writables.js +0 -16
- package/dist/lib/transitions/bootstrap/collapse.d.ts +0 -2
- package/dist/lib/transitions/bootstrap/fade.d.ts +0 -1
- package/dist/lib/transitions/bootstrap/index.d.ts +0 -2
- package/dist/lib/transitions/bootstrap/index.js +0 -2
- package/dist/lib/transitions/collapse.d.ts +0 -29
- package/dist/lib/transitions/index.d.ts +0 -5
- package/dist/lib/transitions/index.js +0 -5
- package/dist/lib/transitions/simpleClassTransition.js +0 -28
- package/dist/lib/transitions/utils.d.ts +0 -20
- package/dist/lib/transitions/utils.js +0 -83
- package/dist/lib/tsdoc-metadata.json +0 -11
- package/dist/lib/types.js +0 -7
- package/dist/lib/utils.d.ts +0 -2
- package/dist/lib/utils.js +0 -2
- /package/{dist/lib/pagination.utils.d.ts → components/pagination/bootstrap.d.ts} +0 -0
- /package/{dist/lib/pagination.utils.js → components/pagination/bootstrap.js} +0 -0
- /package/{dist/lib/services → services}/focustrack.d.ts +0 -0
- /package/{dist/lib → services}/transitions/bootstrap/collapse.js +0 -0
- /package/{dist/lib → services}/transitions/bootstrap/fade.js +0 -0
- /package/{dist/lib/services/directiveUtils.d.ts → utils/directive.d.ts} +0 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* a number type guard
|
|
3
|
+
* @param value - the value to check
|
|
4
|
+
* @returns true if the value is a number
|
|
5
|
+
*/
|
|
6
|
+
export function isNumber(value) {
|
|
7
|
+
return typeof value === 'number' && !isNaN(value) && Number.isFinite(value);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* a boolean type guard
|
|
11
|
+
* @param value - the value to check
|
|
12
|
+
* @returns true if the value is a boolean
|
|
13
|
+
*/
|
|
14
|
+
export function isBoolean(value) {
|
|
15
|
+
return value === true || value === false;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* a function type guard
|
|
19
|
+
* @param value - the value to check
|
|
20
|
+
* @returns true if the value is a function
|
|
21
|
+
*/
|
|
22
|
+
export function isFunction(value) {
|
|
23
|
+
return typeof value === 'function';
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* a string type guard
|
|
27
|
+
* @param value - the value to check
|
|
28
|
+
* @returns true if the value is a string
|
|
29
|
+
*/
|
|
30
|
+
export function isString(value) {
|
|
31
|
+
return typeof value === 'string';
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* an array type guard
|
|
35
|
+
* @returns true if the value is an array
|
|
36
|
+
*/
|
|
37
|
+
export const isArray = Array.isArray;
|
|
38
|
+
// TODO should we check that max > min?
|
|
39
|
+
/**
|
|
40
|
+
* Clamp the value based on a maximum and optional minimum
|
|
41
|
+
* @param value - the value to check
|
|
42
|
+
* @param max - the max to clamp to
|
|
43
|
+
* @param [min] - the min to clamp to
|
|
44
|
+
* @returns the clamped value
|
|
45
|
+
*/
|
|
46
|
+
export function clamp(value, max, min = 0) {
|
|
47
|
+
return Math.max(Math.min(value, max), min);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* an html element type guard
|
|
51
|
+
* @param value - the value to check
|
|
52
|
+
* @returns true if the value is an instance of HTMLElement
|
|
53
|
+
*/
|
|
54
|
+
export const isHTMLElement = (value) => value instanceof HTMLElement;
|
|
55
|
+
/**
|
|
56
|
+
* Returns a new type guard that is based on the provided type guard and also returns true for null values.
|
|
57
|
+
* @param isType - base type guard
|
|
58
|
+
* @returns A type guard function that returns true for null values and calls the provided type guard for other values.
|
|
59
|
+
*/
|
|
60
|
+
export const allowNull = (isType) => (value) => value === null || isType(value);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the common ancestor of the provided DOM elements.
|
|
3
|
+
* @param elements - array of DOM elements
|
|
4
|
+
* @returns the common ancestor, or null if the array is empty or if there is no common ancestor (e.g.: if elements are detached)
|
|
5
|
+
*/
|
|
6
|
+
export declare const computeCommonAncestor: (elements: HTMLElement[]) => HTMLElement | null;
|
|
7
|
+
/**
|
|
8
|
+
* Launch a reflow using a call to the provided html element getBoudingClientRect
|
|
9
|
+
* @param element - the html element
|
|
10
|
+
*/
|
|
11
|
+
export declare function reflow(element?: HTMLElement): void;
|
|
12
|
+
/**
|
|
13
|
+
* Attach the given css classes to the element
|
|
14
|
+
*
|
|
15
|
+
* @param element - the HTML element
|
|
16
|
+
* @param classes - the css lcasses
|
|
17
|
+
*/
|
|
18
|
+
export declare const addClasses: (element: HTMLElement, classes?: string[]) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Remove the given css classes to the element
|
|
21
|
+
*
|
|
22
|
+
* @param element - the HTML element
|
|
23
|
+
* @param classes - the css classes
|
|
24
|
+
*/
|
|
25
|
+
export declare const removeClasses: (element: HTMLElement, classes?: string[]) => void;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the common ancestor of the provided DOM elements.
|
|
3
|
+
* @param elements - array of DOM elements
|
|
4
|
+
* @returns the common ancestor, or null if the array is empty or if there is no common ancestor (e.g.: if elements are detached)
|
|
5
|
+
*/
|
|
6
|
+
export const computeCommonAncestor = (elements) => {
|
|
7
|
+
const length = elements.length;
|
|
8
|
+
if (length === 0)
|
|
9
|
+
return null;
|
|
10
|
+
let ancestor = elements[0];
|
|
11
|
+
for (let i = 1; i < length && ancestor; i++) {
|
|
12
|
+
const element = elements[i];
|
|
13
|
+
while (ancestor) {
|
|
14
|
+
if (ancestor === element) {
|
|
15
|
+
break;
|
|
16
|
+
}
|
|
17
|
+
const comparison = ancestor.compareDocumentPosition(element);
|
|
18
|
+
if (comparison & Node.DOCUMENT_POSITION_CONTAINED_BY) {
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
else if (comparison & Node.DOCUMENT_POSITION_CONTAINS) {
|
|
22
|
+
ancestor = element;
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
else if (comparison & Node.DOCUMENT_POSITION_DISCONNECTED) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
ancestor = ancestor.parentElement;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return ancestor;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Launch a reflow using a call to the provided html element getBoudingClientRect
|
|
35
|
+
* @param element - the html element
|
|
36
|
+
*/
|
|
37
|
+
export function reflow(element = document.body) {
|
|
38
|
+
element.getBoundingClientRect();
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Attach the given css classes to the element
|
|
42
|
+
*
|
|
43
|
+
* @param element - the HTML element
|
|
44
|
+
* @param classes - the css lcasses
|
|
45
|
+
*/
|
|
46
|
+
export const addClasses = (element, classes) => {
|
|
47
|
+
if (classes && classes.length > 0) {
|
|
48
|
+
element.classList.add(...classes);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Remove the given css classes to the element
|
|
53
|
+
*
|
|
54
|
+
* @param element - the HTML element
|
|
55
|
+
* @param classes - the css classes
|
|
56
|
+
*/
|
|
57
|
+
export const removeClasses = (element, classes) => {
|
|
58
|
+
if (classes && classes.length > 0) {
|
|
59
|
+
element.classList.remove(...classes);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns true if the given HTML element is programmatically focusable.
|
|
3
|
+
* Warning: this is a best-effort approximation of whether the element is really focusable.
|
|
4
|
+
* It may not handle all use cases accurately.
|
|
5
|
+
*
|
|
6
|
+
* @param element - element to test
|
|
7
|
+
* @returns true if the element is programmatically focusable.
|
|
8
|
+
*/
|
|
9
|
+
export declare const isFocusable: (element: HTMLElement) => boolean;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const isInertOrInvisible = (element) => {
|
|
2
|
+
let curElement = element;
|
|
3
|
+
while (curElement) {
|
|
4
|
+
const style = getComputedStyle(curElement);
|
|
5
|
+
if (curElement.inert || curElement.hidden || style.display === 'none' || style.visibility === 'hidden') {
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
curElement = curElement.parentElement;
|
|
9
|
+
}
|
|
10
|
+
return false;
|
|
11
|
+
};
|
|
12
|
+
const checkNotDisabled = (element) => {
|
|
13
|
+
if (element.disabled) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
const parentFieldset = element.parentElement?.closest('fieldset');
|
|
17
|
+
return parentFieldset ? checkNotDisabled(parentFieldset) : true;
|
|
18
|
+
};
|
|
19
|
+
const isFocusableOtherTags = (element) => element.isContentEditable || !!element.hasAttribute('tabindex');
|
|
20
|
+
const isFocusableByTagName = {
|
|
21
|
+
INPUT: (element) => element.type !== 'hidden' && checkNotDisabled(element),
|
|
22
|
+
SELECT: checkNotDisabled,
|
|
23
|
+
TEXTAREA: checkNotDisabled,
|
|
24
|
+
BUTTON: checkNotDisabled,
|
|
25
|
+
A: (element) => !!element.href || isFocusableOtherTags(element),
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Returns true if the given HTML element is programmatically focusable.
|
|
29
|
+
* Warning: this is a best-effort approximation of whether the element is really focusable.
|
|
30
|
+
* It may not handle all use cases accurately.
|
|
31
|
+
*
|
|
32
|
+
* @param element - element to test
|
|
33
|
+
* @returns true if the element is programmatically focusable.
|
|
34
|
+
*/
|
|
35
|
+
export const isFocusable = (element) => !isInertOrInvisible(element) && (isFocusableByTagName[element.tagName] ?? isFocusableOtherTags)(element);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const decimalRegExp = /(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/;
|
|
2
|
+
/**
|
|
3
|
+
* @param number - decimal number
|
|
4
|
+
* @returns the decimal precision of the number
|
|
5
|
+
*/
|
|
6
|
+
export function getDecimalPrecision(number) {
|
|
7
|
+
const matches = ('' + number).match(decimalRegExp);
|
|
8
|
+
return Math.max(0,
|
|
9
|
+
// Number of digits right of decimal point.
|
|
10
|
+
(matches[1]?.length ?? 0) -
|
|
11
|
+
// Adjust for exponential notation.
|
|
12
|
+
(+matches[2] || 0));
|
|
13
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { ReadableSignal } from '@amadeus-it-group/tansu';
|
|
2
|
+
export interface PromisePendingResult {
|
|
3
|
+
/** Pending status */
|
|
4
|
+
status: 'pending';
|
|
5
|
+
}
|
|
6
|
+
export declare const promisePending: PromisePendingResult;
|
|
7
|
+
export type PromiseState<T> = PromiseFulfilledResult<T> | PromiseRejectedResult | PromisePendingResult;
|
|
8
|
+
/**
|
|
9
|
+
* Create a readable promise state store from a promise.
|
|
10
|
+
*
|
|
11
|
+
* The state of the returned store tracks the state of the promise and the resolved value or rejection reason.
|
|
12
|
+
*
|
|
13
|
+
* @param value - the promise
|
|
14
|
+
* @returns the readable promise state store
|
|
15
|
+
*/
|
|
16
|
+
export declare const promiseStateStore: <T>(value: T) => ReadableSignal<Readonly<PromiseState<Awaited<T>>>>;
|
|
17
|
+
/**
|
|
18
|
+
* Create a readable promise state store from a promise store.
|
|
19
|
+
*
|
|
20
|
+
* @param promiseStore$ - the promise store
|
|
21
|
+
* @returns the readable promise state store
|
|
22
|
+
*/
|
|
23
|
+
export declare const promiseStoreToPromiseStateStore: <T>(promiseStore$: ReadableSignal<T>) => ReadableSignal<PromiseState<Awaited<T>>>;
|
|
24
|
+
/**
|
|
25
|
+
* Create a value store from a promise state store
|
|
26
|
+
*
|
|
27
|
+
* The returned value store is only updated if the promise is fulfilled.
|
|
28
|
+
*
|
|
29
|
+
* @param store$ - the promise state store
|
|
30
|
+
* @param initialValue - the initial value of the returned value store
|
|
31
|
+
* @param equal - an equal function to compare values
|
|
32
|
+
* @returns the value store
|
|
33
|
+
*/
|
|
34
|
+
export declare const promiseStateStoreToValueStore: <T>(store$: ReadableSignal<PromiseState<T>>, initialValue: T, equal?: ((a: T, b: T) => boolean) | undefined) => ReadableSignal<T>;
|
|
35
|
+
/**
|
|
36
|
+
* Create a value store from a promise store
|
|
37
|
+
*
|
|
38
|
+
* The returned value store is only updated if the promise is fulfilled.
|
|
39
|
+
*
|
|
40
|
+
* @param promiseStore$ - the promise store
|
|
41
|
+
* @param initialValue - the initial value of the returned value store
|
|
42
|
+
* @param equal - an equal function to compare values
|
|
43
|
+
* @returns the value store
|
|
44
|
+
*/
|
|
45
|
+
export declare const promiseStoreToValueStore: <T>(promiseStore$: ReadableSignal<T>, initialValue: Awaited<T>, equal?: ((a: Awaited<T>, b: Awaited<T>) => boolean) | undefined) => ReadableSignal<Awaited<T>>;
|
|
46
|
+
/**
|
|
47
|
+
* Create a promise from a readable store and a fulfilled condition function.
|
|
48
|
+
*
|
|
49
|
+
* The promise is fulfilled when the state of the store respects the provided condition function.
|
|
50
|
+
*
|
|
51
|
+
* @param store - the readable store
|
|
52
|
+
* @param condition - the condition function
|
|
53
|
+
* @returns the promise and an unsubscribe function
|
|
54
|
+
*/
|
|
55
|
+
export declare const promiseFromStore: <T>(store: ReadableSignal<T>, condition?: (value: T) => boolean) => {
|
|
56
|
+
promise: Promise<T>;
|
|
57
|
+
unsubscribe(): void;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Create a promise from an HTML element event.
|
|
61
|
+
*
|
|
62
|
+
* @param element - the event target
|
|
63
|
+
* @param event - the event to listen to
|
|
64
|
+
* @returns the promise and an unsubscribe function
|
|
65
|
+
*/
|
|
66
|
+
export declare const promiseFromEvent: (element: EventTarget, event: string) => {
|
|
67
|
+
promise: Promise<Event>;
|
|
68
|
+
unsubscribe(): void;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Create a promise that resolves once a timeout has been reached.
|
|
72
|
+
*
|
|
73
|
+
* @param delay - the delay in milli seconds
|
|
74
|
+
* @returns a promise and an unsubscribe function
|
|
75
|
+
*/
|
|
76
|
+
export declare const promiseFromTimeout: (delay: number) => {
|
|
77
|
+
promise: Promise<void>;
|
|
78
|
+
unsubscribe(): void;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Utility method to create a promise with resolve
|
|
82
|
+
* @returns a promise with resolve
|
|
83
|
+
*/
|
|
84
|
+
export declare const promiseWithResolve: () => {
|
|
85
|
+
promise: Promise<void>;
|
|
86
|
+
resolve: (value: void | Promise<void>) => void;
|
|
87
|
+
};
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { asReadable, computed, derived, equal, readable, writable } from '@amadeus-it-group/tansu';
|
|
2
|
+
import { noop } from './func';
|
|
3
|
+
export const promisePending = { status: 'pending' };
|
|
4
|
+
const isThenable = (value) => {
|
|
5
|
+
// cf https://tc39.es/ecma262/#sec-promise-resolve-functions
|
|
6
|
+
const type = typeof value;
|
|
7
|
+
return (type === 'object' && value !== null) || type === 'function' ? typeof value.then === 'function' : false;
|
|
8
|
+
};
|
|
9
|
+
const createPromiseStateStore = (promise) => {
|
|
10
|
+
const store = writable(promisePending);
|
|
11
|
+
Promise.resolve(promise).then((value) => store.set({ status: 'fulfilled', value }), (reason) => store.set({ status: 'rejected', reason }));
|
|
12
|
+
return asReadable(store);
|
|
13
|
+
};
|
|
14
|
+
const promiseWeakMap = new WeakMap();
|
|
15
|
+
/**
|
|
16
|
+
* Create a readable promise state store from a promise.
|
|
17
|
+
*
|
|
18
|
+
* The state of the returned store tracks the state of the promise and the resolved value or rejection reason.
|
|
19
|
+
*
|
|
20
|
+
* @param value - the promise
|
|
21
|
+
* @returns the readable promise state store
|
|
22
|
+
*/
|
|
23
|
+
export const promiseStateStore = (value) => {
|
|
24
|
+
if (!isThenable(value)) {
|
|
25
|
+
return readable({ status: 'fulfilled', value: value });
|
|
26
|
+
}
|
|
27
|
+
let response = promiseWeakMap.get(value);
|
|
28
|
+
if (!response) {
|
|
29
|
+
response = createPromiseStateStore(value);
|
|
30
|
+
promiseWeakMap.set(value, response);
|
|
31
|
+
}
|
|
32
|
+
return response;
|
|
33
|
+
};
|
|
34
|
+
const promiseStateStoreEqual = (a, b) => Object.is(a, b) ||
|
|
35
|
+
(a.status === b.status &&
|
|
36
|
+
(a.status !== 'fulfilled' || equal(a.value, b.value)) &&
|
|
37
|
+
(a.status !== 'rejected' || equal(a.reason, b.reason)));
|
|
38
|
+
/**
|
|
39
|
+
* Create a readable promise state store from a promise store.
|
|
40
|
+
*
|
|
41
|
+
* @param promiseStore$ - the promise store
|
|
42
|
+
* @returns the readable promise state store
|
|
43
|
+
*/
|
|
44
|
+
export const promiseStoreToPromiseStateStore = (promiseStore$) => computed(() => promiseStateStore(promiseStore$())(), { equal: promiseStateStoreEqual });
|
|
45
|
+
/**
|
|
46
|
+
* Create a value store from a promise state store
|
|
47
|
+
*
|
|
48
|
+
* The returned value store is only updated if the promise is fulfilled.
|
|
49
|
+
*
|
|
50
|
+
* @param store$ - the promise state store
|
|
51
|
+
* @param initialValue - the initial value of the returned value store
|
|
52
|
+
* @param equal - an equal function to compare values
|
|
53
|
+
* @returns the value store
|
|
54
|
+
*/
|
|
55
|
+
export const promiseStateStoreToValueStore = (store$, initialValue, equal) => derived(store$, {
|
|
56
|
+
derive: (state, set) => {
|
|
57
|
+
if (state.status === 'fulfilled') {
|
|
58
|
+
set(state.value);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
equal,
|
|
62
|
+
}, initialValue);
|
|
63
|
+
/**
|
|
64
|
+
* Create a value store from a promise store
|
|
65
|
+
*
|
|
66
|
+
* The returned value store is only updated if the promise is fulfilled.
|
|
67
|
+
*
|
|
68
|
+
* @param promiseStore$ - the promise store
|
|
69
|
+
* @param initialValue - the initial value of the returned value store
|
|
70
|
+
* @param equal - an equal function to compare values
|
|
71
|
+
* @returns the value store
|
|
72
|
+
*/
|
|
73
|
+
export const promiseStoreToValueStore = (promiseStore$, initialValue, equal) => promiseStateStoreToValueStore(promiseStoreToPromiseStateStore(promiseStore$), initialValue, equal);
|
|
74
|
+
const truthyValue = (value) => !!value;
|
|
75
|
+
/**
|
|
76
|
+
* Create a promise from a readable store and a fulfilled condition function.
|
|
77
|
+
*
|
|
78
|
+
* The promise is fulfilled when the state of the store respects the provided condition function.
|
|
79
|
+
*
|
|
80
|
+
* @param store - the readable store
|
|
81
|
+
* @param condition - the condition function
|
|
82
|
+
* @returns the promise and an unsubscribe function
|
|
83
|
+
*/
|
|
84
|
+
export const promiseFromStore = (store, condition = truthyValue) => {
|
|
85
|
+
let resolve;
|
|
86
|
+
const promise = new Promise((r) => (resolve = r));
|
|
87
|
+
let unsubscribe = () => {
|
|
88
|
+
storeUnsubscribe();
|
|
89
|
+
unsubscribe = noop;
|
|
90
|
+
};
|
|
91
|
+
let storeUnsubscribe = noop;
|
|
92
|
+
storeUnsubscribe = store.subscribe((value) => {
|
|
93
|
+
if (condition(value)) {
|
|
94
|
+
resolve(value);
|
|
95
|
+
unsubscribe();
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
if (unsubscribe === noop) {
|
|
99
|
+
storeUnsubscribe();
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
promise,
|
|
103
|
+
unsubscribe() {
|
|
104
|
+
unsubscribe();
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Create a promise from an HTML element event.
|
|
110
|
+
*
|
|
111
|
+
* @param element - the event target
|
|
112
|
+
* @param event - the event to listen to
|
|
113
|
+
* @returns the promise and an unsubscribe function
|
|
114
|
+
*/
|
|
115
|
+
export const promiseFromEvent = (element, event) => {
|
|
116
|
+
let resolve;
|
|
117
|
+
const promise = new Promise((r) => (resolve = r));
|
|
118
|
+
let unsubscribe = () => {
|
|
119
|
+
element.removeEventListener(event, eventListener);
|
|
120
|
+
unsubscribe = noop;
|
|
121
|
+
};
|
|
122
|
+
const eventListener = (event) => {
|
|
123
|
+
if (event.target === element) {
|
|
124
|
+
resolve(event);
|
|
125
|
+
unsubscribe();
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
element.addEventListener(event, eventListener);
|
|
129
|
+
return {
|
|
130
|
+
promise,
|
|
131
|
+
unsubscribe() {
|
|
132
|
+
unsubscribe();
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* Create a promise that resolves once a timeout has been reached.
|
|
138
|
+
*
|
|
139
|
+
* @param delay - the delay in milli seconds
|
|
140
|
+
* @returns a promise and an unsubscribe function
|
|
141
|
+
*/
|
|
142
|
+
export const promiseFromTimeout = (delay) => {
|
|
143
|
+
let timeout;
|
|
144
|
+
return {
|
|
145
|
+
promise: new Promise((r) => {
|
|
146
|
+
timeout = setTimeout(() => {
|
|
147
|
+
timeout = undefined;
|
|
148
|
+
r();
|
|
149
|
+
}, delay);
|
|
150
|
+
}),
|
|
151
|
+
unsubscribe() {
|
|
152
|
+
if (timeout) {
|
|
153
|
+
clearTimeout(timeout);
|
|
154
|
+
timeout = undefined;
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
};
|
|
159
|
+
/**
|
|
160
|
+
* Utility method to create a promise with resolve
|
|
161
|
+
* @returns a promise with resolve
|
|
162
|
+
*/
|
|
163
|
+
export const promiseWithResolve = () => {
|
|
164
|
+
let resolve;
|
|
165
|
+
const promise = new Promise((r) => {
|
|
166
|
+
resolve = r;
|
|
167
|
+
});
|
|
168
|
+
return { promise, resolve: resolve };
|
|
169
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A function to remove the scrollbars on the body element. It can be reverted using the {@link revertScrollbars} function.
|
|
3
|
+
*/
|
|
4
|
+
export declare const removeScrollbars: () => void;
|
|
5
|
+
/**
|
|
6
|
+
* A function to revert the removal of scrollbars performed by the {@link removeScrollbars} function.
|
|
7
|
+
*/
|
|
8
|
+
export declare const revertScrollbars: () => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { noop } from '
|
|
1
|
+
import { noop } from './func';
|
|
2
2
|
const internalRemoveScrollbars = () => {
|
|
3
3
|
const scrollbarWidth = Math.abs(window.innerWidth - document.documentElement.clientWidth);
|
|
4
4
|
const body = document.body;
|
|
@@ -17,10 +17,16 @@ const internalRemoveScrollbars = () => {
|
|
|
17
17
|
};
|
|
18
18
|
};
|
|
19
19
|
let internalRevert = noop;
|
|
20
|
+
/**
|
|
21
|
+
* A function to remove the scrollbars on the body element. It can be reverted using the {@link revertScrollbars} function.
|
|
22
|
+
*/
|
|
20
23
|
export const removeScrollbars = () => {
|
|
21
24
|
internalRevert();
|
|
22
25
|
internalRevert = internalRemoveScrollbars();
|
|
23
26
|
};
|
|
27
|
+
/**
|
|
28
|
+
* A function to revert the removal of scrollbars performed by the {@link removeScrollbars} function.
|
|
29
|
+
*/
|
|
24
30
|
export const revertScrollbars = () => {
|
|
25
31
|
internalRevert();
|
|
26
32
|
internalRevert = noop;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The default comparision between two values, using the javascript < and > signs.
|
|
3
|
+
*
|
|
4
|
+
* @param a - the first input
|
|
5
|
+
* @param b - the second input
|
|
6
|
+
* @returns 1, 0 or -1 depending on the default compare
|
|
7
|
+
*/
|
|
8
|
+
export declare const compareDefault: (a: any, b: any) => 0 | 1 | -1;
|
|
9
|
+
/**
|
|
10
|
+
* A comparision function between DOM elements, based on [Node.compareDocumentPosition](https://developer.mozilla.org/fr/docs/Web/API/Node/compareDocumentPosition).
|
|
11
|
+
*
|
|
12
|
+
* @param element1 - the first node
|
|
13
|
+
* @param element2 - the second node
|
|
14
|
+
* @returns 1, 0 or -1
|
|
15
|
+
*/
|
|
16
|
+
export declare const compareDomOrder: (element1: Node, element2: Node) => 0 | 1 | -1;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The default comparision between two values, using the javascript < and > signs.
|
|
3
|
+
*
|
|
4
|
+
* @param a - the first input
|
|
5
|
+
* @param b - the second input
|
|
6
|
+
* @returns 1, 0 or -1 depending on the default compare
|
|
7
|
+
*/
|
|
8
|
+
export const compareDefault = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
|
|
9
|
+
/**
|
|
10
|
+
* A comparision function between DOM elements, based on [Node.compareDocumentPosition](https://developer.mozilla.org/fr/docs/Web/API/Node/compareDocumentPosition).
|
|
11
|
+
*
|
|
12
|
+
* @param element1 - the first node
|
|
13
|
+
* @param element2 - the second node
|
|
14
|
+
* @returns 1, 0 or -1
|
|
15
|
+
*/
|
|
16
|
+
export const compareDomOrder = (element1, element2) => {
|
|
17
|
+
if (element1 === element2) {
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
const result = element1.compareDocumentPosition(element2);
|
|
21
|
+
if (result & Node.DOCUMENT_POSITION_FOLLOWING) {
|
|
22
|
+
return -1;
|
|
23
|
+
}
|
|
24
|
+
else if (result & Node.DOCUMENT_POSITION_PRECEDING) {
|
|
25
|
+
return 1;
|
|
26
|
+
}
|
|
27
|
+
throw new Error('failed to compare elements');
|
|
28
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the text direction of an element, using a call to `getComputedStyle`.
|
|
3
|
+
*
|
|
4
|
+
* @param element - the HTML element
|
|
5
|
+
* @returns the text direction of the element, 'ltr' or 'rtl'
|
|
6
|
+
*/
|
|
7
|
+
export declare const getTextDirection: (element: HTMLElement) => "rtl" | "ltr";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the text direction of an element, using a call to `getComputedStyle`.
|
|
3
|
+
*
|
|
4
|
+
* @param element - the HTML element
|
|
5
|
+
* @returns the text direction of the element, 'ltr' or 'rtl'
|
|
6
|
+
*/
|
|
7
|
+
export const getTextDirection = (element) => getComputedStyle(element).direction;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
interface TraversalFnOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Remove symbol to return to remove the value
|
|
4
|
+
*/
|
|
5
|
+
removeSymbol?: symbol;
|
|
6
|
+
/**
|
|
7
|
+
* index of the array, when looping on the elements
|
|
8
|
+
*/
|
|
9
|
+
index?: number;
|
|
10
|
+
}
|
|
11
|
+
type TraversalFn = (key: string, value: any, options: TraversalFnOptions) => any;
|
|
12
|
+
/**
|
|
13
|
+
* Creates a JSON walker function that can be used to traverse and transform
|
|
14
|
+
* the properties of a JSON object.
|
|
15
|
+
*
|
|
16
|
+
* @param fn - The callback function called for each property in the JSON object.
|
|
17
|
+
* @returns A function that takes a JSON object as input and applies the provided
|
|
18
|
+
* callback function to each property.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* const json = {
|
|
23
|
+
* name: 'John',
|
|
24
|
+
* age: 30,
|
|
25
|
+
* address: {
|
|
26
|
+
* city: 'New York',
|
|
27
|
+
* country: 'USA',
|
|
28
|
+
* },
|
|
29
|
+
* useless: '',
|
|
30
|
+
* };
|
|
31
|
+
*
|
|
32
|
+
* const transform = createTraversal((key, value, {removeSymbol}) => {
|
|
33
|
+
* if (key === 'age') {
|
|
34
|
+
* return value * 2; // Double the age
|
|
35
|
+
* }
|
|
36
|
+
* if (key === 'useless') {
|
|
37
|
+
* return removeSymbol;
|
|
38
|
+
* }
|
|
39
|
+
* return value;
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* const transformedJson = transform(json);
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare function createTraversal(fn: TraversalFn): (json: any) => any;
|
|
46
|
+
/**
|
|
47
|
+
* Utility method to create a promise with resolve
|
|
48
|
+
* @returns a promise with resolve
|
|
49
|
+
*/
|
|
50
|
+
export declare const promiseWithResolve: () => {
|
|
51
|
+
promise: Promise<void>;
|
|
52
|
+
resolve: (value: void | Promise<void>) => void;
|
|
53
|
+
};
|
|
54
|
+
export {};
|