@bemedev/mind-flow 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/lib/index.cjs.js +1 -1
- package/lib/index.es.js +34 -32
- package/lib/server.cjs.js +31 -17
- package/lib/server.es.js +31 -17
- package/lib/services/main.machine.d.ts.map +1 -1
- package/lib/ui/components/FlowChart.context.d.ts.map +1 -1
- package/lib/ui/components/FlowChart.types.d.ts +7 -7
- package/lib/ui/components/FlowChart.types.d.ts.map +1 -1
- package/lib/ui/components/NodeComponent.d.ts.map +1 -1
- package/lib/ui/components/Panels.d.ts.map +1 -1
- package/lib/ui/globals/directives/mouseOut.d.ts +18 -9
- package/lib/ui/globals/directives/mouseOut.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/services/main.machine.ts +2 -0
- package/src/ui/components/FlowChart.types.ts +7 -7
- package/src/ui/components/NodeComponent.tsx +3 -0
- package/src/ui/components/Panels.tsx +3 -12
- package/src/ui/globals/directives/mouseOut.test.ts +127 -0
- package/src/ui/globals/directives/mouseOut.ts +51 -12
|
@@ -1,23 +1,31 @@
|
|
|
1
1
|
import { onCleanup } from 'solid-js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Callback function type invoked when the mouse leaves
|
|
4
|
+
* Callback function type invoked when the mouse leaves or focus is lost from the
|
|
5
|
+
* bound element.
|
|
5
6
|
*
|
|
6
|
-
* @param event - Optional mouse event that triggered the leave.
|
|
7
|
+
* @param event - Optional mouse or focus event that triggered the leave.
|
|
7
8
|
*/
|
|
8
|
-
export type MouseOutCallback = (event?: MouseEvent) => void;
|
|
9
|
+
export type MouseOutCallback = (event?: MouseEvent | FocusEvent) => void;
|
|
9
10
|
|
|
10
11
|
/** Configuration options for the {@linkcode mouseOut} directive. */
|
|
11
12
|
export type MouseOutOptions = {
|
|
12
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Callback function to trigger after the timer elapses of type
|
|
15
|
+
* {@linkcode MouseOutCallback}.
|
|
16
|
+
*/
|
|
13
17
|
callback?: MouseOutCallback;
|
|
14
18
|
|
|
15
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* Alternative callback property name for triggering after the timer elapses of
|
|
21
|
+
* type {@linkcode MouseOutCallback}.
|
|
22
|
+
*/
|
|
16
23
|
onMouseOut?: MouseOutCallback;
|
|
17
24
|
|
|
18
25
|
/**
|
|
19
|
-
* Delay in milliseconds before triggering the callback after the mouse leaves
|
|
20
|
-
* the cursor re-enters the element
|
|
26
|
+
* Delay in milliseconds before triggering the callback after the mouse leaves or
|
|
27
|
+
* focus is lost. If the cursor re-enters the element or focus is regained before
|
|
28
|
+
* this duration, the timer is reset.
|
|
21
29
|
*
|
|
22
30
|
* @defaultValue 0
|
|
23
31
|
*/
|
|
@@ -32,8 +40,9 @@ export type MouseOutParam =
|
|
|
32
40
|
|
|
33
41
|
/**
|
|
34
42
|
* Solid custom directive that triggers a callback when the mouse leaves the bound
|
|
35
|
-
* element after a specified timer duration. If the user
|
|
36
|
-
* before the timer expires, the timer is
|
|
43
|
+
* element and focus is not inside it, after a specified timer duration. If the user
|
|
44
|
+
* re-enters the component or gains focus before the timer expires, the timer is
|
|
45
|
+
* reset/cancelled.
|
|
37
46
|
*
|
|
38
47
|
* @param el - The bound DOM element.
|
|
39
48
|
* @param accessor - Accessor returning a callback, tuple `[callback, delay]`, or
|
|
@@ -44,6 +53,7 @@ export const mouseOut = (
|
|
|
44
53
|
accessor: () => MouseOutParam,
|
|
45
54
|
) => {
|
|
46
55
|
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
56
|
+
let isHovered = false;
|
|
47
57
|
|
|
48
58
|
const clear = () => {
|
|
49
59
|
if (timer !== undefined) {
|
|
@@ -52,11 +62,12 @@ export const mouseOut = (
|
|
|
52
62
|
}
|
|
53
63
|
};
|
|
54
64
|
|
|
55
|
-
const
|
|
56
|
-
|
|
65
|
+
const isFocused = () => {
|
|
66
|
+
const active = el.ownerDocument?.activeElement ?? document.activeElement;
|
|
67
|
+
return !!active && el.contains(active);
|
|
57
68
|
};
|
|
58
69
|
|
|
59
|
-
const
|
|
70
|
+
const triggerLeave = (event?: MouseEvent | FocusEvent) => {
|
|
60
71
|
clear();
|
|
61
72
|
|
|
62
73
|
const param = accessor();
|
|
@@ -87,12 +98,40 @@ export const mouseOut = (
|
|
|
87
98
|
}
|
|
88
99
|
};
|
|
89
100
|
|
|
101
|
+
const onMouseEnter = () => {
|
|
102
|
+
isHovered = true;
|
|
103
|
+
clear();
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const onMouseLeave = (event: MouseEvent) => {
|
|
107
|
+
isHovered = false;
|
|
108
|
+
if (isFocused()) return;
|
|
109
|
+
triggerLeave(event);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const onFocusIn = () => {
|
|
113
|
+
clear();
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const onFocusOut = (event: FocusEvent) => {
|
|
117
|
+
const nextTarget = event.relatedTarget as Node | null;
|
|
118
|
+
const stillHasFocus = !!nextTarget && el.contains(nextTarget);
|
|
119
|
+
|
|
120
|
+
if (!stillHasFocus && !isHovered) {
|
|
121
|
+
triggerLeave(event);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
90
125
|
el.addEventListener('mouseleave', onMouseLeave as EventListener);
|
|
91
126
|
el.addEventListener('mouseenter', onMouseEnter as EventListener);
|
|
127
|
+
el.addEventListener('focusin', onFocusIn as EventListener);
|
|
128
|
+
el.addEventListener('focusout', onFocusOut as EventListener);
|
|
92
129
|
|
|
93
130
|
onCleanup(() => {
|
|
94
131
|
clear();
|
|
95
132
|
el.removeEventListener('mouseleave', onMouseLeave as EventListener);
|
|
96
133
|
el.removeEventListener('mouseenter', onMouseEnter as EventListener);
|
|
134
|
+
el.removeEventListener('focusin', onFocusIn as EventListener);
|
|
135
|
+
el.removeEventListener('focusout', onFocusOut as EventListener);
|
|
97
136
|
});
|
|
98
137
|
};
|