Skip to content

Commit

Permalink
Rearranged some DevTools Components code
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Vaughn committed Feb 26, 2020
1 parent d166319 commit 71418fd
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 258 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
.Components {
position: relative;
width: 100%;
height: 100%;
display: flex;
flex-direction: row;
background-color: var(--color-background);
color: var(--color-text);
font-family: var(--font-family-sans);
}

.TreeWrapper {
flex: 0 0 var(--horizontal-resize-percentage);
overflow: auto;
Expand All @@ -23,6 +34,10 @@
}

@media screen and (max-width: 600px) {
.Components {
flex-direction: column;
}

.TreeWrapper {
flex: 0 0 var(--vertical-resize-percentage);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,49 +8,155 @@
*/

import * as React from 'react';
import {Suspense, Fragment} from 'react';
import {
Fragment,
Suspense,
useEffect,
useLayoutEffect,
useReducer,
useRef,
} from 'react';
import Tree from './Tree';
import SelectedElement from './SelectedElement';
import {InspectedElementContextController} from './InspectedElementContext';
import {NativeStyleContextController} from './NativeStyleEditor/context';
import {OwnersListContextController} from './OwnersListContext';
import ComponentsResizer from './ComponentsResizer';
import portaledContent from '../portaledContent';
import {SettingsModalContextController} from 'react-devtools-shared/src/devtools/views/Settings/SettingsModalContext';
import {
localStorageGetItem,
localStorageSetItem,
} from 'react-devtools-shared/src/storage';
import SelectedElement from './SelectedElement';
import {ModalDialog} from '../ModalDialog';
import SettingsModal from 'react-devtools-shared/src/devtools/views/Settings/SettingsModal';
import {SettingsModalContextController} from 'react-devtools-shared/src/devtools/views/Settings/SettingsModalContext';
import {NativeStyleContextController} from './NativeStyleEditor/context';

import styles from './Components.css';

function Components(_: {||}) {
const wrapperElementRef = useRef<HTMLElement>(null);
const resizeElementRef = useRef<HTMLElement>(null);

const [state, dispatch] = useReducer<ResizeState, ResizeAction>(
resizeReducer,
null,
initResizeState,
);

const {horizontalPercentage, verticalPercentage} = state;

useLayoutEffect(() => {
const resizeElement = resizeElementRef.current;

setResizeCSSVariable(
resizeElement,
'horizontal',
horizontalPercentage * 100,
);
setResizeCSSVariable(resizeElement, 'vertical', verticalPercentage * 100);
}, []);

useEffect(() => {
const timeoutID = setTimeout(() => {
localStorageSetItem(
LOCAL_STORAGE_KEY,
JSON.stringify({
horizontalPercentage,
verticalPercentage,
}),
);
}, 500);

return () => clearTimeout(timeoutID);
}, [horizontalPercentage, verticalPercentage]);

const {isResizing} = state;

const onResizeStart = () =>
dispatch({type: 'ACTION_SET_IS_RESIZING', payload: true});

let onResize;
let onResizeEnd;
if (isResizing) {
onResizeEnd = () =>
dispatch({type: 'ACTION_SET_IS_RESIZING', payload: false});

onResize = event => {
const resizeElement = resizeElementRef.current;
const wrapperElement = wrapperElementRef.current;

if (!isResizing || wrapperElement === null || resizeElement === null) {
return;
}

event.preventDefault();

const orientation = getOrientation(wrapperElement);

const {height, width, left, top} = wrapperElement.getBoundingClientRect();

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'
? 'ACTION_SET_HORIZONTAL_PERCENTAGE'
: 'ACTION_SET_VERTICAL_PERCENTAGE';
const percentage =
(currentMousePosition / resizedElementDimension) * 100;

setResizeCSSVariable(resizeElement, orientation, percentage);

dispatch({
type: actionType,
payload: currentMousePosition / resizedElementDimension,
});
}
};
}

return (
<SettingsModalContextController>
<OwnersListContextController>
<InspectedElementContextController>
<ComponentsResizer>
{({resizeElementRef, onResizeStart}) => (
<Fragment>
<div ref={resizeElementRef} className={styles.TreeWrapper}>
<Tree />
</div>
<div className={styles.ResizeBarWrapper}>
<div
onMouseDown={onResizeStart}
className={styles.ResizeBar}
/>
</div>
<div className={styles.SelectedElementWrapper}>
<NativeStyleContextController>
<Suspense fallback={<Loading />}>
<SelectedElement />
</Suspense>
</NativeStyleContextController>
</div>
<ModalDialog />
<SettingsModal />
</Fragment>
)}
</ComponentsResizer>
<div
ref={wrapperElementRef}
className={styles.Components}
onMouseMove={onResize}
onMouseLeave={onResizeEnd}
onMouseUp={onResizeEnd}>
<Fragment>
<div ref={resizeElementRef} className={styles.TreeWrapper}>
<Tree />
</div>
<div className={styles.ResizeBarWrapper}>
<div onMouseDown={onResizeStart} className={styles.ResizeBar} />
</div>
<div className={styles.SelectedElementWrapper}>
<NativeStyleContextController>
<Suspense fallback={<Loading />}>
<SelectedElement />
</Suspense>
</NativeStyleContextController>
</div>
<ModalDialog />
<SettingsModal />
</Fragment>
</div>
</InspectedElementContextController>
</OwnersListContextController>
</SettingsModalContextController>
Expand All @@ -61,4 +167,92 @@ function Loading() {
return <div className={styles.Loading}>Loading...</div>;
}

const LOCAL_STORAGE_KEY = 'React::DevTools::createResizeReducer';
const VERTICAL_MODE_MAX_WIDTH = 600;
const MINIMUM_SIZE = 50;

type Orientation = 'horizontal' | 'vertical';

type ResizeActionType =
| 'ACTION_SET_DID_MOUNT'
| 'ACTION_SET_IS_RESIZING'
| 'ACTION_SET_HORIZONTAL_PERCENTAGE'
| 'ACTION_SET_VERTICAL_PERCENTAGE';

type ResizeAction = {|
type: ResizeActionType,
payload: any,
|};

type ResizeState = {|
horizontalPercentage: number,
isResizing: boolean,
verticalPercentage: number,
|};

function initResizeState(): ResizeState {
let horizontalPercentage = 0.65;
let verticalPercentage = 0.5;

try {
let data = localStorageGetItem(LOCAL_STORAGE_KEY);
if (data != null) {
data = JSON.parse(data);
horizontalPercentage = data.horizontalPercentage;
verticalPercentage = data.verticalPercentage;
}
} catch (error) {}

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,
horizontalPercentage: action.payload,
};
case 'ACTION_SET_VERTICAL_PERCENTAGE':
return {
...state,
verticalPercentage: action.payload,
};
default:
return state;
}
}

function getOrientation(
wrapperElement: null | HTMLElement,
): null | Orientation {
if (wrapperElement != null) {
const {width} = wrapperElement.getBoundingClientRect();
return width > VERTICAL_MODE_MAX_WIDTH ? 'horizontal' : 'vertical';
}
return null;
}

function setResizeCSSVariable(
resizeElement: null | HTMLElement,
orientation: null | Orientation,
percentage: number,
): void {
if (resizeElement !== null && orientation !== null) {
resizeElement.style.setProperty(
`--${orientation}-resize-percentage`,
`${percentage}%`,
);
}
}

export default portaledContent(Components);

This file was deleted.

Loading

0 comments on commit 71418fd

Please sign in to comment.