mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[DevTools] More robust resize handling (#34036)
This commit is contained in:
committed by
GitHub
parent
9c9136b441
commit
b1cbb482d5
@@ -608,6 +608,7 @@ module.exports = {
|
||||
symbol: 'readonly',
|
||||
SyntheticEvent: 'readonly',
|
||||
SyntheticMouseEvent: 'readonly',
|
||||
SyntheticPointerEvent: 'readonly',
|
||||
Thenable: 'readonly',
|
||||
TimeoutID: 'readonly',
|
||||
WheelEventHandler: 'readonly',
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
.TreeWrapper {
|
||||
flex: 0 0 var(--horizontal-resize-percentage);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.InspectedElementWrapper {
|
||||
@@ -32,7 +31,14 @@
|
||||
|
||||
.ResizeBar {
|
||||
position: absolute;
|
||||
left: -2px;
|
||||
/*
|
||||
* moving the bar out of its bounding box might cause its hitbox to overlap
|
||||
* with another scrollbar creating disorienting UX where you both resize and scroll
|
||||
* at the same time.
|
||||
* If you adjust this value, double check that starting resize right on this edge
|
||||
* doesn't also cause scroll
|
||||
*/
|
||||
left: 1px;
|
||||
width: 5px;
|
||||
height: 100%;
|
||||
cursor: ew-resize;
|
||||
@@ -52,7 +58,7 @@
|
||||
}
|
||||
|
||||
.ResizeBar {
|
||||
top: -2px;
|
||||
top: 1px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 5px;
|
||||
|
||||
+55
-64
@@ -29,7 +29,6 @@ type Orientation = 'horizontal' | 'vertical';
|
||||
|
||||
type ResizeActionType =
|
||||
| 'ACTION_SET_DID_MOUNT'
|
||||
| 'ACTION_SET_IS_RESIZING'
|
||||
| 'ACTION_SET_HORIZONTAL_PERCENTAGE'
|
||||
| 'ACTION_SET_VERTICAL_PERCENTAGE';
|
||||
|
||||
@@ -40,7 +39,6 @@ type ResizeAction = {
|
||||
|
||||
type ResizeState = {
|
||||
horizontalPercentage: number,
|
||||
isResizing: boolean,
|
||||
verticalPercentage: number,
|
||||
};
|
||||
|
||||
@@ -81,82 +79,81 @@ function Components(_: {}) {
|
||||
return () => clearTimeout(timeoutID);
|
||||
}, [horizontalPercentage, verticalPercentage]);
|
||||
|
||||
const {isResizing} = state;
|
||||
const onResizeStart = (event: SyntheticPointerEvent<HTMLElement>) => {
|
||||
const element = event.currentTarget;
|
||||
element.setPointerCapture(event.pointerId);
|
||||
};
|
||||
|
||||
const onResizeStart = () =>
|
||||
dispatch({type: 'ACTION_SET_IS_RESIZING', payload: true});
|
||||
const onResizeEnd = (event: SyntheticPointerEvent<HTMLElement>) => {
|
||||
const element = event.currentTarget;
|
||||
element.releasePointerCapture(event.pointerId);
|
||||
};
|
||||
|
||||
let onResize;
|
||||
let onResizeEnd;
|
||||
if (isResizing) {
|
||||
onResizeEnd = () =>
|
||||
dispatch({type: 'ACTION_SET_IS_RESIZING', payload: false});
|
||||
const onResize = (event: SyntheticPointerEvent<HTMLElement>) => {
|
||||
const element = event.currentTarget;
|
||||
const isResizing = element.hasPointerCapture(event.pointerId);
|
||||
if (!isResizing) {
|
||||
return;
|
||||
}
|
||||
|
||||
// $FlowFixMe[missing-local-annot]
|
||||
onResize = event => {
|
||||
const resizeElement = resizeElementRef.current;
|
||||
const wrapperElement = wrapperElementRef.current;
|
||||
const resizeElement = resizeElementRef.current;
|
||||
const wrapperElement = wrapperElementRef.current;
|
||||
|
||||
if (!isResizing || wrapperElement === null || resizeElement === null) {
|
||||
return;
|
||||
}
|
||||
if (wrapperElement === null || resizeElement === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
event.preventDefault();
|
||||
|
||||
const orientation = getOrientation(wrapperElement);
|
||||
const orientation = getOrientation(wrapperElement);
|
||||
|
||||
const {height, width, left, top} = wrapperElement.getBoundingClientRect();
|
||||
const {height, width, left, top} = wrapperElement.getBoundingClientRect();
|
||||
|
||||
const currentMousePosition =
|
||||
const currentMousePosition =
|
||||
orientation === 'horizontal' ? event.clientX - left : event.clientY - top;
|
||||
|
||||
const boundaryMin = MINIMUM_SIZE;
|
||||
const boundaryMax =
|
||||
orientation === 'horizontal'
|
||||
? width - MINIMUM_SIZE
|
||||
: height - MINIMUM_SIZE;
|
||||
|
||||
const isMousePositionInBounds =
|
||||
currentMousePosition > boundaryMin && currentMousePosition < boundaryMax;
|
||||
|
||||
if (isMousePositionInBounds) {
|
||||
const resizedElementDimension =
|
||||
orientation === 'horizontal' ? width : height;
|
||||
const actionType =
|
||||
orientation === 'horizontal'
|
||||
? event.clientX - left
|
||||
: event.clientY - top;
|
||||
? 'ACTION_SET_HORIZONTAL_PERCENTAGE'
|
||||
: 'ACTION_SET_VERTICAL_PERCENTAGE';
|
||||
const percentage = (currentMousePosition / resizedElementDimension) * 100;
|
||||
|
||||
const boundaryMin = MINIMUM_SIZE;
|
||||
const boundaryMax =
|
||||
orientation === 'horizontal'
|
||||
? width - MINIMUM_SIZE
|
||||
: height - MINIMUM_SIZE;
|
||||
setResizeCSSVariable(resizeElement, orientation, percentage);
|
||||
|
||||
const isMousePositionInBounds =
|
||||
currentMousePosition > boundaryMin &&
|
||||
currentMousePosition < boundaryMax;
|
||||
|
||||
if (isMousePositionInBounds) {
|
||||
const resizedElementDimension =
|
||||
orientation === 'horizontal' ? width : height;
|
||||
const actionType =
|
||||
orientation === 'horizontal'
|
||||
? 'ACTION_SET_HORIZONTAL_PERCENTAGE'
|
||||
: 'ACTION_SET_VERTICAL_PERCENTAGE';
|
||||
const percentage =
|
||||
(currentMousePosition / resizedElementDimension) * 100;
|
||||
|
||||
setResizeCSSVariable(resizeElement, orientation, percentage);
|
||||
|
||||
dispatch({
|
||||
type: actionType,
|
||||
payload: currentMousePosition / resizedElementDimension,
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
dispatch({
|
||||
type: actionType,
|
||||
payload: currentMousePosition / resizedElementDimension,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<SettingsModalContextController>
|
||||
<OwnersListContextController>
|
||||
<div
|
||||
ref={wrapperElementRef}
|
||||
className={styles.Components}
|
||||
onMouseMove={onResize}
|
||||
onMouseLeave={onResizeEnd}
|
||||
onMouseUp={onResizeEnd}>
|
||||
<div ref={wrapperElementRef} className={styles.Components}>
|
||||
<Fragment>
|
||||
<div ref={resizeElementRef} className={styles.TreeWrapper}>
|
||||
<Tree />
|
||||
</div>
|
||||
<div className={styles.ResizeBarWrapper}>
|
||||
<div onMouseDown={onResizeStart} className={styles.ResizeBar} />
|
||||
<div
|
||||
onPointerDown={onResizeStart}
|
||||
onPointerMove={onResize}
|
||||
onPointerUp={onResizeEnd}
|
||||
className={styles.ResizeBar}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.InspectedElementWrapper}>
|
||||
<NativeStyleContextController>
|
||||
@@ -193,18 +190,12 @@ function initResizeState(): ResizeState {
|
||||
|
||||
return {
|
||||
horizontalPercentage,
|
||||
isResizing: false,
|
||||
verticalPercentage,
|
||||
};
|
||||
}
|
||||
|
||||
function resizeReducer(state: ResizeState, action: ResizeAction): ResizeState {
|
||||
switch (action.type) {
|
||||
case 'ACTION_SET_IS_RESIZING':
|
||||
return {
|
||||
...state,
|
||||
isResizing: action.payload,
|
||||
};
|
||||
case 'ACTION_SET_HORIZONTAL_PERCENTAGE':
|
||||
return {
|
||||
...state,
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
font-family: var(--font-family-monospace);
|
||||
font-size: var(--font-size-monospace-normal);
|
||||
line-height: var(--line-height-data);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.VRule {
|
||||
|
||||
Reference in New Issue
Block a user