@lightningtv/solid 3.0.0-2 → 3.0.0-21
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/LICENSE +1 -1
- package/README.md +6 -0
- package/dist/src/activeElement.d.ts +1 -1
- package/dist/src/core/animation.d.ts +35 -0
- package/dist/src/core/animation.js +120 -0
- package/dist/src/core/animation.js.map +1 -0
- package/dist/src/core/config.d.ts +47 -0
- package/dist/src/core/config.js +23 -0
- package/dist/src/core/config.js.map +1 -0
- package/dist/src/core/domRenderer.d.ts +117 -0
- package/dist/src/core/domRenderer.js +1160 -0
- package/dist/src/core/domRenderer.js.map +1 -0
- package/dist/src/core/elementNode.d.ts +209 -0
- package/dist/src/core/elementNode.js +829 -0
- package/dist/src/core/elementNode.js.map +1 -0
- package/dist/src/core/flex.d.ts +2 -0
- package/dist/src/core/flex.js +243 -0
- package/dist/src/core/flex.js.map +1 -0
- package/dist/src/core/focusKeyTypes.d.ts +42 -0
- package/dist/src/core/focusKeyTypes.js +2 -0
- package/dist/src/core/focusKeyTypes.js.map +1 -0
- package/dist/src/core/focusManager.d.ts +13 -0
- package/dist/src/core/focusManager.js +269 -0
- package/dist/src/core/focusManager.js.map +1 -0
- package/dist/src/core/index.d.ts +12 -0
- package/dist/src/core/index.js +12 -0
- package/dist/src/core/index.js.map +1 -0
- package/dist/src/core/intrinsicTypes.d.ts +90 -0
- package/dist/src/core/intrinsicTypes.js +2 -0
- package/dist/src/core/intrinsicTypes.js.map +1 -0
- package/dist/src/core/lightningInit.d.ts +89 -0
- package/dist/src/core/lightningInit.js +26 -0
- package/dist/src/core/lightningInit.js.map +1 -0
- package/dist/src/core/nodeTypes.d.ts +6 -0
- package/dist/src/core/nodeTypes.js +6 -0
- package/dist/src/core/nodeTypes.js.map +1 -0
- package/dist/src/core/shaders.d.ts +51 -0
- package/dist/src/core/shaders.js +446 -0
- package/dist/src/core/shaders.js.map +1 -0
- package/dist/src/core/states.d.ts +12 -0
- package/dist/src/core/states.js +84 -0
- package/dist/src/core/states.js.map +1 -0
- package/dist/src/core/timings.d.ts +36 -0
- package/dist/src/core/timings.js +199 -0
- package/dist/src/core/timings.js.map +1 -0
- package/dist/src/core/utils.d.ts +39 -0
- package/dist/src/core/utils.js +164 -0
- package/dist/src/core/utils.js.map +1 -0
- package/dist/src/devtools/index.d.ts +1 -1
- package/dist/src/devtools/index.js +1 -1
- package/dist/src/devtools/index.js.map +1 -1
- package/dist/src/index.d.ts +3 -3
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/jsx-runtime.d.ts +1 -3
- package/dist/src/primitives/Column.jsx +9 -10
- package/dist/src/primitives/Column.jsx.map +1 -1
- package/dist/src/primitives/FPSCounter.jsx +14 -1
- package/dist/src/primitives/FPSCounter.jsx.map +1 -1
- package/dist/src/primitives/Grid.d.ts +15 -6
- package/dist/src/primitives/Grid.jsx +35 -22
- package/dist/src/primitives/Grid.jsx.map +1 -1
- package/dist/src/primitives/Image.d.ts +8 -0
- package/dist/src/primitives/Image.jsx +24 -0
- package/dist/src/primitives/Image.jsx.map +1 -0
- package/dist/src/primitives/KeepAlive.d.ts +30 -0
- package/dist/src/primitives/KeepAlive.jsx +77 -0
- package/dist/src/primitives/KeepAlive.jsx.map +1 -0
- package/dist/src/primitives/Lazy.d.ts +8 -7
- package/dist/src/primitives/Lazy.jsx +52 -23
- package/dist/src/primitives/Lazy.jsx.map +1 -1
- package/dist/src/primitives/Marquee.d.ts +64 -0
- package/dist/src/primitives/Marquee.jsx +86 -0
- package/dist/src/primitives/Marquee.jsx.map +1 -0
- package/dist/src/primitives/Preserve.d.ts +4 -0
- package/dist/src/primitives/Preserve.jsx +11 -0
- package/dist/src/primitives/Preserve.jsx.map +1 -0
- package/dist/src/primitives/Row.jsx +9 -10
- package/dist/src/primitives/Row.jsx.map +1 -1
- package/dist/src/primitives/Suspense.d.ts +22 -0
- package/dist/src/primitives/Suspense.jsx +33 -0
- package/dist/src/primitives/Suspense.jsx.map +1 -0
- package/dist/src/primitives/Virtual.d.ts +18 -0
- package/dist/src/primitives/Virtual.jsx +434 -0
- package/dist/src/primitives/Virtual.jsx.map +1 -0
- package/dist/src/primitives/VirtualGrid.d.ts +13 -0
- package/dist/src/primitives/VirtualGrid.jsx +160 -0
- package/dist/src/primitives/VirtualGrid.jsx.map +1 -0
- package/dist/src/primitives/VirtualList.d.ts +11 -0
- package/dist/src/primitives/VirtualList.jsx +96 -0
- package/dist/src/primitives/VirtualList.jsx.map +1 -0
- package/dist/src/primitives/VirtualRow.d.ts +13 -0
- package/dist/src/primitives/VirtualRow.jsx +97 -0
- package/dist/src/primitives/VirtualRow.jsx.map +1 -0
- package/dist/src/primitives/Visible.d.ts +0 -1
- package/dist/src/primitives/Visible.jsx +1 -1
- package/dist/src/primitives/Visible.jsx.map +1 -1
- package/dist/src/primitives/announcer/announcer.d.ts +2 -0
- package/dist/src/primitives/announcer/announcer.js +7 -5
- package/dist/src/primitives/announcer/announcer.js.map +1 -1
- package/dist/src/primitives/announcer/index.d.ts +5 -1
- package/dist/src/primitives/announcer/index.js +8 -2
- package/dist/src/primitives/announcer/index.js.map +1 -1
- package/dist/src/primitives/announcer/speech.d.ts +2 -2
- package/dist/src/primitives/announcer/speech.js +157 -28
- package/dist/src/primitives/announcer/speech.js.map +1 -1
- package/dist/src/primitives/createFocusStack.d.ts +4 -4
- package/dist/src/primitives/createFocusStack.jsx +15 -6
- package/dist/src/primitives/createFocusStack.jsx.map +1 -1
- package/dist/src/primitives/createTag.d.ts +8 -0
- package/dist/src/primitives/createTag.jsx +20 -0
- package/dist/src/primitives/createTag.jsx.map +1 -0
- package/dist/src/primitives/index.d.ts +14 -4
- package/dist/src/primitives/index.js +13 -3
- package/dist/src/primitives/index.js.map +1 -1
- package/dist/src/primitives/types.d.ts +5 -2
- package/dist/src/primitives/useFocusManager.d.ts +2 -2
- package/dist/src/primitives/useFocusManager.js +2 -2
- package/dist/src/primitives/useFocusManager.js.map +1 -1
- package/dist/src/primitives/useHold.d.ts +27 -0
- package/dist/src/primitives/useHold.js +54 -0
- package/dist/src/primitives/useHold.js.map +1 -0
- package/dist/src/primitives/useMouse.d.ts +18 -2
- package/dist/src/primitives/useMouse.js +171 -47
- package/dist/src/primitives/useMouse.js.map +1 -1
- package/dist/src/primitives/utils/chainFunctions.d.ts +30 -4
- package/dist/src/primitives/utils/chainFunctions.js +14 -3
- package/dist/src/primitives/utils/chainFunctions.js.map +1 -1
- package/dist/src/primitives/utils/createBlurredImage.d.ts +56 -0
- package/dist/src/primitives/utils/createBlurredImage.js +223 -0
- package/dist/src/primitives/utils/createBlurredImage.js.map +1 -0
- package/dist/src/primitives/utils/createSpriteMap.d.ts +2 -2
- package/dist/src/primitives/utils/createSpriteMap.js +1 -1
- package/dist/src/primitives/utils/createSpriteMap.js.map +1 -1
- package/dist/src/primitives/utils/handleNavigation.d.ts +79 -5
- package/dist/src/primitives/utils/handleNavigation.js +242 -69
- package/dist/src/primitives/utils/handleNavigation.js.map +1 -1
- package/dist/src/primitives/utils/withScrolling.d.ts +14 -2
- package/dist/src/primitives/utils/withScrolling.js +66 -7
- package/dist/src/primitives/utils/withScrolling.js.map +1 -1
- package/dist/src/render.d.ts +8 -7
- package/dist/src/render.js +5 -1
- package/dist/src/render.js.map +1 -1
- package/dist/src/solidOpts.d.ts +1 -7
- package/dist/src/solidOpts.js +32 -16
- package/dist/src/solidOpts.js.map +1 -1
- package/dist/src/types.d.ts +1 -13
- package/dist/src/universal.d.ts +25 -0
- package/dist/src/universal.js +232 -0
- package/dist/src/universal.js.map +1 -0
- package/dist/src/utils.d.ts +3 -1
- package/dist/src/utils.js +9 -1
- package/dist/src/utils.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/jsx-runtime.d.ts +2 -4
- package/package.json +17 -15
- package/src/activeElement.ts +1 -1
- package/src/core/animation.ts +183 -0
- package/src/core/config.ts +77 -0
- package/src/core/domRenderer.ts +1308 -0
- package/src/core/elementNode.ts +1198 -0
- package/src/core/flex.ts +284 -0
- package/src/core/focusKeyTypes.ts +87 -0
- package/src/core/focusManager.ts +359 -0
- package/src/core/index.ts +13 -0
- package/src/core/intrinsicTypes.ts +199 -0
- package/src/core/lightningInit.ts +147 -0
- package/src/core/nodeTypes.ts +6 -0
- package/src/core/shaders.ts +567 -0
- package/src/core/states.ts +91 -0
- package/src/core/timings.ts +261 -0
- package/src/core/utils.ts +222 -0
- package/src/devtools/index.ts +1 -1
- package/src/index.ts +3 -3
- package/src/primitives/Column.tsx +10 -12
- package/src/primitives/FPSCounter.tsx +15 -1
- package/src/primitives/Grid.tsx +57 -33
- package/src/primitives/Image.tsx +36 -0
- package/src/primitives/KeepAlive.tsx +124 -0
- package/src/primitives/Lazy.tsx +66 -37
- package/src/primitives/Marquee.tsx +149 -0
- package/src/primitives/Preserve.tsx +18 -0
- package/src/primitives/Row.tsx +13 -14
- package/src/primitives/Suspense.tsx +39 -0
- package/src/primitives/Virtual.tsx +478 -0
- package/src/primitives/VirtualGrid.tsx +220 -0
- package/src/primitives/Visible.tsx +1 -2
- package/src/primitives/announcer/announcer.ts +16 -10
- package/src/primitives/announcer/index.ts +12 -2
- package/src/primitives/announcer/speech.ts +188 -27
- package/src/primitives/createFocusStack.tsx +18 -7
- package/src/primitives/createTag.tsx +31 -0
- package/src/primitives/index.ts +18 -4
- package/src/primitives/types.ts +12 -2
- package/src/primitives/useFocusManager.ts +3 -3
- package/src/primitives/useHold.ts +69 -0
- package/src/primitives/useMouse.ts +306 -67
- package/src/primitives/utils/chainFunctions.ts +40 -9
- package/src/primitives/utils/createBlurredImage.ts +366 -0
- package/src/primitives/utils/createSpriteMap.ts +6 -4
- package/src/primitives/utils/handleNavigation.ts +300 -84
- package/src/primitives/utils/withScrolling.ts +91 -18
- package/src/render.ts +10 -8
- package/src/solidOpts.ts +31 -24
- package/src/types.ts +1 -15
- package/src/utils.ts +11 -1
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
import { ElementNode, activeElement, isElementNode, isTextNode, rootNode,
|
|
1
|
+
import { Config, ElementNode, activeElement, isElementNode, isFunc, isTextNode, rootNode, } from '../index.js';
|
|
2
2
|
import { makeEventListener } from '@solid-primitives/event-listener';
|
|
3
3
|
import { useMousePosition } from '@solid-primitives/mouse';
|
|
4
4
|
import { createScheduled, throttle } from '@solid-primitives/scheduled';
|
|
5
|
-
import { createEffect } from 'solid-js';
|
|
5
|
+
import { createEffect, getOwner, runWithOwner } from 'solid-js';
|
|
6
|
+
export function addCustomStateToElement(element, state) {
|
|
7
|
+
element.states?.add(state);
|
|
8
|
+
}
|
|
9
|
+
export function removeCustomStateFromElement(element, state) {
|
|
10
|
+
element?.states?.remove(state);
|
|
11
|
+
}
|
|
12
|
+
export function hasCustomState(element, state) {
|
|
13
|
+
return element.states?.has(state);
|
|
14
|
+
}
|
|
6
15
|
function createKeyboardEvent(key, keyCode, eventName = 'keydown') {
|
|
7
16
|
return new KeyboardEvent(eventName, {
|
|
8
17
|
key,
|
|
@@ -15,6 +24,7 @@ function createKeyboardEvent(key, keyCode, eventName = 'keydown') {
|
|
|
15
24
|
bubbles: true,
|
|
16
25
|
});
|
|
17
26
|
}
|
|
27
|
+
let scrollTimeout;
|
|
18
28
|
const handleScroll = throttle((e) => {
|
|
19
29
|
const deltaY = e.deltaY;
|
|
20
30
|
if (deltaY < 0) {
|
|
@@ -23,19 +33,126 @@ const handleScroll = throttle((e) => {
|
|
|
23
33
|
else if (deltaY > 0) {
|
|
24
34
|
document.body.dispatchEvent(createKeyboardEvent('ArrowDown', 40));
|
|
25
35
|
}
|
|
36
|
+
// clear the last timeout if the user is still scrolling
|
|
37
|
+
clearTimeout(scrollTimeout);
|
|
38
|
+
// after 250ms of no scroll events, we send a keyup event to stop the scrolling
|
|
39
|
+
scrollTimeout = setTimeout(() => {
|
|
40
|
+
document.body.dispatchEvent(createKeyboardEvent('ArrowUp', 38, 'keyup'));
|
|
41
|
+
document.body.dispatchEvent(createKeyboardEvent('ArrowDown', 40, 'keyup'));
|
|
42
|
+
}, 250);
|
|
26
43
|
}, 250);
|
|
27
|
-
|
|
44
|
+
function findElementWithCustomState(myApp, x, y, customState) {
|
|
45
|
+
const result = getChildrenByPosition(myApp, x, y).filter((el) => hasCustomState(el, customState));
|
|
46
|
+
if (result.length === 0) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
let element = result[result.length - 1];
|
|
50
|
+
while (element) {
|
|
51
|
+
const elmParent = element.parent;
|
|
52
|
+
if (elmParent?.forwardStates && hasCustomState(elmParent, customState)) {
|
|
53
|
+
element = elmParent;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return element;
|
|
60
|
+
}
|
|
61
|
+
function findElementByActiveElement(e) {
|
|
28
62
|
const active = activeElement();
|
|
29
63
|
const precision = Config.rendererOptions?.deviceLogicalPixelRatio || 1;
|
|
30
64
|
if (active instanceof ElementNode &&
|
|
31
|
-
testCollision(e.clientX, e.clientY, active.lng.absX || 0 * precision, active.lng.absY || 0 * precision, active.width || 0 * precision, active.height || 0 * precision)) {
|
|
65
|
+
testCollision(e.clientX, e.clientY, (active.lng.absX || 0) * precision, (active.lng.absY || 0) * precision, (active.width || 0) * precision, (active.height || 0) * precision)) {
|
|
66
|
+
return active;
|
|
67
|
+
}
|
|
68
|
+
let parent = active?.parent;
|
|
69
|
+
while (parent) {
|
|
70
|
+
if (isFunc(parent.onMouseClick) &&
|
|
71
|
+
active &&
|
|
72
|
+
testCollision(e.clientX, e.clientY, (parent.lng.absX || 0) * precision, (parent.lng.absY || 0) * precision, (parent.width || 0) * precision, (parent.height || 0) * precision)) {
|
|
73
|
+
return parent;
|
|
74
|
+
}
|
|
75
|
+
parent = parent.parent;
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
function applyPressedState(element, pressedState) {
|
|
80
|
+
addCustomStateToElement(element, pressedState);
|
|
81
|
+
}
|
|
82
|
+
function handleElementClick(clickedElement, e, customStates, pressedElementRef) {
|
|
83
|
+
if (customStates?.pressedState && pressedElementRef?.current) {
|
|
84
|
+
removeCustomStateFromElement(pressedElementRef.current, customStates.pressedState);
|
|
85
|
+
pressedElementRef.current = null;
|
|
86
|
+
}
|
|
87
|
+
if (isFunc(clickedElement.onMouseClick)) {
|
|
88
|
+
clickedElement.onMouseClick(e, clickedElement);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
else if (isFunc(clickedElement.onEnter)) {
|
|
92
|
+
clickedElement.onEnter();
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
clickedElement.setFocus();
|
|
96
|
+
setTimeout(() => {
|
|
32
97
|
document.dispatchEvent(createKeyboardEvent('Enter', 13));
|
|
33
98
|
setTimeout(() => document.body.dispatchEvent(createKeyboardEvent('Enter', 13, 'keyup')), 1);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
99
|
+
}, 1);
|
|
100
|
+
}
|
|
101
|
+
function createHandleClick(myApp, customStates, pressedElementRef) {
|
|
102
|
+
return (e) => {
|
|
103
|
+
const clickedElement = customStates
|
|
104
|
+
? findElementWithCustomState(myApp, e.clientX, e.clientY, customStates.hoverState)
|
|
105
|
+
: findElementByActiveElement(e);
|
|
106
|
+
if (!clickedElement) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
handleElementClick(clickedElement, e, customStates, pressedElementRef);
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function createHandleMouseDown(myApp, customStates, pressedElementRef) {
|
|
113
|
+
return (e) => {
|
|
114
|
+
if (!customStates) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const pressedElement = findElementWithCustomState(myApp, e.clientX, e.clientY, customStates.hoverState);
|
|
118
|
+
if (!pressedElement) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
applyPressedState(pressedElement, customStates.pressedState);
|
|
122
|
+
if (pressedElementRef) {
|
|
123
|
+
pressedElementRef.current = pressedElement;
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
36
127
|
function testCollision(px, py, cx, cy, cw = 0, ch = 0) {
|
|
37
128
|
return px >= cx && px <= cx + cw && py >= cy && py <= cy + ch;
|
|
38
129
|
}
|
|
130
|
+
function isNodeAtPosition(node, x, y, precision) {
|
|
131
|
+
if (!isElementNode(node)) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
return (node.alpha !== 0 &&
|
|
135
|
+
!node.skipFocus &&
|
|
136
|
+
testCollision(x, y, (node.lng.absX || 0) * precision, (node.lng.absY || 0) * precision, (node.width || 0) * precision, (node.height || 0) * precision));
|
|
137
|
+
}
|
|
138
|
+
function findHighestZIndexNode(nodes) {
|
|
139
|
+
if (nodes.length === 0) {
|
|
140
|
+
return undefined;
|
|
141
|
+
}
|
|
142
|
+
if (nodes.length === 1) {
|
|
143
|
+
return nodes[0];
|
|
144
|
+
}
|
|
145
|
+
let maxZIndex = -1;
|
|
146
|
+
let highestNode = undefined;
|
|
147
|
+
for (const node of nodes) {
|
|
148
|
+
const zIndex = node.zIndex ?? -1;
|
|
149
|
+
if (zIndex >= maxZIndex) {
|
|
150
|
+
maxZIndex = zIndex;
|
|
151
|
+
highestNode = node;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return highestNode;
|
|
155
|
+
}
|
|
39
156
|
function getChildrenByPosition(node, x, y) {
|
|
40
157
|
const result = [];
|
|
41
158
|
const precision = Config.rendererOptions?.deviceLogicalPixelRatio || 1;
|
|
@@ -43,72 +160,79 @@ function getChildrenByPosition(node, x, y) {
|
|
|
43
160
|
let queue = [node];
|
|
44
161
|
while (queue.length > 0) {
|
|
45
162
|
// Process nodes at the current level
|
|
46
|
-
const currentLevelNodes =
|
|
47
|
-
|
|
48
|
-
if (isElementNode(currentNode) &&
|
|
49
|
-
currentNode.alpha !== 0 &&
|
|
50
|
-
!currentNode.skipFocus &&
|
|
51
|
-
testCollision(x, y, currentNode.lng.absX || 0 * precision, currentNode.lng.absY || 0 * precision, (currentNode.width || 0) * precision, (currentNode.height || 0) * precision)) {
|
|
52
|
-
currentLevelNodes.push(currentNode);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
const size = currentLevelNodes.length;
|
|
56
|
-
if (size === 0) {
|
|
163
|
+
const currentLevelNodes = queue.filter((currentNode) => isNodeAtPosition(currentNode, x, y, precision));
|
|
164
|
+
if (currentLevelNodes.length === 0) {
|
|
57
165
|
break;
|
|
58
166
|
}
|
|
59
|
-
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
else {
|
|
64
|
-
let maxZIndex = -1;
|
|
65
|
-
for (const node of currentLevelNodes) {
|
|
66
|
-
const zIndex = node.zIndex ?? -1;
|
|
67
|
-
if (zIndex > maxZIndex) {
|
|
68
|
-
maxZIndex = zIndex;
|
|
69
|
-
highestZIndexNode = node;
|
|
70
|
-
}
|
|
71
|
-
else if (zIndex === maxZIndex) {
|
|
72
|
-
highestZIndexNode = node;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
if (highestZIndexNode && !isTextNode(highestZIndexNode)) {
|
|
77
|
-
result.push(highestZIndexNode);
|
|
78
|
-
queue = highestZIndexNode.children;
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
queue = [];
|
|
167
|
+
const highestZIndexNode = findHighestZIndexNode(currentLevelNodes);
|
|
168
|
+
if (!highestZIndexNode || isTextNode(highestZIndexNode)) {
|
|
169
|
+
break;
|
|
82
170
|
}
|
|
171
|
+
result.push(highestZIndexNode);
|
|
172
|
+
queue = highestZIndexNode.children;
|
|
83
173
|
}
|
|
84
174
|
return result;
|
|
85
175
|
}
|
|
86
|
-
export function useMouse(myApp = rootNode, throttleBy = 100) {
|
|
176
|
+
export function useMouse(myApp = rootNode, throttleBy = 100, options) {
|
|
87
177
|
const pos = useMousePosition();
|
|
88
178
|
const scheduled = createScheduled((fn) => throttle(fn, throttleBy));
|
|
179
|
+
let previousElement = null;
|
|
180
|
+
const pressedElementRef = { current: null };
|
|
181
|
+
const customStates = options?.customStates;
|
|
182
|
+
const hoverState = customStates?.hoverState;
|
|
183
|
+
const handleClick = createHandleClick(myApp, customStates, pressedElementRef);
|
|
184
|
+
const handleMouseDown = createHandleMouseDown(myApp, customStates, pressedElementRef);
|
|
185
|
+
const owner = getOwner();
|
|
186
|
+
const handleClickContext = (e) => {
|
|
187
|
+
runWithOwner(owner, () => handleClick(e));
|
|
188
|
+
};
|
|
189
|
+
const handleMouseDownContext = (e) => {
|
|
190
|
+
runWithOwner(owner, () => handleMouseDown(e));
|
|
191
|
+
};
|
|
89
192
|
makeEventListener(window, 'wheel', handleScroll);
|
|
90
|
-
makeEventListener(window, 'click',
|
|
193
|
+
makeEventListener(window, 'click', handleClickContext);
|
|
194
|
+
makeEventListener(window, 'mousedown', handleMouseDownContext);
|
|
91
195
|
createEffect(() => {
|
|
92
196
|
if (scheduled()) {
|
|
93
|
-
const result = getChildrenByPosition(myApp, pos.x, pos.y).filter((el) => el.
|
|
197
|
+
const result = getChildrenByPosition(myApp, pos.x, pos.y).filter((el) => !!(el.onEnter ||
|
|
198
|
+
el.onMouseClick ||
|
|
199
|
+
el.onFocus ||
|
|
200
|
+
el[Config.focusStateKey] ||
|
|
201
|
+
(hoverState ? el[hoverState] : false)));
|
|
94
202
|
if (result.length) {
|
|
95
203
|
let activeElm = result[result.length - 1];
|
|
96
204
|
while (activeElm) {
|
|
97
205
|
const elmParent = activeElm.parent;
|
|
98
206
|
if (elmParent?.forwardStates) {
|
|
99
|
-
activeElm =
|
|
207
|
+
activeElm = elmParent;
|
|
100
208
|
}
|
|
101
209
|
else {
|
|
102
210
|
break;
|
|
103
211
|
}
|
|
104
212
|
}
|
|
213
|
+
if (!activeElm) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
105
216
|
// Update Row & Column Selected property
|
|
106
|
-
const activeElmParent = activeElm
|
|
107
|
-
if (
|
|
217
|
+
const activeElmParent = activeElm.parent;
|
|
218
|
+
if (activeElmParent?.selected !== undefined) {
|
|
108
219
|
activeElmParent.selected =
|
|
109
220
|
activeElmParent.children.indexOf(activeElm);
|
|
110
221
|
}
|
|
111
|
-
activeElm
|
|
222
|
+
if (previousElement && previousElement !== activeElm && hoverState) {
|
|
223
|
+
removeCustomStateFromElement(previousElement, hoverState);
|
|
224
|
+
}
|
|
225
|
+
if (hoverState) {
|
|
226
|
+
addCustomStateToElement(activeElm, hoverState);
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
activeElm.setFocus();
|
|
230
|
+
}
|
|
231
|
+
previousElement = activeElm;
|
|
232
|
+
}
|
|
233
|
+
else if (previousElement && hoverState) {
|
|
234
|
+
removeCustomStateFromElement(previousElement, hoverState);
|
|
235
|
+
previousElement = null;
|
|
112
236
|
}
|
|
113
237
|
}
|
|
114
238
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMouse.js","sourceRoot":"","sources":["../../../src/primitives/useMouse.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,aAAa,EACb,aAAa,EACb,UAAU,EACV,QAAQ,
|
|
1
|
+
{"version":3,"file":"useMouse.js","sourceRoot":"","sources":["../../../src/primitives/useMouse.ts"],"names":[],"mappings":"AACA,OAAO,EACL,MAAM,EACN,WAAW,EACX,aAAa,EACb,aAAa,EACb,MAAM,EACN,UAAU,EACV,QAAQ,GACT,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAehE,MAAM,UAAU,uBAAuB,CACrC,OAAuB,EACvB,KAAkB;IAElB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,OAAuB,EACvB,KAAkB;IAElB,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,OAAuB,EACvB,KAAkB;IAElB,OAAO,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,mBAAmB,CAC1B,GAAW,EACX,OAAe,EACf,YAAoB,SAAS;IAE7B,OAAO,IAAI,aAAa,CAAC,SAAS,EAAE;QAClC,GAAG;QACH,OAAO;QACP,KAAK,EAAE,OAAO;QACd,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,KAAK;QACf,OAAO,EAAE,KAAK;QACd,OAAO,EAAE,IAAI;KACd,CAAC,CAAC;AACL,CAAC;AAED,IAAI,aAA4C,CAAC;AACjD,MAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAa,EAAQ,EAAE;IACpD,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IACxB,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACf,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC;IAClE,CAAC;SAAM,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,wDAAwD;IACxD,YAAY,CAAC,aAAa,CAAC,CAAC;IAC5B,+EAA+E;IAC/E,aAAa,GAAG,UAAU,CAAC,GAAG,EAAE;QAC9B,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,SAAS,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;QACzE,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,WAAW,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;IAC7E,CAAC,EAAE,GAAG,CAAC,CAAC;AACV,CAAC,EAAE,GAAG,CAAC,CAAC;AAER,SAAS,0BAA0B,CACjC,KAAW,EACX,CAAS,EACT,CAAS,EACT,WAAwB;IAExB,MAAM,MAAM,GAAG,qBAAqB,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAC9D,cAAc,CAAC,EAAE,EAAE,WAAW,CAAC,CAChC,CAAC;IAEF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,OAAO,GAA4B,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEjE,OAAO,OAAO,EAAE,CAAC;QACf,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;QACjC,IAAI,SAAS,EAAE,aAAa,IAAI,cAAc,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,CAAC;YACvE,OAAO,GAAG,SAAS,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,MAAM;QACR,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,0BAA0B,CAAC,CAAa;IAC/C,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,eAAe,EAAE,uBAAuB,IAAI,CAAC,CAAC;IAEvE,IACE,MAAM,YAAY,WAAW;QAC7B,aAAa,CACX,CAAC,CAAC,OAAO,EACT,CAAC,CAAC,OAAO,EACT,CAAE,MAAM,CAAC,GAAG,CAAC,IAAe,IAAI,CAAC,CAAC,GAAG,SAAS,EAC9C,CAAE,MAAM,CAAC,GAAG,CAAC,IAAe,IAAI,CAAC,CAAC,GAAG,SAAS,EAC9C,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,SAAS,EAC/B,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,SAAS,CACjC,EACD,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,MAAM,GAAG,MAAM,EAAE,MAAM,CAAC;IAC5B,OAAO,MAAM,EAAE,CAAC;QACd,IACE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC;YAC3B,MAAM;YACN,aAAa,CACX,CAAC,CAAC,OAAO,EACT,CAAC,CAAC,OAAO,EACT,CAAE,MAAM,CAAC,GAAG,CAAC,IAAe,IAAI,CAAC,CAAC,GAAG,SAAS,EAC9C,CAAE,MAAM,CAAC,GAAG,CAAC,IAAe,IAAI,CAAC,CAAC,GAAG,SAAS,EAC9C,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,SAAS,EAC/B,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,SAAS,CACjC,EACD,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IACzB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,iBAAiB,CACxB,OAAoB,EACpB,YAAyB;IAEzB,uBAAuB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,kBAAkB,CACzB,cAA2B,EAC3B,CAAa,EACb,YAAgC,EAChC,iBAAmD;IAEnD,IAAI,YAAY,EAAE,YAAY,IAAI,iBAAiB,EAAE,OAAO,EAAE,CAAC;QAC7D,4BAA4B,CAC1B,iBAAiB,CAAC,OAAO,EACzB,YAAY,CAAC,YAAY,CAC1B,CAAC;QACF,iBAAiB,CAAC,OAAO,GAAG,IAAI,CAAC;IACnC,CAAC;IAED,IAAI,MAAM,CAAC,cAAc,CAAC,YAAY,CAAC,EAAE,CAAC;QACxC,cAAc,CAAC,YAAY,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;QAC/C,OAAO;IACT,CAAC;SAAM,IAAI,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1C,cAAc,CAAC,OAAO,EAAE,CAAC;QACzB,OAAO;IACT,CAAC;IAED,cAAc,CAAC,QAAQ,EAAE,CAAC;IAC1B,UAAU,CAAC,GAAG,EAAE;QACd,QAAQ,CAAC,aAAa,CAAC,mBAAmB,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;QACzD,UAAU,CACR,GAAG,EAAE,CACH,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,EACxE,CAAC,CACF,CAAC;IACJ,CAAC,EAAE,CAAC,CAAC,CAAC;AACR,CAAC;AAED,SAAS,iBAAiB,CACxB,KAAW,EACX,YAAgC,EAChC,iBAAmD;IAEnD,OAAO,CAAC,CAAa,EAAQ,EAAE;QAC7B,MAAM,cAAc,GAAG,YAAY;YACjC,CAAC,CAAC,0BAA0B,CACxB,KAAK,EACL,CAAC,CAAC,OAAO,EACT,CAAC,CAAC,OAAO,EACT,YAAY,CAAC,UAAU,CACxB;YACH,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC;QAElC,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,OAAO;QACT,CAAC;QAED,kBAAkB,CAAC,cAAc,EAAE,CAAC,EAAE,YAAY,EAAE,iBAAiB,CAAC,CAAC;IACzE,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAC5B,KAAW,EACX,YAAgC,EAChC,iBAAmD;IAEnD,OAAO,CAAC,CAAa,EAAQ,EAAE;QAC7B,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QAED,MAAM,cAAc,GAAG,0BAA0B,CAC/C,KAAK,EACL,CAAC,CAAC,OAAO,EACT,CAAC,CAAC,OAAO,EACT,YAAY,CAAC,UAAU,CACxB,CAAC;QAEF,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,OAAO;QACT,CAAC;QAED,iBAAiB,CAAC,cAAc,EAAE,YAAY,CAAC,YAAY,CAAC,CAAC;QAC7D,IAAI,iBAAiB,EAAE,CAAC;YACtB,iBAAiB,CAAC,OAAO,GAAG,cAAc,CAAC;QAC7C,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CACpB,EAAU,EACV,EAAU,EACV,EAAU,EACV,EAAU,EACV,KAAa,CAAC,EACd,KAAa,CAAC;IAEd,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AAChE,CAAC;AAED,SAAS,gBAAgB,CACvB,IAA0C,EAC1C,CAAS,EACT,CAAS,EACT,SAAiB;IAEjB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,CACL,IAAI,CAAC,KAAK,KAAK,CAAC;QAChB,CAAC,IAAI,CAAC,SAAS;QACf,aAAa,CACX,CAAC,EACD,CAAC,EACD,CAAE,IAAI,CAAC,GAAG,CAAC,IAAe,IAAI,CAAC,CAAC,GAAG,SAAS,EAC5C,CAAE,IAAI,CAAC,GAAG,CAAC,IAAe,IAAI,CAAC,CAAC,GAAG,SAAS,EAC5C,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,SAAS,EAC7B,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,SAAS,CAC/B,CACF,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAoB;IACjD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC;IACnB,IAAI,WAAW,GAA4B,SAAS,CAAC;IAErD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;QACjC,IAAI,MAAM,IAAI,SAAS,EAAE,CAAC;YACxB,SAAS,GAAG,MAAM,CAAC;YACnB,WAAW,GAAG,IAAI,CAAC;QACrB,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAS,qBAAqB,CAC5B,IAAc,EACd,CAAS,EACT,CAAS;IAET,MAAM,MAAM,GAAe,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,MAAM,CAAC,eAAe,EAAE,uBAAuB,IAAI,CAAC,CAAC;IACvE,gBAAgB;IAEhB,IAAI,KAAK,GAA6C,CAAC,IAAI,CAAC,CAAC;IAE7D,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,qCAAqC;QACrC,MAAM,iBAAiB,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CACrD,gBAAgB,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAC/C,CAAC;QAEF,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnC,MAAM;QACR,CAAC;QAED,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,iBAAiB,CAAC,CAAC;QAEnE,IAAI,CAAC,iBAAiB,IAAI,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACxD,MAAM;QACR,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,iBAA6B,CAAC,CAAC;QAC3C,KAAK,GAAG,iBAAiB,CAAC,QAAQ,CAAC;IACrC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,QAAQ,CACtB,QAAc,QAAgB,EAC9B,aAAqB,GAAG,EACxB,OAAyB;IAEzB,MAAM,GAAG,GAAG,gBAAgB,EAAE,CAAC;IAC/B,MAAM,SAAS,GAAG,eAAe,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC;IACpE,IAAI,eAAe,GAAuB,IAAI,CAAC;IAC/C,MAAM,iBAAiB,GAAoC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC7E,MAAM,YAAY,GAAG,OAAO,EAAE,YAAY,CAAC;IAC3C,MAAM,UAAU,GAAG,YAAY,EAAE,UAAU,CAAC;IAC5C,MAAM,WAAW,GAAG,iBAAiB,CAAC,KAAK,EAAE,YAAY,EAAE,iBAAiB,CAAC,CAAC;IAC9E,MAAM,eAAe,GAAG,qBAAqB,CAC3C,KAAK,EACL,YAAY,EACZ,iBAAiB,CAClB,CAAC;IACF,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,MAAM,kBAAkB,GAAG,CAAC,CAAa,EAAE,EAAE;QAC3C,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC;IACF,MAAM,sBAAsB,GAAG,CAAC,CAAa,EAAE,EAAE;QAC/C,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC,CAAC;IAEF,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;IACjD,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAAC;IACvD,iBAAiB,CAAC,MAAM,EAAE,WAAW,EAAE,sBAAsB,CAAC,CAAC;IAC/D,YAAY,CAAC,GAAG,EAAE;QAChB,IAAI,SAAS,EAAE,EAAE,CAAC;YAChB,MAAM,MAAM,GAAG,qBAAqB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAC9D,CAAC,EAAE,EAAE,EAAE,CACL,CAAC,CAAC,CACA,EAAE,CAAC,OAAO;gBACV,EAAE,CAAC,YAAY;gBACf,EAAE,CAAC,OAAO;gBACV,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC;gBACxB,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CACtC,CACJ,CAAC;YAEF,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClB,IAAI,SAAS,GAA4B,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAEnE,OAAO,SAAS,EAAE,CAAC;oBACjB,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC;oBACnC,IAAI,SAAS,EAAE,aAAa,EAAE,CAAC;wBAC7B,SAAS,GAAG,SAAS,CAAC;oBACxB,CAAC;yBAAM,CAAC;wBACN,MAAM;oBACR,CAAC;gBACH,CAAC;gBAED,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,OAAO;gBACT,CAAC;gBAED,wCAAwC;gBACxC,MAAM,eAAe,GAAG,SAAS,CAAC,MAAM,CAAC;gBACzC,IAAI,eAAe,EAAE,QAAQ,KAAK,SAAS,EAAE,CAAC;oBAC5C,eAAe,CAAC,QAAQ;wBACtB,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;gBAChD,CAAC;gBAED,IAAI,eAAe,IAAI,eAAe,KAAK,SAAS,IAAI,UAAU,EAAE,CAAC;oBACnE,4BAA4B,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;gBAC5D,CAAC;gBAED,IAAI,UAAU,EAAE,CAAC;oBACf,uBAAuB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;gBACjD,CAAC;qBAAM,CAAC;oBACN,SAAS,CAAC,QAAQ,EAAE,CAAC;gBACvB,CAAC;gBAED,eAAe,GAAG,SAAS,CAAC;YAC9B,CAAC;iBAAM,IAAI,eAAe,IAAI,UAAU,EAAE,CAAC;gBACzC,4BAA4B,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;gBAC1D,eAAe,GAAG,IAAI,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,4 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import * as s from 'solid-js';
|
|
2
|
+
export type AnyFunction = (this: any, ...args: any[]) => any;
|
|
3
|
+
/**
|
|
4
|
+
* take an array of functions and if you return `true` from a function, it will stop the chain
|
|
5
|
+
* @param fns list of functions to chain together, can be `undefined`, `null`, or `false` to skip them
|
|
6
|
+
* @returns a function that will call each function in the list until one returns `true` or all functions are called.
|
|
7
|
+
* If no functions are provided, it will return `undefined`.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* function Button (props: NodeProps) {
|
|
12
|
+
* function onEnter (el: ElementNode) {...}
|
|
13
|
+
* return <view onEnter={chainFunctions(props.onEnter, onEnter)} />
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function chainFunctions<T extends AnyFunction>(...fns: T[]): T;
|
|
18
|
+
export declare function chainFunctions<T extends AnyFunction>(...fns: (T | undefined | null | false)[]): T | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Utility for chaining multiple `ref` assignments with `props.ref` forwarding.
|
|
21
|
+
* @param refs list of ref setters. Can be a `props.ref` prop for ref forwarding or a setter to a local variable (`el => ref = el`).
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* function Button (props: NodeProps) {
|
|
25
|
+
* let localRef: ElementNode | undefined
|
|
26
|
+
* return <view ref={chainRefs(props.ref, el => localRef = el)} />
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare const chainRefs: <T>(...refs: (s.Ref<T> | undefined)[]) => (el: T) => void;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const onlyFunctions = args.filter((func) => typeof func === 'function');
|
|
1
|
+
export function chainFunctions(...fns) {
|
|
2
|
+
const onlyFunctions = fns.filter((func) => typeof func === 'function');
|
|
4
3
|
if (onlyFunctions.length === 0) {
|
|
5
4
|
return undefined;
|
|
6
5
|
}
|
|
@@ -18,4 +17,16 @@ export function chainFunctions(...args) {
|
|
|
18
17
|
return result;
|
|
19
18
|
};
|
|
20
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Utility for chaining multiple `ref` assignments with `props.ref` forwarding.
|
|
22
|
+
* @param refs list of ref setters. Can be a `props.ref` prop for ref forwarding or a setter to a local variable (`el => ref = el`).
|
|
23
|
+
* @example
|
|
24
|
+
* ```tsx
|
|
25
|
+
* function Button (props: NodeProps) {
|
|
26
|
+
* let localRef: ElementNode | undefined
|
|
27
|
+
* return <view ref={chainRefs(props.ref, el => localRef = el)} />
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export const chainRefs = chainFunctions;
|
|
21
32
|
//# sourceMappingURL=chainFunctions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chainFunctions.js","sourceRoot":"","sources":["../../../../src/primitives/utils/chainFunctions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"chainFunctions.js","sourceRoot":"","sources":["../../../../src/primitives/utils/chainFunctions.ts"],"names":[],"mappings":"AAsBA,MAAM,UAAU,cAAc,CAC5B,GAAG,GAA+C;IAElD,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,UAAU,CAAC,CAAC;IACvE,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,UAAU,GAAG,SAAS;QAC3B,IAAI,MAAM,CAAC;QACX,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;YACjC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YACrC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBACpB,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,cAEL,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type Accessor, type Resource } from 'solid-js';
|
|
2
|
+
/**
|
|
3
|
+
* Represents a valid image source that can be used for blurring
|
|
4
|
+
*/
|
|
5
|
+
type ImageSource = string | URL;
|
|
6
|
+
/**
|
|
7
|
+
* Represents a valid image source or null/undefined
|
|
8
|
+
*/
|
|
9
|
+
type NullableImageSource = ImageSource | null | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Configuration options for Gaussian blur operation
|
|
12
|
+
*/
|
|
13
|
+
interface BlurOptions {
|
|
14
|
+
/**
|
|
15
|
+
* The blur radius in pixels
|
|
16
|
+
* @default 10
|
|
17
|
+
*/
|
|
18
|
+
readonly radius?: number;
|
|
19
|
+
/**
|
|
20
|
+
* CORS setting for image loading
|
|
21
|
+
* @default 'anonymous'
|
|
22
|
+
*/
|
|
23
|
+
readonly crossOrigin?: 'anonymous' | 'use-credentials' | '';
|
|
24
|
+
/**
|
|
25
|
+
* The resolution of the output image in pixels
|
|
26
|
+
* @default 1
|
|
27
|
+
*/
|
|
28
|
+
readonly resolution?: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Type for the resource return value from createBlurredImage
|
|
32
|
+
*/
|
|
33
|
+
type BlurredImageResource<T extends NullableImageSource> = Resource<T extends null | undefined ? null : string>;
|
|
34
|
+
/**
|
|
35
|
+
* Applies Gaussian blur to an image URL
|
|
36
|
+
* @param imageUrl - Image source (string or URL)
|
|
37
|
+
* @param options - Blur configuration options
|
|
38
|
+
* @returns Promise resolving to data URL of blurred image
|
|
39
|
+
* @throws {Error} If image fails to load or blur operation fails
|
|
40
|
+
*/
|
|
41
|
+
export declare function applyGaussianBlur<TSource extends ImageSource>(imageUrl: TSource, options?: Readonly<BlurOptions>): Promise<string>;
|
|
42
|
+
/**
|
|
43
|
+
* Hook to create a blurred image resource
|
|
44
|
+
* @param imageUrl - Accessor function returning image source or null/undefined
|
|
45
|
+
* @param options - Blur configuration options
|
|
46
|
+
* @returns Resource containing blurred image data URL or null
|
|
47
|
+
* @template TSource - Type of image source (string, URL, or null/undefined)
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* const imageUrl = () => 'https://example.com/image.jpg';
|
|
52
|
+
* const blurred = createBlurredImage(imageUrl, { radius: 15 });
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare function createBlurredImage<TSource extends NullableImageSource>(imageUrl: Accessor<TSource>, options?: Readonly<BlurOptions>): BlurredImageResource<TSource>;
|
|
56
|
+
export {};
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { createResource } from 'solid-js';
|
|
2
|
+
/**
|
|
3
|
+
* Default blur options
|
|
4
|
+
*/
|
|
5
|
+
const DEFAULT_BLUR_OPTIONS = {
|
|
6
|
+
radius: 10,
|
|
7
|
+
crossOrigin: 'anonymous',
|
|
8
|
+
resolution: 1,
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Validates that radius is a positive number
|
|
12
|
+
*/
|
|
13
|
+
function isValidRadius(radius) {
|
|
14
|
+
return radius > 0 && Number.isFinite(radius);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Ensures a resolution is a positive number
|
|
18
|
+
*/
|
|
19
|
+
function isValidResolution(resolution) {
|
|
20
|
+
return resolution > 0 && resolution <= 1 && Number.isFinite(resolution);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Applies vertical Gaussian blur to image data
|
|
24
|
+
* @param input - Input pixel data
|
|
25
|
+
* @param output - Output pixel data buffer
|
|
26
|
+
* @param width - Image width
|
|
27
|
+
* @param height - Image height
|
|
28
|
+
* @param kernel - Gaussian kernel weights
|
|
29
|
+
* @param half - Half of kernel size
|
|
30
|
+
*/
|
|
31
|
+
function applyVerticalBlur(input, output, width, height, kernel, half) {
|
|
32
|
+
for (let y = 0; y < height; y++) {
|
|
33
|
+
for (let x = 0; x < width; x++) {
|
|
34
|
+
let r = 0, g = 0, b = 0, a = 0;
|
|
35
|
+
let weightSum = 0;
|
|
36
|
+
for (let ky = -half; ky <= half; ky++) {
|
|
37
|
+
const py = y + ky;
|
|
38
|
+
if (py >= 0 && py < height) {
|
|
39
|
+
const pixelIndex = (py * width + x) * 4;
|
|
40
|
+
const weight = kernel[ky + half];
|
|
41
|
+
r += input[pixelIndex] * weight;
|
|
42
|
+
g += input[pixelIndex + 1] * weight;
|
|
43
|
+
b += input[pixelIndex + 2] * weight;
|
|
44
|
+
a += input[pixelIndex + 3] * weight;
|
|
45
|
+
weightSum += weight;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const outputIndex = (y * width + x) * 4;
|
|
49
|
+
output[outputIndex] = r / weightSum;
|
|
50
|
+
output[outputIndex + 1] = g / weightSum;
|
|
51
|
+
output[outputIndex + 2] = b / weightSum;
|
|
52
|
+
output[outputIndex + 3] = a / weightSum;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Applies horizontal Gaussian blur to image data
|
|
58
|
+
* @param input - Input pixel data
|
|
59
|
+
* @param output - Output pixel data buffer
|
|
60
|
+
* @param width - Image width
|
|
61
|
+
* @param height - Image height
|
|
62
|
+
* @param kernel - Gaussian kernel weights
|
|
63
|
+
* @param half - Half of kernel size
|
|
64
|
+
*/
|
|
65
|
+
function applyHorizontalBlur(input, output, width, height, kernel, half) {
|
|
66
|
+
for (let y = 0; y < height; y++) {
|
|
67
|
+
for (let x = 0; x < width; x++) {
|
|
68
|
+
let r = 0, g = 0, b = 0, a = 0;
|
|
69
|
+
let weightSum = 0;
|
|
70
|
+
for (let kx = -half; kx <= half; kx++) {
|
|
71
|
+
const px = x + kx;
|
|
72
|
+
if (px >= 0 && px < width) {
|
|
73
|
+
const pixelIndex = (y * width + px) * 4;
|
|
74
|
+
const weight = kernel[kx + half];
|
|
75
|
+
r += input[pixelIndex] * weight;
|
|
76
|
+
g += input[pixelIndex + 1] * weight;
|
|
77
|
+
b += input[pixelIndex + 2] * weight;
|
|
78
|
+
a += input[pixelIndex + 3] * weight;
|
|
79
|
+
weightSum += weight;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const outputIndex = (y * width + x) * 4;
|
|
83
|
+
output[outputIndex] = r / weightSum;
|
|
84
|
+
output[outputIndex + 1] = g / weightSum;
|
|
85
|
+
output[outputIndex + 2] = b / weightSum;
|
|
86
|
+
output[outputIndex + 3] = a / weightSum;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Generates a normalized Gaussian kernel
|
|
92
|
+
* @param size - Kernel size (must be odd)
|
|
93
|
+
* @param sigma - Standard deviation
|
|
94
|
+
* @returns Normalized Gaussian kernel
|
|
95
|
+
*/
|
|
96
|
+
function generateGaussianKernel(size, sigma) {
|
|
97
|
+
const kernel = [];
|
|
98
|
+
const half = Math.floor(size / 2);
|
|
99
|
+
let sum = 0;
|
|
100
|
+
for (let i = -half; i <= half; i++) {
|
|
101
|
+
const value = Math.exp(-(i * i) / (2 * sigma * sigma));
|
|
102
|
+
kernel.push(value);
|
|
103
|
+
sum += value;
|
|
104
|
+
}
|
|
105
|
+
return Object.freeze(kernel.map((value) => value / sum));
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Applies Gaussian blur convolution to image data
|
|
109
|
+
* @param imageData - Source image data
|
|
110
|
+
* @param dimensions - Image dimensions
|
|
111
|
+
* @param radius - Blur radius
|
|
112
|
+
* @returns Blurred image data
|
|
113
|
+
*/
|
|
114
|
+
function gaussianBlurConvolution(imageData, dimensions, radius) {
|
|
115
|
+
const { data } = imageData;
|
|
116
|
+
const { width, height } = dimensions;
|
|
117
|
+
const output = new Uint8ClampedArray(data.length);
|
|
118
|
+
const kernelSize = Math.ceil(radius * 2) * 2 + 1;
|
|
119
|
+
const kernel = generateGaussianKernel(kernelSize, radius);
|
|
120
|
+
const half = Math.floor(kernelSize / 2);
|
|
121
|
+
applyHorizontalBlur(data, output, width, height, kernel, half);
|
|
122
|
+
const tempData = new Uint8ClampedArray(output);
|
|
123
|
+
applyVerticalBlur(tempData, output, width, height, kernel, half);
|
|
124
|
+
return new ImageData(output, width, height);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Applies Gaussian blur to an image URL
|
|
128
|
+
* @param imageUrl - Image source (string or URL)
|
|
129
|
+
* @param options - Blur configuration options
|
|
130
|
+
* @returns Promise resolving to data URL of blurred image
|
|
131
|
+
* @throws {Error} If image fails to load or blur operation fails
|
|
132
|
+
*/
|
|
133
|
+
export async function applyGaussianBlur(imageUrl, options) {
|
|
134
|
+
const opts = { ...DEFAULT_BLUR_OPTIONS, ...options };
|
|
135
|
+
const radius = opts.radius;
|
|
136
|
+
const resolution = opts.resolution;
|
|
137
|
+
if (!isValidRadius(radius)) {
|
|
138
|
+
throw new Error(`Invalid blur radius: ${radius}. Must be a positive number.`);
|
|
139
|
+
}
|
|
140
|
+
if (!isValidResolution(resolution)) {
|
|
141
|
+
throw new Error(`Invalid resolution: ${resolution}. Must be a number between 0 and 1.`);
|
|
142
|
+
}
|
|
143
|
+
return new Promise((resolve, reject) => {
|
|
144
|
+
const img = new Image();
|
|
145
|
+
img.crossOrigin = opts.crossOrigin;
|
|
146
|
+
img.onload = () => {
|
|
147
|
+
try {
|
|
148
|
+
const canvas = document.createElement('canvas');
|
|
149
|
+
const ctx = canvas.getContext('2d', {
|
|
150
|
+
willReadFrequently: true,
|
|
151
|
+
});
|
|
152
|
+
if (ctx === null) {
|
|
153
|
+
reject(new Error('Failed to get canvas context'));
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const scaledWidth = Math.max(1, Math.round(img.width * resolution));
|
|
157
|
+
const scaledHeight = Math.max(1, Math.round(img.height * resolution));
|
|
158
|
+
const dimensions = {
|
|
159
|
+
width: scaledWidth,
|
|
160
|
+
height: scaledHeight,
|
|
161
|
+
};
|
|
162
|
+
canvas.width = dimensions.width;
|
|
163
|
+
canvas.height = dimensions.height;
|
|
164
|
+
const hasFilterSupport = ctx.filter !== undefined;
|
|
165
|
+
if (hasFilterSupport) {
|
|
166
|
+
ctx.filter = `blur(${radius}px)`;
|
|
167
|
+
ctx.drawImage(img, 0, 0, scaledWidth, scaledHeight);
|
|
168
|
+
ctx.filter = 'none';
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
ctx.drawImage(img, 0, 0, scaledWidth, scaledHeight);
|
|
172
|
+
const imageData = ctx.getImageData(0, 0, dimensions.width, dimensions.height);
|
|
173
|
+
const blurredData = gaussianBlurConvolution(imageData, dimensions, radius);
|
|
174
|
+
ctx.putImageData(blurredData, 0, 0);
|
|
175
|
+
}
|
|
176
|
+
const dataUrl = canvas.toDataURL();
|
|
177
|
+
if (dataUrl) {
|
|
178
|
+
resolve(dataUrl);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
reject(new Error('Failed to create image data URL'));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
reject(error instanceof Error
|
|
186
|
+
? error
|
|
187
|
+
: new Error('Unknown error during blur operation'));
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
img.onerror = () => {
|
|
191
|
+
reject(new Error('Failed to load image'));
|
|
192
|
+
};
|
|
193
|
+
const srcString = typeof imageUrl === 'string' ? imageUrl : imageUrl.toString();
|
|
194
|
+
img.src = srcString;
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Hook to create a blurred image resource
|
|
199
|
+
* @param imageUrl - Accessor function returning image source or null/undefined
|
|
200
|
+
* @param options - Blur configuration options
|
|
201
|
+
* @returns Resource containing blurred image data URL or null
|
|
202
|
+
* @template TSource - Type of image source (string, URL, or null/undefined)
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```ts
|
|
206
|
+
* const imageUrl = () => 'https://example.com/image.jpg';
|
|
207
|
+
* const blurred = createBlurredImage(imageUrl, { radius: 15 });
|
|
208
|
+
* ```
|
|
209
|
+
*/
|
|
210
|
+
export function createBlurredImage(imageUrl, options) {
|
|
211
|
+
const imageUrlString = () => {
|
|
212
|
+
const url = imageUrl();
|
|
213
|
+
if (url === null || url === undefined) {
|
|
214
|
+
return url;
|
|
215
|
+
}
|
|
216
|
+
return typeof url === 'string' ? url : url.toString();
|
|
217
|
+
};
|
|
218
|
+
const [blurredImage] = createResource(imageUrlString, async (url) => {
|
|
219
|
+
return await applyGaussianBlur(url, options);
|
|
220
|
+
});
|
|
221
|
+
return blurredImage;
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=createBlurredImage.js.map
|