hikma-flow
v1.1.0
Published
A framework-agnostic flow library with TypeScript support.
Maintainers
Readme
Hikma-Flow
A comprehensive, framework-agnostic flow library built with TypeScript. Create interactive node-based diagrams with drag-and-drop functionality, customizable nodes and edges, and rich interaction features.
🚀 Features
Core Functionality
- Node Management: Create, position, and customize nodes with rich content
- Edge Rendering: Multiple edge types (straight, bezier, smooth-step) with customizable styling
- Drag & Drop: Intuitive drag-and-drop for nodes and viewport panning
- Zoom & Pan: Smooth zooming and panning with mouse wheel and drag support
- Handle System: Visual connection points with source/target validation
- Multi-Selection: Select multiple nodes with Ctrl/Cmd + click
- Keyboard Shortcuts: Delete selected elements, zoom controls
Advanced Features
- Event System: Comprehensive event handling for user interactions
- Background Patterns: Customizable grid patterns (dots, lines, cross)
- Controls Component: Built-in zoom and pan controls
- MiniMap Component: Overview map for large diagrams
- Node Toolbar: Contextual toolbar for node actions
- TypeScript Support: Full TypeScript definitions and type safety
- Framework Agnostic: Works with any JavaScript framework or vanilla JS
📦 Installation
npm install hikma-flow🎯 Quick Start
import { Flow, Node, Edge } from 'hikma-flow';
// Create a container
const container = document.getElementById('flow-container');
// Define a custom node renderer
const nodeRenderer = (node: Node) => {
const foreignObject = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
foreignObject.setAttribute('x', node.x.toString());
foreignObject.setAttribute('y', node.y.toString());
foreignObject.setAttribute('width', node.width.toString());
foreignObject.setAttribute('height', node.height.toString());
const div = document.createElement('div');
div.style.backgroundColor = node.backgroundColor || 'lightblue';
div.style.border = '1px solid black';
div.style.borderRadius = '4px';
div.style.padding = '10px';
div.textContent = `Node ${node.id}`;
foreignObject.appendChild(div);
return foreignObject;
};
// Create the flow instance
const flow = new Flow(container, nodeRenderer);
// Add nodes and edges
const nodes: Node[] = [
{ id: '1', x: 100, y: 100, width: 100, height: 60, handles: [{ id: 'out', position: 'right', type: 'source' }] },
{ id: '2', x: 300, y: 100, width: 100, height: 60, handles: [{ id: 'in', position: 'left', type: 'target' }] }
];
const edges: Edge[] = [
{ id: 'e1-2', source: '1', target: '2', sourceHandle: 'out', targetHandle: 'in' }
];
flow.setData(nodes, edges);📚 API Reference
Flow Class
The main class for creating and managing flow diagrams.
constructor(
container: HTMLElement,
nodeRenderer: NodeRenderer,
edgeRenderer?: EdgeRenderer,
snapGridSize?: number,
miniMapElement?: HTMLElement,
showGrid?: boolean,
backgroundColor?: string,
backgroundOpacity?: number,
options?: FlowOptions
)Methods
setData(nodes: Node[], edges: Edge[])- Set the flow dataaddNode(node: Node)- Add a single noderemoveNode(nodeId: string)- Remove a nodeaddEdge(edge: Edge)- Add a single edgeremoveEdge(edgeId: string)- Remove an edgezoomIn()- Zoom inzoomOut()- Zoom outfitView()- Fit all nodes in viewgetConnectedEdges(nodeId: string)- Get edges connected to a nodegetIncomers(nodeId: string)- Get nodes that connect to the given nodegetOutgoers(nodeId: string)- Get nodes that the given node connects to
Node Interface
interface Node {
id: string;
x: number;
y: number;
width: number;
height: number;
backgroundColor?: string;
borderColor?: string;
borderRadius?: number;
handles?: Handle[];
selected?: boolean;
data?: any;
type?: string;
}Edge Interface
interface Edge {
id: string;
source: string;
target: string;
sourceHandle?: string;
targetHandle?: string;
strokeColor?: string;
strokeWidth?: number;
type?: 'straight' | 'bezier' | 'smoothstep';
animated?: boolean;
data?: any;
}Handle Interface
interface Handle {
id: string;
position: 'top' | 'right' | 'bottom' | 'left';
type: 'source' | 'target' | 'both';
}🎨 Components
Background
import { Background } from 'hikma-flow';
const background = new Background({
variant: 'dots', // 'dots' | 'lines' | 'cross'
color: '#f0f0f0',
patternColor: '#e0e0e0',
gap: 20,
size: 1
});Controls
import { Controls } from 'hikma-flow';
const controls = new Controls(container, flow, {
position: 'top-left',
showZoomIn: true,
showZoomOut: true,
showFitView: true
});MiniMap
import { MiniMap } from 'hikma-flow';
const miniMap = new MiniMap(container, flow, {
position: 'bottom-right',
width: 200,
height: 150,
nodeColor: '#6b7280',
backgroundColor: '#f8fafc'
});🎮 Events
// Node events
flow.on('node:click', (node) => console.log('Node clicked:', node));
flow.on('node:drag', (node) => console.log('Node dragged:', node));
// Connection events
flow.on('connect', (connection) => console.log('New connection:', connection));
// Pane events
flow.on('pane:click', (event) => console.log('Pane clicked:', event));🎯 Examples
See the example.ts file for a comprehensive example demonstrating all features.
🏗️ Development
# Install dependencies
npm install
# Start development server
npm run dev
# Build for production
npm run build
# Run example
npm run example📝 License
ISC
🤝 Contributing
Contributions are welcome! Please feel free to submit issues and pull requests.
Built with ❤️ and TypeScript
