style(devtools): put styles in css file

This commit is contained in:
moklick
2024-04-03 11:33:21 +02:00
parent 79dbdc27f6
commit b302cb59e8
6 changed files with 123 additions and 59 deletions

View File

@@ -29,7 +29,7 @@ function ChangeInfo({ change }: ChangeInfoProps) {
);
}
export default function ChangeLogger({ color = '#555', limit = 20 }: ChangeLoggerProps) {
export default function ChangeLogger({ limit = 20 }: ChangeLoggerProps) {
const [changes, setChanges] = useState<NodeChange[]>([]);
const onNodesChangeIntercepted = useRef(false);
const onNodesChange = useStore((s) => s.onNodesChange);
@@ -62,19 +62,13 @@ export default function ChangeLogger({ color = '#555', limit = 20 }: ChangeLogge
}, [onNodesChange]);
return (
<div
style={{ fontFamily: 'monospace', fontSize: 10, position: 'relative', top: 45, left: 15, width: '100%', color }}
>
<div style={{ margin: '5px 0' }}>
<strong>Change Logger</strong>
</div>
<div>
{changes.length === 0 ? (
<>no changes triggered</>
) : (
changes.map((change, index) => <ChangeInfo key={index} change={change} />)
)}
</div>
<div className="react-flow__devtools-changelogger">
<div className="react-flow__devtools-title">Change Logger</div>
{changes.length === 0 ? (
<>no changes triggered</>
) : (
changes.map((change, index) => <ChangeInfo key={index} change={change} />)
)}
</div>
);
}

View File

@@ -12,17 +12,15 @@ type NodeInfoProps = {
function NodeInfo({ id, type, x, y, width, height, data }: NodeInfoProps) {
if (!width || !height) {
return <div></div>;
return null;
}
return (
<div
className="react-flow__devtools-nodeinfo"
style={{
position: 'absolute',
zIndex: 9999,
transform: `translate(${x}px, ${y + height}px)`,
padding: 5,
boxSizing: 'border-box',
width: width * 2,
}}
>
@@ -39,16 +37,12 @@ function NodeInfo({ id, type, x, y, width, height, data }: NodeInfoProps) {
);
}
type NodeInspectorProps = {
color: string;
};
export default function NodeInspector({ color = '#555' }: NodeInspectorProps) {
export default function NodeInspector() {
const nodes = useNodes();
return (
<ViewportPortal>
<div style={{ color, fontSize: 10, fontFamily: 'monospace' }}>
<div className="react-flow__devtools-nodeinspector">
{nodes.map((node) => {
const x = node.computed?.positionAbsolute?.x || 0;
const y = node.computed?.positionAbsolute?.y || 0;

View File

@@ -0,0 +1,42 @@
import { useState, type Dispatch, type SetStateAction, type ReactNode, HTMLAttributes } from 'react';
import { Panel } from '@xyflow/react';
import NodeInspector from './NodeInspector';
import ChangeLogger from './ChangeLogger';
export default function ReactFlowDevTools() {
const [nodeInspectorActive, setNodeInspectorActive] = useState(false);
const [changeLoggerActive, setChangeLoggerActive] = useState(false);
return (
<div className="react-flow__devtools">
<Panel position="top-left">
<DevToolButton setActive={setNodeInspectorActive} active={nodeInspectorActive} title="Toggle Node Inspector">
Node Inspector
</DevToolButton>
<DevToolButton setActive={setChangeLoggerActive} active={changeLoggerActive} title="Toggle Change Logger">
Change Logger
</DevToolButton>
</Panel>
{changeLoggerActive && <ChangeLogger />}
{nodeInspectorActive && <NodeInspector />}
</div>
);
}
function DevToolButton({
active,
setActive,
children,
...rest
}: {
active: boolean;
setActive: Dispatch<SetStateAction<boolean>>;
children: ReactNode;
} & HTMLAttributes<HTMLButtonElement>) {
return (
<button onClick={() => setActive((a) => !a)} className={active ? 'active' : ''} {...rest}>
{children}
</button>
);
}

View File

@@ -0,0 +1,63 @@
.react-flow__devtools {
--border-radius: 4px;
--highlight-color: rgba(238, 58, 115, 1);
--font: monospace, sans-serif;
border-radius: var(--border-radius);
font-size: 11px;
font-family: var(--font);
}
.react-flow__devtools button {
background: white;
border: none;
padding: 5px 15px;
color: #222;
font-weight: bold;
font-size: 12px;
cursor: pointer;
font-family: var(--font);
background-color: #f4f4f4;
}
.react-flow__devtools button:hover {
background: var(--highlight-color);
color: white;
}
.react-flow__devtools button.active {
background: var(--highlight-color);
color: white;
}
.react-flow__devtools button:first-child {
border-radius: var(--border-radius) 0 0 var(--border-radius);
border-right: 1px solid #ddd;
}
.react-flow__devtools button:last-child {
border-radius: 0 var(--border-radius) var(--border-radius) 0;
}
.react-flow__devtools-changelogger {
pointer-events: none;
position: relative;
top: 50px;
left: 20px;
font-family: var(--font);
}
.react-flow__devtools-title {
font-weight: bold;
margin-bottom: 5px;
}
.react-flow__devtools-nodeinspector {
pointer-events: none;
font-family: monospace, sans-serif;
font-size: 10px;
}
.react-flow__devtools-nodeinfo {
top: 5px;
}

View File

@@ -1,26 +0,0 @@
import { useState } from 'react';
import { Panel, PanelPosition } from '@xyflow/react';
import NodeInspector from './NodeInspector';
import ChangeLogger from './ChangeLogger';
type ReactFlowDevToolsProps = {
position?: PanelPosition;
color?: string;
};
export default function ReactFlowDevTools({ color = '#aaa', position = 'top-left' }: ReactFlowDevToolsProps) {
const [isNodeInspectorActive, setIsNodeInspectorActive] = useState(false);
const [isChangeLoggerActive, setIsChangeLoggerActive] = useState(false);
return (
<>
<Panel position={position}>
<button onClick={() => setIsNodeInspectorActive((a) => !a)}>node inspector</button>
<button onClick={() => setIsChangeLoggerActive((a) => !a)}>change logger</button>
</Panel>
{isNodeInspectorActive && <NodeInspector color={color} />}
{isChangeLoggerActive && <ChangeLogger color={color} />}
</>
);
}

View File

@@ -1,6 +1,8 @@
import { useCallback } from 'react';
import { ReactFlow, addEdge, Node, Connection, Edge, useNodesState, useEdgesState } from '@xyflow/react';
import ReactFlowDevTools from './ReactFlowDevTools';
import DevTools from './DevTools';
import './Devtools/style.css';
const initNodes: Node[] = [
{
@@ -8,32 +10,26 @@ const initNodes: Node[] = [
type: 'input',
data: { label: 'Node 1' },
position: { x: 250, y: 5 },
className: 'light',
ariaLabel: 'Input Node 1',
},
{
id: '2a',
data: { label: 'Node 2' },
position: { x: 100, y: 100 },
className: 'light',
ariaLabel: 'Default Node 2',
},
{
id: '3a',
data: { label: 'Node 3' },
position: { x: 400, y: 100 },
className: 'light',
},
{
id: '4a',
data: { label: 'Node 4' },
position: { x: 400, y: 200 },
className: 'light',
},
];
const initEdges: Edge[] = [
{ id: 'e1-2', source: '1a', target: '2a', ariaLabel: undefined },
{ id: 'e1-2', source: '1a', target: '2a' },
{ id: 'e1-3', source: '1a', target: '3a' },
];
@@ -50,8 +46,9 @@ const BasicFlow = () => {
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
fitView
>
<ReactFlowDevTools />
<DevTools />
</ReactFlow>
);
};