/* eslint-disable react-perf/jsx-no-new-function-as-prop */ /* eslint-disable react-perf/jsx-no-new-object-as-prop */ // We have pre-loaded tailwind css import { createElements, createLinks, GraphProvider, Paper, Port, type InferElement, } from '@joint/react'; import type { dia } from '@joint/core'; import { util } from '@joint/core'; import { useCallback, useState } from 'react'; import { HTMLNode } from 'storybook-config/decorators/with-simple-data'; type Data = { id: string; title: string; description: string; nodeType: 'user-action' | 'entity' | 'confirm' | 'message'; x: number; y: number; }; const nodes = createElements([ { id: '1', title: 'User Action', description: 'Transfer funds', nodeType: 'user-action', x: 50, y: 50, attrs: { root: { magnet: false, }, }, }, { id: '2', title: 'Entity', description: 'Transfer funds', nodeType: 'entity', x: 120, y: 200, attrs: { root: { magnet: false, }, }, }, { id: '3', title: 'User Action', description: 'Get account balance', nodeType: 'user-action', attrs: { root: { magnet: false, }, }, x: 190, y: 350, }, ]); const links = createLinks([ { id: 'link1', source: { id: '1', port: '1' }, target: { id: '2', port: 'in' }, }, { id: 'link2', source: { id: '2', port: '1' }, target: { id: '3', port: 'in' }, }, { id: 'link3', source: { id: '3', port: '2' }, target: { id: '1', port: 'in' }, }, ]); type NodeType = InferElement; interface PortProps { id: string; label?: string; onRemove: (id: dia.Cell.ID) => void; x: number; } function PortItem({ id, label, onRemove, x }: Readonly) { const onRemovePress = useCallback( (event: React.MouseEvent) => { event.stopPropagation(); onRemove(id); }, [id, onRemove] ); return (
{label}
); } function RenderElement({ title, description, nodeType }: NodeType) { let icon: string; switch (nodeType) { case 'user-action': { icon = 'fas fa-user'; break; } case 'entity': { icon = 'fas fa-building'; break; } case 'confirm': { icon = 'fas fa-check'; break; } case 'message': { icon = 'fas fa-comment'; break; } default: { icon = 'fas fa-question'; break; } } const [ports, setPorts] = useState([ { id: '1', label: 'Port 1' }, { id: '2', label: 'Port 2' }, ]); const PORT_IN_SIZE = 15; const onRemove = useCallback( (id: dia.Cell.ID) => { setPorts((previous) => previous.filter((port) => port.id !== id)); }, [setPorts] ); return (
{title}
{description}
{ports.map((port, index) => ( ))} ); } function Main() { return ( { return magnet.getAttribute('magnet') !== 'passive'; }} validateConnection={(cellViewS, magnetS, cellViewT, magnetT) => { if (cellViewS === cellViewT) return false; if (cellViewS.model.isLink() || cellViewT.model.isLink()) return false; if (cellViewS.findAttribute('port-group', magnetS) === 'port-in-group') return false; return cellViewT.findAttribute('port-group', magnetT) !== 'port-out-group'; }} defaultConnectionPoint={{ name: 'boundary', args: { offset: 0, extrapolate: false, }, }} defaultRouter={{ name: 'rightAngle', args: { margin: 20 }, }} defaultConnector={{ name: 'straight', args: { cornerType: 'line', cornerPreserveAspectRatio: true }, }} /> ); } export default function App() { return (
); }