Skip to content

Commit 2cfbb53

Browse files
feat: DevTools - Finished refactoring.
1 parent f1b3a80 commit 2cfbb53

File tree

2 files changed

+117
-65
lines changed

2 files changed

+117
-65
lines changed

packages/react-devtools-shared/src/devtools/views/Components/Components.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
}
4444

4545
.SelectedElementWrapper {
46-
flex: 0 0 50%;
46+
flex: 1 1 50%;
4747
}
4848

4949
.ResizeBar {

packages/react-devtools-shared/src/devtools/views/Components/Components.js

Lines changed: 116 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,7 @@
77
* @flow
88
*/
99

10-
import React, {
11-
Suspense,
12-
Fragment,
13-
useRef,
14-
useState,
15-
useLayoutEffect,
16-
useCallback,
17-
} from 'react';
10+
import React, {Suspense, Fragment, useRef, useEffect, useReducer} from 'react';
1811
import Tree from './Tree';
1912
import SelectedElement from './SelectedElement';
2013
import {InspectedElementContextController} from './InspectedElementContext';
@@ -79,44 +72,113 @@ const RESIZE_DIRECTIONS: {|
7972
VERTICAL: 'VERTICAL',
8073
};
8174

82-
const LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_HORIZONTAL_KEY = `React::DevTools::resizedElementPercentage::${RESIZE_DIRECTIONS.HORIZONTAL}`;
83-
const LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_VERTICAL_KEY = `React::DevTools::resizedElementPercentage::${RESIZE_DIRECTIONS.VERTICAL}`;
84-
85-
function ComponentResizer({children}): {|children: Function|} {
86-
const [isResizing, setIsResizing] = useState<boolean>(false);
75+
function createResizeReducer(wrapperRef) {
76+
const LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_HORIZONTAL_KEY = `React::DevTools::resizedElementPercentage::${RESIZE_DIRECTIONS.HORIZONTAL}`;
77+
const LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_VERTICAL_KEY = `React::DevTools::resizedElementPercentage::${RESIZE_DIRECTIONS.VERTICAL}`;
8778
const [
8879
horizontalPercentage,
8980
setHorizontalPercentage,
90-
] = useLocalStorage<number>(
81+
] = useLocalStorage<string>(
9182
LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_HORIZONTAL_KEY,
92-
65,
83+
'65%',
9384
);
94-
const [verticalPercentage, setVerticalPercentage] = useLocalStorage<number>(
85+
const [verticalPercentage, setVerticalPercentage] = useLocalStorage<string>(
9586
LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_VERTICAL_KEY,
96-
50,
87+
'50%',
9788
);
98-
const updateLocalStorageTimeoutId = useRef<number>(null);
99-
const componentsWrapperRef = useRef<HTMLDivElement>(null);
100-
const resizeElementRef = useRef<HTMLElement>(null);
101-
const [resizeElementStyles, setResizeElementStyles] = useState<Object>({});
102-
const getResizeDirection: Function = useCallback(() => {
103-
if (componentsWrapperRef.current === null) {
104-
return RESIZE_DIRECTIONS.HORIZONTAL;
89+
const resizeTimeout = useRef(null);
90+
91+
const getResizeDirection: Function = ref => () => {
92+
if (ref.current != null) {
93+
const VERTICAL_MODE_MAX_WIDTH: number = 600;
94+
const {width} = ref.current.getBoundingClientRect();
95+
96+
return width > VERTICAL_MODE_MAX_WIDTH
97+
? RESIZE_DIRECTIONS.HORIZONTAL
98+
: RESIZE_DIRECTIONS.VERTICAL;
99+
}
100+
101+
return RESIZE_DIRECTIONS.HORIZONTAL;
102+
};
103+
104+
// We need to watch/set for changes to this ref in order to get the correct resize direction.
105+
useEffect(() => {
106+
if (wrapperRef.current != null) {
107+
dispatch({type: 'setWrapperRef', payload: wrapperRef});
108+
}
109+
}, [wrapperRef]);
110+
111+
const initialState = {
112+
wrapperRef: wrapperRef,
113+
isResizing: false,
114+
horizontalPercentage,
115+
verticalPercentage,
116+
getResizeDirection: getResizeDirection(wrapperRef),
117+
};
118+
119+
const ACTION_TYPES = {
120+
SET_IS_RESIZING: 'setIsResizing',
121+
SET_WRAPPER_REF: 'setWrapperRef',
122+
SET_HORIZONTAL_PERCENTAGE: 'setHorizontalPercentage',
123+
SET_VERTICAL_PERCENTAGE: 'setVerticalPercentage',
124+
};
125+
126+
// eslint-disable-next-line no-shadow
127+
const [state, dispatch] = useReducer((state, action) => {
128+
switch (action.type) {
129+
case ACTION_TYPES.SET_IS_RESIZING:
130+
return {
131+
...state,
132+
isResizing: action.payload,
133+
};
134+
case ACTION_TYPES.SET_WRAPPER_REF:
135+
return {
136+
...state,
137+
wrapperRef: action.payload,
138+
getResizeDirection: getResizeDirection(action.payload),
139+
};
140+
case ACTION_TYPES.SET_HORIZONTAL_PERCENTAGE:
141+
case ACTION_TYPES.SET_VERTICAL_PERCENTAGE:
142+
const percentageState = {
143+
[action.type === ACTION_TYPES.SET_HORIZONTAL_PERCENTAGE
144+
? 'horizontalPercentage'
145+
: 'verticalPercentage']: action.payload,
146+
};
147+
148+
clearTimeout(resizeTimeout.current);
149+
resizeTimeout.current = setTimeout(() => {
150+
if (action.type === ACTION_TYPES.SET_HORIZONTAL_PERCENTAGE) {
151+
setHorizontalPercentage(action.payload);
152+
} else {
153+
setVerticalPercentage(action.payload);
154+
}
155+
}, 400);
156+
157+
return {
158+
...state,
159+
...percentageState,
160+
};
161+
default:
162+
return state;
105163
}
106-
const VERTICAL_MODE_MAX_WIDTH: number = 600;
107-
const {width} = componentsWrapperRef.current.getBoundingClientRect();
164+
}, initialState);
108165

109-
return width > VERTICAL_MODE_MAX_WIDTH
110-
? RESIZE_DIRECTIONS.HORIZONTAL
111-
: RESIZE_DIRECTIONS.VERTICAL;
112-
}, [componentsWrapperRef]);
166+
return [state, dispatch, ACTION_TYPES];
167+
}
113168

114-
const onResizeStart = () => setIsResizing(true);
115-
const onResizeEnd = () => setIsResizing(false);
169+
function ComponentResizer({children}): {|children: Function|} {
170+
const componentsWrapperRef = useRef<HTMLDivElement>(null);
171+
const resizeElementRef = useRef<HTMLElement>(null);
172+
const [state, dispatch, ACTION_TYPES] = createResizeReducer(componentsWrapperRef);
173+
174+
const onResizeStart = () =>
175+
dispatch({type: ACTION_TYPES.SET_IS_RESIZING, payload: true});
176+
const onResizeEnd = () =>
177+
dispatch({type: ACTION_TYPES.SET_IS_RESIZING, payload: false});
116178
const onResize = e => {
117179
if (
118-
!isResizing ||
119-
componentsWrapperRef.current === null ||
180+
!state.isResizing ||
181+
state.wrapperRef.current === null ||
120182
resizeElementRef.current === null
121183
) {
122184
return;
@@ -129,13 +191,14 @@ function ComponentResizer({children}): {|children: Function|} {
129191
width,
130192
left,
131193
top,
132-
} = componentsWrapperRef.current.getBoundingClientRect();
133-
const resizeDirection = getResizeDirection();
194+
} = state.wrapperRef.current.getBoundingClientRect();
195+
const resizeDirection = state.getResizeDirection();
196+
134197
const currentMousePosition: number =
135198
resizeDirection === RESIZE_DIRECTIONS.HORIZONTAL
136199
? e.clientX - left
137200
: e.clientY - top;
138-
const BOUNDARY_PADDING: number = 40;
201+
const BOUNDARY_PADDING: number = 42;
139202
const boundary: {|
140203
min: number,
141204
max: number,
@@ -153,42 +216,31 @@ function ComponentResizer({children}): {|children: Function|} {
153216
if (isMousePositionInBounds) {
154217
const resizedElementDimension: number =
155218
resizeDirection === RESIZE_DIRECTIONS.HORIZONTAL ? width : height;
156-
const updatedFlexBasisValue: number =
157-
(currentMousePosition / resizedElementDimension) * 100;
158-
159-
resizeElementRef.current.style.flexBasis = `${updatedFlexBasisValue}%`;
160-
161-
clearTimeout(updateLocalStorageTimeoutId.current);
219+
const updatedFlexBasisValue: string = `${(currentMousePosition /
220+
resizedElementDimension) *
221+
100}%`;
222+
const SET_PERCENTAGE_ACTION =
223+
resizeDirection === RESIZE_DIRECTIONS.HORIZONTAL
224+
? ACTION_TYPES.SET_HORIZONTAL_PERCENTAGE
225+
: ACTION_TYPES.SET_VERTICAL_PERCENTAGE;
162226

163-
updateLocalStorageTimeoutId.current = setTimeout(() => {
164-
if (resizeDirection === RESIZE_DIRECTIONS.HORIZONTAL) {
165-
setHorizontalPercentage(updatedFlexBasisValue);
166-
} else {
167-
setVerticalPercentage(updatedFlexBasisValue);
168-
}
169-
}, 500);
227+
resizeElementRef.current.style.flexBasis = updatedFlexBasisValue;
228+
dispatch({type: SET_PERCENTAGE_ACTION, payload: updatedFlexBasisValue});
170229
}
171230
};
172231

173-
useLayoutEffect(() => {
174-
if (componentsWrapperRef.current !== null) {
175-
if (getResizeDirection() === RESIZE_DIRECTIONS.HORIZONTAL) {
176-
setResizeElementStyles({
177-
flexBasis: `${horizontalPercentage}%`,
178-
});
179-
} else {
180-
setResizeElementStyles({
181-
flexBasis: `${verticalPercentage}%`,
182-
});
183-
}
184-
}
185-
}, [componentsWrapperRef, horizontalPercentage, verticalPercentage]);
232+
const resizeElementStyles = {
233+
flexBasis:
234+
state.getResizeDirection() === RESIZE_DIRECTIONS.HORIZONTAL
235+
? state.horizontalPercentage
236+
: state.verticalPercentage,
237+
};
186238

187239
return (
188240
<div
189241
ref={componentsWrapperRef}
190242
className={styles.ComponentsWrapper}
191-
{...(isResizing && {
243+
{...(state.isResizing && {
192244
onMouseMove: onResize,
193245
onMouseLeave: onResizeEnd,
194246
onMouseUp: onResizeEnd,

0 commit comments

Comments
 (0)