@t007/utils 0.0.25 → 0.0.27
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 +91 -4
- package/dist/arrowNavigation-DK8mqVOk.d.cts +31 -0
- package/dist/arrowNavigation-VenvPI4H.d.ts +31 -0
- package/dist/chunk-N5KX6IW4.js +198 -0
- package/dist/chunk-NLR4ANGT.js +168 -0
- package/dist/chunk-OGFBI6PS.js +16 -0
- package/dist/components/react.cjs +51 -0
- package/dist/components/react.d.cts +17 -0
- package/dist/components/react.d.ts +17 -0
- package/dist/components/react.js +15 -0
- package/dist/hooks/react.cjs +467 -0
- package/dist/hooks/react.d.cts +46 -0
- package/dist/hooks/react.d.ts +46 -0
- package/dist/hooks/react.js +277 -0
- package/dist/hooks/vanilla.cjs +408 -0
- package/dist/hooks/vanilla.d.cts +35 -0
- package/dist/hooks/vanilla.d.ts +35 -0
- package/dist/hooks/vanilla.js +233 -0
- package/dist/index.cjs +69 -119
- package/dist/index.d.cts +48 -68
- package/dist/index.d.ts +48 -68
- package/dist/index.js +63 -215
- package/dist/ripple-CVQx46Xq.d.cts +71 -0
- package/dist/ripple-CVQx46Xq.d.ts +71 -0
- package/dist/scrollAssist-y9wFmYgt.d.cts +72 -0
- package/dist/scrollAssist-y9wFmYgt.d.ts +72 -0
- package/dist/styles/ripple.css +55 -0
- package/dist/styles/scroll-assist.css +44 -0
- package/dist/useHighlight-DMpDCILK.d.cts +19 -0
- package/dist/useHighlight-DMpDCILK.d.ts +19 -0
- package/package.json +43 -5
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_CONFIG,
|
|
3
|
+
H_NAV_KEYS,
|
|
4
|
+
NAV_KEYS,
|
|
5
|
+
getCommonAncestor,
|
|
6
|
+
getGrid,
|
|
7
|
+
getTargetIndex,
|
|
8
|
+
initFocusTrap,
|
|
9
|
+
initOutsideClick,
|
|
10
|
+
removeFocusTrap,
|
|
11
|
+
removeOutsideClick,
|
|
12
|
+
rippleHandler
|
|
13
|
+
} from "../chunk-NLR4ANGT.js";
|
|
14
|
+
import {
|
|
15
|
+
INTERACTIVE_SELECTOR,
|
|
16
|
+
createEl,
|
|
17
|
+
getActiveEl
|
|
18
|
+
} from "../chunk-N5KX6IW4.js";
|
|
19
|
+
|
|
20
|
+
// src/hooks/vanilla/scrollAssist.ts
|
|
21
|
+
import { NIL } from "sia-reactor";
|
|
22
|
+
function initScrollAssist(el, { pxPerSecond = 80, assistClassName = "t007-scroll-assist", vertical = true, horizontal = true } = NIL) {
|
|
23
|
+
const parent = el?.parentElement, existing = (t007._scrollers ??= /* @__PURE__ */ new WeakMap()).get(el);
|
|
24
|
+
if (!parent || existing) return existing ? existing : void 0;
|
|
25
|
+
t007._scrollers_r_observer ??= new ResizeObserver((entries) => {
|
|
26
|
+
for (const { target } of entries) t007._scrollers.get(target)?.update();
|
|
27
|
+
});
|
|
28
|
+
t007._scrollers_m_observer ??= new MutationObserver((entries) => {
|
|
29
|
+
const els = /* @__PURE__ */ new Set();
|
|
30
|
+
for (const entry of entries) {
|
|
31
|
+
let node = entry.target instanceof Element ? entry.target : null;
|
|
32
|
+
while (node && !t007._scrollers.has(node)) node = node.parentElement;
|
|
33
|
+
if (node) els.add(node);
|
|
34
|
+
}
|
|
35
|
+
for (const el2 of els) t007._scrollers.get(el2)?.update();
|
|
36
|
+
});
|
|
37
|
+
const assist = {};
|
|
38
|
+
let scrollId = null, last = performance.now(), assistWidth = 20, assistHeight = 20;
|
|
39
|
+
const update = () => {
|
|
40
|
+
const hasInteractive = !!parent.querySelector(INTERACTIVE_SELECTOR);
|
|
41
|
+
if (horizontal) {
|
|
42
|
+
const w = assist.left?.offsetWidth || assistWidth, check = hasInteractive ? el.clientWidth < w * 2 : false;
|
|
43
|
+
assist.left.style.display = check ? "none" : el.scrollLeft > 0 ? "block" : "none";
|
|
44
|
+
assist.right.style.display = check ? "none" : el.scrollLeft + el.clientWidth < el.scrollWidth - 1 ? "block" : "none";
|
|
45
|
+
assistWidth = w;
|
|
46
|
+
}
|
|
47
|
+
if (vertical) {
|
|
48
|
+
const h = assist.up?.offsetHeight || assistHeight, check = hasInteractive ? el.clientHeight < h * 2 : false;
|
|
49
|
+
assist.up.style.display = check ? "none" : el.scrollTop > 0 ? "block" : "none";
|
|
50
|
+
assist.down.style.display = check ? "none" : el.scrollTop + el.clientHeight < el.scrollHeight - 1 ? "block" : "none";
|
|
51
|
+
assistHeight = h;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
const scroll = (dir) => {
|
|
55
|
+
const frame = () => {
|
|
56
|
+
const now = performance.now(), dt = now - last;
|
|
57
|
+
last = now;
|
|
58
|
+
const d = pxPerSecond * dt / 1e3;
|
|
59
|
+
if (dir === "left") el.scrollLeft = Math.max(0, el.scrollLeft - d);
|
|
60
|
+
if (dir === "right") el.scrollLeft = Math.min(el.scrollWidth - el.clientWidth, el.scrollLeft + d);
|
|
61
|
+
if (dir === "up") el.scrollTop = Math.max(0, el.scrollTop - d);
|
|
62
|
+
if (dir === "down") el.scrollTop = Math.min(el.scrollHeight - el.clientHeight, el.scrollTop + d);
|
|
63
|
+
scrollId = requestAnimationFrame(frame);
|
|
64
|
+
};
|
|
65
|
+
last = performance.now();
|
|
66
|
+
frame();
|
|
67
|
+
};
|
|
68
|
+
const stop = () => (cancelAnimationFrame(scrollId ?? 0), scrollId = null);
|
|
69
|
+
const addAssist = (dir) => {
|
|
70
|
+
const div = createEl("div", { className: assistClassName }, { scrollDirection: dir }, { display: "none" });
|
|
71
|
+
if (!div) return;
|
|
72
|
+
for (const evt of ["pointerenter", "dragenter"]) div.addEventListener(evt, () => scroll(dir));
|
|
73
|
+
for (const evt of ["pointerleave", "pointerup", "pointercancel", "dragleave", "dragend"]) div.addEventListener(evt, stop);
|
|
74
|
+
dir === "left" || dir === "up" ? parent.insertBefore(div, el) : parent.append(div);
|
|
75
|
+
assist[dir] = div;
|
|
76
|
+
};
|
|
77
|
+
if (horizontal) for (const dir of ["left", "right"]) addAssist(dir);
|
|
78
|
+
if (vertical) for (const dir of ["up", "down"]) addAssist(dir);
|
|
79
|
+
const handle = {
|
|
80
|
+
update,
|
|
81
|
+
destroy() {
|
|
82
|
+
stop(), el.removeEventListener("scroll", update);
|
|
83
|
+
t007._scrollers_r_observer.unobserve(el), t007._scrollers.delete(el);
|
|
84
|
+
for (const a of Object.values(assist)) a.remove();
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
update(), el.addEventListener("scroll", update);
|
|
88
|
+
t007._scrollers_r_observer.observe(el), t007._scrollers_m_observer.observe(el, { childList: true, subtree: true, characterData: true });
|
|
89
|
+
return t007._scrollers.set(el, handle), handle;
|
|
90
|
+
}
|
|
91
|
+
var removeScrollAssist = (el) => t007._scrollers.get(el)?.destroy();
|
|
92
|
+
|
|
93
|
+
// src/hooks/vanilla/scrollerator.ts
|
|
94
|
+
import { NIL as NIL2 } from "sia-reactor";
|
|
95
|
+
function initVScrollerator({ baseSpeed = 3, maxSpeed = 10, stepDelay = 2e3, baseRate = 16, lineHeight = 80, margin = 80, car = window } = NIL2) {
|
|
96
|
+
let linesPerSec = baseSpeed, accelId = null, lastTime = null;
|
|
97
|
+
const drive = (clientY, brake = false, offsetY = 0) => {
|
|
98
|
+
if (car !== window) clientY -= offsetY;
|
|
99
|
+
const now = performance.now(), speed = linesPerSec * lineHeight * ((lastTime ? now - lastTime : baseRate) / 1e3);
|
|
100
|
+
if (!brake && (clientY < margin || clientY > (car.innerHeight ?? car.offsetHeight) - margin)) {
|
|
101
|
+
accelId === null ? accelId = setTimeout(() => linesPerSec += 1, stepDelay) : linesPerSec > baseSpeed && (linesPerSec = Math.min(linesPerSec + 1, maxSpeed));
|
|
102
|
+
car.scrollBy?.(0, clientY < margin ? -speed : speed);
|
|
103
|
+
} else reset();
|
|
104
|
+
return lastTime = !brake ? now : null, speed;
|
|
105
|
+
};
|
|
106
|
+
const reset = () => (accelId && clearTimeout(accelId), accelId = null, linesPerSec = baseSpeed, lastTime = null);
|
|
107
|
+
return { drive, reset };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// src/hooks/vanilla/arrowNavigation.ts
|
|
111
|
+
function initArrowNavigation(container, config = {}) {
|
|
112
|
+
const existing = (t007._arrownavs ??= /* @__PURE__ */ new WeakMap()).get(container);
|
|
113
|
+
if (!config.enabled || existing) return existing ? existing : void 0;
|
|
114
|
+
const { enabled: isEnabled, selector, focusOnHover, loop, virtual, typeahead, resetMs, activeClass, inputSelector, defaultTabbableIndex, baseTabIndex, grid, rtl: isRtl, focusOptions, scrollIntoView, onSelect, onFocusOut, rovingTab } = { ...DEFAULT_CONFIG, ...config };
|
|
115
|
+
let gridX = grid.x || 1, gridY = grid.y || 1, vGridY = grid.vY || 1, activeIndex = -1, buffer = "", timeout = null, items = [];
|
|
116
|
+
const enabled = isEnabled ?? virtual, roving = rovingTab ?? !virtual, rtl = isRtl ?? getComputedStyle(container).direction === "rtl", shouldSnub = () => !enabled || !container, isItemDisabled = (el) => !el || el.hasAttribute("disabled") || el.hasAttribute("aria-disabled"), getItems = () => items = Array.from(container.querySelectorAll(selector));
|
|
117
|
+
const getAbleIndex = (targetIndex, e = { key: "ArrowRight", ctrlKey: false }) => {
|
|
118
|
+
if (shouldSnub() || !items.length) return null;
|
|
119
|
+
let index = targetIndex;
|
|
120
|
+
let attempts = 0;
|
|
121
|
+
while (attempts < items.length) {
|
|
122
|
+
if (!isItemDisabled(items[index])) return index;
|
|
123
|
+
index = getTargetIndex({ key: e.key, currIndex: index, gridX, gridY, vGridY, length: items.length, loop, ctrlKey: e.ctrlKey, rtl });
|
|
124
|
+
attempts++;
|
|
125
|
+
}
|
|
126
|
+
return null;
|
|
127
|
+
};
|
|
128
|
+
const goToIndex = (targetIndex, e = { key: "ArrowRight" }) => {
|
|
129
|
+
if (shouldSnub()) return;
|
|
130
|
+
const idx = getAbleIndex(targetIndex, e);
|
|
131
|
+
if (idx === null) return;
|
|
132
|
+
resetActiveIndex(idx);
|
|
133
|
+
onSelect?.(items[idx], e), updateDOM();
|
|
134
|
+
if (virtual) {
|
|
135
|
+
items[idx]?.scrollIntoView(scrollIntoView);
|
|
136
|
+
container.setAttribute("aria-activedescendant", items[idx].id || "");
|
|
137
|
+
} else items[idx]?.focus(focusOptions);
|
|
138
|
+
};
|
|
139
|
+
const updateDOM = () => {
|
|
140
|
+
if (shouldSnub() || !virtual && !roving || !items.length) return;
|
|
141
|
+
const hasDefaultTabbable = defaultTabbableIndex !== null && defaultTabbableIndex !== void 0, tabbableIndex = hasDefaultTabbable && !isItemDisabled(items[defaultTabbableIndex]) ? defaultTabbableIndex : getAbleIndex(0);
|
|
142
|
+
for (let i = 0, len = items.length; i < len; i++) {
|
|
143
|
+
const el = items[i], isActive = i === activeIndex;
|
|
144
|
+
if (roving) el.setAttribute("tabindex", i === activeIndex || activeIndex === -1 && i === tabbableIndex ? baseTabIndex : "-1");
|
|
145
|
+
else if (virtual && activeIndex > 0) el.setAttribute("tabindex", i > activeIndex ? baseTabIndex : "-1");
|
|
146
|
+
else el.setAttribute("tabindex", baseTabIndex);
|
|
147
|
+
if (virtual) el.setAttribute("aria-selected", String(isActive)), el.classList.toggle(activeClass, isActive);
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
const resetActiveIndex = (index = -1) => (activeIndex = index, updateDOM());
|
|
151
|
+
const typeAhead = (key) => {
|
|
152
|
+
if (shouldSnub() || !typeahead) return;
|
|
153
|
+
buffer += key.toLowerCase();
|
|
154
|
+
if (timeout) clearTimeout(timeout);
|
|
155
|
+
timeout = setTimeout(() => buffer = "", resetMs);
|
|
156
|
+
const start = activeIndex >= 0 ? activeIndex + 1 : 0;
|
|
157
|
+
for (let i = 0; i < items.length; i++) {
|
|
158
|
+
const idx = (start + i) % items.length, label = (items[idx].getAttribute("data-label") || items[idx].innerText || "").trim().toLowerCase();
|
|
159
|
+
if (label.startsWith(buffer)) return goToIndex(idx);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
const simulateKey = (e) => {
|
|
163
|
+
const t = e.target;
|
|
164
|
+
if (shouldSnub() || getActiveEl(t?.ownerDocument)?.matches("option")) return;
|
|
165
|
+
const { key } = e;
|
|
166
|
+
if (!items.length) return;
|
|
167
|
+
if (virtual && (key === " " || key === "Enter")) return items[activeIndex]?.click();
|
|
168
|
+
if (t?.matches(DEFAULT_CONFIG.inputSelector) && !virtual) return;
|
|
169
|
+
if (typeahead && key.length === 1 && /^[a-z0-9]$/i.test(key)) return typeAhead(key);
|
|
170
|
+
if (!NAV_KEYS.includes(key)) return;
|
|
171
|
+
if (!(e.currentTarget?.matches(DEFAULT_CONFIG.inputSelector) && gridX <= 1 && H_NAV_KEYS.includes(key))) e.preventDefault?.(), e.stopPropagation?.();
|
|
172
|
+
const currIndex = virtual ? activeIndex : items.indexOf(getActiveEl(t?.ownerDocument)), targetIndex = getTargetIndex({ currIndex, gridX, gridY, vGridY, length: items.length, loop, rtl, key, ctrlKey: e.ctrlKey });
|
|
173
|
+
goToIndex(targetIndex, e);
|
|
174
|
+
};
|
|
175
|
+
getItems(), updateDOM();
|
|
176
|
+
const interactiveEls = !virtual ? [container] : [container.querySelector(inputSelector)];
|
|
177
|
+
for (const el of interactiveEls) el?.addEventListener("keydown", simulateKey);
|
|
178
|
+
const handleFocusOut = (e) => {
|
|
179
|
+
if (!container.contains(e.relatedTarget)) return resetActiveIndex(), updateDOM(), onFocusOut?.(e);
|
|
180
|
+
const among = items.includes(e.relatedTarget);
|
|
181
|
+
if (!among && (defaultTabbableIndex ?? -1) >= 0) return resetActiveIndex(), updateDOM();
|
|
182
|
+
if (virtual) resetActiveIndex(), updateDOM();
|
|
183
|
+
};
|
|
184
|
+
container.addEventListener("focusout", handleFocusOut);
|
|
185
|
+
const handleHover = (e) => {
|
|
186
|
+
if (!enabled || !focusOnHover) return;
|
|
187
|
+
const el = e.currentTarget, idx = items.indexOf(el);
|
|
188
|
+
if (idx !== -1) goToIndex(idx);
|
|
189
|
+
};
|
|
190
|
+
for (const el of items) el.addEventListener("mouseenter", handleHover);
|
|
191
|
+
const mutationObserver = new MutationObserver(() => {
|
|
192
|
+
const oldEl = items[activeIndex];
|
|
193
|
+
getItems();
|
|
194
|
+
const newEl = items[activeIndex];
|
|
195
|
+
updateDOM();
|
|
196
|
+
if (oldEl && newEl && oldEl === newEl) return;
|
|
197
|
+
resetActiveIndex();
|
|
198
|
+
updateDOM();
|
|
199
|
+
});
|
|
200
|
+
mutationObserver.observe(container, { childList: true, subtree: true });
|
|
201
|
+
const setGrid = (g) => {
|
|
202
|
+
if (g.x !== void 0) gridX = g.x;
|
|
203
|
+
if (g.y !== void 0) gridY = g.y;
|
|
204
|
+
if (g.vY !== void 0) vGridY = g.vY;
|
|
205
|
+
};
|
|
206
|
+
const calcGrid = () => setGrid(getGrid(items, !grid.x, !grid.y, !grid.vY));
|
|
207
|
+
setGrid(grid), calcGrid();
|
|
208
|
+
const ancestor = items.length > 1 ? getCommonAncestor(items[0], items[1]) : container;
|
|
209
|
+
const resizeObserver = new ResizeObserver(calcGrid);
|
|
210
|
+
if (ancestor) resizeObserver.observe(ancestor);
|
|
211
|
+
const destroy = () => {
|
|
212
|
+
for (const el of interactiveEls) el?.removeEventListener("keydown", simulateKey);
|
|
213
|
+
container.removeEventListener("focusout", handleFocusOut);
|
|
214
|
+
for (const el of items) el.removeEventListener("mouseenter", handleHover);
|
|
215
|
+
mutationObserver.disconnect(), resizeObserver.disconnect();
|
|
216
|
+
if (timeout) clearTimeout(timeout);
|
|
217
|
+
};
|
|
218
|
+
const handle = { gridX: () => gridX, gridY: () => gridY, vGridY: () => vGridY, items: () => items, activeIndex: () => activeIndex, activeItem: () => items[activeIndex] ?? null, getAbleIndex, typeAhead, goToIndex, simulateKey, destroy };
|
|
219
|
+
return t007._arrownavs.set(container, handle), handle;
|
|
220
|
+
}
|
|
221
|
+
var removeArrowNavigation = (container) => t007._arrownavs?.get(container)?.destroy();
|
|
222
|
+
export {
|
|
223
|
+
initArrowNavigation,
|
|
224
|
+
initFocusTrap,
|
|
225
|
+
initOutsideClick,
|
|
226
|
+
initScrollAssist,
|
|
227
|
+
initVScrollerator,
|
|
228
|
+
removeArrowNavigation,
|
|
229
|
+
removeFocusTrap,
|
|
230
|
+
removeOutsideClick,
|
|
231
|
+
removeScrollAssist,
|
|
232
|
+
rippleHandler
|
|
233
|
+
};
|
package/dist/index.cjs
CHANGED
|
@@ -20,53 +20,63 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
INTERACTIVE_SELECTOR: () => INTERACTIVE_SELECTOR,
|
|
24
|
+
NIL: () => import_sia_reactor.NIL,
|
|
25
|
+
NOOP: () => import_sia_reactor.NOOP,
|
|
23
26
|
VIRTUAL_RESOURCE: () => VIRTUAL_RESOURCE,
|
|
24
27
|
assignEl: () => import_utils.assignEl,
|
|
25
|
-
bindAllMethods: () =>
|
|
28
|
+
bindAllMethods: () => import_utils7.bindAllMethods,
|
|
26
29
|
bindCleanupToSignal: () => bindCleanupToSignal,
|
|
27
30
|
breath: () => breath,
|
|
28
|
-
clamp: () =>
|
|
29
|
-
cleanKeyCombo: () =>
|
|
31
|
+
clamp: () => import_utils4.clamp,
|
|
32
|
+
cleanKeyCombo: () => import_utils6.cleanKeyCombo,
|
|
30
33
|
createEl: () => import_utils.createEl,
|
|
31
34
|
deepBreath: () => deepBreath,
|
|
32
|
-
formatKeyForDisplay: () =>
|
|
33
|
-
formatKeyShortcutsForDisplay: () =>
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
formatKeyForDisplay: () => import_utils6.formatKeyForDisplay,
|
|
36
|
+
formatKeyShortcutsForDisplay: () => import_utils6.formatKeyShortcutsForDisplay,
|
|
37
|
+
formatSize: () => formatSize,
|
|
38
|
+
getActiveEl: () => import_utils2.getActiveEl,
|
|
39
|
+
getTermsForKey: () => import_utils6.getTermsForKey,
|
|
40
|
+
guardAllMethods: () => import_utils7.guardAllMethods,
|
|
41
|
+
guardMethod: () => import_utils7.guardMethod,
|
|
37
42
|
inBoolArrOpt: () => inBoolArrOpt,
|
|
38
|
-
initScrollAssist: () => initScrollAssist,
|
|
39
|
-
initVScrollerator: () => initVScrollerator,
|
|
40
43
|
isArr: () => isArr,
|
|
41
44
|
isBool: () => isBool,
|
|
42
45
|
isDef: () => isDef,
|
|
43
46
|
isFunc: () => isFunc,
|
|
47
|
+
isInteractive: () => isInteractive,
|
|
44
48
|
isIter: () => isIter,
|
|
45
49
|
isNum: () => isNum,
|
|
46
|
-
isObj: () =>
|
|
50
|
+
isObj: () => import_utils3.isObj,
|
|
47
51
|
isPOJO: () => isPOJO,
|
|
48
52
|
isSameURL: () => isSameURL,
|
|
49
53
|
isStr: () => isStr,
|
|
50
54
|
isSym: () => isSym,
|
|
51
|
-
keyEventAllowed: () =>
|
|
55
|
+
keyEventAllowed: () => import_utils6.keyEventAllowed,
|
|
52
56
|
limited: () => limited,
|
|
53
57
|
loadResource: () => loadResource,
|
|
54
|
-
matchKeys: () =>
|
|
58
|
+
matchKeys: () => import_utils6.matchKeys,
|
|
55
59
|
mockAsync: () => mockAsync,
|
|
56
|
-
onAllMethods: () =>
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
onAllMethods: () => import_utils7.onAllMethods,
|
|
61
|
+
parseCSSSize: () => parseCSSSize,
|
|
62
|
+
parseCSSTime: () => parseCSSTime,
|
|
63
|
+
parseForARIAKS: () => import_utils6.parseForARIAKS,
|
|
64
|
+
parseKeyCombo: () => import_utils6.parseKeyCombo,
|
|
65
|
+
pxToRem: () => pxToRem,
|
|
66
|
+
remToPx: () => remToPx,
|
|
67
|
+
requestAnimationFrame: () => import_utils5.requestAnimationFrame,
|
|
68
|
+
setInterval: () => import_utils5.setInterval,
|
|
69
|
+
setTimeout: () => import_utils5.setTimeout,
|
|
70
|
+
stringifyKeyEvent: () => import_utils6.stringifyKeyEvent,
|
|
64
71
|
uid: () => uid
|
|
65
72
|
});
|
|
66
73
|
module.exports = __toCommonJS(index_exports);
|
|
67
74
|
|
|
68
75
|
// src/core/dom.ts
|
|
69
76
|
var import_utils = require("sia-reactor/utils");
|
|
77
|
+
var import_utils2 = require("sia-reactor/utils");
|
|
78
|
+
var INTERACTIVE_SELECTOR = ":is(button,[href],input:not([type='hidden']),select,textarea,details>summary,[contenteditable='true'],iframe,audio[controls],video[controls],[tabindex]):not([disabled],[tabindex='-1'],[data-focus-guard],[inert],[inert] *)";
|
|
79
|
+
var isInteractive = (target) => target instanceof HTMLElement && target.matches(INTERACTIVE_SELECTOR);
|
|
70
80
|
var VIRTUAL_RESOURCE = /* @__PURE__ */ Symbol.for("T007_VIRTUAL_RESOURCE");
|
|
71
81
|
function loadResource(req, type = "style", { module: module2, media, crossOrigin, integrity, referrerPolicy, nonce, fetchPriority, attempts = 3, retryKey = false } = {}, w = window) {
|
|
72
82
|
w.t007 ??= {}, w.t007._resourceCache ??= {};
|
|
@@ -96,8 +106,11 @@ function loadResource(req, type = "style", { module: module2, media, crossOrigin
|
|
|
96
106
|
return w.t007._resourceCache[src];
|
|
97
107
|
}
|
|
98
108
|
|
|
109
|
+
// src/index.ts
|
|
110
|
+
var import_sia_reactor = require("sia-reactor");
|
|
111
|
+
|
|
99
112
|
// src/core/obj.ts
|
|
100
|
-
var
|
|
113
|
+
var import_utils3 = require("sia-reactor/utils");
|
|
101
114
|
function isDef(val) {
|
|
102
115
|
return "undefined" !== typeof val;
|
|
103
116
|
}
|
|
@@ -117,7 +130,7 @@ function isArr(obj) {
|
|
|
117
130
|
return Array.isArray(obj);
|
|
118
131
|
}
|
|
119
132
|
function isPOJO(obj, crossRealms = false, typecheck = true) {
|
|
120
|
-
return (typecheck ? (0,
|
|
133
|
+
return (typecheck ? (0, import_utils3.isObj)(obj, false) : true) && (crossRealms ? Object.prototype.toString.call(obj) === "[object Object]" : obj.constructor === Object);
|
|
121
134
|
}
|
|
122
135
|
function isIter(obj) {
|
|
123
136
|
return obj != null && "function" === typeof obj[Symbol.iterator];
|
|
@@ -130,12 +143,24 @@ function inBoolArrOpt(opt, str) {
|
|
|
130
143
|
}
|
|
131
144
|
|
|
132
145
|
// src/core/num.ts
|
|
133
|
-
var
|
|
146
|
+
var import_utils4 = require("sia-reactor/utils");
|
|
134
147
|
|
|
135
148
|
// src/core/str.ts
|
|
136
149
|
function uid(prefix = "") {
|
|
137
150
|
return prefix + Date.now().toString(36) + "_" + performance.now().toString(36).replace(".", "") + "_" + Math.random().toString(36).slice(2);
|
|
138
151
|
}
|
|
152
|
+
function remToPx(rem, el = document.documentElement) {
|
|
153
|
+
return rem * parseFloat(getComputedStyle(el).fontSize);
|
|
154
|
+
}
|
|
155
|
+
function pxToRem(px, el = document.documentElement) {
|
|
156
|
+
return px / parseFloat(getComputedStyle(el).fontSize);
|
|
157
|
+
}
|
|
158
|
+
function parseCSSTime(time) {
|
|
159
|
+
return time?.endsWith?.("ms") ? parseFloat(time) : parseFloat(time) * 1e3;
|
|
160
|
+
}
|
|
161
|
+
function parseCSSSize(size, el) {
|
|
162
|
+
return size?.endsWith?.("px") ? parseFloat(size) : remToPx(parseFloat(size), el);
|
|
163
|
+
}
|
|
139
164
|
function isSameURL(src1, src2) {
|
|
140
165
|
if (!isStr(src1) || !isStr(src2) || !src1 || !src2) return false;
|
|
141
166
|
try {
|
|
@@ -147,7 +172,7 @@ function isSameURL(src1, src2) {
|
|
|
147
172
|
}
|
|
148
173
|
|
|
149
174
|
// src/core/fn.ts
|
|
150
|
-
var
|
|
175
|
+
var import_utils5 = require("sia-reactor/utils");
|
|
151
176
|
function limited(FN_KEY, fn, opts = {}) {
|
|
152
177
|
let count = 0, { key, maxTimes: max = 1 } = isStr(opts) ? { key: opts } : opts;
|
|
153
178
|
const getReg = () => JSON.parse(localStorage.getItem(FN_KEY) || "{}"), setReg = (r) => localStorage.setItem(FN_KEY, JSON.stringify(r));
|
|
@@ -171,103 +196,21 @@ function bindCleanupToSignal(cleanup, signal) {
|
|
|
171
196
|
}
|
|
172
197
|
|
|
173
198
|
// src/core/keys.ts
|
|
174
|
-
var import_utils5 = require("sia-reactor/utils");
|
|
175
|
-
|
|
176
|
-
// src/mixins/methd.ts
|
|
177
199
|
var import_utils6 = require("sia-reactor/utils");
|
|
178
200
|
|
|
179
|
-
// src/
|
|
180
|
-
function
|
|
181
|
-
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
const now = performance.now(), speed = linesPerSec * lineHeight * ((lastTime ? now - lastTime : baseRate) / 1e3);
|
|
185
|
-
if (!brake && (clientY < margin || clientY > (car.innerHeight ?? car.offsetHeight) - margin)) {
|
|
186
|
-
accelId === null ? accelId = setTimeout(() => linesPerSec += 1, stepDelay) : linesPerSec > baseSpeed && (linesPerSec = Math.min(linesPerSec + 1, maxSpeed));
|
|
187
|
-
car.scrollBy?.(0, clientY < margin ? -speed : speed);
|
|
188
|
-
} else reset();
|
|
189
|
-
return lastTime = !brake ? now : null, speed;
|
|
190
|
-
};
|
|
191
|
-
const reset = () => (accelId && clearTimeout(accelId), accelId = null, linesPerSec = baseSpeed, lastTime = null);
|
|
192
|
-
return { drive, reset };
|
|
193
|
-
}
|
|
194
|
-
function initScrollAssist(el, { pxPerSecond = 80, assistClassName = "t007-scroll-assist", vertical = true, horizontal = true } = {}) {
|
|
195
|
-
t007._scrollers ??= /* @__PURE__ */ new WeakMap();
|
|
196
|
-
t007._scroller_r_observer ??= new ResizeObserver((entries) => entries.forEach(({ target }) => t007._scrollers.get(target)?.update()));
|
|
197
|
-
t007._scroller_m_observer ??= new MutationObserver((entries) => {
|
|
198
|
-
const els = /* @__PURE__ */ new Set();
|
|
199
|
-
for (const entry of entries) {
|
|
200
|
-
let node = entry.target instanceof Element ? entry.target : null;
|
|
201
|
-
while (node && !t007._scrollers.has(node)) node = node.parentElement;
|
|
202
|
-
if (node) els.add(node);
|
|
203
|
-
}
|
|
204
|
-
for (const el2 of els) t007._scrollers.get(el2)?.update();
|
|
205
|
-
});
|
|
206
|
-
const parent = el?.parentElement;
|
|
207
|
-
if (!parent || t007._scrollers.has(el)) return;
|
|
208
|
-
const assist = {};
|
|
209
|
-
let scrollId = null, last = performance.now(), assistWidth = 20, assistHeight = 20;
|
|
210
|
-
const update = () => {
|
|
211
|
-
const hasInteractive = !!parent.querySelector('button, a[href], input, select, textarea, [contenteditable="true"], [tabindex]:not([tabindex="-1"])');
|
|
212
|
-
if (horizontal) {
|
|
213
|
-
const w = assist.left?.offsetWidth || assistWidth, check = hasInteractive ? el.clientWidth < w * 2 : false;
|
|
214
|
-
assist.left.style.display = check ? "none" : el.scrollLeft > 0 ? "block" : "none";
|
|
215
|
-
assist.right.style.display = check ? "none" : el.scrollLeft + el.clientWidth < el.scrollWidth - 1 ? "block" : "none";
|
|
216
|
-
assistWidth = w;
|
|
217
|
-
}
|
|
218
|
-
if (vertical) {
|
|
219
|
-
const h = assist.up?.offsetHeight || assistHeight, check = hasInteractive ? el.clientHeight < h * 2 : false;
|
|
220
|
-
assist.up.style.display = check ? "none" : el.scrollTop > 0 ? "block" : "none";
|
|
221
|
-
assist.down.style.display = check ? "none" : el.scrollTop + el.clientHeight < el.scrollHeight - 1 ? "block" : "none";
|
|
222
|
-
assistHeight = h;
|
|
223
|
-
}
|
|
224
|
-
};
|
|
225
|
-
const scroll = (dir) => {
|
|
226
|
-
const frame = () => {
|
|
227
|
-
const now = performance.now(), dt = now - last;
|
|
228
|
-
last = now;
|
|
229
|
-
const d = pxPerSecond * dt / 1e3;
|
|
230
|
-
if (dir === "left") el.scrollLeft = Math.max(0, el.scrollLeft - d);
|
|
231
|
-
if (dir === "right") el.scrollLeft = Math.min(el.scrollWidth - el.clientWidth, el.scrollLeft + d);
|
|
232
|
-
if (dir === "up") el.scrollTop = Math.max(0, el.scrollTop - d);
|
|
233
|
-
if (dir === "down") el.scrollTop = Math.min(el.scrollHeight - el.clientHeight, el.scrollTop + d);
|
|
234
|
-
scrollId = requestAnimationFrame(frame);
|
|
235
|
-
};
|
|
236
|
-
last = performance.now();
|
|
237
|
-
frame();
|
|
238
|
-
};
|
|
239
|
-
const stop = () => (cancelAnimationFrame(scrollId ?? 0), scrollId = null);
|
|
240
|
-
const addAssist = (dir) => {
|
|
241
|
-
const div = (0, import_utils.createEl)("div", { className: assistClassName }, { scrollDirection: dir }, { display: "none" });
|
|
242
|
-
if (!div) return;
|
|
243
|
-
["pointerenter", "dragenter"].forEach((evt) => div.addEventListener(evt, () => scroll(dir)));
|
|
244
|
-
["pointerleave", "pointerup", "pointercancel", "dragleave", "dragend"].forEach((evt) => div.addEventListener(evt, stop));
|
|
245
|
-
dir === "left" || dir === "up" ? parent.insertBefore(div, el) : parent.append(div);
|
|
246
|
-
assist[dir] = div;
|
|
247
|
-
};
|
|
248
|
-
if (horizontal) ["left", "right"].forEach(addAssist);
|
|
249
|
-
if (vertical) ["up", "down"].forEach(addAssist);
|
|
250
|
-
el.addEventListener("scroll", update);
|
|
251
|
-
t007._scroller_r_observer.observe(el);
|
|
252
|
-
t007._scroller_m_observer.observe(el, { childList: true, subtree: true, characterData: true });
|
|
253
|
-
t007._scrollers.set(el, {
|
|
254
|
-
update,
|
|
255
|
-
destroy() {
|
|
256
|
-
stop();
|
|
257
|
-
el.removeEventListener("scroll", update);
|
|
258
|
-
t007._scroller_r_observer.unobserve(el);
|
|
259
|
-
t007._scrollers.delete(el);
|
|
260
|
-
Object.values(assist).forEach((a) => a.remove());
|
|
261
|
-
}
|
|
262
|
-
});
|
|
263
|
-
return update(), t007._scrollers.get(el);
|
|
201
|
+
// src/core/file.ts
|
|
202
|
+
function formatSize(bytes, decimals = 3, base = 1e3) {
|
|
203
|
+
if (bytes < base) return `${bytes} byte${bytes == 1 ? "" : "s"}`;
|
|
204
|
+
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);
|
|
205
|
+
return `${(bytes / Math.pow(base, exponent)).toFixed(decimals).replace(/\.0+$/, "")} ${units[exponent]}`;
|
|
264
206
|
}
|
|
265
|
-
|
|
207
|
+
|
|
208
|
+
// src/mixins/methd.ts
|
|
209
|
+
var import_utils7 = require("sia-reactor/utils");
|
|
266
210
|
|
|
267
211
|
// src/index.ts
|
|
268
212
|
if ("undefined" !== typeof window) {
|
|
269
|
-
window.t007 ??= {};
|
|
270
|
-
t007.VIRTUAL_RESOURCE = VIRTUAL_RESOURCE;
|
|
213
|
+
(window.t007 ??= {}).VIRTUAL_RESOURCE = VIRTUAL_RESOURCE;
|
|
271
214
|
window.T007_TOAST_JS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/toast@latest`;
|
|
272
215
|
window.T007_INPUT_JS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/input@latest`;
|
|
273
216
|
window.T007_DIALOG_JS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/dialog@latest`;
|
|
@@ -277,6 +220,9 @@ if ("undefined" !== typeof window) {
|
|
|
277
220
|
}
|
|
278
221
|
// Annotate the CommonJS export names for ESM import in node:
|
|
279
222
|
0 && (module.exports = {
|
|
223
|
+
INTERACTIVE_SELECTOR,
|
|
224
|
+
NIL,
|
|
225
|
+
NOOP,
|
|
280
226
|
VIRTUAL_RESOURCE,
|
|
281
227
|
assignEl,
|
|
282
228
|
bindAllMethods,
|
|
@@ -288,16 +234,17 @@ if ("undefined" !== typeof window) {
|
|
|
288
234
|
deepBreath,
|
|
289
235
|
formatKeyForDisplay,
|
|
290
236
|
formatKeyShortcutsForDisplay,
|
|
237
|
+
formatSize,
|
|
238
|
+
getActiveEl,
|
|
291
239
|
getTermsForKey,
|
|
292
240
|
guardAllMethods,
|
|
293
241
|
guardMethod,
|
|
294
242
|
inBoolArrOpt,
|
|
295
|
-
initScrollAssist,
|
|
296
|
-
initVScrollerator,
|
|
297
243
|
isArr,
|
|
298
244
|
isBool,
|
|
299
245
|
isDef,
|
|
300
246
|
isFunc,
|
|
247
|
+
isInteractive,
|
|
301
248
|
isIter,
|
|
302
249
|
isNum,
|
|
303
250
|
isObj,
|
|
@@ -311,9 +258,12 @@ if ("undefined" !== typeof window) {
|
|
|
311
258
|
matchKeys,
|
|
312
259
|
mockAsync,
|
|
313
260
|
onAllMethods,
|
|
261
|
+
parseCSSSize,
|
|
262
|
+
parseCSSTime,
|
|
314
263
|
parseForARIAKS,
|
|
315
264
|
parseKeyCombo,
|
|
316
|
-
|
|
265
|
+
pxToRem,
|
|
266
|
+
remToPx,
|
|
317
267
|
requestAnimationFrame,
|
|
318
268
|
setInterval,
|
|
319
269
|
setTimeout,
|