Skip to content

Commit 8709332

Browse files
committed
rewrite splitview-component
1 parent 7070aee commit 8709332

File tree

3 files changed

+81
-93
lines changed

3 files changed

+81
-93
lines changed

frontend/Main.tsx

+1-29
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
import { Component, For, createSignal, Show, Setter, JSX } from "solid-js";
1+
import { Component, For, createSignal, Setter } from "solid-js";
22
import {
33
Flex,
44
Box,
5-
Tooltip,
6-
IconButton,
75
createDisclosure,
86
Heading,
97
} from "@hope-ui/solid";
10-
import { IoCaretBackOutline, IoCaretForwardOutline } from "solid-icons/io";
118

129
import { instances } from "./store";
1310
import InstancesButtons from "./InstancesButtons";
@@ -62,29 +59,4 @@ const Main: Component = () => {
6259
</>
6360
);
6461
};
65-
66-
const SidebarButton: Component<{
67-
label: string;
68-
onClick: () => void;
69-
icon: JSX.Element;
70-
top: string;
71-
right: string;
72-
}> = (props) => {
73-
return (
74-
<Tooltip label={props.label}>
75-
<IconButton
76-
variant="ghost"
77-
size="sm"
78-
position="relative"
79-
top={props.top}
80-
right={props.right}
81-
onClick={props.onClick}
82-
aria-label={props.label}
83-
backgroundColor="white"
84-
icon={props.icon}
85-
/>
86-
</Tooltip>
87-
);
88-
};
89-
9062
export default Main;

frontend/SplitView.tsx

+77-61
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,94 @@
11

2-
import { Box } from "@hope-ui/solid";
3-
import { ParentComponent, onMount } from "solid-js";
4-
2+
import { Box, IconButton, Tooltip } from "@hope-ui/solid";
3+
import { Accessor } from "solid-js";
4+
import { createMemo, ParentComponent, Component, JSX, createSignal, children } from "solid-js";
5+
import { ResolvedJSXElement } from "solid-js/types/reactive/signal";
6+
7+
8+
const SidebarButton: Component<{
9+
label: string;
10+
onClick: () => void;
11+
icon: JSX.Element;
12+
top: string;
13+
right: string;
14+
}> = (props) => {
15+
return (
16+
<Tooltip label={props.label}>
17+
<IconButton
18+
variant="ghost"
19+
size="sm"
20+
position="relative"
21+
top={props.top}
22+
right={props.right}
23+
onClick={props.onClick}
24+
aria-label={props.label}
25+
backgroundColor="white"
26+
icon={props.icon}
27+
/>
28+
</Tooltip>
29+
);
30+
};
531

32+
let x = 0;
33+
let initialLeftWidth = 0;
634
const SplitView: ParentComponent<{
735
}> = (props) => {
8-
onMount(() => {
9-
document.addEventListener('DOMContentLoaded', function () {
10-
// Query the element
11-
const resizer = document.getElementById('dragMe');
12-
const leftSide = resizer.previousElementSibling as HTMLElement;
13-
const rightSide = resizer.nextElementSibling as HTMLElement;
14-
15-
// The current position of mouse
16-
let x = 0;
17-
let y = 0;
18-
let leftWidth = 0;
19-
20-
// Handle the mousedown event
21-
// that's triggered when user drags the resizer
22-
const mouseDownHandler = function (e) {
23-
// Get the current mouse position
24-
x = e.clientX;
25-
y = e.clientY;
26-
leftWidth = leftSide.getBoundingClientRect().width;
27-
28-
// Attach the listeners to `document`
29-
document.addEventListener('mousemove', mouseMoveHandler);
30-
document.addEventListener('mouseup', mouseUpHandler);
31-
};
3236

33-
const mouseMoveHandler = function (e) {
34-
// How far the mouse has been moved
35-
const dx = e.clientX - x;
36-
const dy = e.clientY - y;
37+
// Somehow using `HtmlElement` here causes a type error
38+
let leftSide: any;
39+
let rightSide: any;
40+
let resizer: any;
3741

38-
const newLeftWidth = ((leftWidth + dx) * 100) / (resizer.parentNode as HTMLElement).getBoundingClientRect().width;
39-
leftSide.style.width = `${newLeftWidth}%`;
4042

41-
resizer.style.cursor = 'col-resize';
42-
document.body.style.cursor = 'col-resize';
43+
const resolvedChildren = children(() => props.children) as Accessor<ResolvedJSXElement[]>;
4344

44-
leftSide.style.userSelect = 'none';
45-
leftSide.style.pointerEvents = 'none';
46-
47-
rightSide.style.userSelect = 'none';
48-
rightSide.style.pointerEvents = 'none';
49-
};
45+
let [isResizing, setIsResizing] = createSignal(false);
46+
let [leftWidth, setLeftWidth] = createSignal(60);
47+
let leftStyleGet = createMemo(() => {
48+
return {
49+
width: leftWidth() + "%",
50+
"user-select": isResizing() ? "none" : "user-select",
51+
"pointer-event": isResizing() ? "none" : "pointer-events"
52+
}
53+
})
54+
let rightStyleGet = createMemo(() => {
55+
return {
56+
"user-select": isResizing() ? "none" : "user-select",
57+
"pointer-event": isResizing() ? "none" : "pointer-events"
58+
}
59+
})
60+
let resizerStyleGet = createMemo(() => {
61+
return isResizing() ? {cursor: 'col-resize'} : undefined
62+
})
5063

51-
const mouseUpHandler = function () {
52-
resizer.style.removeProperty('cursor');
53-
document.body.style.removeProperty('cursor');
5464

55-
leftSide.style.removeProperty('user-select');
56-
leftSide.style.removeProperty('pointer-events');
65+
function mouseMoveHandler(e: MouseEvent) {
66+
const dx = e.clientX - x;
67+
setLeftWidth(((initialLeftWidth + dx) * 100) / (resizer.parentNode as HTMLElement).getBoundingClientRect().width)
68+
document.body.style.cursor = 'col-resize';
69+
};
5770

58-
rightSide.style.removeProperty('user-select');
59-
rightSide.style.removeProperty('pointer-events');
71+
function mouseUpHandler () {
72+
setIsResizing(false);
73+
document.body.style.removeProperty('cursor');
74+
document.removeEventListener('mousemove', mouseMoveHandler);
75+
document.removeEventListener('mouseup', mouseUpHandler);
76+
};
6077

61-
// Remove the handlers of `mousemove` and `mouseup`
62-
document.removeEventListener('mousemove', mouseMoveHandler);
63-
document.removeEventListener('mouseup', mouseUpHandler);
64-
};
78+
function mouseDownHandler(e: MouseEvent) {
79+
x = e.clientX;
80+
initialLeftWidth = leftSide.getBoundingClientRect().width;
81+
setIsResizing(true);
82+
document.addEventListener('mousemove', mouseMoveHandler);
83+
document.addEventListener('mouseup', mouseUpHandler);
84+
};
6585

66-
// Attach the handler
67-
resizer.addEventListener('mousedown', mouseDownHandler);
68-
});
69-
})
7086
return (
71-
<Box h="$full" class="splitview-container">
72-
<div class="splitview-container__left">{props.children[0]}</div>
73-
<div class="splitview-resizer" id="dragMe"></div>
74-
<div class="splitview-container__right">{props.children[1]}</div>
75-
</Box>
87+
<Box h="$full" class="splitview-container">
88+
<div class="splitview-container-left" style={leftStyleGet()} ref={leftSide}>{resolvedChildren()[0]}</div>
89+
<div class="splitview-resizer" style={resizerStyleGet()} ref={resizer} onMouseDown={mouseDownHandler}></div>
90+
<div class="splitview-container-right" style={rightStyleGet()} ref={rightSide}>{resolvedChildren()[1]}</div>
91+
</Box>
7692
);
7793
};
7894

frontend/index.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
border: 1px solid #cbd5e0;
1313
width: 100%;
1414
}
15-
.splitview-container__left {
15+
.splitview-container-left {
1616
width: 60%;
1717
min-width: 440px;
1818
display: flex;
@@ -23,9 +23,9 @@
2323
background-color: #cbd5e0;
2424
cursor: ew-resize;
2525
height: 100%;
26-
width: 2px;
26+
width: 5px;
2727
}
28-
.splitview-container__right {
28+
.splitview-container-right {
2929
flex: 1;
3030
display: flex;
3131
padding: 5px;

0 commit comments

Comments
 (0)