@fluentui/react-positioning 9.18.2 → 9.18.4
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/CHANGELOG.md +20 -2
- package/dist/index.d.ts +18 -18
- package/lib/hooks/useSafeZoneArea/SafeZoneArea.js +156 -0
- package/lib/hooks/useSafeZoneArea/SafeZoneArea.js.map +1 -0
- package/lib/{SafeZoneArea.styles.js → hooks/useSafeZoneArea/SafeZoneArea.styles.js} +2 -4
- package/lib/hooks/useSafeZoneArea/SafeZoneArea.styles.js.map +1 -0
- package/lib/hooks/useSafeZoneArea/computeOutsideClipPath.js +27 -0
- package/lib/hooks/useSafeZoneArea/computeOutsideClipPath.js.map +1 -0
- package/lib/hooks/useSafeZoneArea/createSafeZoneAreaStateStore.js +25 -0
- package/lib/hooks/useSafeZoneArea/createSafeZoneAreaStateStore.js.map +1 -0
- package/lib/hooks/useSafeZoneArea/getMouseAnchor.js +51 -0
- package/lib/hooks/useSafeZoneArea/getMouseAnchor.js.map +1 -0
- package/lib/hooks/useSafeZoneArea/getRectCorners.js +24 -0
- package/lib/hooks/useSafeZoneArea/getRectCorners.js.map +1 -0
- package/lib/hooks/useSafeZoneArea/pointsToSvgPath.js +7 -0
- package/lib/hooks/useSafeZoneArea/pointsToSvgPath.js.map +1 -0
- package/lib/hooks/useSafeZoneArea/types.js +5 -0
- package/lib/hooks/useSafeZoneArea/types.js.map +1 -0
- package/lib/{useSafeZoneArea.js → hooks/useSafeZoneArea/useSafeZoneArea.js} +6 -4
- package/lib/hooks/useSafeZoneArea/useSafeZoneArea.js.map +1 -0
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib-commonjs/hooks/useSafeZoneArea/SafeZoneArea.js +168 -0
- package/lib-commonjs/hooks/useSafeZoneArea/SafeZoneArea.js.map +1 -0
- package/lib-commonjs/{SafeZoneArea.styles.js → hooks/useSafeZoneArea/SafeZoneArea.styles.js} +1 -5
- package/lib-commonjs/hooks/useSafeZoneArea/SafeZoneArea.styles.js.map +1 -0
- package/lib-commonjs/hooks/useSafeZoneArea/computeOutsideClipPath.js +33 -0
- package/lib-commonjs/hooks/useSafeZoneArea/computeOutsideClipPath.js.map +1 -0
- package/lib-commonjs/hooks/useSafeZoneArea/createSafeZoneAreaStateStore.js +35 -0
- package/lib-commonjs/hooks/useSafeZoneArea/createSafeZoneAreaStateStore.js.map +1 -0
- package/lib-commonjs/hooks/useSafeZoneArea/getMouseAnchor.js +62 -0
- package/lib-commonjs/hooks/useSafeZoneArea/getMouseAnchor.js.map +1 -0
- package/lib-commonjs/hooks/useSafeZoneArea/getRectCorners.js +34 -0
- package/lib-commonjs/hooks/useSafeZoneArea/getRectCorners.js.map +1 -0
- package/lib-commonjs/hooks/useSafeZoneArea/pointsToSvgPath.js +17 -0
- package/lib-commonjs/hooks/useSafeZoneArea/pointsToSvgPath.js.map +1 -0
- package/lib-commonjs/hooks/useSafeZoneArea/types.js +8 -0
- package/lib-commonjs/hooks/useSafeZoneArea/types.js.map +1 -0
- package/lib-commonjs/{useSafeZoneArea.js → hooks/useSafeZoneArea/useSafeZoneArea.js} +6 -4
- package/lib-commonjs/hooks/useSafeZoneArea/useSafeZoneArea.js.map +1 -0
- package/lib-commonjs/index.js +1 -1
- package/lib-commonjs/index.js.map +1 -1
- package/package.json +2 -2
- package/lib/SafeZoneArea.js +0 -309
- package/lib/SafeZoneArea.js.map +0 -1
- package/lib/SafeZoneArea.styles.js.map +0 -1
- package/lib/useSafeZoneArea.js.map +0 -1
- package/lib-commonjs/SafeZoneArea.js +0 -319
- package/lib-commonjs/SafeZoneArea.js.map +0 -1
- package/lib-commonjs/SafeZoneArea.styles.js.map +0 -1
- package/lib-commonjs/useSafeZoneArea.js.map +0 -1
package/CHANGELOG.md
CHANGED
@@ -1,12 +1,30 @@
|
|
1
1
|
# Change Log - @fluentui/react-positioning
|
2
2
|
|
3
|
-
This log was last generated on
|
3
|
+
This log was last generated on Thu, 26 Jun 2025 14:07:54 GMT and should not be manually modified.
|
4
4
|
|
5
5
|
<!-- Start content -->
|
6
6
|
|
7
|
+
## [9.18.4](https://github.com/microsoft/fluentui/tree/@fluentui/react-positioning_v9.18.4)
|
8
|
+
|
9
|
+
Thu, 26 Jun 2025 14:07:54 GMT
|
10
|
+
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-positioning_v9.18.3..@fluentui/react-positioning_v9.18.4)
|
11
|
+
|
12
|
+
### Patches
|
13
|
+
|
14
|
+
- Bump @fluentui/react-utilities to v9.22.0 ([PR #34529](https://github.com/microsoft/fluentui/pull/34529) by beachball)
|
15
|
+
|
16
|
+
## [9.18.3](https://github.com/microsoft/fluentui/tree/@fluentui/react-positioning_v9.18.3)
|
17
|
+
|
18
|
+
Mon, 23 Jun 2025 15:49:47 GMT
|
19
|
+
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-positioning_v9.18.2..@fluentui/react-positioning_v9.18.3)
|
20
|
+
|
21
|
+
### Patches
|
22
|
+
|
23
|
+
- feat: improve handling of different shapes of rectangles in useSafeZoneArea() ([PR #34677](https://github.com/microsoft/fluentui/pull/34677) by olfedias@microsoft.com)
|
24
|
+
|
7
25
|
## [9.18.2](https://github.com/microsoft/fluentui/tree/@fluentui/react-positioning_v9.18.2)
|
8
26
|
|
9
|
-
Wed, 18 Jun 2025 17:
|
27
|
+
Wed, 18 Jun 2025 17:33:58 GMT
|
10
28
|
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-positioning_v9.18.1..@fluentui/react-positioning_v9.18.2)
|
11
29
|
|
12
30
|
### Patches
|
package/dist/index.d.ts
CHANGED
@@ -297,23 +297,6 @@ export declare type PositioningVirtualElement = {
|
|
297
297
|
|
298
298
|
export declare function resolvePositioningShorthand(shorthand: PositioningShorthand | undefined | null): Readonly<PositioningProps>;
|
299
299
|
|
300
|
-
export declare type SafeBufferAreaOptions = {
|
301
|
-
/** Enables debug mode: makes drawn shapes visible. */
|
302
|
-
debug?: boolean;
|
303
|
-
/** Disables the safe zone area. */
|
304
|
-
disabled?: boolean;
|
305
|
-
/** The time in milliseconds to wait before clearing the safe zone. */
|
306
|
-
timeout?: number;
|
307
|
-
/** Called when the mouse enters the safe zone. */
|
308
|
-
onSafeZoneEnter?: (e: React_2.MouseEvent) => void;
|
309
|
-
/** Called when the mouse moves within the safe zone. */
|
310
|
-
onSafeZoneMove?: (e: React_2.MouseEvent) => void;
|
311
|
-
/** Called when the mouse leaves the safe zone. */
|
312
|
-
onSafeZoneLeave?: (e: React_2.MouseEvent) => void;
|
313
|
-
/** Called when the safe zone times out, even if a cursor is still over a safe zone. */
|
314
|
-
onSafeZoneTimeout?: () => void;
|
315
|
-
};
|
316
|
-
|
317
300
|
export declare type SetVirtualMouseTarget = (event: React_2.MouseEvent | MouseEvent | undefined | null) => void;
|
318
301
|
|
319
302
|
declare type TargetElement = HTMLElement | PositioningVirtualElement;
|
@@ -340,10 +323,27 @@ declare interface UsePositioningReturn {
|
|
340
323
|
arrowRef: React_2.MutableRefObject<any>;
|
341
324
|
}
|
342
325
|
|
343
|
-
export declare function useSafeZoneArea({ debug, disabled, onSafeZoneEnter, onSafeZoneMove, onSafeZoneLeave, onSafeZoneTimeout, timeout, }?:
|
326
|
+
export declare function useSafeZoneArea({ debug, disabled, onSafeZoneEnter, onSafeZoneMove, onSafeZoneLeave, onSafeZoneTimeout, timeout, }?: UseSafeZoneOptions): {
|
344
327
|
containerRef: RefObjectFunction<HTMLElement>;
|
345
328
|
targetRef: RefObjectFunction<HTMLElement>;
|
346
329
|
elementToRender: JSX.Element | null;
|
347
330
|
};
|
348
331
|
|
332
|
+
export declare type UseSafeZoneOptions = {
|
333
|
+
/** Enables debug mode: makes drawn shapes visible. */
|
334
|
+
debug?: boolean;
|
335
|
+
/** Disables the safe zone area. */
|
336
|
+
disabled?: boolean;
|
337
|
+
/** The time in milliseconds to wait before clearing the safe zone. */
|
338
|
+
timeout?: number;
|
339
|
+
/** Called when the mouse enters the safe zone. */
|
340
|
+
onSafeZoneEnter?: (e: React_2.MouseEvent) => void;
|
341
|
+
/** Called when the mouse moves within the safe zone. */
|
342
|
+
onSafeZoneMove?: (e: React_2.MouseEvent) => void;
|
343
|
+
/** Called when the mouse leaves the safe zone. */
|
344
|
+
onSafeZoneLeave?: (e: React_2.MouseEvent) => void;
|
345
|
+
/** Called when the safe zone times out, even if a cursor is still over a safe zone. */
|
346
|
+
onSafeZoneTimeout?: () => void;
|
347
|
+
};
|
348
|
+
|
349
349
|
export { }
|
@@ -0,0 +1,156 @@
|
|
1
|
+
import { mergeClasses } from '@griffel/react';
|
2
|
+
import { useId } from '@fluentui/react-utilities';
|
3
|
+
import * as React from 'react';
|
4
|
+
import { useSyncExternalStore } from 'use-sync-external-store/shim';
|
5
|
+
import { getRectCorners } from './getRectCorners';
|
6
|
+
import { getMouseAnchor } from './getMouseAnchor';
|
7
|
+
import { pointsToSvgPath } from './pointsToSvgPath';
|
8
|
+
import { useStyles } from './SafeZoneArea.styles';
|
9
|
+
import { computeOutsideClipPath } from './computeOutsideClipPath';
|
10
|
+
// ---
|
11
|
+
const EMPTY_RECT = {
|
12
|
+
top: 0,
|
13
|
+
right: 0,
|
14
|
+
bottom: 0,
|
15
|
+
left: 0,
|
16
|
+
width: 0,
|
17
|
+
height: 0,
|
18
|
+
x: 0,
|
19
|
+
y: 0,
|
20
|
+
toJSON () {
|
21
|
+
return '';
|
22
|
+
}
|
23
|
+
};
|
24
|
+
export function isSameRect(a, b) {
|
25
|
+
return a.top === b.top && a.right === b.right && a.bottom === b.bottom && a.left === b.left && a.width === b.width && a.height === b.height;
|
26
|
+
}
|
27
|
+
export function isSameCoordinates(a, b) {
|
28
|
+
return a[0] === b[0] && a[1] === b[1];
|
29
|
+
}
|
30
|
+
// ---
|
31
|
+
/**
|
32
|
+
* A component that renders a safe zone area with SVG shapes. Uses `useSyncExternalStore` to manage its active state
|
33
|
+
* to avoid causing re-renders in `useSafeZoneArea()` as the hook might be used in host components like `Menu`.
|
34
|
+
*
|
35
|
+
* Draws two shapes:
|
36
|
+
* - a triangle that points to the target element which is an actual safe zone
|
37
|
+
* - a rectangle for a clip path that clips out the target element
|
38
|
+
*
|
39
|
+
* @internal
|
40
|
+
*/ export const SafeZoneArea = /*#__PURE__*/ React.memo((props)=>{
|
41
|
+
const { debug, onMouseEnter, onMouseMove, onMouseLeave, stateStore } = props;
|
42
|
+
const clipPathId = useId();
|
43
|
+
const styles = useStyles();
|
44
|
+
const active = useSyncExternalStore(stateStore.subscribe, stateStore.isActive);
|
45
|
+
const svgRef = React.useRef(null);
|
46
|
+
const [state, setState] = React.useState(()=>({
|
47
|
+
containerRect: EMPTY_RECT,
|
48
|
+
targetRect: EMPTY_RECT,
|
49
|
+
mouseCoordinates: [
|
50
|
+
0,
|
51
|
+
0
|
52
|
+
]
|
53
|
+
}));
|
54
|
+
React.useImperativeHandle(props.imperativeRef, ()=>({
|
55
|
+
updateSVG (newState) {
|
56
|
+
setState((prevState)=>{
|
57
|
+
// Heads up!
|
58
|
+
// A small optimization to avoid unnecessary re-renders
|
59
|
+
if (isSameRect(prevState.containerRect, newState.containerRect) && isSameRect(prevState.targetRect, newState.targetRect) && isSameCoordinates(prevState.mouseCoordinates, newState.mouseCoordinates)) {
|
60
|
+
return prevState;
|
61
|
+
}
|
62
|
+
return newState;
|
63
|
+
});
|
64
|
+
}
|
65
|
+
}), []);
|
66
|
+
const { containerRect, targetRect, mouseCoordinates } = state;
|
67
|
+
const topOffset = Math.min(targetRect.top, containerRect.top);
|
68
|
+
const leftOffset = Math.min(targetRect.left, containerRect.left);
|
69
|
+
const bottomOffset = Math.max(targetRect.bottom, containerRect.bottom);
|
70
|
+
const rightOffset = Math.max(targetRect.right, containerRect.right);
|
71
|
+
// ---
|
72
|
+
const containerCorners = getRectCorners(containerRect, [
|
73
|
+
leftOffset,
|
74
|
+
topOffset
|
75
|
+
]);
|
76
|
+
const targetCorners = getRectCorners(targetRect, [
|
77
|
+
leftOffset,
|
78
|
+
topOffset
|
79
|
+
]);
|
80
|
+
// Heads up!
|
81
|
+
// The SVG coordinate system starts at the top-left corner of the SVG element,
|
82
|
+
// so we need to adjust the mouse coordinates relative to the SVG's top-left corner.
|
83
|
+
const relativeMouseCoordinates = [
|
84
|
+
mouseCoordinates[0] - leftOffset,
|
85
|
+
mouseCoordinates[1] - topOffset
|
86
|
+
];
|
87
|
+
const mouseAnchor = getMouseAnchor(containerCorners.topLeft, containerCorners.bottomRight, relativeMouseCoordinates);
|
88
|
+
const triangleA = [
|
89
|
+
mouseAnchor,
|
90
|
+
containerCorners.topLeft,
|
91
|
+
containerCorners.topRight
|
92
|
+
];
|
93
|
+
const triangleB = [
|
94
|
+
mouseAnchor,
|
95
|
+
containerCorners.topRight,
|
96
|
+
containerCorners.bottomRight
|
97
|
+
];
|
98
|
+
const triangleC = [
|
99
|
+
mouseAnchor,
|
100
|
+
containerCorners.bottomRight,
|
101
|
+
containerCorners.bottomLeft
|
102
|
+
];
|
103
|
+
const triangleD = [
|
104
|
+
mouseAnchor,
|
105
|
+
containerCorners.bottomLeft,
|
106
|
+
containerCorners.topLeft
|
107
|
+
];
|
108
|
+
const svgWidth = rightOffset - leftOffset;
|
109
|
+
const svgHeight = bottomOffset - topOffset;
|
110
|
+
const clipPath = computeOutsideClipPath(svgWidth, svgHeight, {
|
111
|
+
x: targetCorners.topLeft[0],
|
112
|
+
y: targetCorners.topLeft[1],
|
113
|
+
width: targetRect.width,
|
114
|
+
height: targetRect.height
|
115
|
+
}, {
|
116
|
+
x: containerCorners.topLeft[0],
|
117
|
+
y: containerCorners.topLeft[1],
|
118
|
+
width: containerRect.width,
|
119
|
+
height: containerRect.height
|
120
|
+
});
|
121
|
+
return /*#__PURE__*/ React.createElement("div", {
|
122
|
+
className: mergeClasses(styles.wrapper, active && styles.wrapperActive),
|
123
|
+
"data-safe-zone": ""
|
124
|
+
}, active ? /*#__PURE__*/ React.createElement("svg", {
|
125
|
+
"aria-hidden": true,
|
126
|
+
className: styles.svg,
|
127
|
+
xmlns: "http://www.w3.org/2000/svg",
|
128
|
+
ref: svgRef,
|
129
|
+
style: {
|
130
|
+
width: `${svgWidth}px`,
|
131
|
+
height: `${svgHeight}px`,
|
132
|
+
transform: `translate(${leftOffset}px, ${topOffset}px)`
|
133
|
+
}
|
134
|
+
}, /*#__PURE__*/ React.createElement("g", {
|
135
|
+
className: mergeClasses(styles.triangle, debug && styles.triangleDebug),
|
136
|
+
clipPath: `url(#${clipPathId})`,
|
137
|
+
onMouseEnter: onMouseEnter,
|
138
|
+
onMouseMove: onMouseMove,
|
139
|
+
onMouseLeave: onMouseLeave
|
140
|
+
}, /*#__PURE__*/ React.createElement("path", {
|
141
|
+
d: pointsToSvgPath(triangleA)
|
142
|
+
}), /*#__PURE__*/ React.createElement("path", {
|
143
|
+
d: pointsToSvgPath(triangleB)
|
144
|
+
}), /*#__PURE__*/ React.createElement("path", {
|
145
|
+
d: pointsToSvgPath(triangleC)
|
146
|
+
}), /*#__PURE__*/ React.createElement("path", {
|
147
|
+
d: pointsToSvgPath(triangleD)
|
148
|
+
})), /*#__PURE__*/ React.createElement("clipPath", {
|
149
|
+
id: clipPathId
|
150
|
+
}, /*#__PURE__*/ React.createElement("path", {
|
151
|
+
d: clipPath
|
152
|
+
})), debug && /*#__PURE__*/ React.createElement("path", {
|
153
|
+
className: styles.rectDebug,
|
154
|
+
d: clipPath
|
155
|
+
})) : null);
|
156
|
+
});
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useSafeZoneArea/SafeZoneArea.tsx"],"sourcesContent":["import { mergeClasses } from '@griffel/react';\nimport { useId } from '@fluentui/react-utilities';\nimport * as React from 'react';\nimport { useSyncExternalStore } from 'use-sync-external-store/shim';\n\nimport type { createSafeZoneAreaStateStore } from './createSafeZoneAreaStateStore';\nimport { getRectCorners } from './getRectCorners';\nimport { getMouseAnchor } from './getMouseAnchor';\nimport { pointsToSvgPath } from './pointsToSvgPath';\nimport { useStyles } from './SafeZoneArea.styles';\nimport type { Point } from './types';\nimport { computeOutsideClipPath } from './computeOutsideClipPath';\n\nexport type SafeZoneAreaImperativeHandle = {\n updateSVG: (options: { containerRect: DOMRect; targetRect: DOMRect; mouseCoordinates: Point }) => void;\n};\n\nexport type SafeZoneAreaProps = {\n /** Enables debug mode: makes drawn shapes visible. */\n debug: boolean;\n\n /** A reference to the SafeZoneArea imperative handle. */\n imperativeRef: React.Ref<SafeZoneAreaImperativeHandle>;\n\n // eslint-disable-next-line @nx/workspace-consistent-callback-type\n onMouseEnter: (e: React.MouseEvent) => void;\n // eslint-disable-next-line @nx/workspace-consistent-callback-type\n onMouseMove: (e: React.MouseEvent) => void;\n // eslint-disable-next-line @nx/workspace-consistent-callback-type\n onMouseLeave: (e: React.MouseEvent) => void;\n\n stateStore: ReturnType<typeof createSafeZoneAreaStateStore>;\n};\n\n/**\n * @internal\n */\ntype SafeZoneAreaState = {\n containerRect: DOMRect;\n targetRect: DOMRect;\n mouseCoordinates: Point;\n};\n\n// ---\n\nconst EMPTY_RECT: DOMRect = {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n width: 0,\n height: 0,\n x: 0,\n y: 0,\n toJSON() {\n return '';\n },\n};\n\nexport function isSameRect(a: DOMRect, b: DOMRect) {\n return (\n a.top === b.top &&\n a.right === b.right &&\n a.bottom === b.bottom &&\n a.left === b.left &&\n a.width === b.width &&\n a.height === b.height\n );\n}\n\nexport function isSameCoordinates(a: Point, b: Point) {\n return a[0] === b[0] && a[1] === b[1];\n}\n\n// ---\n\n/**\n * A component that renders a safe zone area with SVG shapes. Uses `useSyncExternalStore` to manage its active state\n * to avoid causing re-renders in `useSafeZoneArea()` as the hook might be used in host components like `Menu`.\n *\n * Draws two shapes:\n * - a triangle that points to the target element which is an actual safe zone\n * - a rectangle for a clip path that clips out the target element\n *\n * @internal\n */\nexport const SafeZoneArea = React.memo((props: SafeZoneAreaProps) => {\n const { debug, onMouseEnter, onMouseMove, onMouseLeave, stateStore } = props;\n\n const clipPathId = useId();\n const styles = useStyles();\n\n const active = useSyncExternalStore(stateStore.subscribe, stateStore.isActive);\n const svgRef = React.useRef<SVGSVGElement>(null);\n\n const [state, setState] = React.useState<SafeZoneAreaState>(() => ({\n containerRect: EMPTY_RECT,\n targetRect: EMPTY_RECT,\n mouseCoordinates: [0, 0],\n }));\n\n React.useImperativeHandle(\n props.imperativeRef,\n () => ({\n updateSVG(newState) {\n setState(prevState => {\n // Heads up!\n // A small optimization to avoid unnecessary re-renders\n if (\n isSameRect(prevState.containerRect, newState.containerRect) &&\n isSameRect(prevState.targetRect, newState.targetRect) &&\n isSameCoordinates(prevState.mouseCoordinates, newState.mouseCoordinates)\n ) {\n return prevState;\n }\n\n return newState;\n });\n },\n }),\n [],\n );\n\n const { containerRect, targetRect, mouseCoordinates } = state;\n\n const topOffset = Math.min(targetRect.top, containerRect.top);\n const leftOffset = Math.min(targetRect.left, containerRect.left);\n const bottomOffset = Math.max(targetRect.bottom, containerRect.bottom);\n const rightOffset = Math.max(targetRect.right, containerRect.right);\n\n // ---\n\n const containerCorners = getRectCorners(containerRect, [leftOffset, topOffset]);\n const targetCorners = getRectCorners(targetRect, [leftOffset, topOffset]);\n\n // Heads up!\n // The SVG coordinate system starts at the top-left corner of the SVG element,\n // so we need to adjust the mouse coordinates relative to the SVG's top-left corner.\n const relativeMouseCoordinates: Point = [mouseCoordinates[0] - leftOffset, mouseCoordinates[1] - topOffset];\n const mouseAnchor = getMouseAnchor(containerCorners.topLeft, containerCorners.bottomRight, relativeMouseCoordinates);\n\n const triangleA = [mouseAnchor, containerCorners.topLeft, containerCorners.topRight];\n const triangleB = [mouseAnchor, containerCorners.topRight, containerCorners.bottomRight];\n const triangleC = [mouseAnchor, containerCorners.bottomRight, containerCorners.bottomLeft];\n const triangleD = [mouseAnchor, containerCorners.bottomLeft, containerCorners.topLeft];\n\n const svgWidth = rightOffset - leftOffset;\n const svgHeight = bottomOffset - topOffset;\n\n const clipPath = computeOutsideClipPath(\n svgWidth,\n svgHeight,\n {\n x: targetCorners.topLeft[0],\n y: targetCorners.topLeft[1],\n width: targetRect.width,\n height: targetRect.height,\n },\n {\n x: containerCorners.topLeft[0],\n y: containerCorners.topLeft[1],\n width: containerRect.width,\n height: containerRect.height,\n },\n );\n\n return (\n <div className={mergeClasses(styles.wrapper, active && styles.wrapperActive)} data-safe-zone=\"\">\n {active ? (\n <svg\n aria-hidden\n className={styles.svg}\n xmlns=\"http://www.w3.org/2000/svg\"\n ref={svgRef}\n style={{\n width: `${svgWidth}px`,\n height: `${svgHeight}px`,\n transform: `translate(${leftOffset}px, ${topOffset}px)`,\n }}\n >\n <g\n className={mergeClasses(styles.triangle, debug && styles.triangleDebug)}\n clipPath={`url(#${clipPathId})`}\n onMouseEnter={onMouseEnter}\n onMouseMove={onMouseMove}\n onMouseLeave={onMouseLeave}\n >\n <path d={pointsToSvgPath(triangleA)} />\n <path d={pointsToSvgPath(triangleB)} />\n <path d={pointsToSvgPath(triangleC)} />\n <path d={pointsToSvgPath(triangleD)} />\n </g>\n\n <clipPath id={clipPathId}>\n <path d={clipPath} />\n </clipPath>\n\n {debug && <path className={styles.rectDebug} d={clipPath} />}\n </svg>\n ) : null}\n </div>\n );\n});\n"],"names":["mergeClasses","useId","React","useSyncExternalStore","getRectCorners","getMouseAnchor","pointsToSvgPath","useStyles","computeOutsideClipPath","EMPTY_RECT","top","right","bottom","left","width","height","x","y","toJSON","isSameRect","a","b","isSameCoordinates","SafeZoneArea","memo","props","debug","onMouseEnter","onMouseMove","onMouseLeave","stateStore","clipPathId","styles","active","subscribe","isActive","svgRef","useRef","state","setState","useState","containerRect","targetRect","mouseCoordinates","useImperativeHandle","imperativeRef","updateSVG","newState","prevState","topOffset","Math","min","leftOffset","bottomOffset","max","rightOffset","containerCorners","targetCorners","relativeMouseCoordinates","mouseAnchor","topLeft","bottomRight","triangleA","topRight","triangleB","triangleC","bottomLeft","triangleD","svgWidth","svgHeight","clipPath","div","className","wrapper","wrapperActive","data-safe-zone","svg","aria-hidden","xmlns","ref","style","transform","g","triangle","triangleDebug","path","d","id","rectDebug"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
@@ -22,13 +22,11 @@ export const useStyles = /*#__PURE__*/__styles({
|
|
22
22
|
},
|
23
23
|
triangleDebug: {
|
24
24
|
Bceei9c: "f7116n6",
|
25
|
-
Bkfmm31: "f1xab38x"
|
26
|
-
ojy3ng: "f1wle4v7",
|
27
|
-
Be5yapy: "f1t0ei4n"
|
25
|
+
Bkfmm31: "f1xab38x"
|
28
26
|
},
|
29
27
|
rectDebug: {
|
30
28
|
Bkfmm31: "fyegryc"
|
31
29
|
}
|
32
30
|
}, {
|
33
|
-
d: [".fjseox{display:none;}", ".fniina8{height:0;}", ".f3tsq5r{width:0;}", ".f1aehjj5{pointer-events:none;}", ".ftgm304{display:block;}", ".f1au8mb3{fill:transparent;}", ".f19dog8a{position:fixed;}", ".f15twtuk{top:0;}", ".f1vgc2s3{left:0;}", ".f1e31b4d{right:0;}", ".f1cguypg{pointer-events:auto;}", ".f7116n6{cursor:crosshair;}", ".f1xab38x{fill:color-mix(in srgb, var(--colorPaletteGreenBackground3) 20%, transparent);}", ".
|
31
|
+
d: [".fjseox{display:none;}", ".fniina8{height:0;}", ".f3tsq5r{width:0;}", ".f1aehjj5{pointer-events:none;}", ".ftgm304{display:block;}", ".f1au8mb3{fill:transparent;}", ".f19dog8a{position:fixed;}", ".f15twtuk{top:0;}", ".f1vgc2s3{left:0;}", ".f1e31b4d{right:0;}", ".f1cguypg{pointer-events:auto;}", ".f7116n6{cursor:crosshair;}", ".f1xab38x{fill:color-mix(in srgb, var(--colorPaletteGreenBackground3) 20%, transparent);}", ".fyegryc{fill:color-mix(in srgb, var(--colorPaletteRedBackground3) 20%, transparent);}"]
|
34
32
|
});
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"names":["__styles","tokens","useStyles","wrapper","mc9l5x","Bqenvij","a9b677","Bkecrkj","wrapperActive","svg","Bkfmm31","qhf8xq","Bhzewxz","oyh7mz","triangle","triangleDebug","Bceei9c","rectDebug","d"],"sources":["SafeZoneArea.styles.js"],"sourcesContent":["import { makeStyles } from '@griffel/react';\nimport { tokens } from '@fluentui/react-theme';\nexport const useStyles = makeStyles({\n wrapper: {\n display: 'none',\n height: 0,\n width: 0,\n pointerEvents: 'none'\n },\n wrapperActive: {\n display: 'block'\n },\n svg: {\n fill: 'transparent',\n pointerEvents: 'none',\n position: 'fixed',\n top: 0,\n left: 0\n },\n triangle: {\n pointerEvents: 'auto'\n },\n triangleDebug: {\n cursor: 'crosshair',\n fill: `color-mix(in srgb, ${tokens.colorPaletteGreenBackground3} 20%, transparent)`\n },\n rectDebug: {\n fill: `color-mix(in srgb, ${tokens.colorPaletteRedBackground3} 20%, transparent)`\n }\n});\n"],"mappings":"AAAA,SAAAA,QAAA,QAA2B,gBAAgB;AAC3C,SAASC,MAAM,QAAQ,uBAAuB;AAC9C,OAAO,MAAMC,SAAS,gBAAGF,QAAA;EAAAG,OAAA;IAAAC,MAAA;IAAAC,OAAA;IAAAC,MAAA;IAAAC,OAAA;EAAA;EAAAC,aAAA;IAAAJ,MAAA;EAAA;EAAAK,GAAA;IAAAC,OAAA;IAAAH,OAAA;IAAAI,MAAA;IAAAC,OAAA;IAAAC,MAAA;EAAA;EAAAC,QAAA;IAAAP,OAAA;EAAA;EAAAQ,aAAA;IAAAC,OAAA;IAAAN,OAAA;EAAA;EAAAO,SAAA;IAAAP,OAAA;EAAA;AAAA;EAAAQ,CAAA;AAAA,CA2BxB,CAAC","ignoreList":[]}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
function drawRectangle(rect) {
|
2
|
+
if (rect.width <= 0 || rect.height <= 0) {
|
3
|
+
return '';
|
4
|
+
}
|
5
|
+
let pathData = '';
|
6
|
+
// Creates a subpath moving in counterclockwise direction to create a hole
|
7
|
+
pathData += `M ${rect.x},${rect.y} `;
|
8
|
+
pathData += `V ${rect.y + rect.height} `; // Down to bottom-left
|
9
|
+
pathData += `H ${rect.x + rect.width} `; // Right to bottom-right
|
10
|
+
pathData += `V ${rect.y} `; // Up to top-right
|
11
|
+
pathData += `H ${rect.x} `; // Left to top-left (closing)
|
12
|
+
pathData += `Z `; // Close path
|
13
|
+
return pathData;
|
14
|
+
}
|
15
|
+
/**
|
16
|
+
* Computes a clip path that covers the area outside multiple rectangles.
|
17
|
+
*
|
18
|
+
* @internal
|
19
|
+
*/ export function computeOutsideClipPath(svgWidth, svgHeight, targetRect, containerRect) {
|
20
|
+
let pathData = `M 0,0 H ${svgWidth} V ${svgHeight} H 0 Z `;
|
21
|
+
// For each rectangle, add a subpath that "cuts out" the rectangle
|
22
|
+
// The trick is to draw each rectangle in the counterclockwise direction
|
23
|
+
// which creates a "hole" in the main path
|
24
|
+
pathData += drawRectangle(targetRect);
|
25
|
+
pathData += drawRectangle(containerRect);
|
26
|
+
return pathData;
|
27
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useSafeZoneArea/computeOutsideClipPath.ts"],"sourcesContent":["function drawRectangle(rect: { x: number; y: number; width: number; height: number }): string {\n if (rect.width <= 0 || rect.height <= 0) {\n return '';\n }\n\n let pathData = '';\n\n // Creates a subpath moving in counterclockwise direction to create a hole\n\n pathData += `M ${rect.x},${rect.y} `;\n pathData += `V ${rect.y + rect.height} `; // Down to bottom-left\n pathData += `H ${rect.x + rect.width} `; // Right to bottom-right\n pathData += `V ${rect.y} `; // Up to top-right\n pathData += `H ${rect.x} `; // Left to top-left (closing)\n pathData += `Z `; // Close path\n\n return pathData;\n}\n\n/**\n * Computes a clip path that covers the area outside multiple rectangles.\n *\n * @internal\n */\nexport function computeOutsideClipPath(\n svgWidth: number,\n svgHeight: number,\n targetRect: { x: number; y: number; width: number; height: number },\n containerRect: { x: number; y: number; width: number; height: number },\n) {\n let pathData = `M 0,0 H ${svgWidth} V ${svgHeight} H 0 Z `;\n\n // For each rectangle, add a subpath that \"cuts out\" the rectangle\n // The trick is to draw each rectangle in the counterclockwise direction\n // which creates a \"hole\" in the main path\n\n pathData += drawRectangle(targetRect);\n pathData += drawRectangle(containerRect);\n\n return pathData;\n}\n"],"names":["drawRectangle","rect","width","height","pathData","x","y","computeOutsideClipPath","svgWidth","svgHeight","targetRect","containerRect"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,cAAcC,IAA6D;IAClF,IAAIA,KAAKC,KAAK,IAAI,KAAKD,KAAKE,MAAM,IAAI,GAAG;QACvC,OAAO;IACT;IAEA,IAAIC,WAAW;IAEf,0EAA0E;IAE1EA,YAAY,CAAC,EAAE,EAAEH,KAAKI,CAAC,CAAC,CAAC,EAAEJ,KAAKK,CAAC,CAAC,CAAC,CAAC;IACpCF,YAAY,CAAC,EAAE,EAAEH,KAAKK,CAAC,GAAGL,KAAKE,MAAM,CAAC,CAAC,CAAC,EAAE,sBAAsB;IAChEC,YAAY,CAAC,EAAE,EAAEH,KAAKI,CAAC,GAAGJ,KAAKC,KAAK,CAAC,CAAC,CAAC,EAAE,wBAAwB;IACjEE,YAAY,CAAC,EAAE,EAAEH,KAAKK,CAAC,CAAC,CAAC,CAAC,EAAE,kBAAkB;IAC9CF,YAAY,CAAC,EAAE,EAAEH,KAAKI,CAAC,CAAC,CAAC,CAAC,EAAE,6BAA6B;IACzDD,YAAY,CAAC,EAAE,CAAC,EAAE,aAAa;IAE/B,OAAOA;AACT;AAEA;;;;CAIC,GACD,OAAO,SAASG,uBACdC,QAAgB,EAChBC,SAAiB,EACjBC,UAAmE,EACnEC,aAAsE;IAEtE,IAAIP,WAAW,CAAC,QAAQ,EAAEI,SAAS,GAAG,EAAEC,UAAU,OAAO,CAAC;IAE1D,kEAAkE;IAClE,wEAAwE;IACxE,0CAA0C;IAE1CL,YAAYJ,cAAcU;IAC1BN,YAAYJ,cAAcW;IAE1B,OAAOP;AACT"}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
export function createSafeZoneAreaStateStore() {
|
2
|
+
let isActive = false;
|
3
|
+
const listeners = [];
|
4
|
+
return {
|
5
|
+
isActive () {
|
6
|
+
return isActive;
|
7
|
+
},
|
8
|
+
toggleActive (newIsActive) {
|
9
|
+
if (isActive === newIsActive) {
|
10
|
+
return;
|
11
|
+
}
|
12
|
+
isActive = newIsActive;
|
13
|
+
listeners.forEach((listener)=>listener(isActive));
|
14
|
+
},
|
15
|
+
subscribe (listener) {
|
16
|
+
listeners.push(listener);
|
17
|
+
return ()=>{
|
18
|
+
const index = listeners.indexOf(listener);
|
19
|
+
if (index > -1) {
|
20
|
+
listeners.splice(index, 1);
|
21
|
+
}
|
22
|
+
};
|
23
|
+
}
|
24
|
+
};
|
25
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useSafeZoneArea/createSafeZoneAreaStateStore.ts"],"sourcesContent":["export function createSafeZoneAreaStateStore() {\n let isActive = false;\n const listeners: ((value: boolean) => void)[] = [];\n\n return {\n isActive() {\n return isActive;\n },\n toggleActive(newIsActive: boolean) {\n if (isActive === newIsActive) {\n return;\n }\n\n isActive = newIsActive;\n listeners.forEach(listener => listener(isActive));\n },\n\n subscribe(listener: (value: boolean) => void) {\n listeners.push(listener);\n\n return () => {\n const index = listeners.indexOf(listener);\n\n if (index > -1) {\n listeners.splice(index, 1);\n }\n };\n },\n };\n}\n"],"names":["createSafeZoneAreaStateStore","isActive","listeners","toggleActive","newIsActive","forEach","listener","subscribe","push","index","indexOf","splice"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,OAAO,SAASA;IACd,IAAIC,WAAW;IACf,MAAMC,YAA0C,EAAE;IAElD,OAAO;QACLD;YACE,OAAOA;QACT;QACAE,cAAaC,WAAoB;YAC/B,IAAIH,aAAaG,aAAa;gBAC5B;YACF;YAEAH,WAAWG;YACXF,UAAUG,OAAO,CAACC,CAAAA,WAAYA,SAASL;QACzC;QAEAM,WAAUD,QAAkC;YAC1CJ,UAAUM,IAAI,CAACF;YAEf,OAAO;gBACL,MAAMG,QAAQP,UAAUQ,OAAO,CAACJ;gBAEhC,IAAIG,QAAQ,CAAC,GAAG;oBACdP,UAAUS,MAAM,CAACF,OAAO;gBAC1B;YACF;QACF;IACF;AACF"}
|
@@ -0,0 +1,51 @@
|
|
1
|
+
const OFFSET_DISTANCE = 20;
|
2
|
+
/**
|
3
|
+
* Measures the distance between two points in a 2D space.
|
4
|
+
*/ export function measureDistance(a, b) {
|
5
|
+
return Math.sqrt((a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2);
|
6
|
+
}
|
7
|
+
/**
|
8
|
+
* Returns a unit vector pointing from point `b` to point `a`.
|
9
|
+
* If the distance is zero, returns a zero vector.
|
10
|
+
*/ export function getUnitVector(a, b) {
|
11
|
+
const distance = measureDistance(a, b);
|
12
|
+
if (distance === 0) {
|
13
|
+
return [
|
14
|
+
0,
|
15
|
+
0
|
16
|
+
];
|
17
|
+
}
|
18
|
+
return [
|
19
|
+
(a[0] - b[0]) / distance,
|
20
|
+
(a[1] - b[1]) / distance
|
21
|
+
];
|
22
|
+
}
|
23
|
+
/**
|
24
|
+
* Calculates the anchor point for a mouse position within a container defined by its top-left and bottom-right corners.
|
25
|
+
* The anchor point is calculated as an offset from the center of the container in the direction of the mouse position.
|
26
|
+
*
|
27
|
+
* @internal
|
28
|
+
*/ export function getMouseAnchor(topLeftCorner, bottomRightCorner, mouseCoordinates) {
|
29
|
+
const containerCenter = [
|
30
|
+
(topLeftCorner[0] + bottomRightCorner[0]) / 2,
|
31
|
+
(topLeftCorner[1] + bottomRightCorner[1]) / 2
|
32
|
+
];
|
33
|
+
const unitVector = getUnitVector([
|
34
|
+
mouseCoordinates[0],
|
35
|
+
mouseCoordinates[1]
|
36
|
+
], [
|
37
|
+
containerCenter[0],
|
38
|
+
containerCenter[1]
|
39
|
+
]);
|
40
|
+
const distance = measureDistance([
|
41
|
+
containerCenter[0],
|
42
|
+
containerCenter[1]
|
43
|
+
], [
|
44
|
+
mouseCoordinates[0],
|
45
|
+
mouseCoordinates[1]
|
46
|
+
]);
|
47
|
+
return [
|
48
|
+
containerCenter[0] + unitVector[0] * (distance + OFFSET_DISTANCE),
|
49
|
+
containerCenter[1] + unitVector[1] * (distance + OFFSET_DISTANCE)
|
50
|
+
];
|
51
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useSafeZoneArea/getMouseAnchor.ts"],"sourcesContent":["import type { Point } from './types';\n\nconst OFFSET_DISTANCE = 20;\n\n/**\n * Measures the distance between two points in a 2D space.\n */\nexport function measureDistance(a: Point, b: Point) {\n return Math.sqrt((a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2);\n}\n\n/**\n * Returns a unit vector pointing from point `b` to point `a`.\n * If the distance is zero, returns a zero vector.\n */\nexport function getUnitVector(a: Point, b: Point): Point {\n const distance = measureDistance(a, b);\n\n if (distance === 0) {\n return [0, 0];\n }\n\n return [(a[0] - b[0]) / distance, (a[1] - b[1]) / distance];\n}\n\n/**\n * Calculates the anchor point for a mouse position within a container defined by its top-left and bottom-right corners.\n * The anchor point is calculated as an offset from the center of the container in the direction of the mouse position.\n *\n * @internal\n */\nexport function getMouseAnchor(topLeftCorner: Point, bottomRightCorner: Point, mouseCoordinates: Point): Point {\n const containerCenter: Point = [\n (topLeftCorner[0] + bottomRightCorner[0]) / 2,\n (topLeftCorner[1] + bottomRightCorner[1]) / 2,\n ];\n\n const unitVector = getUnitVector(\n [mouseCoordinates[0], mouseCoordinates[1]],\n [containerCenter[0], containerCenter[1]],\n );\n const distance = measureDistance(\n [containerCenter[0], containerCenter[1]],\n [mouseCoordinates[0], mouseCoordinates[1]],\n );\n\n return [\n containerCenter[0] + unitVector[0] * (distance + OFFSET_DISTANCE),\n containerCenter[1] + unitVector[1] * (distance + OFFSET_DISTANCE),\n ];\n}\n"],"names":["OFFSET_DISTANCE","measureDistance","a","b","Math","sqrt","getUnitVector","distance","getMouseAnchor","topLeftCorner","bottomRightCorner","mouseCoordinates","containerCenter","unitVector"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAEA,MAAMA,kBAAkB;AAExB;;CAEC,GACD,OAAO,SAASC,gBAAgBC,CAAQ,EAAEC,CAAQ;IAChD,OAAOC,KAAKC,IAAI,CAAC,AAACH,CAAAA,CAAC,CAAC,EAAE,GAAGC,CAAC,CAAC,EAAE,AAAD,KAAM,IAAI,AAACD,CAAAA,CAAC,CAAC,EAAE,GAAGC,CAAC,CAAC,EAAE,AAAD,KAAM;AACzD;AAEA;;;CAGC,GACD,OAAO,SAASG,cAAcJ,CAAQ,EAAEC,CAAQ;IAC9C,MAAMI,WAAWN,gBAAgBC,GAAGC;IAEpC,IAAII,aAAa,GAAG;QAClB,OAAO;YAAC;YAAG;SAAE;IACf;IAEA,OAAO;QAAEL,CAAAA,CAAC,CAAC,EAAE,GAAGC,CAAC,CAAC,EAAE,AAAD,IAAKI;QAAWL,CAAAA,CAAC,CAAC,EAAE,GAAGC,CAAC,CAAC,EAAE,AAAD,IAAKI;KAAS;AAC7D;AAEA;;;;;CAKC,GACD,OAAO,SAASC,eAAeC,aAAoB,EAAEC,iBAAwB,EAAEC,gBAAuB;IACpG,MAAMC,kBAAyB;QAC5BH,CAAAA,aAAa,CAAC,EAAE,GAAGC,iBAAiB,CAAC,EAAE,AAAD,IAAK;QAC3CD,CAAAA,aAAa,CAAC,EAAE,GAAGC,iBAAiB,CAAC,EAAE,AAAD,IAAK;KAC7C;IAED,MAAMG,aAAaP,cACjB;QAACK,gBAAgB,CAAC,EAAE;QAAEA,gBAAgB,CAAC,EAAE;KAAC,EAC1C;QAACC,eAAe,CAAC,EAAE;QAAEA,eAAe,CAAC,EAAE;KAAC;IAE1C,MAAML,WAAWN,gBACf;QAACW,eAAe,CAAC,EAAE;QAAEA,eAAe,CAAC,EAAE;KAAC,EACxC;QAACD,gBAAgB,CAAC,EAAE;QAAEA,gBAAgB,CAAC,EAAE;KAAC;IAG5C,OAAO;QACLC,eAAe,CAAC,EAAE,GAAGC,UAAU,CAAC,EAAE,GAAIN,CAAAA,WAAWP,eAAc;QAC/DY,eAAe,CAAC,EAAE,GAAGC,UAAU,CAAC,EAAE,GAAIN,CAAAA,WAAWP,eAAc;KAChE;AACH"}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
/**
|
2
|
+
* Calculates the corners of a rectangle based on its DOMRect and an offset.
|
3
|
+
*
|
4
|
+
* @internal
|
5
|
+
*/ export function getRectCorners(rect, offset) {
|
6
|
+
return {
|
7
|
+
topLeft: [
|
8
|
+
rect.left - offset[0],
|
9
|
+
rect.top - offset[1]
|
10
|
+
],
|
11
|
+
topRight: [
|
12
|
+
rect.right - offset[0],
|
13
|
+
rect.top - offset[1]
|
14
|
+
],
|
15
|
+
bottomRight: [
|
16
|
+
rect.right - offset[0],
|
17
|
+
rect.bottom - offset[1]
|
18
|
+
],
|
19
|
+
bottomLeft: [
|
20
|
+
rect.left - offset[0],
|
21
|
+
rect.bottom - offset[1]
|
22
|
+
]
|
23
|
+
};
|
24
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useSafeZoneArea/getRectCorners.ts"],"sourcesContent":["import type { Point } from './types';\n\n/**\n * Calculates the corners of a rectangle based on its DOMRect and an offset.\n *\n * @internal\n */\nexport function getRectCorners(\n rect: DOMRect,\n offset: Point,\n): Record<'topLeft' | 'topRight' | 'bottomRight' | 'bottomLeft', Point> {\n return {\n topLeft: [rect.left - offset[0], rect.top - offset[1]],\n topRight: [rect.right - offset[0], rect.top - offset[1]],\n bottomRight: [rect.right - offset[0], rect.bottom - offset[1]],\n bottomLeft: [rect.left - offset[0], rect.bottom - offset[1]],\n };\n}\n"],"names":["getRectCorners","rect","offset","topLeft","left","top","topRight","right","bottomRight","bottom","bottomLeft"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAEA;;;;CAIC,GACD,OAAO,SAASA,eACdC,IAAa,EACbC,MAAa;IAEb,OAAO;QACLC,SAAS;YAACF,KAAKG,IAAI,GAAGF,MAAM,CAAC,EAAE;YAAED,KAAKI,GAAG,GAAGH,MAAM,CAAC,EAAE;SAAC;QACtDI,UAAU;YAACL,KAAKM,KAAK,GAAGL,MAAM,CAAC,EAAE;YAAED,KAAKI,GAAG,GAAGH,MAAM,CAAC,EAAE;SAAC;QACxDM,aAAa;YAACP,KAAKM,KAAK,GAAGL,MAAM,CAAC,EAAE;YAAED,KAAKQ,MAAM,GAAGP,MAAM,CAAC,EAAE;SAAC;QAC9DQ,YAAY;YAACT,KAAKG,IAAI,GAAGF,MAAM,CAAC,EAAE;YAAED,KAAKQ,MAAM,GAAGP,MAAM,CAAC,EAAE;SAAC;IAC9D;AACF"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useSafeZoneArea/pointsToSvgPath.ts"],"sourcesContent":["import type { Point } from './types';\n\n/**\n * Calculates the corners of a rectangle based on its DOMRect and an offset.\n *\n * @internal\n */\nexport function pointsToSvgPath(points: Point[]) {\n return `M ${points} z`;\n}\n"],"names":["pointsToSvgPath","points"],"rangeMappings":";;;;;;","mappings":"AAEA;;;;CAIC,GACD,OAAO,SAASA,gBAAgBC,MAAe;IAC7C,OAAO,CAAC,EAAE,EAAEA,OAAO,EAAE,CAAC;AACxB"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useSafeZoneArea/types.ts"],"sourcesContent":["/**\n * A type representing a point in a 2D space as an array of two numbers (x & y coordinates).\n *\n * @internal\n */\nexport type Point = [number, number];\n"],"names":[],"rangeMappings":";;;;","mappings":"AAAA;;;;CAIC,GACD,WAAqC"}
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import { useFluent_unstable } from '@fluentui/react-shared-contexts';
|
2
2
|
import { useEventCallback, useMergedRefs } from '@fluentui/react-utilities';
|
3
3
|
import * as React from 'react';
|
4
|
-
import { createSafeZoneAreaStateStore
|
5
|
-
import {
|
4
|
+
import { createSafeZoneAreaStateStore } from './createSafeZoneAreaStateStore';
|
5
|
+
import { SafeZoneArea } from './SafeZoneArea';
|
6
6
|
export function useSafeZoneArea({ debug = false, disabled = false, onSafeZoneEnter, onSafeZoneMove, onSafeZoneLeave, onSafeZoneTimeout, timeout = 1500 } = {}) {
|
7
7
|
const [stateStore] = React.useState(createSafeZoneAreaStateStore);
|
8
8
|
const { targetDocument } = useFluent_unstable();
|
@@ -122,9 +122,11 @@ export function useSafeZoneArea({ debug = false, disabled = false, onSafeZoneEnt
|
|
122
122
|
if (containerEl && targetEl) {
|
123
123
|
var _safeZoneAreaRef_current;
|
124
124
|
(_safeZoneAreaRef_current = safeZoneAreaRef.current) === null || _safeZoneAreaRef_current === void 0 ? void 0 : _safeZoneAreaRef_current.updateSVG({
|
125
|
-
containerPlacementSide: parseFloatingUIPlacement(containerEl.dataset.popperPlacement).side,
|
126
125
|
containerRect: containerEl.getBoundingClientRect(),
|
127
|
-
mouseCoordinates:
|
126
|
+
mouseCoordinates: [
|
127
|
+
mouseCoordinatesRef.current.x,
|
128
|
+
mouseCoordinatesRef.current.y
|
129
|
+
],
|
128
130
|
targetRect: targetEl.getBoundingClientRect()
|
129
131
|
});
|
130
132
|
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useSafeZoneArea/useSafeZoneArea.tsx"],"sourcesContent":["import { useFluent_unstable } from '@fluentui/react-shared-contexts';\nimport { useEventCallback, useMergedRefs } from '@fluentui/react-utilities';\nimport * as React from 'react';\n\nimport { createSafeZoneAreaStateStore } from './createSafeZoneAreaStateStore';\nimport { type SafeZoneAreaImperativeHandle, SafeZoneArea } from './SafeZoneArea';\n\nexport type UseSafeZoneOptions = {\n /** Enables debug mode: makes drawn shapes visible. */\n debug?: boolean;\n\n /** Disables the safe zone area. */\n disabled?: boolean;\n\n /** The time in milliseconds to wait before clearing the safe zone. */\n timeout?: number;\n\n /** Called when the mouse enters the safe zone. */\n onSafeZoneEnter?: (e: React.MouseEvent) => void;\n\n /** Called when the mouse moves within the safe zone. */\n onSafeZoneMove?: (e: React.MouseEvent) => void;\n\n /** Called when the mouse leaves the safe zone. */\n onSafeZoneLeave?: (e: React.MouseEvent) => void;\n\n /** Called when the safe zone times out, even if a cursor is still over a safe zone. */\n onSafeZoneTimeout?: () => void;\n};\n\nexport function useSafeZoneArea({\n debug = false,\n disabled = false,\n\n onSafeZoneEnter,\n onSafeZoneMove,\n onSafeZoneLeave,\n onSafeZoneTimeout,\n\n timeout = 1500,\n}: UseSafeZoneOptions = {}) {\n const [stateStore] = React.useState(createSafeZoneAreaStateStore);\n const { targetDocument } = useFluent_unstable();\n\n const safeZoneAreaRef = React.useRef<SafeZoneAreaImperativeHandle>(null);\n const containerRef = React.useRef<HTMLElement>(null);\n const targetRef = React.useRef<HTMLElement>(null);\n\n const timeoutIdRef = React.useRef<number | null>(null);\n const mouseMoveIdRef = React.useRef<number | null>(null);\n\n const mouseCoordinatesRef = React.useRef<{ x: number; y: number }>({ x: 0, y: 0 });\n\n const containerListenerRef = React.useMemo(() => {\n if (disabled) {\n return () => {\n // do nothing\n };\n }\n\n let containerEl: HTMLElement | null = null;\n\n function onContainerMouseEnter() {\n const targetWindow = targetDocument?.defaultView;\n\n if (!targetWindow) {\n return;\n }\n\n if (timeoutIdRef.current) {\n targetWindow.clearTimeout(timeoutIdRef.current);\n timeoutIdRef.current = null;\n }\n\n stateStore.toggleActive(false);\n }\n\n return (el: HTMLElement | null) => {\n if (el === null) {\n containerEl?.removeEventListener('mouseenter', onContainerMouseEnter);\n }\n\n containerEl = el;\n el?.addEventListener('mouseenter', onContainerMouseEnter);\n };\n }, [disabled, stateStore, targetDocument]);\n\n const targetListenerRef = React.useMemo(() => {\n if (disabled) {\n return () => {\n // do nothing\n };\n }\n\n let targetEl: HTMLElement | null = null;\n\n function onTargetMouseMove(e: MouseEvent) {\n mouseCoordinatesRef.current = { x: e.clientX, y: e.clientY };\n\n if (timeoutIdRef.current) {\n targetDocument?.defaultView?.clearTimeout(timeoutIdRef.current);\n timeoutIdRef.current = null;\n }\n\n if (!stateStore.isActive()) {\n stateStore.toggleActive(true);\n }\n }\n\n return (el: HTMLElement | null) => {\n if (el === null) {\n const targetWindow = targetDocument?.defaultView;\n\n if (targetWindow) {\n if (mouseMoveIdRef.current) {\n targetWindow.cancelAnimationFrame(mouseMoveIdRef.current);\n mouseMoveIdRef.current = null;\n }\n\n if (timeoutIdRef.current) {\n targetWindow.clearTimeout(timeoutIdRef.current);\n timeoutIdRef.current = null;\n }\n }\n\n targetEl?.removeEventListener('mousemove', onTargetMouseMove);\n }\n\n targetEl = el;\n el?.addEventListener('mousemove', onTargetMouseMove);\n };\n }, [disabled, stateStore, targetDocument]);\n\n const onSvgMouseEnter = useEventCallback((e: React.MouseEvent) => {\n onSafeZoneEnter?.(e);\n\n const targetWindow = targetDocument?.defaultView;\n\n if (!targetWindow) {\n return;\n }\n\n if (timeoutIdRef.current) {\n targetWindow.clearTimeout(timeoutIdRef.current);\n timeoutIdRef.current = null;\n }\n\n // React 17 still uses pooled synthetic events\n e.persist();\n\n timeoutIdRef.current = targetWindow.setTimeout(() => {\n stateStore.toggleActive(false);\n onSafeZoneTimeout?.();\n }, timeout);\n });\n\n const onSvgMouseMove = useEventCallback((e: React.MouseEvent) => {\n onSafeZoneMove?.(e);\n });\n\n const onSvgMouseLeave = useEventCallback((e: React.MouseEvent) => {\n onSafeZoneLeave?.(e);\n });\n\n React.useEffect(() => {\n return stateStore.subscribe(isActive => {\n if (isActive) {\n function updateSVGs() {\n const containerEl = containerRef.current;\n const targetEl = targetRef.current;\n const targetWindow = targetDocument?.defaultView;\n\n if (containerEl && targetEl) {\n safeZoneAreaRef.current?.updateSVG({\n containerRect: containerEl.getBoundingClientRect(),\n mouseCoordinates: [mouseCoordinatesRef.current.x, mouseCoordinatesRef.current.y],\n targetRect: targetEl.getBoundingClientRect(),\n });\n }\n\n if (targetWindow) {\n mouseMoveIdRef.current = targetWindow.requestAnimationFrame(updateSVGs);\n }\n }\n\n updateSVGs();\n return;\n }\n\n if (mouseMoveIdRef.current) {\n targetDocument?.defaultView?.cancelAnimationFrame(mouseMoveIdRef.current);\n mouseMoveIdRef.current = null;\n }\n });\n }, [stateStore, targetDocument]);\n\n return {\n containerRef: useMergedRefs(containerRef, containerListenerRef),\n targetRef: useMergedRefs(targetRef, targetListenerRef),\n\n elementToRender: React.useMemo(\n () =>\n disabled ? null : (\n <SafeZoneArea\n debug={debug}\n onMouseEnter={onSvgMouseEnter}\n onMouseMove={onSvgMouseMove}\n onMouseLeave={onSvgMouseLeave}\n imperativeRef={safeZoneAreaRef}\n stateStore={stateStore}\n />\n ),\n [disabled, debug, onSvgMouseEnter, onSvgMouseMove, onSvgMouseLeave, stateStore],\n ),\n };\n}\n"],"names":["useFluent_unstable","useEventCallback","useMergedRefs","React","createSafeZoneAreaStateStore","SafeZoneArea","useSafeZoneArea","debug","disabled","onSafeZoneEnter","onSafeZoneMove","onSafeZoneLeave","onSafeZoneTimeout","timeout","stateStore","useState","targetDocument","safeZoneAreaRef","useRef","containerRef","targetRef","timeoutIdRef","mouseMoveIdRef","mouseCoordinatesRef","x","y","containerListenerRef","useMemo","containerEl","onContainerMouseEnter","targetWindow","defaultView","current","clearTimeout","toggleActive","el","removeEventListener","addEventListener","targetListenerRef","targetEl","onTargetMouseMove","e","clientX","clientY","isActive","cancelAnimationFrame","onSvgMouseEnter","persist","setTimeout","onSvgMouseMove","onSvgMouseLeave","useEffect","subscribe","updateSVGs","updateSVG","containerRect","getBoundingClientRect","mouseCoordinates","targetRect","requestAnimationFrame","elementToRender","onMouseEnter","onMouseMove","onMouseLeave","imperativeRef"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
package/lib/index.js
CHANGED
@@ -4,5 +4,5 @@ export { createSlideStyles } from './createSlideStyles';
|
|
4
4
|
export { PositioningConfigurationProvider } from './PositioningConfigurationContext';
|
5
5
|
export { usePositioning } from './usePositioning';
|
6
6
|
export { usePositioningMouseTarget } from './usePositioningMouseTarget';
|
7
|
-
export { useSafeZoneArea } from './useSafeZoneArea';
|
7
|
+
export { useSafeZoneArea } from './hooks/useSafeZoneArea/useSafeZoneArea';
|
8
8
|
export { resolvePositioningShorthand, mergeArrowOffset } from './utils/index';
|
package/lib/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { createVirtualElementFromClick } from './createVirtualElementFromClick';\nexport { createArrowHeightStyles, createArrowStyles } from './createArrowStyles';\nexport { createSlideStyles } from './createSlideStyles';\nexport type { CreateArrowStylesOptions } from './createArrowStyles';\n\nexport { PositioningConfigurationProvider } from './PositioningConfigurationContext';\n\nexport { usePositioning } from './usePositioning';\nexport { usePositioningMouseTarget } from './usePositioningMouseTarget';\nexport { useSafeZoneArea } from './useSafeZoneArea';\nexport type {
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { createVirtualElementFromClick } from './createVirtualElementFromClick';\nexport { createArrowHeightStyles, createArrowStyles } from './createArrowStyles';\nexport { createSlideStyles } from './createSlideStyles';\nexport type { CreateArrowStylesOptions } from './createArrowStyles';\n\nexport { PositioningConfigurationProvider } from './PositioningConfigurationContext';\n\nexport { usePositioning } from './usePositioning';\nexport { usePositioningMouseTarget } from './usePositioningMouseTarget';\nexport { useSafeZoneArea } from './hooks/useSafeZoneArea/useSafeZoneArea';\nexport type { UseSafeZoneOptions } from './hooks/useSafeZoneArea/useSafeZoneArea';\nexport { resolvePositioningShorthand, mergeArrowOffset } from './utils/index';\n\nexport type {\n Alignment,\n AutoSize,\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n Boundary,\n Offset,\n OffsetFunction,\n OffsetFunctionParam,\n OffsetObject,\n OffsetShorthand,\n Position,\n PositioningBoundary,\n PositioningImperativeRef,\n PositioningProps,\n PositioningRect,\n PositioningShorthand,\n PositioningShorthandValue,\n PositioningVirtualElement,\n SetVirtualMouseTarget,\n PositioningConfigurationFn,\n PositioningConfigurationFnOptions,\n} from './types';\n"],"names":["createVirtualElementFromClick","createArrowHeightStyles","createArrowStyles","createSlideStyles","PositioningConfigurationProvider","usePositioning","usePositioningMouseTarget","useSafeZoneArea","resolvePositioningShorthand","mergeArrowOffset"],"rangeMappings":";;;;;;;","mappings":"AAAA,SAASA,6BAA6B,QAAQ,kCAAkC;AAChF,SAASC,uBAAuB,EAAEC,iBAAiB,QAAQ,sBAAsB;AACjF,SAASC,iBAAiB,QAAQ,sBAAsB;AAGxD,SAASC,gCAAgC,QAAQ,oCAAoC;AAErF,SAASC,cAAc,QAAQ,mBAAmB;AAClD,SAASC,yBAAyB,QAAQ,8BAA8B;AACxE,SAASC,eAAe,QAAQ,0CAA0C;AAE1E,SAASC,2BAA2B,EAAEC,gBAAgB,QAAQ,gBAAgB"}
|