summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam Nystrom <sam@samnystrom.dev>2024-03-08 08:09:18 +0000
committerSam Nystrom <sam@samnystrom.dev>2024-03-09 02:05:58 -0500
commit9fb6fa12590609a4cd25d2e212166c61e1c23580 (patch)
tree94f494fb4a0a841a8d17b3215227b7a7d77a3685 /src
parent5d06d2359e8ad50f7a61ecd1787a0ad558329964 (diff)
Add basic toolbar
Diffstat (limited to 'src')
-rw-r--r--src/AddNodeMenu.tsx21
-rw-r--r--src/NodeEditor.tsx12
-rw-r--r--src/Toolbar.module.css76
-rw-r--r--src/Toolbar.tsx30
4 files changed, 116 insertions, 23 deletions
diff --git a/src/AddNodeMenu.tsx b/src/AddNodeMenu.tsx
deleted file mode 100644
index 197f56d..0000000
--- a/src/AddNodeMenu.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { useId } from 'preact/hooks';
-import { NodeInfo } from './node.tsx';
-
-export interface AddNodeMenuProps {
- nodes: Record<string, NodeInfo>;
- onClick?: (NodeInfo) => void;
-}
-
-export const AddNodeMenu = ({ nodes, onClick = _ => {} }: AddNodeMenuProps) => {
- const id = useId();
- return (
- <>
- <menu id={id} popover>
- {Object.entries(nodes).map(([name, node]) => (
- <li><button onClick={() => onClick(node)}>{name}</button></li>
- ))}
- </menu>
- <button popoverTarget={id}>Add</button>
- </>
- );
-}; \ No newline at end of file
diff --git a/src/NodeEditor.tsx b/src/NodeEditor.tsx
index 0340a49..17e7c27 100644
--- a/src/NodeEditor.tsx
+++ b/src/NodeEditor.tsx
@@ -3,7 +3,7 @@ import { signal, computed, batch, useSignal, useComputed, Signal } from '@preact
import { nodeRegistry } from './nodes';
import { SocketHandlers, SocketHandler, NodeInfo } from './node.tsx';
import { InputSocket } from './dataflow.ts';
-import { AddNodeMenu } from './AddNodeMenu.tsx';
+import { Toolbar } from './Toolbar.tsx';
import styles from './NodeEditor.module.css';
export const nodeFactory = () => {
@@ -221,9 +221,16 @@ export const NodeEditor = () => {
scale.value *= 1 + delta;
});
+ const onNodeAdded = (node: NodeInfo) => {
+ nodes.value = nodes.value.concat(instantiateNode(100, 100, node));
+ };
+
return (
<>
- <AddNodeMenu nodes={nodeRegistry} onClick={node => nodes.value = nodes.value.concat(instantiateNode(100, 100, node))} />
+ <header>
+ <Toolbar nodes={nodeRegistry} onNodeAdded={onNodeAdded} />
+ </header>
+ <main>
<svg width="100vw" height="100vh" ref={svgRef} onMouseDown={onBgMouseDown} onWheel={onBgWheel}>
<pattern
id="bg-grid-major"
@@ -251,6 +258,7 @@ export const NodeEditor = () => {
</SocketHandlers.Provider>
</g>
</svg>
+ </main>
</>
);
}; \ No newline at end of file
diff --git a/src/Toolbar.module.css b/src/Toolbar.module.css
new file mode 100644
index 0000000..edea713
--- /dev/null
+++ b/src/Toolbar.module.css
@@ -0,0 +1,76 @@
+.toolbar {
+ background-color: var(--surface);
+ border-bottom: 1px solid var(--overlay);
+ width: 100%;
+ margin: 0;
+ padding: 0;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-between;
+
+ > * {
+ flex-grow: 1;
+ display: flex;
+ justify-content: center;
+ }
+ :first-child, :last-child { flex-basis: 0 }
+ :first-child { justify-content: flex-start }
+ :last-child { justify-content: flex-end }
+
+ > menu {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ display: flex;
+ flex-direction: row;
+ }
+
+ h1 {
+ font-size: 1.5rem;
+ font-weight: normal;
+ margin: 0;
+ }
+
+ button {
+ background-color: transparent;
+ border: none;
+ outline: none;
+ padding: 1rem;
+ color: var(--text);
+ font-size: 1em;
+ :hover { background-color: var(--overlay) }
+ }
+
+ path {
+ fill: var(--text);
+ }
+}
+
+.addMenu:popover-open {
+ background-color: var(--surface);
+ list-style: none;
+ border: none;
+ position: absolute;
+ inset: unset;
+ width: auto;
+ height: auto;
+ left: 140px;
+ top: 52px;
+ margin: 0;
+ padding: 0;
+ display: flex;
+ flex-direction: column;
+ --shadow-color: 0deg 0% 0%;
+ box-shadow:
+ 0.1px 0.4px 0.6px hsl(var(--shadow-color) / 0.04),
+ 0.5px 3.3px 4.8px -0.2px hsl(var(--shadow-color) / 0.15),
+ 1.4px 10.2px 14.7px -0.5px hsl(var(--shadow-color) / 0.27);
+
+ button {
+ padding: 4px;
+ width: 100%;
+ text-align: left;
+ &:hover { background-color: var(--overlay) }
+ }
+} \ No newline at end of file
diff --git a/src/Toolbar.tsx b/src/Toolbar.tsx
new file mode 100644
index 0000000..62c79fe
--- /dev/null
+++ b/src/Toolbar.tsx
@@ -0,0 +1,30 @@
+import { useId } from 'preact/hooks';
+import { NodeInfo } from './node.tsx';
+import styles from './Toolbar.module.css';
+
+export interface ToolbarProps {
+ nodes: Record<string, NodeInfo>;
+ onNodeAdded?: (NodeInfo) => void;
+}
+
+export const Toolbar = ({ nodes, onNodeAdded = _ => {} }: ToolbarProps) => {
+ const id = useId();
+ return (
+ <div class={styles.toolbar}>
+ <menu>
+ <li><button>Edit</button></li>
+ <li><button>Select</button></li>
+ <li>
+ <menu id={id} class={styles.addMenu} popover="auto">
+ {Object.entries(nodes).map(([name, node]) => (
+ <li><button onClick={() => onNodeAdded(node)}>{name}</button></li>
+ ))}
+ </menu>
+ <button popoverTarget={id}>Add</button>
+ </li>
+ </menu>
+ <h1>My Project</h1>
+ <div></div>
+ </div>
+ );
+}; \ No newline at end of file