WIP: tree-slider
continuous-integration/drone/push Build is failing Details

maxime.batista 1 year ago
parent 4fe1ddfbd2
commit a8a00ea687

@ -0,0 +1,66 @@
import {ReactNode, useCallback, useEffect, useRef, useState} from "react";
export interface SlideLayoutProps {
children: ReactNode[2]
}
export default function CurtainLayout({children}: SlideLayoutProps) {
const [rightWidth, setRightWidth] = useState(80)
const curtainRef = useRef<HTMLDivElement>(null)
const sliderRef = useRef<HTMLDivElement>(null)
const resize = useCallback((e: MouseEvent) => {
const sliderPosX = e.clientX
const curtainWidth = curtainRef.current!.getBoundingClientRect().width
setRightWidth((sliderPosX / curtainWidth) * 100)
}, [curtainRef, setRightWidth])
const [resizing, setResizing] = useState(false)
useEffect(() => {
const curtain = curtainRef.current!
const slider = sliderRef.current!
if (resizing) {
const handleMouseUp = () => setResizing(false)
curtain.addEventListener('mousemove', resize)
curtain.addEventListener('mouseup', handleMouseUp)
return () => {
curtain.removeEventListener('mousemove', resize)
curtain.removeEventListener('mouseup', handleMouseUp)
}
}
const handleMouseDown = () => setResizing(true)
slider.addEventListener('mousedown', handleMouseDown)
return () => {
slider.removeEventListener('mousedown', handleMouseDown)
}
}, [sliderRef, curtainRef, resizing, setResizing])
return (
<div className={"curtain"} ref={curtainRef} style={{display: "flex"}}>
<div className={"curtain-left"} style={{width: `${rightWidth}%`}}>
{children[0]}
</div>
<div ref={sliderRef}
style={{
width: 2,
height: "100%",
backgroundColor: "grey",
cursor: "col-resize"
}}>
</div>
<div className={"curtain-right"} style={{width: `${100 - rightWidth}%`}}>
{children[1]}
</div>
</div>
)
}

@ -92,6 +92,7 @@ import {
getStepNode, getStepNode,
removeStepNode, removeStepNode,
} from "../editor/StepsDomain" } from "../editor/StepsDomain"
import CurtainLayout from "../components/CurtainLayout";
const ERROR_STYLE: CSSProperties = { const ERROR_STYLE: CSSProperties = {
borderColor: "red", borderColor: "red",
@ -777,34 +778,7 @@ function EditorPage({
[courtRef, doDeleteAction, doUpdateAction], [courtRef, doDeleteAction, doUpdateAction],
) )
return ( const contentNode = <div id="content-div">
<div id="main-div">
<div id="topbar-div">
<div id="topbar-left">
<SavingState state={saveState} />
</div>
<div id="title-input-div">
<TitleInput
style={titleStyle}
default_value={name}
onValidated={useCallback(
(new_name) => {
onNameChange(new_name).then((success) => {
setTitleStyle(success ? {} : ERROR_STYLE)
})
},
[onNameChange],
)}
/>
</div>
<div id="topbar-right">
<button onClick={() => setStepsTreeVisible((b) => !b)}>
ETAPES
</button>
</div>
</div>
<div id="editor-div">
<div id="content-div">
<div id="racks"> <div id="racks">
<PlayerRack <PlayerRack
id={"allies"} id={"allies"}
@ -860,7 +834,8 @@ function EditorPage({
</div> </div>
</div> </div>
</div> </div>
<EditorStepsTree
const stepsTreeNode = <EditorStepsTree
isVisible={isStepsTreeVisible} isVisible={isStepsTreeVisible}
selectedStepId={currentStepId} selectedStepId={currentStepId}
root={rootStepsNode} root={rootStepsNode}
@ -902,13 +877,47 @@ function EditorPage({
[selectStep], [selectStep],
)} )}
/> />
return (
<div id="main-div">
<div id="topbar-div">
<div id="topbar-left">
<SavingState state={saveState}/>
</div>
<div id="title-input-div">
<TitleInput
style={titleStyle}
default_value={name}
onValidated={useCallback(
(new_name) => {
onNameChange(new_name).then((success) => {
setTitleStyle(success ? {} : ERROR_STYLE)
})
},
[onNameChange],
)}
/>
</div>
<div id="topbar-right">
<button onClick={() => setStepsTreeVisible((b) => !b)}>
ETAPES
</button>
</div>
</div>
<div id="editor-div">
{isStepsTreeVisible
? <CurtainLayout>
{contentNode}
{stepsTreeNode}
</CurtainLayout>
: {contentNode}
}
</div> </div>
</div> </div>
) )
} }
interface EditorStepsTreeProps { interface EditorStepsTreeProps {
isVisible: boolean
selectedStepId: number selectedStepId: number
root: StepInfoNode root: StepInfoNode
onAddChildren: (parent: StepInfoNode) => void onAddChildren: (parent: StepInfoNode) => void
@ -917,7 +926,6 @@ interface EditorStepsTreeProps {
} }
function EditorStepsTree({ function EditorStepsTree({
isVisible,
selectedStepId, selectedStepId,
root, root,
onAddChildren, onAddChildren,
@ -926,10 +934,7 @@ function EditorStepsTree({
}: EditorStepsTreeProps) { }: EditorStepsTreeProps) {
return ( return (
<div <div
id="steps-div" id="steps-div">
style={{
transform: isVisible ? "translateX(0)" : "translateX(100%)",
}}>
<StepsTree <StepsTree
root={root} root={root}
selectedStepId={selectedStepId} selectedStepId={selectedStepId}

@ -50,28 +50,21 @@
} }
#content-div, #content-div,
#editor-div { #editor-div,
#steps-div {
height: 100%; height: 100%;
width: 100%; width: 100%;
} }
#content-div { .curtain {
width: 100%; width: 100%;
} }
#steps-div { #steps-div {
background-color: var(--editor-tree-background); background-color: var(--editor-tree-background);
width: 20%;
transform: translateX(100%);
transition: transform 500ms;
overflow: scroll; overflow: scroll;
} }
#steps-div::-webkit-scrollbar {
display: none;
}
#allies-rack, #allies-rack,
#opponent-rack { #opponent-rack {
width: 125px; width: 125px;

Loading…
Cancel
Save