@v-c/util 1.0.18-beta.1 → 1.0.19
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/Dom/focus.d.ts +4 -1
- package/dist/Dom/focus.js +34 -13
- package/dist/Dom/focusBoundary.d.ts +5 -0
- package/dist/Dom/focusBoundary.js +9 -0
- package/package.json +1 -1
package/dist/Dom/focus.d.ts
CHANGED
|
@@ -16,4 +16,7 @@ export declare function lockFocus(element: HTMLElement, id: string): VoidFunctio
|
|
|
16
16
|
* If multiple elements are locked, only the last locked element will be effective.
|
|
17
17
|
* @returns A function to mark an element as ignored, which will temporarily allow focus on that element even if it's outside the locked area.
|
|
18
18
|
*/
|
|
19
|
-
export declare function useLockFocus(lock: Ref<boolean>, getElement: () => HTMLElement | null): [
|
|
19
|
+
export declare function useLockFocus(lock: Ref<boolean>, getElement: () => HTMLElement | null): [
|
|
20
|
+
ignoreElement: (ele: HTMLElement) => void,
|
|
21
|
+
registerAllowedElement: (ele: HTMLElement) => VoidFunction
|
|
22
|
+
];
|
package/dist/Dom/focus.js
CHANGED
|
@@ -49,21 +49,27 @@ var lastFocusElement = null;
|
|
|
49
49
|
var focusElements = [];
|
|
50
50
|
var idToElementMap = /* @__PURE__ */ new Map();
|
|
51
51
|
var ignoredElementMap = /* @__PURE__ */ new Map();
|
|
52
|
+
var allowedElementMap = /* @__PURE__ */ new Map();
|
|
52
53
|
function getLastElement() {
|
|
53
54
|
return focusElements[focusElements.length - 1];
|
|
54
55
|
}
|
|
55
|
-
function
|
|
56
|
+
function getLastLockId() {
|
|
56
57
|
const lastElement = getLastElement();
|
|
57
|
-
if (
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
58
|
+
if (!lastElement) return void 0;
|
|
59
|
+
for (const [id, ele] of idToElementMap.entries()) if (ele === lastElement) return id;
|
|
60
|
+
}
|
|
61
|
+
function isIgnoredElement(element) {
|
|
62
|
+
const lockId = getLastLockId();
|
|
63
|
+
if (!lockId || !element) return false;
|
|
64
|
+
const ignoredEle = ignoredElementMap.get(lockId);
|
|
65
|
+
return !!ignoredEle && (ignoredEle === element || ignoredEle.contains(element));
|
|
66
|
+
}
|
|
67
|
+
function isAllowedElement(element) {
|
|
68
|
+
const lockId = getLastLockId();
|
|
69
|
+
if (!lockId || !element) return false;
|
|
70
|
+
const allowedElements = allowedElementMap.get(lockId);
|
|
71
|
+
if (!allowedElements?.size) return false;
|
|
72
|
+
for (const allowedElement of allowedElements) if (allowedElement === element || allowedElement.contains(element)) return true;
|
|
67
73
|
return false;
|
|
68
74
|
}
|
|
69
75
|
function hasFocus(element) {
|
|
@@ -73,7 +79,7 @@ function hasFocus(element) {
|
|
|
73
79
|
function syncFocus() {
|
|
74
80
|
const lastElement = getLastElement();
|
|
75
81
|
const { activeElement } = document;
|
|
76
|
-
if (isIgnoredElement(activeElement)) return;
|
|
82
|
+
if (isIgnoredElement(activeElement) || isAllowedElement(activeElement)) return;
|
|
77
83
|
if (lastElement && !hasFocus(lastElement)) {
|
|
78
84
|
const focusableList = getFocusNodeList(lastElement);
|
|
79
85
|
(focusableList.includes(lastFocusElement) ? lastFocusElement : focusableList[0])?.focus({ preventScroll: true });
|
|
@@ -102,6 +108,7 @@ function lockFocus(element, id) {
|
|
|
102
108
|
focusElements = focusElements.filter((ele) => ele !== element);
|
|
103
109
|
idToElementMap.delete(id);
|
|
104
110
|
ignoredElementMap.delete(id);
|
|
111
|
+
allowedElementMap.delete(id);
|
|
105
112
|
if (focusElements.length === 0) {
|
|
106
113
|
window.removeEventListener("focusin", syncFocus);
|
|
107
114
|
window.removeEventListener("keydown", onWindowKeyDown, true);
|
|
@@ -120,6 +127,20 @@ function useLockFocus(lock, getElement) {
|
|
|
120
127
|
const ignoreElement = (ele) => {
|
|
121
128
|
if (ele) ignoredElementMap.set(id, ele);
|
|
122
129
|
};
|
|
123
|
-
|
|
130
|
+
const registerAllowedElement = (ele) => {
|
|
131
|
+
if (!ele) return () => {};
|
|
132
|
+
let allowedElements = allowedElementMap.get(id);
|
|
133
|
+
if (!allowedElements) {
|
|
134
|
+
allowedElements = /* @__PURE__ */ new Set();
|
|
135
|
+
allowedElementMap.set(id, allowedElements);
|
|
136
|
+
}
|
|
137
|
+
allowedElements.add(ele);
|
|
138
|
+
return () => {
|
|
139
|
+
const nextAllowedElements = allowedElementMap.get(id);
|
|
140
|
+
nextAllowedElements?.delete(ele);
|
|
141
|
+
if (!nextAllowedElements?.size) allowedElementMap.delete(id);
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
return [ignoreElement, registerAllowedElement];
|
|
124
145
|
}
|
|
125
146
|
export { getFocusNodeList, lockFocus, triggerFocus, useLockFocus };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export interface FocusBoundaryContextProps {
|
|
2
|
+
registerAllowedElement: (element: HTMLElement) => VoidFunction;
|
|
3
|
+
}
|
|
4
|
+
export declare function useFocusBoundaryProvider(props: FocusBoundaryContextProps): void;
|
|
5
|
+
export declare function useFocusBoundary(): FocusBoundaryContextProps;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { inject, provide } from "vue";
|
|
2
|
+
var FocusBoundaryContextKey = Symbol("FocusBoundaryContext");
|
|
3
|
+
function useFocusBoundaryProvider(props) {
|
|
4
|
+
provide(FocusBoundaryContextKey, props);
|
|
5
|
+
}
|
|
6
|
+
function useFocusBoundary() {
|
|
7
|
+
return inject(FocusBoundaryContextKey, null);
|
|
8
|
+
}
|
|
9
|
+
export { useFocusBoundary, useFocusBoundaryProvider };
|