@t007/utils 0.0.33 → 0.0.35
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/{arrowNavigation-DK8mqVOk.d.cts → arrowNavigation-B9bEdoqR.d.ts} +5 -2
- package/dist/{arrowNavigation-VenvPI4H.d.ts → arrowNavigation-zEJbo8Er.d.cts} +5 -2
- package/dist/{chunk-QJ72EQCJ.js → chunk-NX2LWYD6.js} +22 -17
- package/dist/chunk-ZALPHCSJ.js +317 -0
- package/dist/components/react.d.cts +1 -1
- package/dist/components/react.d.ts +1 -1
- package/dist/hooks/react.cjs +67 -53
- package/dist/hooks/react.d.cts +9 -6
- package/dist/hooks/react.d.ts +9 -6
- package/dist/hooks/react.js +34 -24
- package/dist/hooks/vanilla.cjs +58 -41
- package/dist/hooks/vanilla.d.cts +10 -10
- package/dist/hooks/vanilla.d.ts +10 -10
- package/dist/hooks/vanilla.js +25 -14
- package/dist/index.cjs +143 -22
- package/dist/index.d.cts +143 -16
- package/dist/index.d.ts +143 -16
- package/dist/index.js +23 -3
- package/dist/ripple-D1kGErTn.d.cts +55 -0
- package/dist/ripple-D1kGErTn.d.ts +55 -0
- package/dist/scrollAssist-BNvPnsJq.d.cts +97 -0
- package/dist/scrollAssist-BNvPnsJq.d.ts +97 -0
- package/dist/{useHighlight-DMpDCILK.d.cts → useHighlight-DYc_GF0R.d.cts} +2 -2
- package/dist/{useHighlight-DMpDCILK.d.ts → useHighlight-DYc_GF0R.d.ts} +2 -2
- package/package.json +4 -3
- package/dist/chunk-4O76EZJ4.js +0 -206
- package/dist/ripple-C5MfEErC.d.cts +0 -73
- package/dist/ripple-C5MfEErC.d.ts +0 -73
- package/dist/scrollAssist-y9wFmYgt.d.cts +0 -72
- package/dist/scrollAssist-y9wFmYgt.d.ts +0 -72
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { K as KeyEvent, C as Config } from './scrollAssist-
|
|
1
|
+
import { K as KeyEvent, C as Config } from './scrollAssist-BNvPnsJq.js';
|
|
2
2
|
|
|
3
3
|
type ArrowNavigationHandle = {
|
|
4
4
|
/** Current computed horizontal grid size. */
|
|
@@ -21,11 +21,14 @@ type ArrowNavigationHandle = {
|
|
|
21
21
|
goToIndex: (index: number, e?: KeyEvent) => void;
|
|
22
22
|
/** Simulate directional key navigation with a keyboard-like event. */
|
|
23
23
|
simulateKey: (e: KeyEvent) => void;
|
|
24
|
+
/** Synchronize the navigation items list with the DOM. */
|
|
25
|
+
sync: () => void;
|
|
24
26
|
/** Remove listeners/observers and release resources. */
|
|
25
27
|
destroy: () => void;
|
|
26
28
|
};
|
|
27
29
|
/** A vanilla JavaScript utility for managing robust arrow-key roving focus navigation. */
|
|
28
30
|
declare function initArrowNavigation(container: HTMLElement, config?: Config): ArrowNavigationHandle | void;
|
|
29
31
|
declare const removeArrowNavigation: (container: HTMLElement) => void | undefined;
|
|
32
|
+
declare const syncArrowNavigation: (container: HTMLElement) => void | undefined;
|
|
30
33
|
|
|
31
|
-
export { type ArrowNavigationHandle as A, initArrowNavigation as i, removeArrowNavigation as r };
|
|
34
|
+
export { type ArrowNavigationHandle as A, initArrowNavigation as i, removeArrowNavigation as r, syncArrowNavigation as s };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { K as KeyEvent, C as Config } from './scrollAssist-
|
|
1
|
+
import { K as KeyEvent, C as Config } from './scrollAssist-BNvPnsJq.cjs';
|
|
2
2
|
|
|
3
3
|
type ArrowNavigationHandle = {
|
|
4
4
|
/** Current computed horizontal grid size. */
|
|
@@ -21,11 +21,14 @@ type ArrowNavigationHandle = {
|
|
|
21
21
|
goToIndex: (index: number, e?: KeyEvent) => void;
|
|
22
22
|
/** Simulate directional key navigation with a keyboard-like event. */
|
|
23
23
|
simulateKey: (e: KeyEvent) => void;
|
|
24
|
+
/** Synchronize the navigation items list with the DOM. */
|
|
25
|
+
sync: () => void;
|
|
24
26
|
/** Remove listeners/observers and release resources. */
|
|
25
27
|
destroy: () => void;
|
|
26
28
|
};
|
|
27
29
|
/** A vanilla JavaScript utility for managing robust arrow-key roving focus navigation. */
|
|
28
30
|
declare function initArrowNavigation(container: HTMLElement, config?: Config): ArrowNavigationHandle | void;
|
|
29
31
|
declare const removeArrowNavigation: (container: HTMLElement) => void | undefined;
|
|
32
|
+
declare const syncArrowNavigation: (container: HTMLElement) => void | undefined;
|
|
30
33
|
|
|
31
|
-
export { type ArrowNavigationHandle as A, initArrowNavigation as i, removeArrowNavigation as r };
|
|
34
|
+
export { type ArrowNavigationHandle as A, initArrowNavigation as i, removeArrowNavigation as r, syncArrowNavigation as s };
|
|
@@ -4,39 +4,39 @@ import {
|
|
|
4
4
|
createEl,
|
|
5
5
|
getActiveEl,
|
|
6
6
|
isInteractive
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-ZALPHCSJ.js";
|
|
8
8
|
|
|
9
9
|
// src/ts/hooks/vanilla/outsideClick.ts
|
|
10
10
|
import { NIL, NOOP } from "sia-reactor";
|
|
11
11
|
function initOutsideClick(el, { enabled = false, onOutside = NOOP, outOnClick = true, outOnEscape = true, outOnFocusOut = false, allowBounds = false, allowInputs = false, root = window, scoped = true, capture = true } = NIL) {
|
|
12
|
-
const
|
|
12
|
+
const stack = t007._outsiders_stack ??= [], existing = (t007._outsiders ??= /* @__PURE__ */ new WeakMap()).get(el);
|
|
13
13
|
if (!enabled || existing) return existing ? existing : void 0;
|
|
14
14
|
scoped = scoped && root instanceof HTMLElement, root = scoped ? root : root === document ? document : window;
|
|
15
|
-
const
|
|
15
|
+
const onScopedOut = (e, t, p = e.touches?.[0] || e, rect = allowBounds ? el.getBoundingClientRect() : null) => {
|
|
16
16
|
if (stack.at(-1) !== el || (allowBounds ? p.clientX >= rect.left && p.clientX <= rect.right && p.clientY >= rect.top && p.clientY <= rect.bottom : el.contains(t))) return false;
|
|
17
17
|
return (!scoped ? true : root.contains(t)) && onOutside(e);
|
|
18
18
|
}, handleClick = ((e) => outOnClick && !(allowInputs && isInteractive(e.target)) && onScopedOut(e, e.target)), handleEscape = ((e) => outOnEscape && e.key === "Escape" && !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey && stack.at(-1) === el && onOutside(e)), handleFocusOut = (e) => outOnFocusOut && !el.contains(e.relatedTarget) && onScopedOut(e, e.relatedTarget);
|
|
19
19
|
root.addEventListener("mousedown", handleClick, capture), root.addEventListener("touchstart", handleClick, { passive: true, capture });
|
|
20
20
|
root.addEventListener("keydown", handleEscape, capture);
|
|
21
21
|
el.addEventListener("focusout", handleFocusOut, capture);
|
|
22
|
-
if (!stack.includes(el)) stack.push(el), stacks.set(root, stack);
|
|
23
22
|
const destroy = () => {
|
|
24
23
|
root.removeEventListener("mousedown", handleClick, capture), root.removeEventListener("touchstart", handleClick, capture);
|
|
25
24
|
root.removeEventListener("keydown", handleEscape, capture);
|
|
26
25
|
el.removeEventListener("focusout", handleFocusOut, capture);
|
|
27
26
|
t007._outsiders.delete(el), stack.splice(stack.indexOf(el), 1);
|
|
28
27
|
};
|
|
29
|
-
return t007._outsiders.set(el, destroy), destroy;
|
|
28
|
+
return !stack.includes(el) && stack.push(el), t007._outsiders.set(el, destroy), destroy;
|
|
30
29
|
}
|
|
31
30
|
var removeOutsideClick = (el) => t007._outsiders?.get(el)?.();
|
|
32
31
|
|
|
33
32
|
// src/ts/hooks/vanilla/focusTrap.ts
|
|
34
33
|
import { NIL as NIL2 } from "sia-reactor";
|
|
35
34
|
function initFocusTrap(el, { enabled = false, initialSelector = "[data-autofocus]", ringClassName = "focus-outline", root = window, scoped = true, capture = true } = NIL2) {
|
|
36
|
-
const
|
|
35
|
+
const stack = t007._ftrappers_stack ??= [], existing = (t007._ftrappers ??= /* @__PURE__ */ new WeakMap()).get(el);
|
|
37
36
|
if (!enabled || existing) return existing ? existing : void 0;
|
|
38
37
|
scoped = scoped && root instanceof HTMLElement, root = scoped ? root : root === document ? document : window;
|
|
39
|
-
|
|
38
|
+
let recovering = false;
|
|
39
|
+
const focused = document.querySelector(":focus"), initial = el.querySelector(initialSelector), first = createEl("span", { tabIndex: 0 }, { focusGuard: "start" }, { position: "absolute", width: "0", height: "0", pointerEvents: "none" }), last = createEl("span", { tabIndex: 0 }, { focusGuard: "end" }, { position: "absolute", width: "0", height: "0", pointerEvents: "none" }), getFocusable = (c = el) => [...c.querySelectorAll(INTERACTIVE_SELECTOR)], resetFocus = (i = 0, els = getFocusable()) => !recovering && (recovering = true, els?.length ? els.at(i).focus() : (!el.hasAttribute("tabindex") && (el.tabIndex = -1), el.focus()), recovering = false), edgeFocus = (pre = false, rt = root) => {
|
|
40
40
|
if (!scoped) return resetFocus(pre ? -1 : 0);
|
|
41
41
|
if (rt.hasAttribute("tabindex")) return rt.focus();
|
|
42
42
|
const items = getFocusable();
|
|
@@ -46,28 +46,29 @@ function initFocusTrap(el, { enabled = false, initialSelector = "[data-autofocus
|
|
|
46
46
|
while (p !== ceil && (!all.length || (pre ? rt.contains(all[0]) : rt.contains(all.at(-1))))) all = getFocusable(p = p.parentElement || ceil);
|
|
47
47
|
for (let target, len = all.length, i = all.indexOf(items[pre ? 0 : items.length - 1]) + (pre ? -1 : 1); pre ? i >= 0 : i < len; pre ? i-- : i++) if (!rt.contains(target = all[i])) return target.focus();
|
|
48
48
|
(pre ? first : last).blur();
|
|
49
|
-
}, handleFocusIn = () => {
|
|
49
|
+
}, handleFocusIn = (e) => {
|
|
50
50
|
if (document.querySelector("dialog:modal") && !el.matches("dialog:modal")) return;
|
|
51
|
-
stack.at(-1) === el && getActiveEl(el.ownerDocument) !== root && !el.contains(getActiveEl(el.ownerDocument)) && resetFocus();
|
|
51
|
+
stack.at(-1) === el && getActiveEl(el.ownerDocument) !== root && !el.contains(getActiveEl(el.ownerDocument)) && !e.composedPath().includes(el) && resetFocus();
|
|
52
52
|
}, handleInitialBlur = () => initial.classList.remove(ringClassName);
|
|
53
53
|
first.addEventListener("focus", (e) => el.contains(e.relatedTarget) ? edgeFocus(true) : resetFocus(), capture), el.prepend(first);
|
|
54
54
|
last.addEventListener("focus", (e) => el.contains(e.relatedTarget) ? edgeFocus() : resetFocus(-1), capture), el.append(last);
|
|
55
55
|
root.addEventListener("focusin", handleFocusIn, capture);
|
|
56
56
|
if (initial || !el.contains(focused)) !initial ? setTimeout(resetFocus) : setTimeout(() => (initial.classList.add(ringClassName), initial.focus(), initial.addEventListener("blur", handleInitialBlur, capture)));
|
|
57
|
-
if (!stack.includes(el)) stack.push(el), stacks.set(root, stack);
|
|
58
57
|
const destroy = () => {
|
|
59
58
|
focused?.isConnected && focused.focus(), first.remove(), last.remove();
|
|
60
59
|
root.removeEventListener("focusin", handleFocusIn, capture);
|
|
61
60
|
initial?.removeEventListener("blur", handleInitialBlur, capture);
|
|
62
61
|
t007._ftrappers.delete(el), stack.splice(stack.indexOf(el), 1);
|
|
63
62
|
};
|
|
64
|
-
|
|
63
|
+
const handle = { destroy, sync: () => (el.prepend(first), el.append(last)) };
|
|
64
|
+
return !stack.includes(el) && stack.push(el), t007._ftrappers.set(el, handle), handle;
|
|
65
65
|
}
|
|
66
|
-
var removeFocusTrap = (el) => t007._ftrappers?.get(el)?.();
|
|
66
|
+
var removeFocusTrap = (el) => t007._ftrappers?.get(el)?.destroy();
|
|
67
|
+
var syncFocusTrap = (el) => t007._ftrappers?.get(el)?.sync();
|
|
67
68
|
|
|
68
69
|
// src/ts/hooks/vanilla/ripple.ts
|
|
69
70
|
import { NIL as NIL3 } from "sia-reactor";
|
|
70
|
-
function rippleHandler(e, { target, forceCenter = false, wrapperClassName = "t007-ripple-wrapper", className = "t007-ripple", holdClassName = "t007-ripple-hold", fadeClassName = "t007-ripple-fade" } = NIL3) {
|
|
71
|
+
function rippleHandler(e, { target, forceCenter = false, wrapperClassName = "t007-ripple-wrapper", className = "t007-ripple", holdClassName = "t007-ripple-hold", fadeClassName = "t007-ripple-fade", maxDuration = 1e3 } = NIL3) {
|
|
71
72
|
const el = target || e.currentTarget;
|
|
72
73
|
if (!el || e.target !== e.currentTarget && isInteractive(e.target) || el.hasAttribute("disabled") || e.pointerType === "mouse" && e.button !== 0) return;
|
|
73
74
|
e.stopPropagation?.();
|
|
@@ -75,10 +76,13 @@ function rippleHandler(e, { target, forceCenter = false, wrapperClassName = "t00
|
|
|
75
76
|
let canRelease = false;
|
|
76
77
|
ripple.addEventListener("animationend", () => canRelease = true, { once: true });
|
|
77
78
|
el.append(wrapper.appendChild(ripple).parentElement);
|
|
78
|
-
|
|
79
|
-
|
|
79
|
+
let released = false;
|
|
80
|
+
const release = (force) => {
|
|
81
|
+
if (released) return;
|
|
82
|
+
if (!canRelease && force !== true) return ripple.addEventListener("animationend", release, { once: true }), void setTimeout(release, maxDuration, true);
|
|
83
|
+
released = true;
|
|
80
84
|
ripple.classList.replace(holdClassName, fadeClassName);
|
|
81
|
-
ripple.addEventListener("animationend", () => setTimeout(() => wrapper.remove()));
|
|
85
|
+
ripple.addEventListener("animationend", () => setTimeout(() => wrapper.remove())), setTimeout(() => wrapper.remove(), maxDuration);
|
|
82
86
|
for (const evt of ["pointerup", "pointercancel"]) (el.ownerDocument?.defaultView || window).removeEventListener(evt, release);
|
|
83
87
|
};
|
|
84
88
|
for (const evt of ["pointerup", "pointercancel"]) (el.ownerDocument?.defaultView || window).addEventListener(evt, release);
|
|
@@ -147,7 +151,7 @@ var DEFAULT_CONFIG = {
|
|
|
147
151
|
rtl: null,
|
|
148
152
|
grid: {},
|
|
149
153
|
activeClass: "focus-outlined",
|
|
150
|
-
inputSelector: "input,textarea,[contenteditable
|
|
154
|
+
inputSelector: "input,textarea,[contenteditable]",
|
|
151
155
|
focusOptions: { preventScroll: false },
|
|
152
156
|
scrollIntoView: { block: "nearest", inline: "nearest" },
|
|
153
157
|
onSelect: NOOP2,
|
|
@@ -165,5 +169,6 @@ export {
|
|
|
165
169
|
DEFAULT_CONFIG,
|
|
166
170
|
initFocusTrap,
|
|
167
171
|
removeFocusTrap,
|
|
172
|
+
syncFocusTrap,
|
|
168
173
|
rippleHandler
|
|
169
174
|
};
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
// src/ts/core/dom.ts
|
|
2
|
+
import { createEl, assignEl } from "sia-reactor/utils";
|
|
3
|
+
import { getActiveEl } from "sia-reactor/utils";
|
|
4
|
+
import { NOOP } from "sia-reactor";
|
|
5
|
+
var INTERACTIVE_SELECTOR = ":is(button,[href],input:not([type='hidden']),select,textarea,details>summary,[contenteditable],iframe,audio[controls],video[controls],[tabindex]):not([disabled],[tabindex='-1'],[data-focus-guard],[inert],[inert] *)";
|
|
6
|
+
var isInteractive = (target) => target instanceof HTMLElement && target.matches(INTERACTIVE_SELECTOR);
|
|
7
|
+
var VIRTUAL_RESOURCE = /* @__PURE__ */ Symbol.for("T007_VIRTUAL_RESOURCE");
|
|
8
|
+
function loadResource(req, type = "style", { module, media, crossOrigin, integrity, referrerPolicy, nonce, fetchPriority, attempts = 3, retryKey = false } = {}, win = window) {
|
|
9
|
+
win.t007 ??= {}, win.t007._resourceCache ??= {};
|
|
10
|
+
if (req === VIRTUAL_RESOURCE || isSym(req)) return Promise.resolve();
|
|
11
|
+
const src = req;
|
|
12
|
+
if (win.t007._resourceCache[src]) return win.t007._resourceCache[src];
|
|
13
|
+
const existing = type === "script" ? Array.prototype.find.call(win.document.scripts, (s) => isSameURL(s.src, src)) : type === "style" ? Array.prototype.find.call(win.document.styleSheets, (s) => isSameURL(s.href, src)) : null;
|
|
14
|
+
if (existing) return win.t007._resourceCache[src] = Promise.resolve(existing);
|
|
15
|
+
win.t007._resourceCache[src] = new Promise((resolve, reject) => {
|
|
16
|
+
(function tryLoad(remaining, el) {
|
|
17
|
+
const onerror = () => {
|
|
18
|
+
el?.remove?.();
|
|
19
|
+
if (remaining > 1) {
|
|
20
|
+
setTimeout(tryLoad, 1e3, remaining - 1);
|
|
21
|
+
console.warn(`Retrying ${type} load for "${src}" (${attempts - remaining + 1})...`);
|
|
22
|
+
} else {
|
|
23
|
+
delete win.t007._resourceCache[src];
|
|
24
|
+
reject(new Error(`${capitalize(type)} load failed for "${src}" after ${attempts - 1} attempts`));
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const url = retryKey && remaining < attempts ? `${src}${src.includes("?") ? "&" : "?"}_${retryKey}=${Date.now()}` : src;
|
|
28
|
+
if (type === "script") win.document.body.append(el = createEl("script", { src: url, type: module ? "module" : "text/javascript", crossOrigin, integrity, referrerPolicy, nonce, fetchPriority, onload: () => resolve(el), onerror }) || "");
|
|
29
|
+
else if (type === "style") win.document.head.append(el = createEl("link", { rel: "stylesheet", href: url, media, crossOrigin, integrity, referrerPolicy, nonce, fetchPriority, onload: () => resolve(el), onerror }) || "");
|
|
30
|
+
else reject(new Error(`Unsupported resource type: ${type}`));
|
|
31
|
+
})(attempts);
|
|
32
|
+
});
|
|
33
|
+
return win.t007._resourceCache[src];
|
|
34
|
+
}
|
|
35
|
+
function getWindow(el = window) {
|
|
36
|
+
return el?.ownerDocument?.defaultView ?? el?.defaultView ?? window;
|
|
37
|
+
}
|
|
38
|
+
function createListRenderer({ container, getKey, createNode, updateNode = NOOP, destroyNode = NOOP, initNode }) {
|
|
39
|
+
let nodeRegistry = /* @__PURE__ */ new Map();
|
|
40
|
+
if (initNode) {
|
|
41
|
+
const children = Array.from(container.children);
|
|
42
|
+
for (let i = 0, len = children.length; i < len; i++) initNode(children[i], (key) => nodeRegistry.set(key, children[i]));
|
|
43
|
+
}
|
|
44
|
+
return function syncDOM(array, strict = true) {
|
|
45
|
+
const newRegistry = /* @__PURE__ */ new Map(), seenKeys = /* @__PURE__ */ new Set(), oldPositions = /* @__PURE__ */ new WeakMap(), children = Array.from(container.children);
|
|
46
|
+
for (let i = 0, len = children.length; i < len; i++) oldPositions.set(children[i], i);
|
|
47
|
+
const futureNodes = [], oldIndices = [];
|
|
48
|
+
for (let i = 0, len = array.length; i < len; i++) {
|
|
49
|
+
const item = array[i], key = getKey(item);
|
|
50
|
+
if (seenKeys.has(key)) throw new Error(`[List Renderer] Duplicate key "${key}" detected`);
|
|
51
|
+
let node = nodeRegistry.get(key);
|
|
52
|
+
if (!node) {
|
|
53
|
+
node = createNode(item);
|
|
54
|
+
if (!node) {
|
|
55
|
+
if (strict) throw new Error(`[List Renderer] No HTMLElement for key "${key}"`);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
oldIndices.push(-1);
|
|
59
|
+
} else updateNode(node, item), oldIndices.push(oldPositions.get(node) ?? -1);
|
|
60
|
+
seenKeys.add(key), futureNodes.push(node), newRegistry.set(key, node);
|
|
61
|
+
}
|
|
62
|
+
for (const [key, node] of nodeRegistry.entries()) !seenKeys.has(key) && node.parentElement === container && (destroyNode(node, key), node.remove());
|
|
63
|
+
const sequence = longestIncreasingSubsequence(oldIndices), stable = new Set(sequence);
|
|
64
|
+
let anchor = null;
|
|
65
|
+
for (let i = futureNodes.length - 1; i >= 0; i--) {
|
|
66
|
+
const node = futureNodes[i];
|
|
67
|
+
if (oldIndices[i] !== -1 && stable.has(i)) {
|
|
68
|
+
anchor = node;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
container.insertBefore(node, anchor), anchor = node;
|
|
72
|
+
}
|
|
73
|
+
nodeRegistry = newRegistry;
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// src/ts/index.ts
|
|
78
|
+
import { NIL, NOOP as NOOP2 } from "sia-reactor";
|
|
79
|
+
|
|
80
|
+
// src/ts/core/obj.ts
|
|
81
|
+
import { isObj } from "sia-reactor/utils";
|
|
82
|
+
function isDef(val) {
|
|
83
|
+
return "undefined" !== typeof val;
|
|
84
|
+
}
|
|
85
|
+
function isSym(val) {
|
|
86
|
+
return "symbol" === typeof val;
|
|
87
|
+
}
|
|
88
|
+
function isBool(val) {
|
|
89
|
+
return "boolean" === typeof val;
|
|
90
|
+
}
|
|
91
|
+
function isNum(val) {
|
|
92
|
+
return "number" === typeof val;
|
|
93
|
+
}
|
|
94
|
+
function isStr(val) {
|
|
95
|
+
return "string" === typeof val;
|
|
96
|
+
}
|
|
97
|
+
function isArr(obj) {
|
|
98
|
+
return Array.isArray(obj);
|
|
99
|
+
}
|
|
100
|
+
function isPOJO(obj, crossRealms = false, typecheck = true) {
|
|
101
|
+
return (typecheck ? isObj(obj, false) : true) && (crossRealms ? Object.prototype.toString.call(obj) === "[object Object]" : obj.constructor === Object);
|
|
102
|
+
}
|
|
103
|
+
function isIter(obj) {
|
|
104
|
+
return obj != null && "function" === typeof obj[Symbol.iterator];
|
|
105
|
+
}
|
|
106
|
+
function isFunc(val) {
|
|
107
|
+
return "function" === typeof val;
|
|
108
|
+
}
|
|
109
|
+
function inBoolArrOpt(opt, str) {
|
|
110
|
+
return opt?.includes?.(str) ?? opt;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// src/ts/core/num.ts
|
|
114
|
+
import { clamp } from "sia-reactor/utils";
|
|
115
|
+
function longestIncreasingSubsequence(array) {
|
|
116
|
+
const n = array.length, parent = new Array(n), tails = [];
|
|
117
|
+
for (let i = 0; i < n; i++) {
|
|
118
|
+
const value = array[i];
|
|
119
|
+
if (value === -1) continue;
|
|
120
|
+
let left = 0;
|
|
121
|
+
let right = tails.length;
|
|
122
|
+
while (left < right) {
|
|
123
|
+
const mid = left + right >> 1;
|
|
124
|
+
if (array[tails[mid]] < value) left = mid + 1;
|
|
125
|
+
else right = mid;
|
|
126
|
+
}
|
|
127
|
+
if (left > 0) parent[i] = tails[left - 1];
|
|
128
|
+
else parent[i] = -1;
|
|
129
|
+
tails[left] = i;
|
|
130
|
+
}
|
|
131
|
+
if (!tails.length) return [];
|
|
132
|
+
const result = [];
|
|
133
|
+
let k = tails[tails.length - 1];
|
|
134
|
+
while (k >= 0) result.push(k), k = parent[k];
|
|
135
|
+
return result.reverse(), result;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// src/ts/core/str.ts
|
|
139
|
+
function uid(prefix = "") {
|
|
140
|
+
return prefix + Date.now().toString(36) + "_" + performance.now().toString(36).replace(".", "") + "_" + Math.random().toString(36).slice(2);
|
|
141
|
+
}
|
|
142
|
+
function capitalize(word = "") {
|
|
143
|
+
return word.replace(/^(\s*)([a-z])/i, (_, s, l) => s + l.toUpperCase());
|
|
144
|
+
}
|
|
145
|
+
function camelize(str = "", { source } = /[\s_-]+/, { preserveInnerCase: pIC = true, upperFirst: uF = false } = {}) {
|
|
146
|
+
return (pIC ? str : str.toLowerCase()).replace(new RegExp(source + "(\\w)", "g"), (_, c) => c.toUpperCase()).replace(/^\w/, (c) => c[uF ? "toUpperCase" : "toLowerCase"]());
|
|
147
|
+
}
|
|
148
|
+
function uncamelize(str, separator = " ") {
|
|
149
|
+
return str.replace(/([a-z])([A-Z])/g, `$1${separator}$2`).toLowerCase();
|
|
150
|
+
}
|
|
151
|
+
function remToPx(rem, el = document.documentElement) {
|
|
152
|
+
return rem * parseFloat(getComputedStyle(el).fontSize);
|
|
153
|
+
}
|
|
154
|
+
function pxToRem(px, el = document.documentElement) {
|
|
155
|
+
return px / parseFloat(getComputedStyle(el).fontSize);
|
|
156
|
+
}
|
|
157
|
+
function parseCSSTime(time) {
|
|
158
|
+
return time?.endsWith?.("ms") ? parseFloat(time) : parseFloat(time) * 1e3;
|
|
159
|
+
}
|
|
160
|
+
function parseCSSSize(size, el) {
|
|
161
|
+
return size?.endsWith?.("px") ? parseFloat(size) : remToPx(parseFloat(size), el);
|
|
162
|
+
}
|
|
163
|
+
function cleanURL(url) {
|
|
164
|
+
try {
|
|
165
|
+
const u = new URL(url, window.location.href);
|
|
166
|
+
return decodeURIComponent(u.origin + u.pathname);
|
|
167
|
+
} catch {
|
|
168
|
+
return url.replace(/\\/g, "/").split("?")[0].trim();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
function isSameURL(url1, url2) {
|
|
172
|
+
if (url1 === url2) return true;
|
|
173
|
+
if (!isStr(url1) || !isStr(url2) || !url1 || !url2) return false;
|
|
174
|
+
return cleanURL(url1) === cleanURL(url2);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// src/ts/core/fn.ts
|
|
178
|
+
import { setTimeout as setTimeout2, setInterval, requestAnimationFrame } from "sia-reactor/utils";
|
|
179
|
+
function throttle(key, fn, delay = 30, strict = true, signal, win) {
|
|
180
|
+
const throttleMap = t007._throttlers ??= /* @__PURE__ */ new Map();
|
|
181
|
+
if (strict === true) {
|
|
182
|
+
const now = performance.now();
|
|
183
|
+
return now - (throttleMap.get(key) ?? 0) < delay ? void 0 : (throttleMap.set(key, now), fn());
|
|
184
|
+
}
|
|
185
|
+
if (throttleMap.has(key)) return;
|
|
186
|
+
const id = strict === false ? setTimeout2(() => throttleMap.delete(key), delay, signal, win) : strict(() => throttleMap.delete(key));
|
|
187
|
+
return throttleMap.set(key, id), fn();
|
|
188
|
+
}
|
|
189
|
+
function debounce(key, fn, delay = 30, strict = true, signal, win) {
|
|
190
|
+
const debounceMap = t007._debouncers ??= /* @__PURE__ */ new Map();
|
|
191
|
+
if (strict) {
|
|
192
|
+
const now = performance.now(), prev = debounceMap.get(key) ?? 0;
|
|
193
|
+
return debounceMap.set(key, now), now - prev < delay ? void 0 : fn();
|
|
194
|
+
}
|
|
195
|
+
const prevId = debounceMap.get(key);
|
|
196
|
+
prevId !== void 0 && (win ?? window).clearTimeout(prevId);
|
|
197
|
+
const id = setTimeout2(() => (debounceMap.delete(key), fn()), delay, signal, win);
|
|
198
|
+
return void debounceMap.set(key, id);
|
|
199
|
+
}
|
|
200
|
+
function RAFLoop(key, fn, signal, win) {
|
|
201
|
+
const rafLoopMap = t007._RAFLoopers ??= /* @__PURE__ */ new Map();
|
|
202
|
+
if (rafLoopMap.has(key)) return void rafLoopMap.set(key, fn);
|
|
203
|
+
rafLoopMap.set(key, fn);
|
|
204
|
+
const loop = (_ = 0, fn2 = rafLoopMap.get(key)) => fn2 && (fn2(), requestAnimationFrame(loop, signal, win));
|
|
205
|
+
loop();
|
|
206
|
+
}
|
|
207
|
+
var cancelRAFLoop = (key) => t007._RAFLoopers ? t007._RAFLoopers.delete(key) : false;
|
|
208
|
+
function limited(FN_KEY, fn, opts = {}) {
|
|
209
|
+
let count = 0, { key, maxTimes: max = 1, oncePerSession = true } = isStr(opts) ? { key: opts } : opts;
|
|
210
|
+
const getReg = () => JSON.parse(localStorage.getItem(FN_KEY) || "{}"), setReg = (r) => localStorage.setItem(FN_KEY, JSON.stringify(r));
|
|
211
|
+
const handle = (...args) => {
|
|
212
|
+
if (oncePerSession && count > 0) return void 0;
|
|
213
|
+
if (!key) return count++ < max ? fn(...args) : void 0;
|
|
214
|
+
const r = getReg(), c = r[key] || 0;
|
|
215
|
+
return c < max ? (count++, r[key] = c + 1, setReg(r), fn(...args)) : void 0;
|
|
216
|
+
};
|
|
217
|
+
handle.left = max - (handle.count = count);
|
|
218
|
+
handle.reset = () => (count = 0, key && ((r) => (delete r[key], setReg(r)))(getReg()));
|
|
219
|
+
handle.block = () => (count = max, key && ((r) => (r[key] = max, setReg(r)))(getReg()));
|
|
220
|
+
return handle;
|
|
221
|
+
}
|
|
222
|
+
var mockAsync = (timeout = 250) => new Promise((resolve) => setTimeout2(resolve, timeout));
|
|
223
|
+
var breath = (w = window) => new Promise((res) => w.requestAnimationFrame(res));
|
|
224
|
+
var deepBreath = (w = window) => new Promise((res) => w.requestAnimationFrame(() => w.requestAnimationFrame(res)));
|
|
225
|
+
function bindCleanupToSignal(cleanup, signal) {
|
|
226
|
+
signal?.aborted ? cleanup() : signal?.addEventListener("abort", cleanup, { once: true });
|
|
227
|
+
if (signal && !signal.aborted) cleanup = (() => (signal.removeEventListener("abort", cleanup), cleanup()));
|
|
228
|
+
return cleanup;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// src/ts/core/keys.ts
|
|
232
|
+
import { KEYS_BLOCKS, parseKeyCombo, stringifyKeyEvent, cleanKeyCombo, matchKeys, getTermsForKey, keyEventAllowed, formatKeyForDisplay, formatKeyShortcutsForDisplay, parseForARIAKS } from "sia-reactor/utils";
|
|
233
|
+
|
|
234
|
+
// src/ts/core/file.ts
|
|
235
|
+
function formatSize(bytes, decimals = 3, base = 1e3) {
|
|
236
|
+
if (bytes < base) return `${bytes} byte${bytes == 1 ? "" : "s"}`;
|
|
237
|
+
const units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"], exponent = Math.min(Math.floor(Math.log(bytes) / Math.log(base)), units.length - 1);
|
|
238
|
+
return `${(bytes / Math.pow(base, exponent)).toFixed(decimals).replace(/\.0+$/, "")} ${units[exponent]}`;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// src/ts/mixins/methd.ts
|
|
242
|
+
import { onAllMethods, bindAllMethods, guardAllMethods, guardMethod } from "sia-reactor/utils";
|
|
243
|
+
|
|
244
|
+
// src/ts/index.ts
|
|
245
|
+
if ("undefined" !== typeof window) {
|
|
246
|
+
(window.t007 ??= {}).VIRTUAL_RESOURCE = VIRTUAL_RESOURCE;
|
|
247
|
+
window.T007_TOAST_JS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/toast@latest`;
|
|
248
|
+
window.T007_INPUT_JS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/input@latest`;
|
|
249
|
+
window.T007_DIALOG_JS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/dialog@latest`;
|
|
250
|
+
window.T007_TOAST_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/toast@latest/dist/index.min.css`;
|
|
251
|
+
window.T007_INPUT_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/input@latest/dist/index.min.css`;
|
|
252
|
+
window.T007_DIALOG_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/dialog@latest/dist/index.min.css`;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export {
|
|
256
|
+
createEl,
|
|
257
|
+
assignEl,
|
|
258
|
+
INTERACTIVE_SELECTOR,
|
|
259
|
+
isInteractive,
|
|
260
|
+
VIRTUAL_RESOURCE,
|
|
261
|
+
loadResource,
|
|
262
|
+
getWindow,
|
|
263
|
+
createListRenderer,
|
|
264
|
+
getActiveEl,
|
|
265
|
+
isObj,
|
|
266
|
+
isDef,
|
|
267
|
+
isSym,
|
|
268
|
+
isBool,
|
|
269
|
+
isNum,
|
|
270
|
+
isStr,
|
|
271
|
+
isArr,
|
|
272
|
+
isPOJO,
|
|
273
|
+
isIter,
|
|
274
|
+
isFunc,
|
|
275
|
+
inBoolArrOpt,
|
|
276
|
+
longestIncreasingSubsequence,
|
|
277
|
+
clamp,
|
|
278
|
+
uid,
|
|
279
|
+
capitalize,
|
|
280
|
+
camelize,
|
|
281
|
+
uncamelize,
|
|
282
|
+
remToPx,
|
|
283
|
+
pxToRem,
|
|
284
|
+
parseCSSTime,
|
|
285
|
+
parseCSSSize,
|
|
286
|
+
cleanURL,
|
|
287
|
+
isSameURL,
|
|
288
|
+
setTimeout2 as setTimeout,
|
|
289
|
+
setInterval,
|
|
290
|
+
requestAnimationFrame,
|
|
291
|
+
throttle,
|
|
292
|
+
debounce,
|
|
293
|
+
RAFLoop,
|
|
294
|
+
cancelRAFLoop,
|
|
295
|
+
limited,
|
|
296
|
+
mockAsync,
|
|
297
|
+
breath,
|
|
298
|
+
deepBreath,
|
|
299
|
+
bindCleanupToSignal,
|
|
300
|
+
KEYS_BLOCKS,
|
|
301
|
+
parseKeyCombo,
|
|
302
|
+
stringifyKeyEvent,
|
|
303
|
+
cleanKeyCombo,
|
|
304
|
+
matchKeys,
|
|
305
|
+
getTermsForKey,
|
|
306
|
+
keyEventAllowed,
|
|
307
|
+
formatKeyForDisplay,
|
|
308
|
+
formatKeyShortcutsForDisplay,
|
|
309
|
+
parseForARIAKS,
|
|
310
|
+
formatSize,
|
|
311
|
+
onAllMethods,
|
|
312
|
+
bindAllMethods,
|
|
313
|
+
guardAllMethods,
|
|
314
|
+
guardMethod,
|
|
315
|
+
NIL,
|
|
316
|
+
NOOP2 as NOOP
|
|
317
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { H as HighlightOptions } from '../useHighlight-
|
|
2
|
+
import { H as HighlightOptions } from '../useHighlight-DYc_GF0R.cjs';
|
|
3
3
|
|
|
4
4
|
interface HighlightTextProps extends HighlightOptions {
|
|
5
5
|
/** The text to be processed and displayed. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { H as HighlightOptions } from '../useHighlight-
|
|
2
|
+
import { H as HighlightOptions } from '../useHighlight-DYc_GF0R.js';
|
|
3
3
|
|
|
4
4
|
interface HighlightTextProps extends HighlightOptions {
|
|
5
5
|
/** The text to be processed and displayed. */
|