From 0dff62a283b4963dd5b2249810f5736552883b80 Mon Sep 17 00:00:00 2001 From: Nicolas Echezarreta Date: Wed, 26 Apr 2023 12:52:54 -0300 Subject: [PATCH] update: Resizable component to allow vertical resizement --- .../@dcl/inspector/src/components/App/App.css | 3 +- .../@dcl/inspector/src/components/App/App.tsx | 23 ++++---- .../src/components/Container/Container.css | 2 + .../src/components/Hierarchy/Hierarchy.tsx | 2 +- .../src/components/Resizable/Resizable.css | 21 ++++++- .../src/components/Resizable/Resizable.tsx | 58 +++++++++---------- .../src/components/Resizable/types.ts | 33 ++++++++++- .../inspector/src/components/Tree/Tree.css | 1 - 8 files changed, 96 insertions(+), 47 deletions(-) diff --git a/packages/@dcl/inspector/src/components/App/App.css b/packages/@dcl/inspector/src/components/App/App.css index 91328acc5..6194cdcba 100644 --- a/packages/@dcl/inspector/src/components/App/App.css +++ b/packages/@dcl/inspector/src/components/App/App.css @@ -74,6 +74,7 @@ code { align-items: center; padding: 8px; cursor: pointer; + user-select: none; } .footer .footer-buttons > div > svg { @@ -87,4 +88,4 @@ code { .footer .footer-content { background: var(--tree-bg-color) !important; height: 250px !important; -} \ No newline at end of file +} diff --git a/packages/@dcl/inspector/src/components/App/App.tsx b/packages/@dcl/inspector/src/components/App/App.tsx index cb59e4410..ca463ffa1 100644 --- a/packages/@dcl/inspector/src/components/App/App.tsx +++ b/packages/@dcl/inspector/src/components/App/App.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react' +import React, { useCallback, useState } from 'react' import { MdImageSearch } from 'react-icons/md' import { AiFillFolder } from 'react-icons/ai' @@ -23,22 +23,21 @@ const App = () => { const [catalog] = useCatalog() const [tab, setTab] = useState(undefined) - function handleTabClick(value: Tab) { - if (tab === value) { - return setTab(undefined) - } - setTab(value) - } + const handleTabClick = useCallback((value: Tab) => () => { + setTab(tab === value ? undefined : value) + }, [tab]) return ( - +
- - + + + +
@@ -54,11 +53,11 @@ const App = () => {
)}
-
handleTabClick(Tab.FileSystem)}> +
Asset Catalog
-
handleTabClick(Tab.AssetsPack)}> +
World Assets Pack
diff --git a/packages/@dcl/inspector/src/components/Container/Container.css b/packages/@dcl/inspector/src/components/Container/Container.css index b6aaabf81..19df7df32 100644 --- a/packages/@dcl/inspector/src/components/Container/Container.css +++ b/packages/@dcl/inspector/src/components/Container/Container.css @@ -5,6 +5,8 @@ background-color: var(--modal); border-radius: 8px; margin: 12px; + height: 100%; + overflow-y: auto; } .Container.hover { diff --git a/packages/@dcl/inspector/src/components/Hierarchy/Hierarchy.tsx b/packages/@dcl/inspector/src/components/Hierarchy/Hierarchy.tsx index 8e6643612..7bd3ca4b8 100644 --- a/packages/@dcl/inspector/src/components/Hierarchy/Hierarchy.tsx +++ b/packages/@dcl/inspector/src/components/Hierarchy/Hierarchy.tsx @@ -27,7 +27,7 @@ const Hierarchy: React.FC = () => { } = useTree() return ( - + div:first-child { + display: flex; + flex-direction: column; +} + +.Resizable.vertical > div:nth-child(3) { + overflow-y: auto; +} diff --git a/packages/@dcl/inspector/src/components/Resizable/Resizable.tsx b/packages/@dcl/inspector/src/components/Resizable/Resizable.tsx index 91a0456cf..160923ba0 100644 --- a/packages/@dcl/inspector/src/components/Resizable/Resizable.tsx +++ b/packages/@dcl/inspector/src/components/Resizable/Resizable.tsx @@ -1,47 +1,49 @@ -import React, { useEffect, useLayoutEffect, useRef, useState } from 'react' +import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react' + +import { PropTypes, TypeProps, HORIZONTAL_PROPS, VERTICAL_PROPS } from './types' import './Resizable.css' -import { PropTypes } from './types' -// TODO: Only width/horizontal resize options for the moment +const getProperties = (type: PropTypes['type']): TypeProps => type === 'horizontal' ? HORIZONTAL_PROPS : VERTICAL_PROPS + function Resizable(props: React.PropsWithChildren) { const ref = useRef(null) - const [width, setWidth] = useState<[number | null, number | null]>([props.initialWidth ?? null, null]) - const [minWidth, setMinWidth] = useState(0) + const [value, setValue] = useState<[number | null, number | null]>([props.initial ?? null, null]) + const [minValue, setMinValue] = useState(0) const [dragging, setDragging] = useState(false) const children = React.Children.toArray(props.children) + const { offsetValue, eventClientValue, css } = getProperties(props.type) if (!children.length) return null - if (children.length !== 2) return
{props.children}
+ if (children.length !== 2) return <>{props.children} useLayoutEffect(() => { if (!ref.current) return - setWidth([ref.current.offsetWidth, getParentWidth() - ref.current.offsetWidth]) + setValue([ref.current[offsetValue], getParentOffset() - ref.current[offsetValue]]) }, []) useEffect(() => { - if (props.minWidth === 'initial') { - setMinWidth(ref.current!.offsetWidth) - } else if (props.minWidth) { - setMinWidth(props.minWidth) + if (props.min === 'initial') { + setMinValue(ref.current![offsetValue]) + } else if (props.min) { + setMinValue(props.min) } - }, [props.minWidth]) + }, [props.min]) - function getParentWidth() { - return ref.current?.parentElement?.parentElement?.offsetWidth ?? 0 - } + const getParentOffset = useCallback(() => { + const parent = ref.current?.parentElement?.parentElement ?? undefined + return parent ? parent[offsetValue] : 0 + }, [value]) const handleDrag = (event: React.MouseEvent) => { - const leftWidth = event.clientX - const rightWidth = getParentWidth() - leftWidth - if (!dragging || leftWidth <= minWidth) return - setWidth([leftWidth, rightWidth]) - if (props.onChange) props.onChange([leftWidth, rightWidth]) + const clientValue = event[eventClientValue] + const diff = getParentOffset() - clientValue + if (!dragging || clientValue <= minValue || clientValue > (props.max || Infinity)) return + setValue([clientValue, diff]) + if (props.onChange) props.onChange([clientValue, diff]) } - function handleMouseUp() { - setDragging(false) - } + const handleMouseUp = useCallback(() => setDragging(false), []) useEffect(() => { document.addEventListener('mouseup', handleMouseUp) @@ -51,12 +53,10 @@ function Resizable(props: React.PropsWithChildren) { }, []) return ( -
-
- {children[0]} -
-
setDragging(true)} /> -
{children[1]}
+
+
{children[0]}
+
setDragging(true)} /> +
{children[1]}
) } diff --git a/packages/@dcl/inspector/src/components/Resizable/types.ts b/packages/@dcl/inspector/src/components/Resizable/types.ts index 119e7a36b..e06cf9103 100644 --- a/packages/@dcl/inspector/src/components/Resizable/types.ts +++ b/packages/@dcl/inspector/src/components/Resizable/types.ts @@ -1,5 +1,34 @@ export interface PropTypes { - minWidth?: 'initial' | number - initialWidth?: number + type: 'horizontal' | 'vertical' + min?: 'initial' | number + initial?: number + max?: number onChange?(value: [number, number]): void } + +export interface TypeProps { + offsetValue: 'offsetWidth' | 'offsetHeight' + eventClientValue: 'clientX' | 'clientY' + css: { + childs: 'width' | 'height' + handle: 'left' | 'top' + } +} + +export const HORIZONTAL_PROPS: TypeProps = { + offsetValue: 'offsetWidth', + eventClientValue: 'clientX', + css: { + childs: 'width', + handle: 'left' + } +} + +export const VERTICAL_PROPS: TypeProps = { + offsetValue: 'offsetHeight', + eventClientValue: 'clientY', + css: { + childs: 'height', + handle: 'top' + } +} diff --git a/packages/@dcl/inspector/src/components/Tree/Tree.css b/packages/@dcl/inspector/src/components/Tree/Tree.css index 1001a22a5..8819895f1 100644 --- a/packages/@dcl/inspector/src/components/Tree/Tree.css +++ b/packages/@dcl/inspector/src/components/Tree/Tree.css @@ -1,6 +1,5 @@ .Tree { font-size: 14px; - background-color: var(--tree-bg-color); color: var(--white); width: 100%; }