From b4d7b00dd1add8e1cffb7771539fa6c419b64846 Mon Sep 17 00:00:00 2001 From: Sam Nystrom Date: Wed, 13 Mar 2024 22:37:58 +0000 Subject: refactor: extract nodes/sockets to components --- src/NodeEditor.tsx | 10 +- src/components/nodes/Input.css | 103 ++++++++++++++++++ src/components/nodes/Input.tsx | 97 +++++++++++++++++ src/components/nodes/NodeShell.css | 47 +++++++++ src/components/nodes/NodeShell.tsx | 46 ++++++++ src/components/nodes/Output.css | 20 ++++ src/components/nodes/Output.tsx | 19 ++++ src/components/nodes/Socket.css | 20 ++++ src/components/nodes/Socket.tsx | 41 ++++++++ src/components/nodes/index.ts | 3 + src/context.ts | 5 +- src/node.css | 150 -------------------------- src/node.ts | 27 +++++ src/node.tsx | 208 ------------------------------------- src/nodes/CombineXYZ.tsx | 3 +- src/nodes/Fourier.tsx | 3 +- src/nodes/Intersperse.tsx | 3 +- src/nodes/Linspace.tsx | 3 +- src/nodes/Math.tsx | 3 +- src/nodes/Plot.tsx | 3 +- src/nodes/SeparateXYZ.tsx | 3 +- src/nodes/Unzip.tsx | 3 +- src/nodes/Viewer.tsx | 3 +- 23 files changed, 446 insertions(+), 377 deletions(-) create mode 100644 src/components/nodes/Input.css create mode 100644 src/components/nodes/Input.tsx create mode 100644 src/components/nodes/NodeShell.css create mode 100644 src/components/nodes/NodeShell.tsx create mode 100644 src/components/nodes/Output.css create mode 100644 src/components/nodes/Output.tsx create mode 100644 src/components/nodes/Socket.css create mode 100644 src/components/nodes/Socket.tsx create mode 100644 src/components/nodes/index.ts delete mode 100644 src/node.css create mode 100644 src/node.ts delete mode 100644 src/node.tsx (limited to 'src') diff --git a/src/NodeEditor.tsx b/src/NodeEditor.tsx index b3ef838..435aec4 100644 --- a/src/NodeEditor.tsx +++ b/src/NodeEditor.tsx @@ -1,8 +1,9 @@ import { useContext, useEffect, useMemo, useRef } from 'preact/hooks'; import { signal, computed, batch, useSignal, useComputed, Signal } from '@preact/signals'; import { Pb } from './context.ts'; +import { SocketHandlers } from './node.ts'; import { nodeRegistry } from './nodes'; -import { SocketHandlers, SocketHandler, NodeInfo } from './node.tsx'; +import type { SocketHandler, NodeInfo } from './node.tsx'; import { InputSocket } from './dataflow.ts'; import { Toolbar, ButtonMenu, MenuItem } from './components'; import './NodeEditor.css'; @@ -37,10 +38,7 @@ const Link = ({ fromX, fromY, toX, toY }: LinkProps) => { const c1x = fromX.value + Math.abs(toX.value - fromX.value) / 3; const c2x = toX.value - Math.abs(toX.value - fromX.value) / 3; return ( - + ); }; @@ -78,8 +76,6 @@ const NodeEditor = ({ user, project }) => { const filter = pb.filter('project.id = {:id}', { id: projectData.id }); const projectNodes = await pb.collection('nodes').getFullList({ filter }); const projectLinks = await pb.collection('links').getFullList({ filter }); - console.log(projectNodes); - console.log(projectLinks); const instances = projectNodes.map(node => instantiateNode(node.x, node.y, node.name)); nodes.value = nodes.value.concat(instances); }, []); diff --git a/src/components/nodes/Input.css b/src/components/nodes/Input.css new file mode 100644 index 0000000..aa01558 --- /dev/null +++ b/src/components/nodes/Input.css @@ -0,0 +1,103 @@ +@scope (.__Input) { + :scope { + display: flex; + justify-content: flex-start; + align-items: center; + padding: 4px 0; + + .__Output + & { + padding-top: 8px; + } + + input { + background-color: var(--overlay); + border: none; + border-radius: 4px; + outline: none; + color: var(--text); + font-size: 1em; + text-align: right; + width: 100%; + max-width: 200px; + margin-right: 12px; + padding-top: 3px; + padding-bottom: 2px; + + .linked & { + display: none; + } + } + } +} + +@scope (.__InputNum) { + & + & { + padding-top: 0; + } + + :scope { + --socket-color: var(--data-float); + + span { + position: relative; + left: 8px; + width: 0; + white-space: nowrap; + padding-bottom: 2px; + } + } +} + +@scope (.__InputVector) { + :scope { + flex-direction: column; + align-items: flex-start; + gap: 1px; + --socket-color: var(--data-vector); + + & :first-child { + display: flex; + flex-direction: row; + align-items: center; + gap: 2px; + margin-bottom: 4px; + .linked & { + margin-bottom: 0; + } + } + + input { + width: 89%; + margin-left: 8px; + margin-right: 16px; + + &:nth-child(2) { border-radius: 4px 4px 0 0 } + &:nth-child(3) { border-radius: 0 } + &:nth-child(4) { border-radius: 0 0 4px 4px } + + .linked & { + display: none; + } + } + } +} + +@scope (.__InputSelect) { + :scope { + --socket-color: var(--data-float); + + select { + background-color: color-mix(in srgb, var(--base) 50%, var(--surface)); + color: var(--text); + border: 1px solid color-mix(in srgb, var(--overlay) 50%, var(--surface)); + border-radius: 4px; + width: 100%; + margin-right: 12px; + padding: 3px 1px; + + .linked & { + display: none; + } + } + } +} \ No newline at end of file diff --git a/src/components/nodes/Input.tsx b/src/components/nodes/Input.tsx new file mode 100644 index 0000000..1160f3f --- /dev/null +++ b/src/components/nodes/Input.tsx @@ -0,0 +1,97 @@ +import { InputSocket } from '../../dataflow.ts'; +import { InSocket } from './Socket.tsx'; +import './Input.css'; + +interface InProps { + children: ComponentChildren; + linked?: boolean; + class: string; +} + +const Input = ({ children, linked = false, ...props }: InProps) => ( +
  • {children}
  • +); + +export interface InputProps { + name: string; + label: string; + value: InputSocket; +} + +export const InputAny = ({ name, label }: Omit, 'value'>) => { + return ( + + + {label} + + ); +}; + +export const InputArray = ({ name, label }: Omit, 'value'>) => { + return ( + + + {label} + + ); +}; + +const InputNum = (parseFunc: (string) => number) => ({ name, label, value }: InputProps) => { + const onInput = (event: InputEvent) => { + value.value = parseFunc((event.target as HTMLInputElement).value); + } + return ( + + + {label} + + + ); +}; + +export const InputInteger = InputNum(parseInt); +export const InputNumber = InputNum(parseFloat); + +export const InputVector = ({ name, label, value }: InputProps<[number, number, number]>) => { + const onInput = (i: 0 | 1 | 2) => (event: InputEvent) => { + const newValue: [number, number, number] = [...value.value]; + newValue[i] = parseFloat((event.target as HTMLInputElement).value); + value.value = newValue; + }; + return ( + +
    + + {label} +
    + + + + + ); +}; + +export interface InputSelectProps extends InputProps { + options: string[] | Record; +} + +export const InputSelect = ({ name, label, value, options }: InputSelectProps) => { + const onChange = (event: InputEvent) => { + value.value = (event.target as HTMLSelectElement).value; + } + return ( + + + + + ); +}; diff --git a/src/components/nodes/NodeShell.css b/src/components/nodes/NodeShell.css new file mode 100644 index 0000000..5e4fb2a --- /dev/null +++ b/src/components/nodes/NodeShell.css @@ -0,0 +1,47 @@ +@scope (.__NodeShell) { + :scope { + width: 0; + height: 0; + overflow: visible; + + > details { + background-color: var(--surface); + min-width: 180px; + width: fit-content; + font-size: 0.9rem; + margin: 4px; + padding-bottom: 8px; + display: flex; + flex-direction: column; + border-radius: 6px; + user-select: none; + --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); + + &:focus-within { + outline: 1px white solid; + } + + summary { + background-color: var(--primary); + padding: 3px; + padding-left: 6px; + margin-bottom: 4px; + border-radius: 6px 6px 0 0; + list-style-image: url('../../icons/chevron-down.svg'); + } + &:not([open]) summary { + list-style-image: url('../../icons/chevron-right.svg'); + } + + ul { + list-style: none; + padding: 0; + margin: 0; + } + } + } +} diff --git a/src/components/nodes/NodeShell.tsx b/src/components/nodes/NodeShell.tsx new file mode 100644 index 0000000..0de1a6d --- /dev/null +++ b/src/components/nodes/NodeShell.tsx @@ -0,0 +1,46 @@ +import { ComponentChildren } from 'preact'; +import { batch, Signal } from '@preact/signals'; +import { NodeId } from '../../node.ts'; +import './NodeShell.css'; + +export interface NodeShellProps { + children: ComponentChildren; + id: number; + name: string; + x: Signal; + y: Signal; +} + +const NodeShell = ({ children, id, name, x, y }: NodeShellProps) => { + const onMouseDown = (event: MouseEvent) => { + event.stopPropagation(); + + const onMouseMove = (event: MouseEvent) => batch(() => { + x.value += event.movementX; + y.value += event.movementY; + }); + + const onMouseUp = () => { + window.removeEventListener('mousemove', onMouseMove); + window.removeEventListener('mouseup', onMouseUp); + }; + + window.addEventListener('mousemove', onMouseMove); + window.addEventListener('mouseup', onMouseUp); + }; + + return ( + +
    + e.stopPropagation()}>{name} +
      + + {children} + +
    +
    +
    + ); +}; + +export default NodeShell; \ No newline at end of file diff --git a/src/components/nodes/Output.css b/src/components/nodes/Output.css new file mode 100644 index 0000000..2c752a1 --- /dev/null +++ b/src/components/nodes/Output.css @@ -0,0 +1,20 @@ +@scope (.__Output) { + :scope { + display: flex; + justify-content: flex-end; + align-items: center; + padding: 4px 0; + } +} + +@scope (.__OutputNumber) { + :scope { + --socket-color: var(--data-float); + } +} + +@scope (.__OutputVector) { + :scope { + --socket-color: var(--data-vector); + } +} \ No newline at end of file diff --git a/src/components/nodes/Output.tsx b/src/components/nodes/Output.tsx new file mode 100644 index 0000000..8cd9c98 --- /dev/null +++ b/src/components/nodes/Output.tsx @@ -0,0 +1,19 @@ +import { OutSocket } from './Socket.tsx'; +import './Output.css'; + +export interface OutputProps { + name: string; + label: string; +} + +const Output = (type: string, cls: string) => ({ name, label }: OutputProps) => { + return ( +
  • + {label} + +
  • + ); +}; + +export const OutputNumber = Output('number', '__OutputNumber'); +export const OutputVector = Output('vector', '__OutputVector'); diff --git a/src/components/nodes/Socket.css b/src/components/nodes/Socket.css new file mode 100644 index 0000000..5879b32 --- /dev/null +++ b/src/components/nodes/Socket.css @@ -0,0 +1,20 @@ +@scope (.__Socket) { + :scope { + position: relative; + circle { + fill: var(--socket-color, var(--data-float)); + } + } +} + +@scope (.__InSocket) { + :scope { + right: 4px; + } +} + +@scope (.__OutSocket) { + :scope { + left: 4px; + } +} diff --git a/src/components/nodes/Socket.tsx b/src/components/nodes/Socket.tsx new file mode 100644 index 0000000..a4f38e1 --- /dev/null +++ b/src/components/nodes/Socket.tsx @@ -0,0 +1,41 @@ +import { useContext } from 'preact/hooks'; +import { NodeId, SocketHandlers } from '../../node.ts'; +import './Socket.css'; + +interface SocketProps { + name: string; + class?: string; + onMouseDown?: SocketHandler; + onMouseUp?: SocketHandler; +} + +const Socket = ({ name, onMouseDown, onMouseUp, ...props }: SocketProps) => { + const nodeId = useContext(NodeId); + const wrap = (func?: SocketHandler) => (event: MouseEvent) => func && func(nodeId, name, event); + return ( + + + + ); +}; + +export const InSocket = ({ name }: { name: string }) => { + const handlers = useContext(SocketHandlers); + return ( + + ); +}; + +export const OutSocket = ({ name }: { name: string }) => { + const handlers = useContext(SocketHandlers); + return ( + + ); +}; diff --git a/src/components/nodes/index.ts b/src/components/nodes/index.ts new file mode 100644 index 0000000..d29f39f --- /dev/null +++ b/src/components/nodes/index.ts @@ -0,0 +1,3 @@ +export { default as NodeShell, NodeShellProps } from './NodeShell.tsx'; +export { OutputNumber, OutputVector, OutputProps } from './Output.tsx'; +export { InputAny, InputArray, InputInteger, InputNumber, InputVector, InputSelect, InputProps, InputSelectProps } from './Input.tsx'; diff --git a/src/context.ts b/src/context.ts index 2e77787..054d796 100644 --- a/src/context.ts +++ b/src/context.ts @@ -1,5 +1,4 @@ import { createContext } from 'preact'; +import type { PocketBase } from 'pocketbase'; -const Pb = createContext(); - -export { Pb }; \ No newline at end of file +export const Pb = createContext(); diff --git a/src/node.css b/src/node.css deleted file mode 100644 index 3b0ba16..0000000 --- a/src/node.css +++ /dev/null @@ -1,150 +0,0 @@ -@scope (.__NodeShell) { - :scope { - width: 0; - height: 0; - overflow: visible; - } - - .node { - background-color: var(--surface); - min-width: 180px; - width: fit-content; - font-size: 0.9rem; - margin: 4px; - padding-bottom: 8px; - display: flex; - flex-direction: column; - border-radius: 6px; - user-select: none; - --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); - - &:focus-within { - outline: 1px white solid; - } - - input[type="number"] { - background-color: var(--overlay); - border: none; - border-radius: 4px; - outline: none; - color: var(--text); - font-size: 1em; - text-align: right; - width: 100%; - max-width: 200px; - margin-right: 12px; - padding-top: 3px; - padding-bottom: 2px; - } - - summary { - background-color: var(--primary); - padding: 3px; - padding-left: 6px; - margin-bottom: 4px; - border-radius: 6px 6px 0 0; - list-style-image: url('icons/chevron-down.svg'); - } - &:not([open]) summary { - list-style-image: url('icons/chevron-right.svg'); - } - - ul { - list-style: none; - padding: 0; - margin: 0; - } - - ul li { - display: flex; - flex-direction: row; - align-items: center; - padding: 4px 0; - - circle { - fill: var(--data-float); - .number & { fill: var(--data-float) } - .vector & { fill: var(--data-vector) } - .select & { fill: var(--data-float) } - } - - &.out + &.in { - padding-top: 8px; - } - - &.out { - justify-content: flex-end; - - svg { - position: relative; - left: 4px; - } - } - - &.in { - justify-content: flex-start; - - svg { - position: relative; - right: 4px; - } - - &.number { - + .number { padding-top: 0 } - &.linked input { display: none } - - span { - position: relative; - left: 8px; - width: 0; - white-space: nowrap; - padding-bottom: 2px; - } - } - - &.vector { - flex-direction: column; - align-items: flex-start; - gap: 1px; - - & :first-child { - display: flex; - flex-direction: row; - align-items: center; - gap: 2px; - margin-bottom: 4px; - .linked & { margin-bottom: 0 } - } - - input { - width: 89%; - margin-left: 8px; - margin-right: 16px; - - &:nth-child(2) { border-radius: 4px 4px 0 0 } - &:nth-child(3) { border-radius: 0 } - &:nth-child(4) { border-radius: 0 0 4px 4px } - - .linked & { display: none } - } - } - - &.select select { - background-color: color-mix(in srgb, var(--base) 50%, var(--surface)); - color: var(--text); - border: 1px solid color-mix(in srgb, var(--overlay) 50%, var(--surface)); - border-radius: 4px; - width: 100%; - margin-right: 12px; - padding: 3px 1px; - - .linked & { display: none } - } - } - } - } -} \ No newline at end of file diff --git a/src/node.ts b/src/node.ts new file mode 100644 index 0000000..1f4d5eb --- /dev/null +++ b/src/node.ts @@ -0,0 +1,27 @@ +import { createContext, FunctionComponent } from 'preact'; +import { InputSocket } from './dataflow.ts'; + +export type SocketHandler = (nodeId: number, socket: string, event: MouseEvent) => void; +export interface SocketHandlers { + onOutMouseDown?: SocketHandler; + onOutMouseUp?: SocketHandler; + onInMouseDown?: SocketHandler; + onInMouseUp?: SocketHandler; +} + +export interface NodeComponentProps { + id: number; + x: Signal; + y: Signal; + inputs: { [Property in keyof I]: InputSocket }; +} +export type NodeComponent = FunctionComponent>; + +export interface NodeInfo { + component: NodeComponent; + func: (inputs: I) => O; + inputs: I; +} + +export const SocketHandlers = createContext({}); +export const NodeId = createContext(0); diff --git a/src/node.tsx b/src/node.tsx deleted file mode 100644 index cb72734..0000000 --- a/src/node.tsx +++ /dev/null @@ -1,208 +0,0 @@ -import { createContext, FunctionComponent, ComponentChildren } from 'preact'; -import { useContext } from 'preact/hooks'; -import { batch, Signal } from '@preact/signals'; -import { InputSocket } from './dataflow.ts'; -import { cls } from './util.ts'; -import './node.css'; - -export type SocketHandler = (nodeId: number, socket: string, event: MouseEvent) => void; -export interface SocketHandlers { - onOutMouseDown?: SocketHandler; - onOutMouseUp?: SocketHandler; - onInMouseDown?: SocketHandler; - onInMouseUp?: SocketHandler; -} - -export const SocketHandlers = createContext({}); -export const NodeId = createContext(0); - -export interface NodeComponentProps { - id: number; - x: Signal; - y: Signal; - inputs: { [Property in keyof I]: InputSocket }; -} -export type NodeComponent = FunctionComponent>; - -export interface NodeInfo { - component: NodeComponent; - func: (inputs: I) => O; - inputs: I; -} - -interface SocketProps { - name: string; - onMouseDown?: SocketHandler; - onMouseUp?: SocketHandler; -} - -const Socket = ({ name, onMouseDown, onMouseUp }: SocketProps) => { - const nodeId = useContext(NodeId); - const wrap = (func?: SocketHandler) => (event: MouseEvent) => func && func(nodeId, name, event); - return ( - - - - ); -}; - -const InSocket = ({ name }: { name: string }) => { - const handlers = useContext(SocketHandlers); - return ( - - ); -}; - -const OutSocket = ({ name }: { name: string }) => { - const handlers = useContext(SocketHandlers); - return ( - - ); -}; - -export interface InputProps { - name: string; - label: string; - value: InputSocket; -} - -export const InputAny = ({ name, label }: Omit, 'value'>) => { - return ( -
  • - - {label} -
  • - ); -}; - -export const InputArray = ({ name, label }: Omit, 'value'>) => { - return ( -
  • - - {label} -
  • - ); -}; - -const InputNum = (parseFunc: (string) => number) => ({ name, label, value }: InputProps) => { - const onInput = (event: InputEvent) => { - value.value = parseFunc((event.target as HTMLInputElement).value); - } - return ( -
  • - - {label} - -
  • - ); -}; - -export const InputNumber = InputNum(parseFloat); -export const InputInteger = InputNum(parseInt); - -export const InputVector = ({ name, label, value }: InputProps<[number, number, number]>) => { - const onInput = (i: 0 | 1 | 2) => (event: InputEvent) => { - const newValue: [number, number, number] = [...value.value]; - newValue[i] = parseFloat((event.target as HTMLInputElement).value); - value.value = newValue; - }; - return ( -
  • -
    - - {label} -
    - - - -
  • - ); -}; - -export interface InputSelectProps extends InputProps { - options: string[] | Record; -} - -export const InputSelect = ({ name, label, value, options }: InputSelectProps) => { - const onChange = (event: InputEvent) => { - value.value = (event.target as HTMLSelectElement).value; - } - return ( -
  • - - -
  • - ); -}; - -export interface OutputProps { - name: string; - label: string; -} - -const Output = ({ name, label, type }: OutputProps & { type: string }) => { - return ( -
  • - {label} - -
  • - ); -}; - -export const OutputNumber = (props: OutputProps) => ; -export const OutputVector = (props: OutputProps) => ; - -export interface NodeShellProps { - id: number; - name: string; - x: Signal; - y: Signal; - children: ComponentChildren; -} - -export const NodeShell = ({ id, name, x, y, children }: NodeShellProps) => { - const onMouseDown = (event: MouseEvent) => { - event.stopPropagation(); - - const onMouseMove = (event: MouseEvent) => batch(() => { - x.value += event.movementX; - y.value += event.movementY; - }); - - const onMouseUp = () => { - window.removeEventListener('mousemove', onMouseMove); - window.removeEventListener('mouseup', onMouseUp); - }; - - window.addEventListener('mousemove', onMouseMove); - window.addEventListener('mouseup', onMouseUp); - }; - - return ( - -
    - e.stopPropagation()}>{name} -
      - - {children} - -
    -
    -
    - ); -}; \ No newline at end of file diff --git a/src/nodes/CombineXYZ.tsx b/src/nodes/CombineXYZ.tsx index 99823fd..5af22ce 100644 --- a/src/nodes/CombineXYZ.tsx +++ b/src/nodes/CombineXYZ.tsx @@ -1,4 +1,5 @@ -import { NodeShell, InputNumber, OutputVector, NodeComponentProps, NodeInfo } from '../node.tsx'; +import { NodeShell, InputNumber, OutputVector } from '../components/nodes'; +import type { NodeComponentProps, NodeInfo } from '../node.ts'; export interface CombineXYZInputs { x: number; diff --git a/src/nodes/Fourier.tsx b/src/nodes/Fourier.tsx index b9bda3f..f33768f 100644 --- a/src/nodes/Fourier.tsx +++ b/src/nodes/Fourier.tsx @@ -1,4 +1,5 @@ -import { NodeShell, InputArray, OutputNumber, NodeComponentProps, NodeInfo } from '../node.tsx'; +import { NodeShell, InputArray, OutputNumber } from '../components/nodes'; +import type { NodeComponentProps, NodeInfo } from '../node.ts'; import { fft } from '../wasm.ts'; export interface FourierInputs { diff --git a/src/nodes/Intersperse.tsx b/src/nodes/Intersperse.tsx index 2ef2a03..0c7e271 100644 --- a/src/nodes/Intersperse.tsx +++ b/src/nodes/Intersperse.tsx @@ -1,4 +1,5 @@ -import { NodeShell, InputArray, OutputNumber, NodeComponentProps, NodeInfo } from '../node.tsx'; +import { NodeShell, InputArray, OutputNumber } from '../components/nodes'; +import type { NodeComponentProps, NodeInfo } from '../node.ts'; import { intersperse } from '../wasm.ts'; export interface IntersperseInputs { diff --git a/src/nodes/Linspace.tsx b/src/nodes/Linspace.tsx index df1dbe6..b8239a1 100644 --- a/src/nodes/Linspace.tsx +++ b/src/nodes/Linspace.tsx @@ -1,4 +1,5 @@ -import { NodeShell, InputNumber, InputInteger, OutputNumber, NodeComponentProps, NodeInfo } from '../node.tsx'; +import { NodeShell, InputNumber, InputInteger, OutputNumber } from '../components/nodes'; +import type { NodeComponentProps, NodeInfo } from '../node.ts'; import { linspace } from '../wasm.ts'; export interface LinspaceInputs { diff --git a/src/nodes/Math.tsx b/src/nodes/Math.tsx index fe46fb4..c885bae 100644 --- a/src/nodes/Math.tsx +++ b/src/nodes/Math.tsx @@ -1,5 +1,6 @@ +import { NodeShell, InputNumber, InputSelect, OutputNumber } from '../components/nodes'; +import type { NodeComponentProps, NodeInfo } from '../node.ts'; import { mathS, mathV, mathSS, mathSV, mathVS, mathVV } from '../wasm.ts'; -import { NodeShell, InputNumber, InputSelect, OutputNumber, NodeComponentProps, NodeInfo } from '../node.tsx'; export enum MathOpFunc { Add = 'Add', diff --git a/src/nodes/Plot.tsx b/src/nodes/Plot.tsx index 649246a..d87fb72 100644 --- a/src/nodes/Plot.tsx +++ b/src/nodes/Plot.tsx @@ -1,4 +1,5 @@ -import { NodeShell, InputAny, InputNumber, NodeComponentProps, NodeInfo } from '../node.tsx'; +import { NodeShell, InputAny, InputNumber } from '../components/nodes'; +import type { NodeComponentProps, NodeInfo } from '../node.ts'; import { useComputed } from '@preact/signals'; export interface PlotInputs { diff --git a/src/nodes/SeparateXYZ.tsx b/src/nodes/SeparateXYZ.tsx index bc14be1..f76c43c 100644 --- a/src/nodes/SeparateXYZ.tsx +++ b/src/nodes/SeparateXYZ.tsx @@ -1,4 +1,5 @@ -import { NodeShell, InputVector, OutputNumber, NodeComponentProps, NodeInfo } from '../node.tsx'; +import { NodeShell, InputVector, OutputNumber } from '../components/nodes'; +import type { NodeComponentProps, NodeInfo } from '../node.ts'; export interface SeparateXYZInputs { vector: [number, number, number]; diff --git a/src/nodes/Unzip.tsx b/src/nodes/Unzip.tsx index ff5832d..5bcb477 100644 --- a/src/nodes/Unzip.tsx +++ b/src/nodes/Unzip.tsx @@ -1,4 +1,5 @@ -import { NodeShell, InputArray, OutputNumber, NodeComponentProps, NodeInfo } from '../node.tsx'; +import { NodeShell, InputArray, OutputNumber } from '../components/nodes'; +import type { NodeComponentProps, NodeInfo } from '../node.ts'; import { unzip } from '../wasm.ts'; export interface UnzipInputs { diff --git a/src/nodes/Viewer.tsx b/src/nodes/Viewer.tsx index b4b7758..d92da3c 100644 --- a/src/nodes/Viewer.tsx +++ b/src/nodes/Viewer.tsx @@ -1,4 +1,5 @@ -import { NodeShell, InputAny, NodeComponentProps, NodeInfo } from '../node.tsx'; +import { NodeShell, InputAny } from '../components/nodes'; +import type { NodeComponentProps, NodeInfo } from '../node.ts'; export interface ViewerInputs { value: any; -- cgit v1.2.3