@itwin/itwinui-react 2.12.17 → 2.12.19
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 +13 -0
- package/LICENSE.md +1 -1
- package/cjs/core/Dialog/DialogMain.js +25 -4
- package/cjs/core/Menu/MenuItem.js +5 -3
- package/cjs/core/utils/components/Resizer.js +1 -1
- package/cjs/core/utils/functions/dom.d.ts +2 -1
- package/cjs/core/utils/functions/dom.js +6 -2
- package/cjs/core/utils/functions/numbers.d.ts +7 -0
- package/cjs/core/utils/functions/numbers.js +12 -1
- package/cjs/core/utils/hooks/useDragAndDrop.js +2 -2
- package/esm/core/Dialog/DialogMain.js +26 -5
- package/esm/core/Menu/MenuItem.js +5 -3
- package/esm/core/utils/components/Resizer.js +2 -2
- package/esm/core/utils/functions/dom.d.ts +2 -1
- package/esm/core/utils/functions/dom.js +4 -1
- package/esm/core/utils/functions/numbers.d.ts +7 -0
- package/esm/core/utils/functions/numbers.js +10 -0
- package/esm/core/utils/hooks/useDragAndDrop.js +3 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.12.19
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1765](https://github.com/iTwin/iTwinUI/pull/1765): Fixed full page `Modal` not showing up.
|
|
8
|
+
- [#1764](https://github.com/iTwin/iTwinUI/pull/1764): Fixed submenu items being unreachable in popout windows.
|
|
9
|
+
|
|
10
|
+
## 2.12.18
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- a68561cf: Fixed an issue where Dialog content was appearing blurred on Windows.
|
|
15
|
+
|
|
3
16
|
## 2.12.17
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
package/LICENSE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# MIT License
|
|
2
2
|
|
|
3
|
-
Copyright © 2021-
|
|
3
|
+
Copyright © 2021-2024 Bentley Systems, Incorporated. All rights reserved.
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
6
|
|
|
@@ -64,7 +64,7 @@ exports.DialogMain = React.forwardRef((props, ref) => {
|
|
|
64
64
|
(0, index_js_1.useTheme)();
|
|
65
65
|
const [style, setStyle] = React.useState();
|
|
66
66
|
const dialogRef = React.useRef(null);
|
|
67
|
-
const
|
|
67
|
+
const [dialogElement, setDialogElement] = React.useState();
|
|
68
68
|
const hasBeenResized = React.useRef(false);
|
|
69
69
|
const previousFocusedElement = React.useRef();
|
|
70
70
|
const originalBodyOverflow = React.useRef('');
|
|
@@ -118,7 +118,7 @@ exports.DialogMain = React.forwardRef((props, ref) => {
|
|
|
118
118
|
return;
|
|
119
119
|
}
|
|
120
120
|
const rect = (_a = dialogRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
|
|
121
|
-
const [translateX, translateY] = (0, index_js_1.
|
|
121
|
+
const [translateX, translateY] = (0, index_js_1.getTranslateValuesFromElement)(dialogRef.current);
|
|
122
122
|
setStyle((oldStyle) => {
|
|
123
123
|
var _a, _b;
|
|
124
124
|
return ({
|
|
@@ -137,13 +137,17 @@ exports.DialogMain = React.forwardRef((props, ref) => {
|
|
|
137
137
|
...newStyle,
|
|
138
138
|
}));
|
|
139
139
|
}, []);
|
|
140
|
+
const roundedTransform = useRoundedTransform({
|
|
141
|
+
element: dialogElement,
|
|
142
|
+
transform,
|
|
143
|
+
});
|
|
140
144
|
const content = (React.createElement("div", { className: (0, classnames_1.default)('iui-dialog', {
|
|
141
145
|
'iui-dialog-default': styleType === 'default',
|
|
142
146
|
'iui-dialog-full-page': styleType === 'fullPage',
|
|
143
147
|
'iui-dialog-visible': isOpen,
|
|
144
148
|
'iui-dialog-draggable': isDraggable,
|
|
145
|
-
}, className), role: 'dialog', ref:
|
|
146
|
-
transform,
|
|
149
|
+
}, className), role: 'dialog', ref: (0, index_js_1.useMergedRefs)(dialogRef, ref, setDialogElement), onKeyDown: handleKeyDown, tabIndex: -1, "data-iui-placement": placement, style: {
|
|
150
|
+
transform: styleType !== 'fullPage' ? roundedTransform : undefined,
|
|
147
151
|
...style,
|
|
148
152
|
...propStyle,
|
|
149
153
|
}, ...rest },
|
|
@@ -176,3 +180,20 @@ exports.DialogMain = React.forwardRef((props, ref) => {
|
|
|
176
180
|
!trapFocus && content)));
|
|
177
181
|
});
|
|
178
182
|
exports.default = exports.DialogMain;
|
|
183
|
+
// ----------------------------------------------------------------------------
|
|
184
|
+
/**
|
|
185
|
+
* Rounds off an element's transform value based on the device's pixel grid, to avoid blurring.
|
|
186
|
+
*/
|
|
187
|
+
const useRoundedTransform = ({ element, transform, }) => {
|
|
188
|
+
const [roundedStyles, setRoundedStyles] = React.useState(transform);
|
|
189
|
+
(0, index_js_1.useIsomorphicLayoutEffect)(() => {
|
|
190
|
+
if (!element || typeof DOMMatrix === 'undefined') {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const [x, y] = transform
|
|
194
|
+
? (0, index_js_1.getTranslateValues)(transform)
|
|
195
|
+
: (0, index_js_1.getTranslateValuesFromElement)(element);
|
|
196
|
+
setRoundedStyles(`translate(${(0, index_js_1.roundByDPR)(x)}px, ${(0, index_js_1.roundByDPR)(y)}px)`);
|
|
197
|
+
}, [element, transform]);
|
|
198
|
+
return roundedStyles;
|
|
199
|
+
};
|
|
@@ -85,10 +85,12 @@ exports.MenuItem = React.forwardRef((props, ref) => {
|
|
|
85
85
|
'iui-disabled': disabled,
|
|
86
86
|
}, className), onClick: () => !disabled && (onClick === null || onClick === void 0 ? void 0 : onClick(value)), ref: refs, style: style, role: role, tabIndex: disabled || role === 'presentation' ? undefined : -1, "aria-selected": isSelected, "aria-haspopup": subMenuItems.length > 0, "aria-disabled": disabled, onKeyDown: onKeyDown, onMouseEnter: () => setIsSubmenuVisible(true), onMouseLeave: (e) => {
|
|
87
87
|
var _a;
|
|
88
|
-
|
|
89
|
-
!((_a = subMenuRef.current) === null || _a === void 0 ? void 0 : _a.contains(e.relatedTarget))) {
|
|
90
|
-
|
|
88
|
+
try {
|
|
89
|
+
if (!((_a = subMenuRef.current) === null || _a === void 0 ? void 0 : _a.contains(e.relatedTarget))) {
|
|
90
|
+
setIsSubmenuVisible(false);
|
|
91
|
+
}
|
|
91
92
|
}
|
|
93
|
+
catch (_b) { }
|
|
92
94
|
}, ...rest },
|
|
93
95
|
icon &&
|
|
94
96
|
React.cloneElement(icon, {
|
|
@@ -51,7 +51,7 @@ const Resizer = (props) => {
|
|
|
51
51
|
}
|
|
52
52
|
const initialPointerX = event.clientX;
|
|
53
53
|
const initialPointerY = event.clientY;
|
|
54
|
-
const [initialTranslateX, initialTranslateY] = (0, index_js_1.
|
|
54
|
+
const [initialTranslateX, initialTranslateY] = (0, index_js_1.getTranslateValuesFromElement)(elementRef.current);
|
|
55
55
|
const { width: initialWidth, height: initialHeight } = elementRef.current.getBoundingClientRect();
|
|
56
56
|
let width = `${initialWidth}px`;
|
|
57
57
|
let height = `${initialHeight}px`;
|
|
@@ -27,4 +27,5 @@ export declare const mergeEventHandlers: <E extends import("react").SyntheticEve
|
|
|
27
27
|
* @param element HTML element you want to get translate value of
|
|
28
28
|
* @returns Translate values in pixels in an array `[translateX, translateY]`
|
|
29
29
|
*/
|
|
30
|
-
export declare const
|
|
30
|
+
export declare const getTranslateValuesFromElement: (element: HTMLElement | null | undefined) => number[];
|
|
31
|
+
export declare const getTranslateValues: (transformValue: string) => number[];
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
5
|
*--------------------------------------------------------------------------------------------*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.getTranslateValues = exports.mergeEventHandlers = exports.getWindow = exports.getDocument = exports.getContainer = void 0;
|
|
7
|
+
exports.getTranslateValues = exports.getTranslateValuesFromElement = exports.mergeEventHandlers = exports.getWindow = exports.getDocument = exports.getContainer = void 0;
|
|
8
8
|
/**
|
|
9
9
|
* Get the container as a child of body, or create one if it doesn't exist.
|
|
10
10
|
* Mostly used for dynamic components like Modal or Toast.
|
|
@@ -58,11 +58,15 @@ exports.mergeEventHandlers = mergeEventHandlers;
|
|
|
58
58
|
* @param element HTML element you want to get translate value of
|
|
59
59
|
* @returns Translate values in pixels in an array `[translateX, translateY]`
|
|
60
60
|
*/
|
|
61
|
-
const
|
|
61
|
+
const getTranslateValuesFromElement = (element) => {
|
|
62
62
|
if (!element) {
|
|
63
63
|
return [];
|
|
64
64
|
}
|
|
65
65
|
const transformValue = getComputedStyle(element).getPropertyValue('transform');
|
|
66
|
+
return (0, exports.getTranslateValues)(transformValue);
|
|
67
|
+
};
|
|
68
|
+
exports.getTranslateValuesFromElement = getTranslateValuesFromElement;
|
|
69
|
+
const getTranslateValues = (transformValue) => {
|
|
66
70
|
const matrix = new DOMMatrix(transformValue);
|
|
67
71
|
return [matrix.m41, matrix.m42];
|
|
68
72
|
};
|
|
@@ -6,3 +6,10 @@ export declare const getBoundedValue: (val: number, min: number, max: number) =>
|
|
|
6
6
|
* Returns a random value of a given length containing `A-Za-z0-9_-` symbols.
|
|
7
7
|
*/
|
|
8
8
|
export declare const getRandomValue: (length?: number) => string;
|
|
9
|
+
/**
|
|
10
|
+
* Rounds a pixel value based on the device's pixel ratio. This ensures that values can be
|
|
11
|
+
* placed evenly on the device’s pixel grid, avoiding any blurring.
|
|
12
|
+
*
|
|
13
|
+
* @see https://floating-ui.com/docs/misc#subpixel-and-accelerated-positioning
|
|
14
|
+
*/
|
|
15
|
+
export declare const roundByDPR: (value: number) => number;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
5
|
*--------------------------------------------------------------------------------------------*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.getRandomValue = exports.getBoundedValue = void 0;
|
|
7
|
+
exports.roundByDPR = exports.getRandomValue = exports.getBoundedValue = void 0;
|
|
8
8
|
/**
|
|
9
9
|
* Return input value bounded by specified range.
|
|
10
10
|
*/
|
|
@@ -24,3 +24,14 @@ const getRandomValue = (length = 21) => {
|
|
|
24
24
|
return id;
|
|
25
25
|
};
|
|
26
26
|
exports.getRandomValue = getRandomValue;
|
|
27
|
+
/**
|
|
28
|
+
* Rounds a pixel value based on the device's pixel ratio. This ensures that values can be
|
|
29
|
+
* placed evenly on the device’s pixel grid, avoiding any blurring.
|
|
30
|
+
*
|
|
31
|
+
* @see https://floating-ui.com/docs/misc#subpixel-and-accelerated-positioning
|
|
32
|
+
*/
|
|
33
|
+
const roundByDPR = (value) => {
|
|
34
|
+
const dpr = window.devicePixelRatio || 1;
|
|
35
|
+
return Math.round(value * dpr) / dpr;
|
|
36
|
+
};
|
|
37
|
+
exports.roundByDPR = roundByDPR;
|
|
@@ -62,7 +62,7 @@ const useDragAndDrop = (elementRef, containerRef, enabled = true) => {
|
|
|
62
62
|
return;
|
|
63
63
|
}
|
|
64
64
|
const { top, right, bottom, left } = (_a = elementRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
|
|
65
|
-
let [newTranslateX, newTranslateY] = (0, index_js_1.
|
|
65
|
+
let [newTranslateX, newTranslateY] = (0, index_js_1.getTranslateValuesFromElement)(elementRef.current);
|
|
66
66
|
containerRectRef.current = getContainerRect(containerRef);
|
|
67
67
|
if (bottom > containerRectRef.current.bottom) {
|
|
68
68
|
newTranslateY -= bottom - containerRectRef.current.bottom;
|
|
@@ -108,7 +108,7 @@ const useDragAndDrop = (elementRef, containerRef, enabled = true) => {
|
|
|
108
108
|
if (!elementRef.current || e.button !== 0 || !enabled) {
|
|
109
109
|
return;
|
|
110
110
|
}
|
|
111
|
-
const [x, y] = (0, index_js_1.
|
|
111
|
+
const [x, y] = (0, index_js_1.getTranslateValuesFromElement)(elementRef.current);
|
|
112
112
|
grabOffsetX.current = e.clientX - x;
|
|
113
113
|
grabOffsetY.current = e.clientY - y;
|
|
114
114
|
originalUserSelect.current = elementRef.current.style.userSelect;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
import * as React from 'react';
|
|
6
6
|
import cx from 'classnames';
|
|
7
|
-
import { FocusTrap,
|
|
7
|
+
import { FocusTrap, getTranslateValuesFromElement, Resizer, useMergedRefs, useTheme, useIsomorphicLayoutEffect, getTranslateValues, roundByDPR, } from '../utils/index.js';
|
|
8
8
|
import { useDialogContext } from './DialogContext.js';
|
|
9
9
|
import { CSSTransition } from 'react-transition-group';
|
|
10
10
|
import { DialogDragContext } from './DialogDragContext.js';
|
|
@@ -35,7 +35,7 @@ export const DialogMain = React.forwardRef((props, ref) => {
|
|
|
35
35
|
useTheme();
|
|
36
36
|
const [style, setStyle] = React.useState();
|
|
37
37
|
const dialogRef = React.useRef(null);
|
|
38
|
-
const
|
|
38
|
+
const [dialogElement, setDialogElement] = React.useState();
|
|
39
39
|
const hasBeenResized = React.useRef(false);
|
|
40
40
|
const previousFocusedElement = React.useRef();
|
|
41
41
|
const originalBodyOverflow = React.useRef('');
|
|
@@ -89,7 +89,7 @@ export const DialogMain = React.forwardRef((props, ref) => {
|
|
|
89
89
|
return;
|
|
90
90
|
}
|
|
91
91
|
const rect = (_a = dialogRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
|
|
92
|
-
const [translateX, translateY] =
|
|
92
|
+
const [translateX, translateY] = getTranslateValuesFromElement(dialogRef.current);
|
|
93
93
|
setStyle((oldStyle) => {
|
|
94
94
|
var _a, _b;
|
|
95
95
|
return ({
|
|
@@ -108,13 +108,17 @@ export const DialogMain = React.forwardRef((props, ref) => {
|
|
|
108
108
|
...newStyle,
|
|
109
109
|
}));
|
|
110
110
|
}, []);
|
|
111
|
+
const roundedTransform = useRoundedTransform({
|
|
112
|
+
element: dialogElement,
|
|
113
|
+
transform,
|
|
114
|
+
});
|
|
111
115
|
const content = (React.createElement("div", { className: cx('iui-dialog', {
|
|
112
116
|
'iui-dialog-default': styleType === 'default',
|
|
113
117
|
'iui-dialog-full-page': styleType === 'fullPage',
|
|
114
118
|
'iui-dialog-visible': isOpen,
|
|
115
119
|
'iui-dialog-draggable': isDraggable,
|
|
116
|
-
}, className), role: 'dialog', ref:
|
|
117
|
-
transform,
|
|
120
|
+
}, className), role: 'dialog', ref: useMergedRefs(dialogRef, ref, setDialogElement), onKeyDown: handleKeyDown, tabIndex: -1, "data-iui-placement": placement, style: {
|
|
121
|
+
transform: styleType !== 'fullPage' ? roundedTransform : undefined,
|
|
118
122
|
...style,
|
|
119
123
|
...propStyle,
|
|
120
124
|
}, ...rest },
|
|
@@ -147,3 +151,20 @@ export const DialogMain = React.forwardRef((props, ref) => {
|
|
|
147
151
|
!trapFocus && content)));
|
|
148
152
|
});
|
|
149
153
|
export default DialogMain;
|
|
154
|
+
// ----------------------------------------------------------------------------
|
|
155
|
+
/**
|
|
156
|
+
* Rounds off an element's transform value based on the device's pixel grid, to avoid blurring.
|
|
157
|
+
*/
|
|
158
|
+
const useRoundedTransform = ({ element, transform, }) => {
|
|
159
|
+
const [roundedStyles, setRoundedStyles] = React.useState(transform);
|
|
160
|
+
useIsomorphicLayoutEffect(() => {
|
|
161
|
+
if (!element || typeof DOMMatrix === 'undefined') {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const [x, y] = transform
|
|
165
|
+
? getTranslateValues(transform)
|
|
166
|
+
: getTranslateValuesFromElement(element);
|
|
167
|
+
setRoundedStyles(`translate(${roundByDPR(x)}px, ${roundByDPR(y)}px)`);
|
|
168
|
+
}, [element, transform]);
|
|
169
|
+
return roundedStyles;
|
|
170
|
+
};
|
|
@@ -56,10 +56,12 @@ export const MenuItem = React.forwardRef((props, ref) => {
|
|
|
56
56
|
'iui-disabled': disabled,
|
|
57
57
|
}, className), onClick: () => !disabled && (onClick === null || onClick === void 0 ? void 0 : onClick(value)), ref: refs, style: style, role: role, tabIndex: disabled || role === 'presentation' ? undefined : -1, "aria-selected": isSelected, "aria-haspopup": subMenuItems.length > 0, "aria-disabled": disabled, onKeyDown: onKeyDown, onMouseEnter: () => setIsSubmenuVisible(true), onMouseLeave: (e) => {
|
|
58
58
|
var _a;
|
|
59
|
-
|
|
60
|
-
!((_a = subMenuRef.current) === null || _a === void 0 ? void 0 : _a.contains(e.relatedTarget))) {
|
|
61
|
-
|
|
59
|
+
try {
|
|
60
|
+
if (!((_a = subMenuRef.current) === null || _a === void 0 ? void 0 : _a.contains(e.relatedTarget))) {
|
|
61
|
+
setIsSubmenuVisible(false);
|
|
62
|
+
}
|
|
62
63
|
}
|
|
64
|
+
catch (_b) { }
|
|
63
65
|
}, ...rest },
|
|
64
66
|
icon &&
|
|
65
67
|
React.cloneElement(icon, {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
import * as React from 'react';
|
|
6
|
-
import { getBoundedValue,
|
|
6
|
+
import { getBoundedValue, getTranslateValuesFromElement, } from '../functions/index.js';
|
|
7
7
|
/**
|
|
8
8
|
* Component that allows to resize parent element.
|
|
9
9
|
* Parent must have `position: relative`.
|
|
@@ -25,7 +25,7 @@ export const Resizer = (props) => {
|
|
|
25
25
|
}
|
|
26
26
|
const initialPointerX = event.clientX;
|
|
27
27
|
const initialPointerY = event.clientY;
|
|
28
|
-
const [initialTranslateX, initialTranslateY] =
|
|
28
|
+
const [initialTranslateX, initialTranslateY] = getTranslateValuesFromElement(elementRef.current);
|
|
29
29
|
const { width: initialWidth, height: initialHeight } = elementRef.current.getBoundingClientRect();
|
|
30
30
|
let width = `${initialWidth}px`;
|
|
31
31
|
let height = `${initialHeight}px`;
|
|
@@ -27,4 +27,5 @@ export declare const mergeEventHandlers: <E extends import("react").SyntheticEve
|
|
|
27
27
|
* @param element HTML element you want to get translate value of
|
|
28
28
|
* @returns Translate values in pixels in an array `[translateX, translateY]`
|
|
29
29
|
*/
|
|
30
|
-
export declare const
|
|
30
|
+
export declare const getTranslateValuesFromElement: (element: HTMLElement | null | undefined) => number[];
|
|
31
|
+
export declare const getTranslateValues: (transformValue: string) => number[];
|
|
@@ -51,11 +51,14 @@ export const mergeEventHandlers = (...callbacks) => (event) => {
|
|
|
51
51
|
* @param element HTML element you want to get translate value of
|
|
52
52
|
* @returns Translate values in pixels in an array `[translateX, translateY]`
|
|
53
53
|
*/
|
|
54
|
-
export const
|
|
54
|
+
export const getTranslateValuesFromElement = (element) => {
|
|
55
55
|
if (!element) {
|
|
56
56
|
return [];
|
|
57
57
|
}
|
|
58
58
|
const transformValue = getComputedStyle(element).getPropertyValue('transform');
|
|
59
|
+
return getTranslateValues(transformValue);
|
|
60
|
+
};
|
|
61
|
+
export const getTranslateValues = (transformValue) => {
|
|
59
62
|
const matrix = new DOMMatrix(transformValue);
|
|
60
63
|
return [matrix.m41, matrix.m42];
|
|
61
64
|
};
|
|
@@ -6,3 +6,10 @@ export declare const getBoundedValue: (val: number, min: number, max: number) =>
|
|
|
6
6
|
* Returns a random value of a given length containing `A-Za-z0-9_-` symbols.
|
|
7
7
|
*/
|
|
8
8
|
export declare const getRandomValue: (length?: number) => string;
|
|
9
|
+
/**
|
|
10
|
+
* Rounds a pixel value based on the device's pixel ratio. This ensures that values can be
|
|
11
|
+
* placed evenly on the device’s pixel grid, avoiding any blurring.
|
|
12
|
+
*
|
|
13
|
+
* @see https://floating-ui.com/docs/misc#subpixel-and-accelerated-positioning
|
|
14
|
+
*/
|
|
15
|
+
export declare const roundByDPR: (value: number) => number;
|
|
@@ -19,3 +19,13 @@ export const getRandomValue = (length = 21) => {
|
|
|
19
19
|
}
|
|
20
20
|
return id;
|
|
21
21
|
};
|
|
22
|
+
/**
|
|
23
|
+
* Rounds a pixel value based on the device's pixel ratio. This ensures that values can be
|
|
24
|
+
* placed evenly on the device’s pixel grid, avoiding any blurring.
|
|
25
|
+
*
|
|
26
|
+
* @see https://floating-ui.com/docs/misc#subpixel-and-accelerated-positioning
|
|
27
|
+
*/
|
|
28
|
+
export const roundByDPR = (value) => {
|
|
29
|
+
const dpr = window.devicePixelRatio || 1;
|
|
30
|
+
return Math.round(value * dpr) / dpr;
|
|
31
|
+
};
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
import * as React from 'react';
|
|
6
|
-
import {
|
|
6
|
+
import { getTranslateValuesFromElement, getWindow, } from '../functions/index.js';
|
|
7
7
|
import { useEventListener } from './useEventListener.js';
|
|
8
8
|
import { useResizeObserver } from './useResizeObserver.js';
|
|
9
9
|
const getContainerRect = (containerRef) => {
|
|
@@ -36,7 +36,7 @@ export const useDragAndDrop = (elementRef, containerRef, enabled = true) => {
|
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
38
|
const { top, right, bottom, left } = (_a = elementRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
|
|
39
|
-
let [newTranslateX, newTranslateY] =
|
|
39
|
+
let [newTranslateX, newTranslateY] = getTranslateValuesFromElement(elementRef.current);
|
|
40
40
|
containerRectRef.current = getContainerRect(containerRef);
|
|
41
41
|
if (bottom > containerRectRef.current.bottom) {
|
|
42
42
|
newTranslateY -= bottom - containerRectRef.current.bottom;
|
|
@@ -82,7 +82,7 @@ export const useDragAndDrop = (elementRef, containerRef, enabled = true) => {
|
|
|
82
82
|
if (!elementRef.current || e.button !== 0 || !enabled) {
|
|
83
83
|
return;
|
|
84
84
|
}
|
|
85
|
-
const [x, y] =
|
|
85
|
+
const [x, y] = getTranslateValuesFromElement(elementRef.current);
|
|
86
86
|
grabOffsetX.current = e.clientX - x;
|
|
87
87
|
grabOffsetY.current = e.clientY - y;
|
|
88
88
|
originalUserSelect.current = elementRef.current.style.userSelect;
|