Skip to content

Commit

Permalink
Added resizable node
Browse files Browse the repository at this point in the history
  • Loading branch information
anna-llorens committed Jun 22, 2024
1 parent 63de46d commit 2ee4574
Show file tree
Hide file tree
Showing 8 changed files with 202 additions and 9 deletions.
95 changes: 95 additions & 0 deletions src/components/flow/edit-flow/resize-and-rotate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { useEffect, useState, useRef } from "react";
import {
Handle,
Position,
useUpdateNodeInternals,
NodeResizer,
} from "reactflow";
import { drag } from "d3-drag";
import { select } from "d3-selection";

import styles from "./style.module.css";

export default function ResizeRotateNode({
id,
sourcePosition = Position.Left,
targetPosition = Position.Right,
data,
}) {
const rotateControlRef = useRef(null);
const updateNodeInternals = useUpdateNodeInternals();
const [rotation, setRotation] = useState(0);
const [resizable, setResizable] = useState(!!data.resizable);
const [rotatable, setRotatable] = useState(!!data.rotatable);

useEffect(() => {
if (!rotateControlRef.current) {
return;
}

const selection = select(rotateControlRef.current);
const dragHandler = drag().on("drag", (evt) => {
const dx = evt.x - 100;
const dy = evt.y - 100;
const rad = Math.atan2(dx, dy);
const deg = rad * (180 / Math.PI);
setRotation(180 - deg);
updateNodeInternals(id);
});

selection.call(dragHandler);
}, [id, updateNodeInternals]);

return (
<>
<div
style={{
transform: `rotate(${rotation}deg)`,
}}
className={styles.node}
>
<NodeResizer isVisible={resizable} minWidth={180} minHeight={100} />
<div
ref={rotateControlRef}
style={{
display: rotatable ? "block" : "none",
}}
className={`nodrag ${styles.rotateHandle}`}
/>
<div>
{data?.label}
<div>
<label>
<input
type="checkbox"
checked={resizable}
onChange={(evt) => setResizable(evt.target.checked)}
/>
resizable
</label>
</div>
<div>
<label>
<input
type="checkbox"
checked={rotatable}
onChange={(evt) => setRotatable(evt.target.checked)}
/>
rotatable
</label>
</div>
</div>
<Handle
style={{ opacity: 0 }}
position={sourcePosition}
type="source"
/>
<Handle
style={{ opacity: 0 }}
position={targetPosition}
type="target"
/>
</div>
</>
);
}
38 changes: 38 additions & 0 deletions src/components/flow/edit-flow/style.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
.node {
width: 100%;
height: 100%;
border-radius: 15px;
border: 1px solid #000;
background-color: #fff;
padding: 20px;
box-sizing: border-box;
}

.node :global .react-flow__resize-control.handle {
width: 10px;
height: 10px;
border-radius: 100%;
}

.rotateHandle {
position: absolute;
width: 10px;
height: 10px;
background: #3367d9;
left: 50%;
top: -30px;
border-radius: 100%;
transform: translate(-50%, -50%);
cursor: alias;
}

.rotateHandle:after {
content: "";
display: block;
position: absolute;
width: 1px;
height: 30px;
background: #3367d9;
left: 4px;
top: 5px;
}
3 changes: 3 additions & 0 deletions src/components/flow/flow-nodes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ type NodeData = {
export const Label = ({ data }: NodeProps<NodeData>) => (
<div>A big number: {data.value}</div>
);
export const Resize = ({ data }: NodeProps<NodeData>) => (
<div>A big number: {data.value}</div>
);

export function InputText({ data }: NodeProps<NodeData>) {
return <div>TextUpdater {data.value}</div>;
Expand Down
3 changes: 2 additions & 1 deletion src/components/flow/flow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ import ReactFlow, {
MiniMap,
} from "reactflow";
import "reactflow/dist/style.css";
import { Label, InputText } from "./flow-nodes";
import { Label, InputText, Resize } from "./flow-nodes";

// Define node types
const nodeTypesDefault: NodeTypes = {
// TODO add more types
label: Label,
editable: InputText,
resize: Resize,
};

const proOptions = { hideAttribution: true };
Expand Down
6 changes: 6 additions & 0 deletions src/components/tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Box from "@mui/material/Box";
import { Edge, Node } from "reactflow";
import { useState } from "react";
import Tab from "@mui/material/Tab";
import { useLocation } from "react-router-dom";

type TabPanelProps = {
children?: React.ReactNode;
Expand Down Expand Up @@ -90,6 +91,9 @@ export const TabsComponent: React.FC<Props> = ({ tabs, children }) => {
const handleChange = (_event: React.SyntheticEvent, teamTab: number) =>
setActiveTeam(teamTab);

const location = useLocation();
console.log("location", location);

return (
<>
<Box sx={{ width: "100%" }}>
Expand All @@ -112,10 +116,12 @@ export const TabsComponent: React.FC<Props> = ({ tabs, children }) => {
{tabs.map((tab, index) => (
<TabPanel key={index} value={activeTeam} index={index}>
{tab?.children}
{/* <Outlet /> ??*/}
</TabPanel>
))}
</Box>
{children}
{/* <Outlet />?? */}
</>
);
};
57 changes: 57 additions & 0 deletions src/pages/members-page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import ReactFlow, { Background, Position } from "reactflow";

import "reactflow/dist/style.css";

import ResizeRotateNode from "../components/flow/edit-flow/resize-and-rotate";

const nodeTypes = {
resizeRotate: ResizeRotateNode,
};

const nodes = [
{
id: "1",
position: { x: 0, y: 0 },
data: { label: "Node 1", resizable: true },
type: "resizeRotate",
targetPosition: Position.Left,
sourcePosition: Position.Right,
selected: true,
style: { width: 180, height: 100 },
},
{
id: "2",
position: { x: 300, y: 0 },
data: { label: "Node 2", rotatable: true },
type: "resizeRotate",
targetPosition: Position.Left,
sourcePosition: Position.Right,
style: { width: 180, height: 100 },
},
];

const edges = [
{
id: "1->2",
source: "1",
target: "2",
type: "smoothstep",
},
];

export const MembersPage = () => {
return (
<div>
<p>Members Page</p>

<ReactFlow
nodeTypes={nodeTypes}
defaultNodes={nodes}
defaultEdges={edges}
fitView
>
<Background />
</ReactFlow>
</div>
);
};
7 changes: 0 additions & 7 deletions src/pages/members.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion src/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { createBrowserRouter } from "react-router-dom";

import { App } from "./App";
import { ErrorPage } from "./pages/error-page";
import { MembersPage } from "./pages/members";
import { MembersPage } from "./pages/members-page";

import { EditFlowPage } from "./components/flow/edit-flow/edit-flow";
import { OrgPage } from "./pages/teams/org-page";
Expand Down

0 comments on commit 2ee4574

Please sign in to comment.