Skip to content

Commit 996c44b

Browse files
committed
resizable windows
1 parent 51a4f01 commit 996c44b

File tree

8 files changed

+162
-66
lines changed

8 files changed

+162
-66
lines changed

frontend/App.tsx

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Component } from "solid-js";
22
import { JSX, createSignal, createEffect } from "solid-js";
3-
import { Box, Tabs, TabList, Tab, TabPanel } from "@hope-ui/solid";
3+
import { Box, Tabs, TabList, Tab, TabPanel, Flex } from "@hope-ui/solid";
44
import { Route, Routes, useNavigate, useLocation } from "solid-app-router";
55

66
import Main from "./Main";
@@ -48,21 +48,21 @@ const App: Component = () => {
4848
};
4949

5050
return (
51-
<Tabs index={tabIndex()} onChange={handleTabsChange}>
52-
<TabList>
53-
<Tab>Main</Tab>
54-
<Tab>Info</Tab>
55-
</TabList>
56-
<TabPanel>
57-
<Panel>
51+
<Tabs h="$screenH" index={tabIndex()} onChange={handleTabsChange}>
52+
<Flex direction={"column"} h="$full" maxH="100vh">
53+
<TabList>
54+
<Tab>Main</Tab>
55+
<Tab>Info</Tab>
56+
</TabList>
57+
<TabPanel flexGrow="1">
5858
<AppRoutes />
59-
</Panel>
60-
</TabPanel>
61-
<TabPanel>
62-
<Panel>
63-
<AppRoutes />
64-
</Panel>
65-
</TabPanel>
59+
</TabPanel>
60+
<TabPanel>
61+
<Panel>
62+
<AppRoutes />
63+
</Panel>
64+
</TabPanel>
65+
</Flex>
6666
</Tabs>
6767
);
6868
};

frontend/Chat.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const Chat: Component<{
3535
<Show when={summary()}>
3636
{(summary) => <Badge>Summary: {summary}</Badge>}
3737
</Show>
38-
<Box width="53vw" maxHeight="36vh" overflow="scroll">
38+
<Box overflow="auto">
3939
<Table id="chat" dense css={{ "table-layout": "fixed" }}>
4040
<Thead>
4141
<Th width="10%" minWidth="7em">

frontend/Filter.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ const Filter: Component<{
2626
}> = (props) => {
2727
return (
2828
<Select size="xs" value={props.value} onChange={props.onChange}>
29-
<SelectTrigger width="$64">
29+
<SelectTrigger>
3030
<SelectPlaceholder>{props.label}</SelectPlaceholder>
3131
<SelectValue />
3232
<SelectIcon />
3333
</SelectTrigger>
34-
<SelectContent width="$64">
34+
<SelectContent>
3535
<SelectListbox>
3636
<For each={props.entries}>
3737
{(entry) => (

frontend/InstancesButtons.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ const InstancesButtons: Component<{
4040

4141
return (
4242
<Flex direction="row" justifyContent="flex-start" gap="$3">
43-
<Button onClick={handleAddInstance}>Add Instance</Button>
43+
<Button colorScheme="neutral" size="xs" onClick={handleAddInstance}>Add Instance</Button>
4444
<Tooltip label={CLEAR_INFO}>
45-
<Button onClick={handleClear}>Reset</Button>
45+
<Button colorScheme="neutral" size="xs" onClick={handleClear}>Reset</Button>
4646
</Tooltip>
4747
</Flex>
4848
);

frontend/Main.tsx

Lines changed: 30 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
Tooltip,
66
IconButton,
77
createDisclosure,
8+
Heading,
89
} from "@hope-ui/solid";
910
import { IoCaretBackOutline, IoCaretForwardOutline } from "solid-icons/io";
1011

@@ -14,6 +15,7 @@ import { scrollToInstance } from "./Instance";
1415
import Sidebar, { Search } from "./Sidebar";
1516
import Instance from "./Instance";
1617
import type { Instance as InstanceData } from "../types/instance";
18+
import SplitView from "./SplitView";
1719

1820
const Main: Component = () => {
1921
const [search, setSearch] = createSignal<Search>({
@@ -29,47 +31,36 @@ const Main: Component = () => {
2931

3032
return (
3133
<>
32-
<Flex justifyContent="space-between">
33-
<Flex flexDirection="column">
34-
<Box m="$8" ml="$1">
35-
<Flex flexWrap="wrap" gap="$5" overflow="scroll" maxHeight="77vh">
36-
<For each={instances()}>
37-
{(instance: InstanceData) => (
38-
<Instance instance={instance} setSearch={setSearchAndOpen} />
39-
)}
40-
</For>
34+
{
35+
<SplitView>
36+
<Flex flexDirection="column">
37+
<Flex mb="$1" justifyContent="space-between">
38+
<Heading level="1">Devices</Heading>
39+
<InstancesButtons
40+
onAfterAdd={(instanceId) => {
41+
scrollToInstance(instanceId);
42+
}}
43+
/>
4144
</Flex>
45+
<Box>
46+
<Flex flexWrap="wrap" gap="$5">
47+
<For each={instances()}>
48+
{(instance: InstanceData) => (
49+
<Instance instance={instance} setSearch={setSearchAndOpen} />
50+
)}
51+
</For>
52+
</Flex>
53+
</Box>
54+
</Flex>
55+
<Box>
56+
<Box position="sticky" top="20px">
57+
<Heading level="1" mb="1">Messages</Heading>
58+
<Sidebar search={search} setSearch={setSearchAndOpen} />
59+
</Box>
4260
</Box>
43-
<InstancesButtons
44-
onAfterAdd={(instanceId) => {
45-
scrollToInstance(instanceId);
46-
}}
47-
/>
48-
</Flex>
49-
<Box height="100wh">
50-
<Show
51-
when={isOpen()}
52-
fallback={
53-
<SidebarButton
54-
label="Open messages"
55-
onClick={onOpen}
56-
top="2rem"
57-
right="-2rem"
58-
icon={<IoCaretBackOutline size={22} color="#000000" />}
59-
/>
60-
}
61-
>
62-
<SidebarButton
63-
label="Close messages"
64-
onClick={onClose}
65-
top="2rem"
66-
right="2rem"
67-
icon={<IoCaretForwardOutline size={22} color="#000000" />}
68-
/>
69-
<Sidebar search={search} setSearch={setSearchAndOpen} />
70-
</Show>
71-
</Box>
72-
</Flex>
61+
</SplitView>
62+
63+
}
7364
</>
7465
);
7566
};

frontend/Messages.tsx

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,13 @@ const Messages: Component<{
2424
});
2525

2626
return (
27-
<Box width="53vw" maxHeight="36vh" overflow="scroll">
27+
<Box overflow="auto">
2828
<Table id="messages" dense css={{ "table-layout": "fixed" }}>
2929
<Thead>
30-
<Th width="10%" minWidth="7em">
31-
Id
32-
</Th>
33-
<Th width="10%">Type</Th>
34-
<Th width="20%">Descr</Th>
35-
<Th minWidth="60%">Payload</Th>
30+
<Th maxW="70px"> Id </Th>
31+
<Th maxW="70px">Type</Th>
32+
<Th maxW="70px">Descr</Th>
33+
<Th>Payload</Th>
3634
</Thead>
3735
<Tbody>
3836
<For

frontend/SplitView.tsx

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
2+
import { Box } from "@hope-ui/solid";
3+
import { ParentComponent, onMount } from "solid-js";
4+
5+
6+
const SplitView: ParentComponent<{
7+
}> = (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+
};
32+
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+
38+
const newLeftWidth = ((leftWidth + dx) * 100) / (resizer.parentNode as HTMLElement).getBoundingClientRect().width;
39+
leftSide.style.width = `${newLeftWidth}%`;
40+
41+
resizer.style.cursor = 'col-resize';
42+
document.body.style.cursor = 'col-resize';
43+
44+
leftSide.style.userSelect = 'none';
45+
leftSide.style.pointerEvents = 'none';
46+
47+
rightSide.style.userSelect = 'none';
48+
rightSide.style.pointerEvents = 'none';
49+
};
50+
51+
const mouseUpHandler = function () {
52+
resizer.style.removeProperty('cursor');
53+
document.body.style.removeProperty('cursor');
54+
55+
leftSide.style.removeProperty('user-select');
56+
leftSide.style.removeProperty('pointer-events');
57+
58+
rightSide.style.removeProperty('user-select');
59+
rightSide.style.removeProperty('pointer-events');
60+
61+
// Remove the handlers of `mousemove` and `mouseup`
62+
document.removeEventListener('mousemove', mouseMoveHandler);
63+
document.removeEventListener('mouseup', mouseUpHandler);
64+
};
65+
66+
// Attach the handler
67+
resizer.addEventListener('mousedown', mouseDownHandler);
68+
});
69+
})
70+
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>
76+
);
77+
};
78+
79+
export default SplitView;
80+

frontend/index.html

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,33 @@
55
<meta name="viewport" content="width=device-width, initial-scale=1" />
66
<meta name="theme-color" content="#000000" />
77
<title>webxdc-dev</title>
8+
9+
<style>
10+
.splitview-container {
11+
display: flex;
12+
border: 1px solid #cbd5e0;
13+
width: 100%;
14+
}
15+
.splitview-container__left {
16+
width: 60%;
17+
display: flex;
18+
overflow: none;
19+
padding: 5px;
20+
}
21+
.splitview-resizer {
22+
background-color: #cbd5e0;
23+
cursor: ew-resize;
24+
height: 100%;
25+
width: 2px;
26+
}
27+
.splitview-container__right {
28+
flex: 1;
29+
display: flex;
30+
padding: 5px;
31+
height: 100%;
32+
min-width: 450px;
33+
}
34+
</style>
835
</head>
936
<body>
1037
<noscript>You need to enable JavaScript to run this app.</noscript>

0 commit comments

Comments
 (0)