Skip to content

Commit

Permalink
feat: Add resizable panes
Browse files Browse the repository at this point in the history
  • Loading branch information
KostyaCholak committed Jul 20, 2024
1 parent 47c3950 commit 068f672
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 45 deletions.
Binary file modified bun.lockb
Binary file not shown.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"react-dom": "^18.2.0",
"react-highlight": "^0.15.0",
"react-konva": "^18.2.10",
"react-resizable-panels": "^2.0.21",
"sonner": "^1.5.0",
"tailwind-merge": "^2.3.0",
"tailwindcss-animate": "^1.0.7",
Expand Down
79 changes: 69 additions & 10 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,21 @@ import "./App.css";
import { Input } from "@/components/ui/input";
import { Cable, Wifi, WifiOff } from "lucide-react";
import { useEffect, useState } from "react";
import { toast } from "sonner";
import ExplainableView from "./ExplainableView";
import { ThemeProvider } from "./components/theme-provider";
import { Button } from "./components/ui/button";
import { toast } from "sonner"
import { useViewStore } from './storages/viewStorage';
import { useWebsocketURIStore } from './storages/websocketURIStore';

import api, { LATEST_VERSION } from "./api";
import NoConnectionComponent from "./components/NoConnectionComponent";
import ServerIsOutdatedComponent from "./components/ServerIsOutdatedComponent";
import { dataclassDisplayConfig } from "./components/canvas/render";
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "./components/ui/resizable";
import { IS_MOCKED, MOCK_VIEWS } from "./mock";
import { Representation } from "./sources";
import { pushHistory } from "./structures/history";
import ServerIsOutdatedComponent from "./components/ServerIsOutdatedComponent";


const didYouKnowMessages = [
Expand Down Expand Up @@ -224,11 +225,70 @@ export default function App() {
);
});

const rows = [];
for (let idx = 0; idx < view_components.length; idx += 2) {
rows.push(
<ResizablePanel
key={idx}
className="rounded-none w-full h-full"
>
<ResizablePanelGroup direction="vertical">
<ResizablePanel className="rounded-none w-full h-full">
{view_components[idx]}
</ResizablePanel>
{view_components[idx + 1] && (
<>
<ResizableHandle withHandle={true}/>
<ResizablePanel className="rounded-none w-full h-full">
{view_components[idx + 1]}
</ResizablePanel>
</>
)}
</ResizablePanelGroup>
</ResizablePanel>
);
if (idx !== view_components.length - 1) {
rows.push(
<ResizableHandle
key={-(idx + 1)}
withHandle={true}
/>
);
}
// if (idx !== view_components.length - 1) {
// panels.push(
// <ResizableHandle
// key={-(idx + 1)}
// withHandle={true}
// />
// );
// }
}
comp = (
<div className="grid gap-4 md:grid-cols-2 md:gap-8 lg:grid-cols-2">
{ view_components}
</div>
);
<>
{/* <HistoryUI
paused={false}
viewSettings={{view_id: ""}}
onBackClick={() => {
}}
onPauseClick={() => {
api.request("pause", true, (_: any) => {
});
}}
onForwardClick={() => {
}}
onSettings={() => {}}
/> */}
<ResizablePanelGroup
direction="horizontal"
className="rounded-none border w-full h-full"
>
{rows}
</ResizablePanelGroup>
</>
)
}

if (isOutdated) {
Expand All @@ -239,13 +299,12 @@ export default function App() {

return (
<ThemeProvider defaultTheme="dark" storageKey="vite-ui-theme">
<div className="flex min-h-screen w-full flex-col">
<div className="flex min-h-screen w-full flex-col h-screen">
<Header
isConnected={isConnected}
/>
<main className="flex flex-1 flex-col gap-4 p-4 md:gap-8 md:p-8">
{/* <ConnectingComponent/> */}
{comp}
<main className="h-full">
{comp}
</main>
</div>
</ThemeProvider>
Expand Down
37 changes: 9 additions & 28 deletions src/ExplainableView.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { useState } from 'react';
import WhiteBoard from './WhiteBoard';
import { Input } from './components/ui/input';
import { ViewType } from './storages/viewStorage';
import render from './components/canvas/render.tsx';
import { ViewType } from './storages/viewStorage';
import WhiteBoard from './WhiteBoard';


export type ViewSettings = {
Expand All @@ -17,7 +15,7 @@ export type ExplainableViewProps = {

function ExplainableView(props: ExplainableViewProps) {
const view = props.view;
const [path, setPath] = useState<string>(view.id);
// const [path, setPath] = useState<string>(view.id);
// useEffect(() => {
// api.onConnected(() => {
// clearHistory();
Expand All @@ -36,34 +34,17 @@ function ExplainableView(props: ExplainableViewProps) {
const component = render(view.structure, view.representation || null, position, view.id, 0);

return (
<div className='slow-appear'>
{/* <HistoryUI
paused={false}
viewSettings={{view_id: ""}}
onBackClick={() => {
}}
onPauseClick={() => {
api.request("pause", true, (paused: any) => {
});
}}
onForwardClick={() => {
}}
onSettings={() => {}}
/> */}
<Input className="p-2 border border-b-0 rounded-none" defaultValue={path} onKeyDown={
<div className='slow-appear h-full'>
{/* <Input className="p-2 border border-b-0 rounded-none" defaultValue={path} onKeyDown={
(e: any) => {
if (e.key === "Enter") {
setPath(e.target.value);
}
}
} name='view-path'/>
<div className="component-container">
<WhiteBoard view_id={view.id}>
{component}
</WhiteBoard>
</div>
} name='view-path'/> */}
<WhiteBoard view_id={view.id}>
{component}
</WhiteBoard>
</div>
)
}
Expand Down
24 changes: 19 additions & 5 deletions src/WhiteBoard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,26 @@ function WhiteBoard(props: WhiteBoardProps) {
} | null>(null);

useEffect(() => {
if (divRef.current?.offsetHeight && divRef.current?.offsetWidth) {
setDimensions({
width: divRef.current.offsetWidth - 2,
height: divRef.current.offsetHeight
});
const observer = new ResizeObserver(entries => {
for (let entry of entries) {
console.log('New width:', entry.contentRect.width);
console.log('New height:', entry.contentRect.height);
setDimensions({
width: entry.contentRect.width - 2,
height: entry.contentRect.height
});
}
});

if (divRef.current) {
observer.observe(divRef.current);
}

return () => {
if (divRef.current) {
observer.unobserve(divRef.current);
}
};
}, []);

const dragStageStart = (evt: KonvaEventObject<MouseEvent>) => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/HistoryUI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type UIButtonProps = {
function UIButton(props: UIButtonProps) {
return (
<Button
className="rounded-none [&:not(:last-child)]:border-r-0 text-slate-300"
className="rounded-none [&:not(:last-child)]:border-r-0 text-slate-300 w-8 h-8"
variant="outline"
size="icon"
onClick={props.onClick}>
Expand Down
2 changes: 1 addition & 1 deletion src/components/NoConnectionComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default function NoConnectionComponent() {
const [copied, setCopied] = useState(false);

return (
<div className="flex flex-col items-center justify-center">
<div className="flex flex-col items-center justify-center mt-10">
<h1 className="text-xl font-extrabold mb-3">How to start</h1>
<div className="relative min-w-[450px]">
<Button
Expand Down
43 changes: 43 additions & 0 deletions src/components/ui/resizable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { GripVertical } from "lucide-react"
import * as ResizablePrimitive from "react-resizable-panels"

import { cn } from "@/lib/utils"

const ResizablePanelGroup = ({
className,
...props
}: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) => (
<ResizablePrimitive.PanelGroup
className={cn(
"flex h-full w-full data-[panel-group-direction=vertical]:flex-col",
className
)}
{...props}
/>
)

const ResizablePanel = ResizablePrimitive.Panel

const ResizableHandle = ({
withHandle,
className,
...props
}: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & {
withHandle?: boolean
}) => (
<ResizablePrimitive.PanelResizeHandle
className={cn(
"relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90",
className
)}
{...props}
>
{withHandle && (
<div className="z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border">
<GripVertical className="h-2.5 w-2.5" />
</div>
)}
</ResizablePrimitive.PanelResizeHandle>
)

export { ResizablePanelGroup, ResizablePanel, ResizableHandle }

0 comments on commit 068f672

Please sign in to comment.