@ghchinoy/litflow 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 G. Hussain Chinoy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,163 @@
1
+ # LitFlow: xyflow + Lit WebComponents
2
+
3
+ LitFlow is a demonstration and starter kit for using the [xyflow](https://xyflow.com/) core system with [Lit](https://lit.dev/) WebComponents. It provides a lightweight, framework-agnostic way to build node-based UIs.
4
+
5
+ ## 🚀 Quick Start
6
+
7
+ ### Prerequisites
8
+ - Node.js (v18+)
9
+ - npm or pnpm
10
+
11
+ ### Installation
12
+ ```bash
13
+ pnpm install
14
+ ```
15
+
16
+ ### Development
17
+ ```bash
18
+ ./start-server.sh
19
+ ```
20
+ This will start the Vite development server and open the examples runner.
21
+
22
+ ## 📖 Usage Guide
23
+
24
+ ### 1. Installation
25
+ ```bash
26
+ pnpm add @ghchinoy/litflow
27
+ ```
28
+
29
+ ### 2. Basic Usage
30
+ Import the library in your main entry point to register the custom elements:
31
+
32
+ ```javascript
33
+ import '@ghchinoy/litflow';
34
+ ```
35
+
36
+ Then use the `<lit-flow>` component in your HTML or framework template:
37
+
38
+ ```html
39
+ <lit-flow id="my-flow" show-controls show-minimap show-grid="false"></lit-flow>
40
+
41
+ <script>
42
+ const flow = document.getElementById('my-flow');
43
+
44
+ // Interactivity controls
45
+ flow.nodesDraggable = false;
46
+ flow.panOnDrag = false;
47
+ flow.showGrid = false;
48
+
49
+ flow.nodes = [
50
+ { id: '1', position: { x: 100, y: 100 }, data: { label: 'Hello' } },
51
+ { id: '2', position: { x: 300, y: 100 }, data: { label: 'World' } }
52
+ ];
53
+
54
+ flow.edges = [
55
+ { id: 'e1-2', source: '1', target: '2' }
56
+ ];
57
+ </script>
58
+ ```
59
+
60
+ ### 3. Interactivity & Display
61
+ You can control the flow's behavior using attributes or properties:
62
+
63
+ | Attribute | Property | Default | Description |
64
+ |-----------|----------|---------|-------------|
65
+ | `show-controls` | `showControls` | `false` | Show zoom/fit controls |
66
+ | `show-minimap` | `showMinimap` | `false` | Show the minimap |
67
+ | `show-grid` | `showGrid` | `true` | Show the background grid |
68
+ | `nodes-draggable` | `nodesDraggable` | `true` | Allow dragging nodes |
69
+ | `nodes-connectable` | `nodesConnectable` | `true` | Allow creating new edges |
70
+ | `pan-on-drag` | `panOnDrag` | `true` | Allow panning the canvas |
71
+ | `zoom-on-scroll` | `zoomOnScroll` | `true` | Allow zooming with mouse wheel |
72
+
73
+ ### 4. Custom Nodes
74
+ To create a custom node, define a Lit component using **Light DOM** and register it with the flow:
75
+
76
+ ```javascript
77
+ import { LitElement, html } from 'lit';
78
+ import { customElement } from 'lit/decorators.js';
79
+
80
+ @customElement('my-custom-node')
81
+ class MyNode extends LitElement {
82
+ createRenderRoot() { return this; } // Required for xyflow compatibility
83
+ render() {
84
+ return html`<div>${this.data.label}</div>`;
85
+ }
86
+ }
87
+
88
+ // Register the type
89
+ const flow = document.querySelector('lit-flow');
90
+ flow.nodeTypes = {
91
+ ...flow.nodeTypes,
92
+ 'special': 'my-custom-node'
93
+ };
94
+ ```
95
+
96
+ ### 4. Styling (Material 3)
97
+ LitFlow comes with a built-in Material 3 theme. You can import the design tokens and apply them to your flow:
98
+
99
+ ```javascript
100
+ import { m3Tokens } from '@ghchinoy/litflow/theme';
101
+
102
+ // These tokens are automatically applied to <lit-flow>
103
+ // but you can also use them in your own custom nodes.
104
+ ```
105
+
106
+ ## 🏗️ Architecture
107
+
108
+ LitFlow leverages `@xyflow/system`, the same headless core that powers React Flow and Svelte Flow.
109
+
110
+ - **`examples/`**: Contains various implementation examples.
111
+ - `examples/index.html`: The main entry point to browse examples.
112
+ - `examples/basic/`: A simple graph implementation.
113
+ - `examples/multiple-handles/`: Nodes with multiple input/output ports.
114
+ - `examples/dynamic-interactivity/`: Adding/removing nodes and edges at runtime.
115
+ - `examples/subflows/`: Nested nodes and parent-child relationships.
116
+ - **`<lit-flow>`**: The root component. It initializes the `XYPanZoom` instance for the viewport and manages the collection of nodes and edges.
117
+ - **`<lit-node>`**: A reactive Lit component for individual nodes. Uses **Light DOM** to ensure compatibility with xyflow's system utilities (like hit-testing).
118
+ - **`<lit-handle>`**: A connection port component. Also uses **Light DOM** to ensure discoverability during connection dragging.
119
+ - **`<lit-controls>`**: A UI overlay providing zoom and fit-view controls.
120
+ - **`<lit-minimap>`**: A live overview of the flow with viewport tracking.
121
+ - **`store.ts`**: A state container using `@lit-labs/signals` for fine-grained, high-performance reactivity.
122
+
123
+ ## 🛠️ Key Features
124
+ - **Panning & Zooming**: Full support for viewport manipulation via d3-zoom (via xyflow).
125
+ - **Node Dragging**: Individual nodes can be dragged, with positions synced back to the state.
126
+ - **Manual Connections**: Drag-to-connect functionality between handles with a live connection line.
127
+ - **Controls & MiniMap**: Built-in utility components for navigation and overview.
128
+ - **Reactive Updates**: Powered by `@lit-labs/signals` for efficient, targeted re-renders.
129
+ - **Light DOM Architecture**: Optimized for `@xyflow/system` compatibility while maintaining Lit's reactive benefits.
130
+ - **Custom Node Support**: Easily build complex nodes with internal state and custom Lit templates.
131
+
132
+ ## 📖 Documentation
133
+ - [Lit vs React for xyflow](./LIT_VS_REACT.md): A comparison of using Lit WebComponents vs React for building flow-based UIs.
134
+ - [Creating Custom Nodes](./CUSTOM_NODES.md): A primer on building complex, data-driven nodes in LitFlow.
135
+ - [GEMINI.md](./GEMINI.md): Project conventions and technical insights for AI agents.
136
+
137
+ ## 🛠️ Development & Publishing
138
+
139
+ ### Build
140
+ To build the library and generate type definitions:
141
+ ```bash
142
+ pnpm run build
143
+ ```
144
+ This will output the compiled files and types to the `dist/` directory.
145
+
146
+ ### Publishing to npm
147
+ The package is published under the `@ghchinoy` scope. To publish a new version:
148
+
149
+ 1. **Update the version**:
150
+ ```bash
151
+ pnpm version patch # or minor, major
152
+ ```
153
+ 2. **Build the project**:
154
+ ```bash
155
+ pnpm run build
156
+ ```
157
+ 3. **Publish**:
158
+ ```bash
159
+ pnpm publish --access public
160
+ ```
161
+
162
+ ## 🤝 Contributing
163
+ This project is an exploration of xyflow's headless capabilities. Feel free to open issues or submit PRs to improve the Lit integration!
@@ -0,0 +1,8 @@
1
+ export * from './lit-flow';
2
+ export * from './lit-node';
3
+ export * from './lit-edge';
4
+ export * from './lit-handle';
5
+ export * from './lit-controls';
6
+ export * from './lit-minimap';
7
+ export * from './store';
8
+ export * from './theme';
@@ -0,0 +1,12 @@
1
+ import { LitElement } from 'lit';
2
+ import { type PanZoomInstance } from '@xyflow/system';
3
+ declare const LitControls_base: typeof LitElement;
4
+ export declare class LitControls extends LitControls_base {
5
+ static styles: import("lit").CSSResult;
6
+ panZoom?: PanZoomInstance;
7
+ private _zoomIn;
8
+ private _zoomOut;
9
+ private _fitView;
10
+ render(): import("lit").TemplateResult<1>;
11
+ }
12
+ export {};
@@ -0,0 +1,15 @@
1
+ import { LitElement } from 'lit';
2
+ import { Position } from '@xyflow/system';
3
+ declare const LitEdge_base: typeof LitElement;
4
+ export declare class LitEdge extends LitEdge_base {
5
+ static styles: import("lit").CSSResult;
6
+ sourceX: number;
7
+ sourceY: number;
8
+ targetX: number;
9
+ targetY: number;
10
+ sourcePosition: Position;
11
+ targetPosition: Position;
12
+ selected: boolean;
13
+ render(): import("lit").TemplateResult<2>;
14
+ }
15
+ export {};
@@ -0,0 +1,43 @@
1
+ import { LitElement } from 'lit';
2
+ import { type Viewport, type NodeBase } from '@xyflow/system';
3
+ import './lit-node';
4
+ import './lit-edge';
5
+ declare const LitFlow_base: typeof LitElement;
6
+ export declare class LitFlow extends LitFlow_base {
7
+ static styles: import("lit").CSSResult[];
8
+ _renderer?: HTMLElement;
9
+ _viewport?: HTMLElement;
10
+ private _panZoom?;
11
+ private _drags;
12
+ private _resizeObserver?;
13
+ private _state;
14
+ nodeTypes: Record<string, string>;
15
+ showControls: boolean;
16
+ showMinimap: boolean;
17
+ showGrid: boolean;
18
+ nodesDraggable: boolean;
19
+ nodesConnectable: boolean;
20
+ panOnDrag: boolean;
21
+ zoomOnScroll: boolean;
22
+ zoomOnPinch: boolean;
23
+ zoomOnDoubleClick: boolean;
24
+ private _width;
25
+ private _height;
26
+ set nodes(nodes: NodeBase[]);
27
+ get nodes(): NodeBase[];
28
+ set edges(edges: any[]);
29
+ get edges(): any[];
30
+ viewport: Viewport;
31
+ connectedCallback(): void;
32
+ disconnectedCallback(): void;
33
+ private _updateNodeDimensions;
34
+ private _selectNode;
35
+ firstUpdated(): void;
36
+ updated(changedProperties: Map<string, any>): void;
37
+ private _setupDrags;
38
+ private _renderEdge;
39
+ private _onHandlePointerDown;
40
+ private _renderConnectionLine;
41
+ render(): import("lit").TemplateResult;
42
+ }
43
+ export {};
@@ -0,0 +1,14 @@
1
+ import { LitElement } from 'lit';
2
+ import { Position } from '@xyflow/system';
3
+ export declare class LitHandle extends LitElement {
4
+ createRenderRoot(): this;
5
+ type: 'source' | 'target';
6
+ position: Position;
7
+ handleId?: string;
8
+ nodeId?: string;
9
+ constructor();
10
+ private _onPointerDown;
11
+ connectedCallback(): void;
12
+ updated(changedProperties: Map<string, any>): void;
13
+ render(): import("lit").TemplateResult<1>;
14
+ }
@@ -0,0 +1,17 @@
1
+ import { LitElement } from 'lit';
2
+ import { type PanZoomInstance, type InternalNodeBase, type Transform } from '@xyflow/system';
3
+ declare const LitMinimap_base: typeof LitElement;
4
+ export declare class LitMinimap extends LitMinimap_base {
5
+ static styles: import("lit").CSSResult;
6
+ panZoom?: PanZoomInstance;
7
+ nodeLookup: Map<string, InternalNodeBase>;
8
+ transform: Transform;
9
+ translateExtent: [[number, number], [number, number]];
10
+ width: number;
11
+ height: number;
12
+ private _minimapInstance?;
13
+ updated(changedProperties: Map<string, any>): void;
14
+ private _getBoundingRect;
15
+ render(): import("lit").TemplateResult<1>;
16
+ }
17
+ export {};
@@ -0,0 +1,12 @@
1
+ import { LitElement } from 'lit';
2
+ declare const LitNode_base: typeof LitElement;
3
+ export declare class LitNode extends LitNode_base {
4
+ createRenderRoot(): this;
5
+ label: string;
6
+ type: string;
7
+ data: any;
8
+ selected: boolean;
9
+ nodeId: string;
10
+ render(): import("lit").TemplateResult<1>;
11
+ }
12
+ export {};