Skip to content

Commit

Permalink
update: Resizable component to allow vertical resizement
Browse files Browse the repository at this point in the history
  • Loading branch information
nicoecheza committed Apr 26, 2023
1 parent 8752a16 commit 0dff62a
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 47 deletions.
3 changes: 2 additions & 1 deletion packages/@dcl/inspector/src/components/App/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ code {
align-items: center;
padding: 8px;
cursor: pointer;
user-select: none;
}

.footer .footer-buttons > div > svg {
Expand All @@ -87,4 +88,4 @@ code {
.footer .footer-content {
background: var(--tree-bg-color) !important;
height: 250px !important;
}
}
23 changes: 11 additions & 12 deletions packages/@dcl/inspector/src/components/App/App.tsx
Original file line number Diff line number Diff line change
@@ -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'

Expand All @@ -23,22 +23,21 @@ const App = () => {
const [catalog] = useCatalog()
const [tab, setTab] = useState<Tab | undefined>(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 (
<Resizable minWidth={220} initialWidth={250} >
<Resizable type="horizontal" min={280} initial={280}>
<Box>
<div
className="sidebar"
data-vscode-context='{"webviewSection": "sidebar", "preventDefaultContextMenuItems": true}'
>
<Hierarchy />
<EntityInspector />
<Resizable type="vertical" min={130} initial={130} max={730}>
<Hierarchy />
<EntityInspector />
</Resizable>
</div>
</Box>
<div className="editor">
Expand All @@ -54,11 +53,11 @@ const App = () => {
</div>
)}
<div className="footer-buttons">
<div onClick={() => handleTabClick(Tab.FileSystem)}>
<div onClick={handleTabClick(Tab.FileSystem)}>
<AiFillFolder />
<span>Asset Catalog</span>
</div>
<div onClick={() => handleTabClick(Tab.AssetsPack)}>
<div onClick={handleTabClick(Tab.AssetsPack)}>
<MdImageSearch />
<span>World Assets Pack</span>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
background-color: var(--modal);
border-radius: 8px;
margin: 12px;
height: 100%;
overflow-y: auto;
}

.Container.hover {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const Hierarchy: React.FC = () => {
} = useTree()

return (
<Container label="">
<Container>
<Tree
value={ROOT}
getExtraContextMenu={ContextMenu}
Expand Down
21 changes: 20 additions & 1 deletion packages/@dcl/inspector/src/components/Resizable/Resizable.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,29 @@
display: flex;
}

/* TODO: Maybe position absolute ? */
.Resizable .resize-handle {
position: absolute;
width: 10px;
height: 100%;
cursor: col-resize;
}

.Resizable.vertical {
display: flex;
flex-direction: column;
}

.Resizable.vertical .resize-handle {
width: 100%;
height: 10px;
cursor: row-resize;
}

.Resizable.vertical > div:first-child {
display: flex;
flex-direction: column;
}

.Resizable.vertical > div:nth-child(3) {
overflow-y: auto;
}
58 changes: 29 additions & 29 deletions packages/@dcl/inspector/src/components/Resizable/Resizable.tsx
Original file line number Diff line number Diff line change
@@ -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<PropTypes>) {
const ref = useRef<HTMLDivElement>(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 <div>{props.children}</div>
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<HTMLDivElement, 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)
Expand All @@ -51,12 +53,10 @@ function Resizable(props: React.PropsWithChildren<PropTypes>) {
}, [])

return (
<div className="Resizable" onMouseMove={handleDrag}>
<div ref={ref} style={{ width: width[0] ?? 'auto' }}>
{children[0]}
</div>
<div className="resize-handle" style={{ left: width[0] ?? 0 }} onMouseDown={() => setDragging(true)} />
<div style={{ width: width[1] ?? 'auto' }}>{children[1]}</div>
<div className={`Resizable ${props.type}`} onMouseMove={handleDrag}>
<div ref={ref} style={{ [css.childs]: value[0] ?? 'auto' }}>{children[0]}</div>
<div className="resize-handle" style={{ [css.handle]: value[0] ?? 0 }} onMouseDown={() => setDragging(true)} />
<div style={{ [css.childs]: value[1] ?? 'auto' }}>{children[1]}</div>
</div>
)
}
Expand Down
33 changes: 31 additions & 2 deletions packages/@dcl/inspector/src/components/Resizable/types.ts
Original file line number Diff line number Diff line change
@@ -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'
}
}
1 change: 0 additions & 1 deletion packages/@dcl/inspector/src/components/Tree/Tree.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
.Tree {
font-size: 14px;
background-color: var(--tree-bg-color);
color: var(--white);
width: 100%;
}
Expand Down

0 comments on commit 0dff62a

Please sign in to comment.