@agnos-ui/core 0.2.0 → 0.3.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 +3 -3
- package/accordion-BaWN0_n-.js +330 -0
- package/accordion-BuIgxZ0S.cjs +329 -0
- package/alert-C4jCg9Pl.cjs +8 -0
- package/alert-Dlf-BV98.js +9 -0
- package/common-DRdsw5m8.js +76 -0
- package/common-nJRMXbwj.cjs +75 -0
- package/components/accordion/accordion.d.ts +38 -49
- package/components/accordion/index.cjs +7 -0
- package/components/accordion/index.js +7 -1
- package/components/alert/alert.d.ts +3 -12
- package/components/alert/common.d.ts +4 -13
- package/components/alert/index.cjs +10 -0
- package/components/alert/index.js +10 -2
- package/components/modal/index.cjs +7 -0
- package/components/modal/index.js +7 -1
- package/components/modal/modal.d.ts +7 -49
- package/components/pagination/index.cjs +5 -0
- package/components/pagination/index.d.ts +0 -1
- package/components/pagination/index.js +5 -2
- package/components/pagination/pagination.d.ts +68 -139
- package/components/progressbar/index.cjs +5 -0
- package/components/progressbar/index.js +5 -1
- package/components/progressbar/progressbar.d.ts +6 -22
- package/components/rating/index.cjs +5 -0
- package/components/rating/index.js +5 -1
- package/components/rating/rating.d.ts +16 -11
- package/components/select/index.cjs +6 -0
- package/components/select/index.js +6 -1
- package/components/select/select.d.ts +15 -33
- package/components/slider/index.cjs +5 -0
- package/components/slider/index.js +5 -1
- package/components/slider/slider.d.ts +29 -35
- package/components/toast/index.cjs +5 -0
- package/components/toast/index.js +5 -1
- package/components/toast/toast.d.ts +11 -8
- package/config.cjs +38 -0
- package/config.d.ts +1 -1
- package/config.js +35 -50
- package/directive-BTSEYLF3.cjs +404 -0
- package/directive-DCYlDznf.js +405 -0
- package/func-DR0n-ShK.js +7 -0
- package/func-Qd3cD9a3.cjs +6 -0
- package/index.cjs +119 -0
- package/index.d.ts +1 -1
- package/index.js +119 -33
- package/modal-BI2qUu1M.js +251 -0
- package/modal-rzMpATf5.cjs +250 -0
- package/package.json +29 -19
- package/pagination--GkwduJn.js +263 -0
- package/pagination-EWSWQT1I.cjs +262 -0
- package/progressbar-DH7DHYMp.cjs +83 -0
- package/progressbar-DuRX7_my.js +84 -0
- package/promise-BMJ8qhA8.cjs +118 -0
- package/promise-CY2U8bTP.js +119 -0
- package/rating-BR5wD7y2.js +173 -0
- package/rating-CmuYUSxy.cjs +172 -0
- package/select-BCs6HQWn.js +358 -0
- package/select-CCIKn8WR.cjs +357 -0
- package/services/extendWidget.cjs +32 -0
- package/services/extendWidget.d.ts +2 -1
- package/services/extendWidget.js +31 -34
- package/services/floatingUI.cjs +131 -0
- package/services/floatingUI.d.ts +30 -14
- package/services/floatingUI.js +128 -102
- package/services/focustrack.cjs +47 -0
- package/services/focustrack.js +45 -44
- package/services/hash.cjs +15 -0
- package/services/hash.js +14 -12
- package/services/intersection.cjs +53 -0
- package/services/intersection.js +48 -50
- package/services/matchMedia.cjs +13 -0
- package/services/matchMedia.d.ts +7 -0
- package/services/matchMedia.js +13 -0
- package/services/navManager.cjs +196 -0
- package/services/navManager.d.ts +9 -9
- package/services/navManager.js +186 -168
- package/services/portal.cjs +43 -0
- package/services/portal.js +41 -42
- package/services/resizeObserver.cjs +32 -0
- package/services/resizeObserver.d.ts +1 -1
- package/services/resizeObserver.js +31 -28
- package/services/siblingsInert.cjs +40 -0
- package/services/siblingsInert.js +31 -31
- package/services/transitions/baseTransitions.cjs +171 -0
- package/services/transitions/baseTransitions.d.ts +16 -16
- package/services/transitions/baseTransitions.js +159 -170
- package/services/transitions/collapse.cjs +44 -0
- package/services/transitions/collapse.js +41 -49
- package/services/transitions/cssTransitions.cjs +32 -0
- package/services/transitions/cssTransitions.d.ts +2 -1
- package/services/transitions/cssTransitions.js +29 -39
- package/services/transitions/simpleClassTransition.cjs +31 -0
- package/services/transitions/simpleClassTransition.js +30 -41
- package/slider-CA_fszn7.js +536 -0
- package/slider-DsLvT87U.cjs +535 -0
- package/toast-8tWp6x89.js +63 -0
- package/toast-Aw8o0Iwe.cjs +62 -0
- package/types.cjs +12 -0
- package/types.d.ts +21 -1
- package/types.js +11 -13
- package/utils/directive.cjs +26 -0
- package/utils/directive.d.ts +148 -5
- package/utils/directive.js +25 -205
- package/utils/internal/dom.d.ts +43 -4
- package/utils/internal/promise.d.ts +2 -2
- package/utils/internal/ssrHTMLElement.d.ts +7 -0
- package/utils/stores.cjs +163 -0
- package/utils/stores.d.ts +9 -17
- package/utils/stores.js +149 -284
- package/utils/writables.cjs +13 -0
- package/utils/writables.js +12 -71
- package/writables-D46sFgGK.cjs +85 -0
- package/writables-DoU_XYTX.js +86 -0
- package/components/accordion/accordion.js +0 -264
- package/components/alert/alert.js +0 -22
- package/components/alert/common.js +0 -69
- package/components/commonProps.js +0 -1
- package/components/modal/modal.js +0 -186
- package/components/pagination/bootstrap.d.ts +0 -8
- package/components/pagination/bootstrap.js +0 -110
- package/components/pagination/pagination.js +0 -195
- package/components/progressbar/progressbar.js +0 -78
- package/components/rating/rating.js +0 -137
- package/components/select/select.js +0 -297
- package/components/slider/slider.js +0 -420
- package/components/toast/toast.js +0 -43
- package/services/transitions/bootstrap/collapse.d.ts +0 -2
- package/services/transitions/bootstrap/collapse.js +0 -15
- package/services/transitions/bootstrap/fade.d.ts +0 -1
- package/services/transitions/bootstrap/fade.js +0 -7
- package/services/transitions/bootstrap.d.ts +0 -2
- package/services/transitions/bootstrap.js +0 -2
- package/utils/internal/checks.js +0 -60
- package/utils/internal/dom.js +0 -82
- package/utils/internal/func.js +0 -11
- package/utils/internal/isFocusable.js +0 -37
- package/utils/internal/math.js +0 -13
- package/utils/internal/promise.js +0 -169
- package/utils/internal/scrollbars.js +0 -33
- package/utils/internal/sort.js +0 -28
- package/utils/internal/textDirection.js +0 -7
- package/utils/internal/traversal.js +0 -105
package/services/focustrack.js
CHANGED
|
@@ -1,46 +1,47 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
},
|
|
22
|
-
equal: Object.is,
|
|
23
|
-
});
|
|
24
|
-
/**
|
|
25
|
-
* Create a HasFocus
|
|
26
|
-
* @returns a HasFocus
|
|
27
|
-
*/
|
|
28
|
-
export function createHasFocus() {
|
|
29
|
-
const { elements$, directive } = createStoreArrayDirective();
|
|
30
|
-
const hasFocus$ = computed(() => {
|
|
31
|
-
const activeElement = activeElement$();
|
|
32
|
-
if (!activeElement) {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
for (const element of elements$()) {
|
|
36
|
-
if (element === activeElement || element.contains(activeElement)) {
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return false;
|
|
41
|
-
});
|
|
42
|
-
return {
|
|
43
|
-
directive,
|
|
44
|
-
hasFocus$,
|
|
1
|
+
import { readable, computed } from "@amadeus-it-group/tansu";
|
|
2
|
+
import { g as createBrowserStoreArrayDirective } from "../directive-DCYlDznf.js";
|
|
3
|
+
import { BROWSER } from "esm-env";
|
|
4
|
+
const evtFocusIn = "focusin";
|
|
5
|
+
const evtFocusOut = "focusout";
|
|
6
|
+
const activeElement$ = !BROWSER ? readable(null) : readable(null, {
|
|
7
|
+
onUse({ set }) {
|
|
8
|
+
function setActiveElement() {
|
|
9
|
+
set(document.activeElement);
|
|
10
|
+
}
|
|
11
|
+
setActiveElement();
|
|
12
|
+
const container = document.documentElement;
|
|
13
|
+
function onFocusOut() {
|
|
14
|
+
setTimeout(setActiveElement);
|
|
15
|
+
}
|
|
16
|
+
container.addEventListener(evtFocusIn, setActiveElement, { capture: true });
|
|
17
|
+
container.addEventListener(evtFocusOut, onFocusOut, { capture: true });
|
|
18
|
+
return () => {
|
|
19
|
+
container.removeEventListener(evtFocusIn, setActiveElement, { capture: true });
|
|
20
|
+
container.removeEventListener(evtFocusOut, onFocusOut, { capture: true });
|
|
45
21
|
};
|
|
22
|
+
},
|
|
23
|
+
equal: Object.is
|
|
24
|
+
});
|
|
25
|
+
function createHasFocus() {
|
|
26
|
+
const { elements$, directive } = createBrowserStoreArrayDirective();
|
|
27
|
+
const hasFocus$ = computed(() => {
|
|
28
|
+
const activeElement = activeElement$();
|
|
29
|
+
if (!activeElement) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
for (const element of elements$()) {
|
|
33
|
+
if (element === activeElement || element.contains(activeElement)) {
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
});
|
|
39
|
+
return {
|
|
40
|
+
directive,
|
|
41
|
+
hasFocus$
|
|
42
|
+
};
|
|
46
43
|
}
|
|
44
|
+
export {
|
|
45
|
+
activeElement$,
|
|
46
|
+
createHasFocus
|
|
47
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const tansu = require("@amadeus-it-group/tansu");
|
|
4
|
+
const hash$ = tansu.readable("", {
|
|
5
|
+
onUse({ set }) {
|
|
6
|
+
function handleHashChange() {
|
|
7
|
+
const hash = location.hash;
|
|
8
|
+
set(hash ? hash.substring(1) : "");
|
|
9
|
+
}
|
|
10
|
+
handleHashChange();
|
|
11
|
+
window.addEventListener("hashchange", handleHashChange);
|
|
12
|
+
return () => window.removeEventListener("hashchange", handleHashChange);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
exports.hash$ = hash$;
|
package/services/hash.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { readable } from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
},
|
|
1
|
+
import { readable } from "@amadeus-it-group/tansu";
|
|
2
|
+
const hash$ = readable("", {
|
|
3
|
+
onUse({ set }) {
|
|
4
|
+
function handleHashChange() {
|
|
5
|
+
const hash = location.hash;
|
|
6
|
+
set(hash ? hash.substring(1) : "");
|
|
7
|
+
}
|
|
8
|
+
handleHashChange();
|
|
9
|
+
window.addEventListener("hashchange", handleHashChange);
|
|
10
|
+
return () => window.removeEventListener("hashchange", handleHashChange);
|
|
11
|
+
}
|
|
13
12
|
});
|
|
13
|
+
export {
|
|
14
|
+
hash$
|
|
15
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const tansu = require("@amadeus-it-group/tansu");
|
|
4
|
+
const func = require("../func-Qd3cD9a3.cjs");
|
|
5
|
+
const utils_stores = require("../utils/stores.cjs");
|
|
6
|
+
const defaultValues = {
|
|
7
|
+
elements: [],
|
|
8
|
+
options: void 0
|
|
9
|
+
};
|
|
10
|
+
const createIntersection = (config) => {
|
|
11
|
+
const [{ elements$, options$ }, patch] = utils_stores.writablesForProps(defaultValues, config);
|
|
12
|
+
const visibleElements$ = tansu.derived(
|
|
13
|
+
[elements$, options$],
|
|
14
|
+
([elements, options], set) => {
|
|
15
|
+
if (elements.length) {
|
|
16
|
+
const visibleElements = /* @__PURE__ */ new Map();
|
|
17
|
+
const observer = new IntersectionObserver((entries) => {
|
|
18
|
+
for (const entry of entries) {
|
|
19
|
+
const { target, isIntersecting } = entry;
|
|
20
|
+
if (isIntersecting) {
|
|
21
|
+
visibleElements.set(target, entry);
|
|
22
|
+
} else {
|
|
23
|
+
visibleElements.delete(target);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
set(visibleElements);
|
|
27
|
+
}, options);
|
|
28
|
+
for (const element of elements) {
|
|
29
|
+
observer.observe(element);
|
|
30
|
+
}
|
|
31
|
+
return () => {
|
|
32
|
+
observer.disconnect();
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return func.noop;
|
|
36
|
+
},
|
|
37
|
+
/* @__PURE__ */ new Map()
|
|
38
|
+
);
|
|
39
|
+
return {
|
|
40
|
+
/**
|
|
41
|
+
* Readable of observed elements
|
|
42
|
+
*/
|
|
43
|
+
elements$: tansu.asReadable(elements$),
|
|
44
|
+
/**
|
|
45
|
+
* Store of map that contains the visible elements (for the key) and the corresponding entries
|
|
46
|
+
*
|
|
47
|
+
* See the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserverEntry)
|
|
48
|
+
*/
|
|
49
|
+
visibleElements$: tansu.asReadable(visibleElements$),
|
|
50
|
+
patch
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
exports.createIntersection = createIntersection;
|
package/services/intersection.js
CHANGED
|
@@ -1,55 +1,53 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { noop } from
|
|
3
|
-
import { writablesForProps } from
|
|
1
|
+
import { derived, asReadable } from "@amadeus-it-group/tansu";
|
|
2
|
+
import { n as noop } from "../func-DR0n-ShK.js";
|
|
3
|
+
import { writablesForProps } from "../utils/stores.js";
|
|
4
4
|
const defaultValues = {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
elements: [],
|
|
6
|
+
options: void 0
|
|
7
7
|
};
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
for (const entry of entries) {
|
|
23
|
-
const { target, isIntersecting } = entry;
|
|
24
|
-
if (isIntersecting) {
|
|
25
|
-
visibleElements.set(target, entry);
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
visibleElements.delete(target);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
set(visibleElements);
|
|
32
|
-
}, options);
|
|
33
|
-
for (const element of elements) {
|
|
34
|
-
observer.observe(element);
|
|
8
|
+
const createIntersection = (config) => {
|
|
9
|
+
const [{ elements$, options$ }, patch] = writablesForProps(defaultValues, config);
|
|
10
|
+
const visibleElements$ = derived(
|
|
11
|
+
[elements$, options$],
|
|
12
|
+
([elements, options], set) => {
|
|
13
|
+
if (elements.length) {
|
|
14
|
+
const visibleElements = /* @__PURE__ */ new Map();
|
|
15
|
+
const observer = new IntersectionObserver((entries) => {
|
|
16
|
+
for (const entry of entries) {
|
|
17
|
+
const { target, isIntersecting } = entry;
|
|
18
|
+
if (isIntersecting) {
|
|
19
|
+
visibleElements.set(target, entry);
|
|
20
|
+
} else {
|
|
21
|
+
visibleElements.delete(target);
|
|
35
22
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
23
|
+
}
|
|
24
|
+
set(visibleElements);
|
|
25
|
+
}, options);
|
|
26
|
+
for (const element of elements) {
|
|
27
|
+
observer.observe(element);
|
|
39
28
|
}
|
|
40
|
-
return
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
29
|
+
return () => {
|
|
30
|
+
observer.disconnect();
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
return noop;
|
|
34
|
+
},
|
|
35
|
+
/* @__PURE__ */ new Map()
|
|
36
|
+
);
|
|
37
|
+
return {
|
|
38
|
+
/**
|
|
39
|
+
* Readable of observed elements
|
|
40
|
+
*/
|
|
41
|
+
elements$: asReadable(elements$),
|
|
42
|
+
/**
|
|
43
|
+
* Store of map that contains the visible elements (for the key) and the corresponding entries
|
|
44
|
+
*
|
|
45
|
+
* See the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserverEntry)
|
|
46
|
+
*/
|
|
47
|
+
visibleElements$: asReadable(visibleElements$),
|
|
48
|
+
patch
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
export {
|
|
52
|
+
createIntersection
|
|
55
53
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const tansu = require("@amadeus-it-group/tansu");
|
|
4
|
+
const esmEnv = require("esm-env");
|
|
5
|
+
const utils_directive = require("../directive-BTSEYLF3.cjs");
|
|
6
|
+
const createMatchMedia = (query) => esmEnv.BROWSER ? tansu.readable(false, {
|
|
7
|
+
onUse({ set }) {
|
|
8
|
+
const mql = window.matchMedia(query.trim());
|
|
9
|
+
set(mql.matches);
|
|
10
|
+
return utils_directive.addEvent(mql, "change", (val) => set(val.matches));
|
|
11
|
+
}
|
|
12
|
+
}) : tansu.readable(false);
|
|
13
|
+
exports.createMatchMedia = createMatchMedia;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create a store tracking the state of a {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia | matchMedia} query.
|
|
3
|
+
*
|
|
4
|
+
* @param query - the query to match
|
|
5
|
+
* @returns a readable store tracking the match media query state
|
|
6
|
+
*/
|
|
7
|
+
export declare const createMatchMedia: (query: string) => import("@amadeus-it-group/tansu").ReadableSignal<boolean>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { readable } from "@amadeus-it-group/tansu";
|
|
2
|
+
import { BROWSER } from "esm-env";
|
|
3
|
+
import { u as addEvent } from "../directive-DCYlDznf.js";
|
|
4
|
+
const createMatchMedia = (query) => BROWSER ? readable(false, {
|
|
5
|
+
onUse({ set }) {
|
|
6
|
+
const mql = window.matchMedia(query.trim());
|
|
7
|
+
set(mql.matches);
|
|
8
|
+
return addEvent(mql, "change", (val) => set(val.matches));
|
|
9
|
+
}
|
|
10
|
+
}) : readable(false);
|
|
11
|
+
export {
|
|
12
|
+
createMatchMedia
|
|
13
|
+
};
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const tansu = require("@amadeus-it-group/tansu");
|
|
4
|
+
const utils_directive = require("../directive-BTSEYLF3.cjs");
|
|
5
|
+
const isInertOrInvisible = (element) => {
|
|
6
|
+
let curElement = element;
|
|
7
|
+
while (curElement) {
|
|
8
|
+
const style = getComputedStyle(curElement);
|
|
9
|
+
if (curElement.inert || curElement.hidden || style.display === "none" || style.visibility === "hidden") {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
curElement = curElement.parentElement;
|
|
13
|
+
}
|
|
14
|
+
return false;
|
|
15
|
+
};
|
|
16
|
+
const checkNotDisabled = (element) => {
|
|
17
|
+
var _a;
|
|
18
|
+
if (element.disabled) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
const parentFieldset = (_a = element.parentElement) == null ? void 0 : _a.closest("fieldset");
|
|
22
|
+
return parentFieldset ? checkNotDisabled(parentFieldset) : true;
|
|
23
|
+
};
|
|
24
|
+
const isFocusableOtherTags = (element) => element.isContentEditable || !!element.hasAttribute("tabindex");
|
|
25
|
+
const isFocusableByTagName = {
|
|
26
|
+
INPUT: (element) => element.type !== "hidden" && checkNotDisabled(element),
|
|
27
|
+
SELECT: checkNotDisabled,
|
|
28
|
+
TEXTAREA: checkNotDisabled,
|
|
29
|
+
BUTTON: checkNotDisabled,
|
|
30
|
+
A: (element) => !!element.href || isFocusableOtherTags(element)
|
|
31
|
+
};
|
|
32
|
+
const isFocusable = (element) => {
|
|
33
|
+
return document.contains(element) && !isInertOrInvisible(element) && (isFocusableByTagName[element.tagName] ?? isFocusableOtherTags)(element);
|
|
34
|
+
};
|
|
35
|
+
const compareDomOrder = (element1, element2) => {
|
|
36
|
+
if (element1 === element2) {
|
|
37
|
+
return 0;
|
|
38
|
+
}
|
|
39
|
+
const result = element1.compareDocumentPosition(element2);
|
|
40
|
+
if (result & Node.DOCUMENT_POSITION_FOLLOWING) {
|
|
41
|
+
return -1;
|
|
42
|
+
} else if (result & Node.DOCUMENT_POSITION_PRECEDING) {
|
|
43
|
+
return 1;
|
|
44
|
+
}
|
|
45
|
+
throw new Error("failed to compare elements");
|
|
46
|
+
};
|
|
47
|
+
const getTextDirection = (element) => getComputedStyle(element).direction;
|
|
48
|
+
const textInputTypes = /* @__PURE__ */ new Set(["text", "search", "url", "tel", "password"]);
|
|
49
|
+
const isTextInput = (element) => element instanceof HTMLInputElement && textInputTypes.has(element.type);
|
|
50
|
+
const getKeyName = (event) => {
|
|
51
|
+
let key = event.key;
|
|
52
|
+
if (event.shiftKey) {
|
|
53
|
+
key = `Shift+${key}`;
|
|
54
|
+
}
|
|
55
|
+
if (event.altKey) {
|
|
56
|
+
key = `Alt+${key}`;
|
|
57
|
+
}
|
|
58
|
+
if (event.ctrlKey) {
|
|
59
|
+
key = `Ctrl+${key}`;
|
|
60
|
+
}
|
|
61
|
+
if (event.metaKey) {
|
|
62
|
+
key = `Meta+${key}`;
|
|
63
|
+
}
|
|
64
|
+
return key;
|
|
65
|
+
};
|
|
66
|
+
const isInternalInputNavigation = (event) => {
|
|
67
|
+
const { target, key } = event;
|
|
68
|
+
if (isTextInput(target) && (key === "ArrowLeft" || key === "ArrowRight" || key === "Home" || key === "End")) {
|
|
69
|
+
let startPosition;
|
|
70
|
+
if (key === "ArrowLeft" || key === "ArrowRight") {
|
|
71
|
+
const direction = getTextDirection(target);
|
|
72
|
+
startPosition = key === (direction === "ltr" ? "ArrowLeft" : "ArrowRight");
|
|
73
|
+
} else {
|
|
74
|
+
startPosition = key === "Home";
|
|
75
|
+
}
|
|
76
|
+
const cursorPosition = target.selectionStart === target.selectionEnd ? target.selectionStart : null;
|
|
77
|
+
if (startPosition && cursorPosition !== 0 || !startPosition && cursorPosition !== target.value.length) {
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return false;
|
|
82
|
+
};
|
|
83
|
+
const defaultSelector = (directiveElement) => [directiveElement];
|
|
84
|
+
const createNavManager = () => {
|
|
85
|
+
const directiveInstances$ = utils_directive.registrationArray();
|
|
86
|
+
const elementsRefresh$ = tansu.writable({});
|
|
87
|
+
const refreshElements = (now = true) => {
|
|
88
|
+
elementsRefresh$.set({});
|
|
89
|
+
if (now) {
|
|
90
|
+
commonAncestor$();
|
|
91
|
+
elementsInDomOrder$();
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
const elements$ = tansu.computed(() => {
|
|
95
|
+
elementsRefresh$();
|
|
96
|
+
const res = [];
|
|
97
|
+
for (const item of directiveInstances$()) {
|
|
98
|
+
res.push(...item());
|
|
99
|
+
}
|
|
100
|
+
return res;
|
|
101
|
+
});
|
|
102
|
+
const commonAncestor$ = tansu.computed(() => utils_directive.computeCommonAncestor(elements$()), { equal: Object.is });
|
|
103
|
+
const elementsInDomOrder$ = tansu.computed(() => [...elements$()].sort(compareDomOrder));
|
|
104
|
+
const ancestorDirection = () => {
|
|
105
|
+
const commonAncestor = commonAncestor$();
|
|
106
|
+
return commonAncestor ? getTextDirection(commonAncestor) : "ltr";
|
|
107
|
+
};
|
|
108
|
+
const preventDefaultIfRelevant = (value, event) => {
|
|
109
|
+
if (value) {
|
|
110
|
+
event == null ? void 0 : event.preventDefault();
|
|
111
|
+
}
|
|
112
|
+
return value;
|
|
113
|
+
};
|
|
114
|
+
const focusIndex = (index, moveDirection = 0) => {
|
|
115
|
+
const array = elementsInDomOrder$();
|
|
116
|
+
while (index >= 0 && index < array.length) {
|
|
117
|
+
const newItem = array[index];
|
|
118
|
+
if (isFocusable(newItem)) {
|
|
119
|
+
newItem.focus();
|
|
120
|
+
if (moveDirection != 0 && isTextInput(newItem)) {
|
|
121
|
+
const changeDirection = ancestorDirection() !== getTextDirection(newItem);
|
|
122
|
+
const position = moveDirection > 0 !== changeDirection ? 0 : newItem.value.length;
|
|
123
|
+
newItem.setSelectionRange(position, position, position === 0 ? "forward" : "backward");
|
|
124
|
+
}
|
|
125
|
+
return newItem;
|
|
126
|
+
}
|
|
127
|
+
if (moveDirection === 0) {
|
|
128
|
+
break;
|
|
129
|
+
} else {
|
|
130
|
+
index += moveDirection;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return null;
|
|
134
|
+
};
|
|
135
|
+
const createFocusNeighbour = (moveDirection) => ({
|
|
136
|
+
event,
|
|
137
|
+
referenceElement = (event == null ? void 0 : event.target) ?? document.activeElement
|
|
138
|
+
} = {}) => {
|
|
139
|
+
const curIndex = referenceElement ? elementsInDomOrder$().indexOf(referenceElement) : -1;
|
|
140
|
+
if (curIndex > -1) {
|
|
141
|
+
return preventDefaultIfRelevant(focusIndex(curIndex + moveDirection, moveDirection), event);
|
|
142
|
+
}
|
|
143
|
+
return null;
|
|
144
|
+
};
|
|
145
|
+
const directive = utils_directive.browserDirective((directiveElement, config) => {
|
|
146
|
+
const onKeyDown = (event) => {
|
|
147
|
+
var _a;
|
|
148
|
+
if (isInternalInputNavigation(event)) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const keyName = getKeyName(event);
|
|
152
|
+
const handler = (_a = config.keys) == null ? void 0 : _a[keyName];
|
|
153
|
+
if (handler) {
|
|
154
|
+
refreshElements(false);
|
|
155
|
+
handler({ event, directiveElement, navManager, context: config.context });
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
directiveElement.addEventListener("keydown", onKeyDown);
|
|
159
|
+
const unregister = directiveInstances$.register(() => ((config == null ? void 0 : config.selector) ?? defaultSelector)(directiveElement));
|
|
160
|
+
return {
|
|
161
|
+
update(newConfig) {
|
|
162
|
+
config = newConfig;
|
|
163
|
+
},
|
|
164
|
+
destroy() {
|
|
165
|
+
directiveElement.removeEventListener("keydown", onKeyDown);
|
|
166
|
+
unregister();
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
});
|
|
170
|
+
const focusPrevious = createFocusNeighbour(-1);
|
|
171
|
+
const focusNext = createFocusNeighbour(1);
|
|
172
|
+
const focusFirst = ({ event } = {}) => preventDefaultIfRelevant(focusIndex(0, 1), event);
|
|
173
|
+
const focusLast = ({ event } = {}) => preventDefaultIfRelevant(focusIndex(elementsInDomOrder$().length - 1, -1), event);
|
|
174
|
+
const focusLeft = (...args) => (ancestorDirection() === "rtl" ? focusNext : focusPrevious)(...args);
|
|
175
|
+
const focusRight = (...args) => (ancestorDirection() === "rtl" ? focusPrevious : focusNext)(...args);
|
|
176
|
+
const focusFirstLeft = (...args) => (ancestorDirection() === "rtl" ? focusLast : focusFirst)(...args);
|
|
177
|
+
const focusFirstRight = (...args) => (ancestorDirection() === "rtl" ? focusFirst : focusLast)(...args);
|
|
178
|
+
const navManager = {
|
|
179
|
+
elementsInDomOrder$,
|
|
180
|
+
directive,
|
|
181
|
+
focusIndex,
|
|
182
|
+
focusPrevious,
|
|
183
|
+
focusNext,
|
|
184
|
+
focusFirst,
|
|
185
|
+
focusFirstLeft,
|
|
186
|
+
focusFirstRight,
|
|
187
|
+
focusLast,
|
|
188
|
+
focusLeft,
|
|
189
|
+
focusRight,
|
|
190
|
+
refreshElements
|
|
191
|
+
};
|
|
192
|
+
return navManager;
|
|
193
|
+
};
|
|
194
|
+
exports.createNavManager = createNavManager;
|
|
195
|
+
exports.getKeyName = getKeyName;
|
|
196
|
+
exports.isInternalInputNavigation = isInternalInputNavigation;
|
package/services/navManager.d.ts
CHANGED
|
@@ -63,21 +63,21 @@ export interface NavManagerItemConfig<T = any> {
|
|
|
63
63
|
*/
|
|
64
64
|
export declare const createNavManager: () => {
|
|
65
65
|
elementsInDomOrder$: import("@amadeus-it-group/tansu").ReadableSignal<HTMLElement[]>;
|
|
66
|
-
directive: <T = any>(
|
|
67
|
-
update(
|
|
68
|
-
destroy()
|
|
66
|
+
directive: <T = any>(node: import("..").SSRHTMLElement, args: NavManagerItemConfig<T>) => void | {
|
|
67
|
+
update?: ((args: NavManagerItemConfig<T>) => void) | undefined;
|
|
68
|
+
destroy?: (() => void) | undefined;
|
|
69
69
|
};
|
|
70
70
|
focusIndex: (index: number, moveDirection?: -1 | 0 | 1) => HTMLElement | null;
|
|
71
71
|
focusPrevious: ({ event, referenceElement, }?: {
|
|
72
|
-
event?: Event
|
|
73
|
-
referenceElement?: HTMLElement | null
|
|
72
|
+
event?: Event;
|
|
73
|
+
referenceElement?: HTMLElement | null;
|
|
74
74
|
}) => HTMLElement | null;
|
|
75
75
|
focusNext: ({ event, referenceElement, }?: {
|
|
76
|
-
event?: Event
|
|
77
|
-
referenceElement?: HTMLElement | null
|
|
76
|
+
event?: Event;
|
|
77
|
+
referenceElement?: HTMLElement | null;
|
|
78
78
|
}) => HTMLElement | null;
|
|
79
79
|
focusFirst: ({ event }?: {
|
|
80
|
-
event?: Event
|
|
80
|
+
event?: Event;
|
|
81
81
|
}) => HTMLElement | null;
|
|
82
82
|
focusFirstLeft: (args_0?: {
|
|
83
83
|
event?: Event | undefined;
|
|
@@ -86,7 +86,7 @@ export declare const createNavManager: () => {
|
|
|
86
86
|
event?: Event | undefined;
|
|
87
87
|
} | undefined) => HTMLElement | null;
|
|
88
88
|
focusLast: ({ event }?: {
|
|
89
|
-
event?: Event
|
|
89
|
+
event?: Event;
|
|
90
90
|
}) => HTMLElement | null;
|
|
91
91
|
focusLeft: (args_0?: {
|
|
92
92
|
event?: Event | undefined;
|