19 lines
2.2 KiB
TypeScript
19 lines
2.2 KiB
TypeScript
"use client";
|
|
import { Handle, Position, BaseEdge, getBezierPath, type NodeProps, type EdgeProps } from '@xyflow/react';
|
|
import { defineComponent, editable, movable } from '@/lib/canvas-core/index';
|
|
import type { ProjectionNode, ProjectionEdge } from '@/lib/canvas-bindings/projection';
|
|
import type { CanvasRuntimeExtension } from '@/lib/canvas-bindings/react-renderers';
|
|
import { useCanvasRendererCommands } from '@/lib/canvas-bindings/renderer-context';
|
|
function Meter({data}:NodeProps<ProjectionNode>){
|
|
const commands=useCanvasRendererCommands(),record=data.__headlessRecord!;
|
|
return <div data-renderer-fixture="meter" style={{width:'100%',height:'100%',background:'white',border:'1px solid #ded7ce',padding:16}}>
|
|
<span>Metric {String(record.data.metric)}</span><button className="nodrag" aria-label={`Increase ${record.id}`} onClick={event=>{event.stopPropagation();commands.transaction(tx=>{tx.dispatch({type:'element.data',target:{id:record.id,incarnation:record.incarnation},patch:{metric:Number(record.data.metric)+1}});tx.dispatch({type:'element.data',target:{id:record.id,incarnation:record.incarnation},patch:{raw:{retained:true,edited:true}}});},{label:'Increase metric'});}}>Increase</button>
|
|
<Handle type="source" id="custom-out" position={Position.Right}/><Handle type="source" id="custom-in" position={Position.Left}/>
|
|
</div>;
|
|
}
|
|
function MeterEdge(props:EdgeProps<ProjectionEdge>){const [path]=getBezierPath(props);return <g data-renderer-fixture="metric-edge"><title>Metric {String(props.data?.__headlessRecord?.data.metric)}</title><BaseEdge id={props.id} path={path}/></g>;}
|
|
export const fixtureExtension:CanvasRuntimeExtension={
|
|
components:[defineComponent({id:'fixture:meter',dataVersion:1,structure:'node',validate:data=>Number.isSafeInteger(data.metric),features:[editable(),movable()],copy:{references:[],omit:[]}}),defineComponent({id:'fixture:metric-edge',dataVersion:1,structure:'connection',validate:data=>typeof data.metric==='number',features:[],copy:{references:[],omit:[]}})],
|
|
renderers:[{componentId:'fixture:meter',dataVersion:1,structure:'node',rendererId:'fixture-meter',render:Meter},{componentId:'fixture:metric-edge',dataVersion:1,structure:'connection',rendererId:'fixture-metric-edge',render:MeterEdge}],
|
|
};
|