@ngx-km/grid 0.0.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngx-km-grid.mjs","sources":["../../../../libs/ngx-km-grid/src/lib/directives/grid-element-ref.directive.ts","../../../../libs/ngx-km-grid/src/lib/components/toolbar/toolbar.component.ts","../../../../libs/ngx-km-grid/src/lib/models/grid.models.ts","../../../../libs/ngx-km-grid/src/lib/ngx-grid/ngx-grid.ts","../../../../libs/ngx-km-grid/src/lib/ngx-grid/ngx-grid.html","../../../../libs/ngx-km-grid/src/index.ts","../../../../libs/ngx-km-grid/src/ngx-km-grid.ts"],"sourcesContent":["import { Directive, ElementRef, inject, input, OnInit, OnDestroy } from '@angular/core';\nimport { GridComponent } from '../ngx-grid/ngx-grid';\n\n/**\n * Directive that automatically registers/unregisters grid elements for dimension tracking\n */\n@Directive({\n selector: '[gridElementRef]',\n standalone: true,\n})\nexport class GridElementRefDirective implements OnInit, OnDestroy {\n private readonly elementRef = inject(ElementRef);\n private readonly gridComponent = inject(GridComponent);\n\n /** The element ID to register */\n gridElementRef = input.required<string>();\n\n ngOnInit(): void {\n this.gridComponent.registerElement(\n this.gridElementRef(),\n this.elementRef.nativeElement\n );\n }\n\n ngOnDestroy(): void {\n this.gridComponent.unregisterElement(this.gridElementRef());\n }\n}\n","import { Component, input, computed, inject } from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { ToolbarConfig, ToolbarButton } from '../../models/grid.models';\n\n@Component({\n selector: 'ngx-grid-toolbar',\n standalone: true,\n template: `\n <div class=\"toolbar\" [class]=\"toolbarClasses()\">\n @for (button of config().buttons; track button.id) {\n <button\n class=\"toolbar-btn\"\n [class.active]=\"button.active\"\n [class.disabled]=\"button.disabled\"\n [disabled]=\"button.disabled\"\n [title]=\"button.label\"\n (click)=\"onButtonClick(button, $event)\">\n @if (button.icon) {\n <span class=\"btn-icon\" [innerHTML]=\"sanitizeHtml(button.icon)\"></span>\n } @else {\n <span class=\"btn-label\">{{ button.label }}</span>\n }\n </button>\n }\n </div>\n `,\n styles: [`\n :host {\n position: absolute;\n z-index: 100;\n pointer-events: none;\n }\n\n .toolbar {\n display: flex;\n gap: 4px;\n padding: 6px;\n background: rgba(30, 30, 46, 0.95);\n border: 1px solid #444;\n border-radius: 6px;\n backdrop-filter: blur(4px);\n pointer-events: auto;\n }\n\n /* Position classes */\n :host(.pos-top-left) {\n top: 12px;\n left: 12px;\n }\n\n :host(.pos-top-center) {\n top: 12px;\n left: 50%;\n transform: translateX(-50%);\n }\n\n :host(.pos-top-right) {\n top: 12px;\n right: 12px;\n }\n\n :host(.pos-bottom-left) {\n bottom: 12px;\n left: 12px;\n }\n\n :host(.pos-bottom-center) {\n bottom: 12px;\n left: 50%;\n transform: translateX(-50%);\n }\n\n :host(.pos-bottom-right) {\n bottom: 12px;\n right: 12px;\n }\n\n .toolbar-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 32px;\n height: 32px;\n padding: 0 8px;\n border: 1px solid #555;\n background: #2a2a3e;\n color: #fff;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.15s ease;\n font-size: 0.875rem;\n }\n\n .toolbar-btn:hover:not(.disabled) {\n background: #3a3a4e;\n border-color: #666;\n }\n\n .toolbar-btn.active {\n background: #4a4a6e;\n border-color: #6a6a8e;\n }\n\n .toolbar-btn.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .btn-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n pointer-events: none;\n }\n\n .btn-icon ::ng-deep svg {\n width: 100%;\n height: 100%;\n pointer-events: none;\n }\n\n .btn-label {\n white-space: nowrap;\n }\n `],\n host: {\n '[class]': 'hostClasses()',\n },\n})\nexport class ToolbarComponent {\n private readonly sanitizer = inject(DomSanitizer);\n\n /** Toolbar configuration */\n config = input.required<ToolbarConfig>();\n\n /** Computed host classes based on position */\n hostClasses = computed(() => {\n const cfg = this.config();\n const posClass = `pos-${cfg.position}`;\n return cfg.className ? `${posClass} ${cfg.className}` : posClass;\n });\n\n /** Computed classes for the toolbar div */\n toolbarClasses = computed(() => {\n return '';\n });\n\n /** Sanitize HTML for safe rendering of SVG icons */\n sanitizeHtml(html: string): SafeHtml {\n return this.sanitizer.bypassSecurityTrustHtml(html);\n }\n\n /** Handle button click */\n onButtonClick(button: ToolbarButton, event: MouseEvent): void {\n event.stopPropagation();\n if (!button.disabled && button.onClick) {\n button.onClick();\n }\n }\n}\n","import { Type, InjectionToken, Signal } from '@angular/core';\n\n/**\n * Injection token for accessing element data in dynamically rendered components.\n * The data can be either a plain value or a Signal for reactive updates.\n */\nexport const GRID_ELEMENT_DATA = new InjectionToken<unknown>('GRID_ELEMENT_DATA');\n\n/**\n * Type alias for data that can be either a plain value or a Signal.\n * Use Signal<T> when you need the component to reactively update based on data changes.\n */\nexport type ReactiveData<T> = T | Signal<T>;\n\n/**\n * Dimension mode for the grid container\n * - 'fixed': Uses explicit width/height values\n * - 'full': Fills the parent container (100% width/height)\n */\nexport type DimensionMode = 'fixed' | 'full';\n\n/**\n * Background mode for the grid\n * - 'lines': Grid lines pattern\n * - 'dots': Dot pattern at intersections\n * - 'none': No background pattern\n */\nexport type BackgroundMode = 'lines' | 'dots' | 'none';\n\n/**\n * Configuration for the grid component\n */\nexport interface GridConfig {\n /** How the grid should size itself */\n dimensionMode: DimensionMode;\n\n /** Fixed width in pixels (only used when dimensionMode is 'fixed') */\n width?: number;\n\n /** Fixed height in pixels (only used when dimensionMode is 'fixed') */\n height?: number;\n\n /** Minimum width constraint in pixels */\n minWidth?: number;\n\n /** Minimum height constraint in pixels */\n minHeight?: number;\n\n /** Maximum width constraint in pixels */\n maxWidth?: number;\n\n /** Maximum height constraint in pixels */\n maxHeight?: number;\n\n /** Background pattern mode (default: 'lines') */\n backgroundMode?: BackgroundMode;\n\n /** Size of each grid cell in pixels (default: 20) */\n cellSize?: number;\n\n /** Color of the grid lines/dots (default: '#2a2a4a') */\n backgroundPatternColor?: string;\n\n /** Opacity of the background pattern 0-1 (default: 1) */\n backgroundPatternOpacity?: number;\n\n /** Background color of the grid (default: '#1a1a2e') */\n backgroundColor?: string;\n\n /** Enable panning (default: true) */\n panEnabled?: boolean;\n\n /** Minimum X pan boundary (undefined = infinite) */\n panMinX?: number;\n\n /** Maximum X pan boundary (undefined = infinite) */\n panMaxX?: number;\n\n /** Minimum Y pan boundary (undefined = infinite) */\n panMinY?: number;\n\n /** Maximum Y pan boundary (undefined = infinite) */\n panMaxY?: number;\n\n /** Enable zooming (default: true) */\n zoomEnabled?: boolean;\n\n /** Minimum zoom level (default: 0.1) */\n zoomMin?: number;\n\n /** Maximum zoom level (default: 5) */\n zoomMax?: number;\n\n /** Zoom speed multiplier (default: 0.001) */\n zoomSpeed?: number;\n\n /** Enable element dragging (default: true) */\n dragEnabled?: boolean;\n\n /** Enable snap-to-grid during drag (default: false) */\n snapEnabled?: boolean;\n\n /** Snap grid size in pixels (default: uses cellSize) */\n snapGridSize?: number;\n\n /** Toolbar configuration (renders toolbar inside grid) */\n toolbar?: GridToolbarConfig;\n\n /** Show loading overlay (default: false) */\n loading?: boolean;\n}\n\n/**\n * Configuration for the grid's integrated toolbar\n */\nexport interface GridToolbarConfig {\n /** Position of the toolbar within the grid */\n position?: ToolbarPosition;\n /** Show default zoom controls (default: true) */\n showZoomControls?: boolean;\n /** Show reset view button (default: true) */\n showResetView?: boolean;\n /** Additional custom buttons */\n customButtons?: ToolbarButton[];\n}\n\n/**\n * Viewport state representing pan and zoom\n */\nexport interface ViewportState {\n /** X offset (pan) */\n x: number;\n /** Y offset (pan) */\n y: number;\n /** Zoom level (1 = 100%) */\n zoom: number;\n}\n\n/**\n * Definition for an element to render on the grid\n * @template T Type of the data passed to the component\n */\nexport interface GridElement<T = unknown> {\n /** Unique identifier for this element */\n id: string;\n /** Angular component class to render */\n component: Type<unknown>;\n /**\n * Data to pass to the component via GRID_ELEMENT_DATA injection token.\n * Can be a plain value or a Signal for reactive updates.\n * When using Signal<T>, the component can reactively respond to data changes.\n */\n data?: ReactiveData<T>;\n /** X coordinate in world space */\n x: number;\n /** Y coordinate in world space */\n y: number;\n}\n\n/**\n * Rendered element with tracked dimensions\n */\nexport interface RenderedElement {\n /** Element ID */\n id: string;\n /** X coordinate in world space */\n x: number;\n /** Y coordinate in world space */\n y: number;\n /** Rendered width in pixels */\n width: number;\n /** Rendered height in pixels */\n height: number;\n}\n\n/**\n * Event emitted when an element position changes during drag\n */\nexport interface ElementPositionChange {\n /** Element ID being dragged */\n id: string;\n /** New X coordinate in world space */\n x: number;\n /** New Y coordinate in world space */\n y: number;\n /** Previous X coordinate */\n previousX: number;\n /** Previous Y coordinate */\n previousY: number;\n}\n\n/** Default cell size in pixels */\nexport const DEFAULT_CELL_SIZE = 20;\n\n/** Default background pattern color */\nexport const DEFAULT_PATTERN_COLOR = '#3a3a5a';\n\n/** Default minimum zoom level */\nexport const DEFAULT_ZOOM_MIN = 0.1;\n\n/** Default maximum zoom level */\nexport const DEFAULT_ZOOM_MAX = 5;\n\n/** Default zoom speed multiplier */\nexport const DEFAULT_ZOOM_SPEED = 0.001;\n\n/** Default background color */\nexport const DEFAULT_BACKGROUND_COLOR = '#1a1a2e';\n\n/**\n * Default grid configuration\n */\nexport const DEFAULT_GRID_CONFIG: GridConfig = {\n dimensionMode: 'full',\n backgroundMode: 'lines',\n cellSize: DEFAULT_CELL_SIZE,\n backgroundPatternColor: DEFAULT_PATTERN_COLOR,\n backgroundPatternOpacity: 1,\n backgroundColor: DEFAULT_BACKGROUND_COLOR,\n panEnabled: true,\n};\n\n/**\n * Default viewport state\n */\nexport const DEFAULT_VIEWPORT_STATE: ViewportState = {\n x: 0,\n y: 0,\n zoom: 1,\n};\n\n/**\n * Position for the floating toolbar\n */\nexport type ToolbarPosition =\n | 'top-left'\n | 'top-center'\n | 'top-right'\n | 'bottom-left'\n | 'bottom-center'\n | 'bottom-right';\n\n/**\n * Configuration for a toolbar button\n */\nexport interface ToolbarButton {\n /** Unique identifier for the button */\n id: string;\n /** Button label text (used as tooltip if icon is provided) */\n label: string;\n /** Optional icon (SVG string or icon name) */\n icon?: string;\n /** Whether the button is currently active/toggled */\n active?: boolean;\n /** Whether the button is disabled */\n disabled?: boolean;\n /** Callback function when button is clicked */\n onClick: () => void;\n}\n\n/**\n * Configuration for the toolbar\n */\nexport interface ToolbarConfig {\n /** Position of the toolbar within the grid */\n position: ToolbarPosition;\n /** Array of button configurations */\n buttons: ToolbarButton[];\n /** Optional CSS class to apply to the toolbar */\n className?: string;\n}\n","import { Component, computed, input, signal, output, ElementRef, inject, Injector, OnDestroy, AfterViewInit, effect, DestroyRef, untracked } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { NgStyle, NgComponentOutlet } from '@angular/common';\nimport { GridElementRefDirective } from '../directives/grid-element-ref.directive';\nimport { ToolbarComponent } from '../components/toolbar/toolbar.component';\nimport {\n GridConfig,\n DEFAULT_GRID_CONFIG,\n DEFAULT_CELL_SIZE,\n DEFAULT_PATTERN_COLOR,\n DEFAULT_BACKGROUND_COLOR,\n ViewportState,\n DEFAULT_VIEWPORT_STATE,\n DEFAULT_ZOOM_MIN,\n DEFAULT_ZOOM_MAX,\n DEFAULT_ZOOM_SPEED,\n GridElement,\n GRID_ELEMENT_DATA,\n RenderedElement,\n ElementPositionChange,\n ToolbarConfig,\n ToolbarButton,\n} from '../models/grid.models';\n\n@Component({\n selector: 'ngx-grid',\n imports: [NgStyle, NgComponentOutlet, GridElementRefDirective, ToolbarComponent],\n templateUrl: './ngx-grid.html',\n styleUrl: './ngx-grid.scss',\n})\nexport class GridComponent implements AfterViewInit, OnDestroy {\n private readonly elementRef = inject(ElementRef);\n private readonly injector = inject(Injector);\n private readonly destroyRef = inject(DestroyRef);\n\n /** Grid configuration */\n config = input<GridConfig>(DEFAULT_GRID_CONFIG);\n\n /** Elements to render on the grid */\n elements = input<GridElement[]>([]);\n\n /** Current viewport state (pan offset and zoom) */\n viewport = signal<ViewportState>({ ...DEFAULT_VIEWPORT_STATE });\n\n /** Emits when viewport changes */\n viewportChange = output<ViewportState>();\n\n /** Emits when element dimensions are measured or change */\n elementsRendered = output<RenderedElement[]>();\n\n /** Emits when an element is dragged to a new position */\n elementPositionChange = output<ElementPositionChange>();\n\n /** Map of element IDs to their DOM elements for dimension tracking */\n private elementRefs = new Map<string, HTMLElement>();\n\n /** ResizeObserver for tracking element dimension changes */\n private resizeObserver: ResizeObserver | null = null;\n\n /** Debounce timer for batching dimension updates */\n private dimensionUpdateTimer: ReturnType<typeof setTimeout> | null = null;\n\n /** Internal state for pan tracking */\n private isPanning = signal(false);\n private panStartX = 0;\n private panStartY = 0;\n private panStartViewportX = 0;\n private panStartViewportY = 0;\n\n /** Internal state for element drag tracking */\n private isDraggingElement = signal(false);\n private draggingElementId: string | null = null;\n private dragStartX = 0;\n private dragStartY = 0;\n private dragStartElementX = 0;\n private dragStartElementY = 0;\n\n /** Internal copy of element positions for drag updates */\n private elementPositions = new Map<string, { x: number; y: number }>();\n\n /** Track if we're currently dragging to avoid overwriting drag position */\n private syncPositionsFromInput = true;\n\n constructor() {\n // Sync element positions from input when elements change\n // This allows external code to update positions programmatically\n effect(() => {\n const inputElements = this.elements();\n\n untracked(() => {\n // Skip sync if currently dragging\n if (this.isDraggingElement()) return;\n\n // Update internal positions from input\n inputElements.forEach(el => {\n const currentPos = this.elementPositions.get(el.id);\n // Only update if position is different (allows external updates)\n if (!currentPos || currentPos.x !== el.x || currentPos.y !== el.y) {\n this.elementPositions.set(el.id, { x: el.x, y: el.y });\n }\n });\n\n // Remove positions for elements that no longer exist\n const inputIds = new Set(inputElements.map(e => e.id));\n for (const id of this.elementPositions.keys()) {\n if (!inputIds.has(id)) {\n this.elementPositions.delete(id);\n }\n }\n });\n });\n }\n\n /** Computed container styles based on config */\n containerStyles = computed(() => {\n const cfg = this.config();\n const styles: Record<string, string> = {};\n\n if (cfg.dimensionMode === 'fixed') {\n if (cfg.width) styles['width'] = `${cfg.width}px`;\n if (cfg.height) styles['height'] = `${cfg.height}px`;\n } else {\n styles['width'] = '100%';\n styles['height'] = '100%';\n }\n\n if (cfg.minWidth) styles['min-width'] = `${cfg.minWidth}px`;\n if (cfg.minHeight) styles['min-height'] = `${cfg.minHeight}px`;\n if (cfg.maxWidth) styles['max-width'] = `${cfg.maxWidth}px`;\n if (cfg.maxHeight) styles['max-height'] = `${cfg.maxHeight}px`;\n\n // Background color\n styles['background-color'] = cfg.backgroundColor ?? DEFAULT_BACKGROUND_COLOR;\n\n // Cursor style\n const panEnabled = cfg.panEnabled ?? true;\n if (panEnabled) {\n styles['cursor'] = this.isPanning() ? 'grabbing' : 'grab';\n }\n\n return styles;\n });\n\n /** Computed background styles for the pattern layer */\n backgroundStyles = computed(() => {\n const cfg = this.config();\n const vp = this.viewport();\n const mode = cfg.backgroundMode ?? 'lines';\n const cellSize = cfg.cellSize ?? DEFAULT_CELL_SIZE;\n const patternColor = cfg.backgroundPatternColor ?? DEFAULT_PATTERN_COLOR;\n const opacity = cfg.backgroundPatternOpacity ?? 1;\n\n const styles: Record<string, string> = {};\n\n if (mode === 'none') {\n return styles;\n }\n\n // Apply zoom to cell size\n const scaledCellSize = cellSize * vp.zoom;\n\n if (mode === 'lines') {\n styles['background-image'] = `linear-gradient(to right, ${patternColor} 1px, transparent 1px), linear-gradient(to bottom, ${patternColor} 1px, transparent 1px)`;\n styles['background-size'] = `${scaledCellSize}px ${scaledCellSize}px`;\n } else if (mode === 'dots') {\n // Scale dot size with zoom\n const dotSize = 1.5 * vp.zoom;\n styles['background-image'] = `radial-gradient(circle, ${patternColor} ${dotSize}px, transparent ${dotSize}px)`;\n styles['background-size'] = `${scaledCellSize}px ${scaledCellSize}px`;\n }\n\n // Apply pan offset to background position for seamless scrolling\n styles['background-position'] = `${vp.x}px ${vp.y}px`;\n styles['opacity'] = String(opacity);\n\n return styles;\n });\n\n /** Computed transform styles for the viewport layer (contains all elements) */\n viewportTransform = computed(() => {\n const vp = this.viewport();\n return `translate(${vp.x}px, ${vp.y}px) scale(${vp.zoom})`;\n });\n\n /** Whether the integrated toolbar should be shown */\n showToolbar = computed(() => !!this.config().toolbar);\n\n /** Whether the loading overlay should be shown */\n isLoading = computed(() => !!this.config().loading);\n\n /** Computed toolbar configuration for the integrated toolbar */\n integratedToolbarConfig = computed<ToolbarConfig | null>(() => {\n const cfg = this.config();\n if (!cfg.toolbar) return null;\n\n const toolbarCfg = cfg.toolbar;\n const buttons: ToolbarButton[] = [];\n\n // Add reset view button if enabled (default: true)\n if (toolbarCfg.showResetView !== false) {\n buttons.push({\n id: 'grid-reset-view',\n label: 'Reset View',\n icon: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\"/><path d=\"M3 3v5h5\"/></svg>',\n onClick: () => this.resetViewport(),\n });\n }\n\n // Add zoom controls if enabled (default: true)\n if (toolbarCfg.showZoomControls !== false) {\n buttons.push({\n id: 'grid-zoom-in',\n label: 'Zoom In',\n icon: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"11\" cy=\"11\" r=\"8\"/><line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"/><line x1=\"11\" y1=\"8\" x2=\"11\" y2=\"14\"/><line x1=\"8\" y1=\"11\" x2=\"14\" y2=\"11\"/></svg>',\n onClick: () => this.zoomIn(),\n });\n buttons.push({\n id: 'grid-zoom-out',\n label: 'Zoom Out',\n icon: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"11\" cy=\"11\" r=\"8\"/><line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"/><line x1=\"8\" y1=\"11\" x2=\"14\" y2=\"11\"/></svg>',\n onClick: () => this.zoomOut(),\n });\n }\n\n // Add custom buttons\n if (toolbarCfg.customButtons?.length) {\n buttons.push(...toolbarCfg.customButtons);\n }\n\n return {\n position: toolbarCfg.position ?? 'top-left',\n buttons,\n };\n });\n\n /** Get screen position styles for an element */\n getElementStyles(element: GridElement): Record<string, string> {\n // Use tracked position if dragging, otherwise use input position\n const pos = this.elementPositions.get(element.id) ?? { x: element.x, y: element.y };\n const cfg = this.config();\n const dragEnabled = cfg.dragEnabled ?? true;\n\n return {\n position: 'absolute',\n left: `${pos.x}px`,\n top: `${pos.y}px`,\n 'transform-origin': 'top left',\n cursor: dragEnabled ? (this.isDraggingElement() && this.draggingElementId === element.id ? 'grabbing' : 'grab') : 'default',\n };\n }\n\n /** Create an injector for passing data to a dynamically rendered component */\n createElementInjector(element: GridElement): Injector {\n return Injector.create({\n providers: [\n { provide: GRID_ELEMENT_DATA, useValue: element.data },\n ],\n parent: this.injector,\n });\n }\n\n /** Handle mouse down to start panning */\n onMouseDown(event: MouseEvent): void {\n const cfg = this.config();\n if (!(cfg.panEnabled ?? true)) return;\n\n // Only pan on left mouse button\n if (event.button !== 0) return;\n\n this.isPanning.set(true);\n this.panStartX = event.clientX;\n this.panStartY = event.clientY;\n const vp = this.viewport();\n this.panStartViewportX = vp.x;\n this.panStartViewportY = vp.y;\n\n // Prevent text selection during drag\n event.preventDefault();\n\n // Add window-level listeners for move and up\n window.addEventListener('mousemove', this.onMouseMove);\n window.addEventListener('mouseup', this.onMouseUp);\n }\n\n /** Handle mouse move during panning */\n private onMouseMove = (event: MouseEvent): void => {\n if (!this.isPanning()) return;\n\n const deltaX = event.clientX - this.panStartX;\n const deltaY = event.clientY - this.panStartY;\n\n let newX = this.panStartViewportX + deltaX;\n let newY = this.panStartViewportY + deltaY;\n\n // Apply boundaries if configured\n const cfg = this.config();\n if (cfg.panMinX !== undefined) newX = Math.max(cfg.panMinX, newX);\n if (cfg.panMaxX !== undefined) newX = Math.min(cfg.panMaxX, newX);\n if (cfg.panMinY !== undefined) newY = Math.max(cfg.panMinY, newY);\n if (cfg.panMaxY !== undefined) newY = Math.min(cfg.panMaxY, newY);\n\n const currentVp = this.viewport();\n const newViewport: ViewportState = { ...currentVp, x: newX, y: newY };\n this.viewport.set(newViewport);\n this.viewportChange.emit(newViewport);\n };\n\n /** Handle mouse up to stop panning */\n private onMouseUp = (): void => {\n this.isPanning.set(false);\n window.removeEventListener('mousemove', this.onMouseMove);\n window.removeEventListener('mouseup', this.onMouseUp);\n };\n\n /** Handle mouse down on an element to start dragging */\n onElementMouseDown(event: MouseEvent, element: GridElement): void {\n const cfg = this.config();\n if (!(cfg.dragEnabled ?? true)) return;\n\n // Only drag on left mouse button\n if (event.button !== 0) return;\n\n // Stop propagation to prevent pan from starting\n event.stopPropagation();\n event.preventDefault();\n\n // Initialize position tracking if not already done\n if (!this.elementPositions.has(element.id)) {\n this.elementPositions.set(element.id, { x: element.x, y: element.y });\n }\n\n const pos = this.elementPositions.get(element.id)!;\n\n this.isDraggingElement.set(true);\n this.draggingElementId = element.id;\n this.dragStartX = event.clientX;\n this.dragStartY = event.clientY;\n this.dragStartElementX = pos.x;\n this.dragStartElementY = pos.y;\n\n // Add window-level listeners for move and up\n window.addEventListener('mousemove', this.onElementMouseMove);\n window.addEventListener('mouseup', this.onElementMouseUp);\n }\n\n /** Handle mouse move during element dragging */\n private onElementMouseMove = (event: MouseEvent): void => {\n if (!this.isDraggingElement() || !this.draggingElementId) return;\n\n const cfg = this.config();\n\n // Calculate delta in screen space, then convert to world space (account for zoom)\n const vp = this.viewport();\n const deltaX = (event.clientX - this.dragStartX) / vp.zoom;\n const deltaY = (event.clientY - this.dragStartY) / vp.zoom;\n\n let newX = this.dragStartElementX + deltaX;\n let newY = this.dragStartElementY + deltaY;\n\n // Apply snap if enabled\n if (cfg.snapEnabled) {\n const snapSize = cfg.snapGridSize ?? cfg.cellSize ?? DEFAULT_CELL_SIZE;\n newX = Math.round(newX / snapSize) * snapSize;\n newY = Math.round(newY / snapSize) * snapSize;\n }\n\n const previousPos = this.elementPositions.get(this.draggingElementId) ?? { x: this.dragStartElementX, y: this.dragStartElementY };\n\n // Update internal position\n this.elementPositions.set(this.draggingElementId, { x: newX, y: newY });\n\n // Emit position change\n this.elementPositionChange.emit({\n id: this.draggingElementId,\n x: newX,\n y: newY,\n previousX: previousPos.x,\n previousY: previousPos.y,\n });\n };\n\n /** Handle mouse up to stop element dragging */\n private onElementMouseUp = (): void => {\n this.isDraggingElement.set(false);\n this.draggingElementId = null;\n window.removeEventListener('mousemove', this.onElementMouseMove);\n window.removeEventListener('mouseup', this.onElementMouseUp);\n };\n\n /** Reset viewport to default position */\n resetViewport(): void {\n const newViewport = { ...DEFAULT_VIEWPORT_STATE };\n this.viewport.set(newViewport);\n this.viewportChange.emit(newViewport);\n }\n\n /**\n * Fit all content to view\n * Centers content in the viewport, optionally zooming out to fit everything\n * @param fitZoom If true, zooms out if needed to fit all content (never zooms in beyond 1.0)\n * @param padding Padding around content in pixels (default: 40)\n */\n fitToView(fitZoom = false, padding = 40): void {\n const currentElements = this.elements();\n if (currentElements.length === 0) {\n this.resetViewport();\n return;\n }\n\n // Calculate bounding box of all elements\n const bounds = this.calculateContentBounds();\n if (!bounds) {\n this.resetViewport();\n return;\n }\n\n // Get container dimensions\n const containerRect = this.elementRef.nativeElement.getBoundingClientRect();\n const containerWidth = containerRect.width;\n const containerHeight = containerRect.height;\n\n // Available space for content (with padding)\n const availableWidth = containerWidth - padding * 2;\n const availableHeight = containerHeight - padding * 2;\n\n let newZoom = 1;\n\n if (fitZoom) {\n // Calculate zoom needed to fit content\n const scaleX = availableWidth / bounds.width;\n const scaleY = availableHeight / bounds.height;\n const fitScale = Math.min(scaleX, scaleY);\n\n // Never zoom in beyond 1.0, only zoom out if needed\n newZoom = Math.min(1, fitScale);\n\n // Respect zoom limits\n const cfg = this.config();\n const zoomMin = cfg.zoomMin ?? DEFAULT_ZOOM_MIN;\n newZoom = Math.max(zoomMin, newZoom);\n }\n\n // Calculate center of content in world space\n const contentCenterX = bounds.x + bounds.width / 2;\n const contentCenterY = bounds.y + bounds.height / 2;\n\n // Calculate viewport offset to center content\n // Container center = contentCenter * zoom + offset\n // offset = containerCenter - contentCenter * zoom\n const newX = containerWidth / 2 - contentCenterX * newZoom;\n const newY = containerHeight / 2 - contentCenterY * newZoom;\n\n const newViewport: ViewportState = {\n x: newX,\n y: newY,\n zoom: newZoom,\n };\n\n this.viewport.set(newViewport);\n this.viewportChange.emit(newViewport);\n }\n\n /**\n * Check if an element is fully visible in the viewport\n * @param elementId The element ID to check\n * @param padding Padding from viewport edges (default: 0)\n * @returns true if element is fully visible, false otherwise\n */\n isElementVisible(elementId: string, padding = 0): boolean {\n const bounds = this.getElementBounds(elementId);\n if (!bounds) return false;\n\n const vp = this.viewport();\n const containerRect = this.elementRef.nativeElement.getBoundingClientRect();\n\n // Convert element bounds to screen space\n const screenLeft = bounds.x * vp.zoom + vp.x;\n const screenTop = bounds.y * vp.zoom + vp.y;\n const screenRight = (bounds.x + bounds.width) * vp.zoom + vp.x;\n const screenBottom = (bounds.y + bounds.height) * vp.zoom + vp.y;\n\n // Check if fully within viewport (with padding)\n return (\n screenLeft >= padding &&\n screenTop >= padding &&\n screenRight <= containerRect.width - padding &&\n screenBottom <= containerRect.height - padding\n );\n }\n\n /**\n * Center viewport on a specific element (no zoom change)\n * @param elementId The element ID to center on\n */\n centerOnElement(elementId: string): void {\n const bounds = this.getElementBounds(elementId);\n if (!bounds) return;\n\n const vp = this.viewport();\n const containerRect = this.elementRef.nativeElement.getBoundingClientRect();\n\n // Calculate element center in world space\n const elementCenterX = bounds.x + bounds.width / 2;\n const elementCenterY = bounds.y + bounds.height / 2;\n\n // Calculate viewport offset to center element\n const newX = containerRect.width / 2 - elementCenterX * vp.zoom;\n const newY = containerRect.height / 2 - elementCenterY * vp.zoom;\n\n const newViewport: ViewportState = {\n x: newX,\n y: newY,\n zoom: vp.zoom,\n };\n\n this.viewport.set(newViewport);\n this.viewportChange.emit(newViewport);\n }\n\n /**\n * Scroll element into view with minimal pan\n * Only pans if element is not fully visible\n * @param elementId The element ID to scroll into view\n * @param padding Padding from viewport edges (default: 40)\n */\n scrollToElement(elementId: string, padding = 40): void {\n if (this.isElementVisible(elementId, padding)) {\n return; // Already visible, no need to scroll\n }\n\n const bounds = this.getElementBounds(elementId);\n if (!bounds) return;\n\n const vp = this.viewport();\n const containerRect = this.elementRef.nativeElement.getBoundingClientRect();\n\n // Convert element bounds to screen space\n const screenLeft = bounds.x * vp.zoom + vp.x;\n const screenTop = bounds.y * vp.zoom + vp.y;\n const screenRight = (bounds.x + bounds.width) * vp.zoom + vp.x;\n const screenBottom = (bounds.y + bounds.height) * vp.zoom + vp.y;\n\n let newX = vp.x;\n let newY = vp.y;\n\n // Calculate minimal pan needed to bring element into view\n // Check horizontal\n if (screenLeft < padding) {\n // Element is too far left, pan right\n newX = vp.x + (padding - screenLeft);\n } else if (screenRight > containerRect.width - padding) {\n // Element is too far right, pan left\n newX = vp.x - (screenRight - (containerRect.width - padding));\n }\n\n // Check vertical\n if (screenTop < padding) {\n // Element is too far up, pan down\n newY = vp.y + (padding - screenTop);\n } else if (screenBottom > containerRect.height - padding) {\n // Element is too far down, pan up\n newY = vp.y - (screenBottom - (containerRect.height - padding));\n }\n\n if (newX !== vp.x || newY !== vp.y) {\n const newViewport: ViewportState = {\n x: newX,\n y: newY,\n zoom: vp.zoom,\n };\n\n this.viewport.set(newViewport);\n this.viewportChange.emit(newViewport);\n }\n }\n\n /**\n * Get bounds of a specific element\n * @param elementId The element ID\n * @returns Element bounds in world coordinates, or null if not found\n */\n private getElementBounds(elementId: string): { x: number; y: number; width: number; height: number } | null {\n const element = this.elements().find(e => e.id === elementId);\n if (!element) return null;\n\n const pos = this.elementPositions.get(elementId) ?? { x: element.x, y: element.y };\n const domElement = this.elementRefs.get(elementId);\n\n let width = 100; // default\n let height = 50; // default\n if (domElement) {\n const rect = domElement.getBoundingClientRect();\n const zoom = this.viewport().zoom;\n width = rect.width / zoom;\n height = rect.height / zoom;\n }\n\n return {\n x: pos.x,\n y: pos.y,\n width,\n height,\n };\n }\n\n /**\n * Calculate the bounding box of all elements\n * @returns Bounding box in world coordinates, or null if no elements\n */\n private calculateContentBounds(): { x: number; y: number; width: number; height: number } | null {\n const currentElements = this.elements();\n if (currentElements.length === 0) return null;\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for (const element of currentElements) {\n const bounds = this.getElementBounds(element.id);\n if (!bounds) continue;\n\n minX = Math.min(minX, bounds.x);\n minY = Math.min(minY, bounds.y);\n maxX = Math.max(maxX, bounds.x + bounds.width);\n maxY = Math.max(maxY, bounds.y + bounds.height);\n }\n\n if (minX === Infinity) return null;\n\n return {\n x: minX,\n y: minY,\n width: maxX - minX,\n height: maxY - minY,\n };\n }\n\n /** Zoom in by a factor (default 1.25x) */\n zoomIn(factor = 1.25): void {\n const cfg = this.config();\n const zoomMax = cfg.zoomMax ?? DEFAULT_ZOOM_MAX;\n const vp = this.viewport();\n const newZoom = Math.min(zoomMax, vp.zoom * factor);\n\n if (newZoom === vp.zoom) return;\n\n const newViewport: ViewportState = { ...vp, zoom: newZoom };\n this.viewport.set(newViewport);\n this.viewportChange.emit(newViewport);\n }\n\n /** Zoom out by a factor (default 1.25x) */\n zoomOut(factor = 1.25): void {\n const cfg = this.config();\n const zoomMin = cfg.zoomMin ?? DEFAULT_ZOOM_MIN;\n const vp = this.viewport();\n const newZoom = Math.max(zoomMin, vp.zoom / factor);\n\n if (newZoom === vp.zoom) return;\n\n const newViewport: ViewportState = { ...vp, zoom: newZoom };\n this.viewport.set(newViewport);\n this.viewportChange.emit(newViewport);\n }\n\n /** Handle mouse wheel for zooming */\n onWheel(event: WheelEvent): void {\n const cfg = this.config();\n if (!(cfg.zoomEnabled ?? true)) return;\n\n // Prevent default scroll behavior\n event.preventDefault();\n\n const zoomMin = cfg.zoomMin ?? DEFAULT_ZOOM_MIN;\n const zoomMax = cfg.zoomMax ?? DEFAULT_ZOOM_MAX;\n const zoomSpeed = cfg.zoomSpeed ?? DEFAULT_ZOOM_SPEED;\n\n const vp = this.viewport();\n\n // Calculate new zoom level\n const delta = -event.deltaY * zoomSpeed;\n const newZoom = Math.max(zoomMin, Math.min(zoomMax, vp.zoom * (1 + delta)));\n\n // If zoom hasn't changed (at limits), don't update\n if (newZoom === vp.zoom) return;\n\n // Get cursor position relative to the grid container\n const rect = this.elementRef.nativeElement.getBoundingClientRect();\n const cursorX = event.clientX - rect.left;\n const cursorY = event.clientY - rect.top;\n\n // Calculate the world position under the cursor before zoom\n // worldX = (cursorX - vp.x) / vp.zoom\n const worldX = (cursorX - vp.x) / vp.zoom;\n const worldY = (cursorY - vp.y) / vp.zoom;\n\n // After zoom, we want the same world position under the cursor\n // cursorX = worldX * newZoom + newVpX\n // newVpX = cursorX - worldX * newZoom\n const newX = cursorX - worldX * newZoom;\n const newY = cursorY - worldY * newZoom;\n\n const newViewport: ViewportState = {\n x: newX,\n y: newY,\n zoom: newZoom,\n };\n\n this.viewport.set(newViewport);\n this.viewportChange.emit(newViewport);\n }\n\n /** Initialize ResizeObserver after view is ready */\n ngAfterViewInit(): void {\n this.setupResizeObserver();\n }\n\n /** Clean up resources */\n ngOnDestroy(): void {\n this.cleanupResizeObserver();\n if (this.dimensionUpdateTimer) {\n clearTimeout(this.dimensionUpdateTimer);\n }\n }\n\n /** Register an element for dimension tracking */\n registerElement(elementId: string, element: HTMLElement): void {\n this.elementRefs.set(elementId, element);\n if (this.resizeObserver) {\n this.resizeObserver.observe(element);\n }\n this.scheduleDimensionUpdate();\n }\n\n /** Unregister an element from dimension tracking */\n unregisterElement(elementId: string): void {\n const element = this.elementRefs.get(elementId);\n if (element && this.resizeObserver) {\n this.resizeObserver.unobserve(element);\n }\n this.elementRefs.delete(elementId);\n this.scheduleDimensionUpdate();\n }\n\n /** Set up the ResizeObserver to track element dimension changes */\n private setupResizeObserver(): void {\n if (typeof ResizeObserver === 'undefined') {\n return;\n }\n\n this.resizeObserver = new ResizeObserver(() => {\n this.scheduleDimensionUpdate();\n });\n\n // Observe any already-registered elements\n this.elementRefs.forEach((element) => {\n this.resizeObserver!.observe(element);\n });\n }\n\n /** Clean up the ResizeObserver */\n private cleanupResizeObserver(): void {\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n }\n\n /** Schedule a debounced dimension update */\n private scheduleDimensionUpdate(): void {\n if (this.dimensionUpdateTimer) {\n clearTimeout(this.dimensionUpdateTimer);\n }\n\n this.dimensionUpdateTimer = setTimeout(() => {\n this.emitRenderedElements();\n }, 10);\n }\n\n /** Collect and emit all rendered element dimensions */\n private emitRenderedElements(): void {\n const currentElements = this.elements();\n const renderedElements: RenderedElement[] = [];\n\n for (const element of currentElements) {\n const domElement = this.elementRefs.get(element.id);\n if (domElement) {\n const rect = domElement.getBoundingClientRect();\n // Get the actual size without zoom transform\n const zoom = this.viewport().zoom;\n renderedElements.push({\n id: element.id,\n x: element.x,\n y: element.y,\n width: rect.width / zoom,\n height: rect.height / zoom,\n });\n }\n }\n\n if (renderedElements.length > 0) {\n this.elementsRendered.emit(renderedElements);\n }\n }\n}\n","<div\n class=\"grid-container\"\n [ngStyle]=\"containerStyles()\"\n (mousedown)=\"onMouseDown($event)\"\n (wheel)=\"onWheel($event)\">\n <div class=\"grid-background\" [ngStyle]=\"backgroundStyles()\"></div>\n <div class=\"grid-viewport\" [style.transform]=\"viewportTransform()\">\n @for (element of elements(); track element.id) {\n <div\n class=\"grid-element\"\n [gridElementRef]=\"element.id\"\n [ngStyle]=\"getElementStyles(element)\"\n (mousedown)=\"onElementMouseDown($event, element)\">\n <ng-container\n *ngComponentOutlet=\"element.component; injector: createElementInjector(element)\" />\n </div>\n }\n </div>\n @if (showToolbar() && integratedToolbarConfig()) {\n <ngx-grid-toolbar [config]=\"integratedToolbarConfig()!\" />\n }\n @if (isLoading()) {\n <div class=\"loading-overlay\">\n <div class=\"loading-spinner\"></div>\n </div>\n }\n</div>\n","// Components\nexport { GridComponent } from './lib/ngx-grid/ngx-grid';\nexport { ToolbarComponent } from './lib/components/toolbar/toolbar.component';\n\n// Models\nexport type {\n GridConfig,\n GridToolbarConfig,\n DimensionMode,\n BackgroundMode,\n ViewportState,\n GridElement,\n ReactiveData,\n RenderedElement,\n ElementPositionChange,\n ToolbarPosition,\n ToolbarButton,\n ToolbarConfig,\n} from './lib/models/grid.models';\nexport {\n DEFAULT_GRID_CONFIG,\n DEFAULT_CELL_SIZE,\n DEFAULT_PATTERN_COLOR,\n DEFAULT_BACKGROUND_COLOR,\n DEFAULT_VIEWPORT_STATE,\n DEFAULT_ZOOM_MIN,\n DEFAULT_ZOOM_MAX,\n DEFAULT_ZOOM_SPEED,\n GRID_ELEMENT_DATA,\n} from './lib/models/grid.models';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/index.d.ts ADDED
@@ -0,0 +1,362 @@
1
+ import * as _angular_core from '@angular/core';
2
+ import { Type, Signal, InjectionToken, AfterViewInit, OnDestroy, Injector } from '@angular/core';
3
+ import { SafeHtml } from '@angular/platform-browser';
4
+
5
+ /**
6
+ * Injection token for accessing element data in dynamically rendered components.
7
+ * The data can be either a plain value or a Signal for reactive updates.
8
+ */
9
+ declare const GRID_ELEMENT_DATA: InjectionToken<unknown>;
10
+ /**
11
+ * Type alias for data that can be either a plain value or a Signal.
12
+ * Use Signal<T> when you need the component to reactively update based on data changes.
13
+ */
14
+ type ReactiveData<T> = T | Signal<T>;
15
+ /**
16
+ * Dimension mode for the grid container
17
+ * - 'fixed': Uses explicit width/height values
18
+ * - 'full': Fills the parent container (100% width/height)
19
+ */
20
+ type DimensionMode = 'fixed' | 'full';
21
+ /**
22
+ * Background mode for the grid
23
+ * - 'lines': Grid lines pattern
24
+ * - 'dots': Dot pattern at intersections
25
+ * - 'none': No background pattern
26
+ */
27
+ type BackgroundMode = 'lines' | 'dots' | 'none';
28
+ /**
29
+ * Configuration for the grid component
30
+ */
31
+ interface GridConfig {
32
+ /** How the grid should size itself */
33
+ dimensionMode: DimensionMode;
34
+ /** Fixed width in pixels (only used when dimensionMode is 'fixed') */
35
+ width?: number;
36
+ /** Fixed height in pixels (only used when dimensionMode is 'fixed') */
37
+ height?: number;
38
+ /** Minimum width constraint in pixels */
39
+ minWidth?: number;
40
+ /** Minimum height constraint in pixels */
41
+ minHeight?: number;
42
+ /** Maximum width constraint in pixels */
43
+ maxWidth?: number;
44
+ /** Maximum height constraint in pixels */
45
+ maxHeight?: number;
46
+ /** Background pattern mode (default: 'lines') */
47
+ backgroundMode?: BackgroundMode;
48
+ /** Size of each grid cell in pixels (default: 20) */
49
+ cellSize?: number;
50
+ /** Color of the grid lines/dots (default: '#2a2a4a') */
51
+ backgroundPatternColor?: string;
52
+ /** Opacity of the background pattern 0-1 (default: 1) */
53
+ backgroundPatternOpacity?: number;
54
+ /** Background color of the grid (default: '#1a1a2e') */
55
+ backgroundColor?: string;
56
+ /** Enable panning (default: true) */
57
+ panEnabled?: boolean;
58
+ /** Minimum X pan boundary (undefined = infinite) */
59
+ panMinX?: number;
60
+ /** Maximum X pan boundary (undefined = infinite) */
61
+ panMaxX?: number;
62
+ /** Minimum Y pan boundary (undefined = infinite) */
63
+ panMinY?: number;
64
+ /** Maximum Y pan boundary (undefined = infinite) */
65
+ panMaxY?: number;
66
+ /** Enable zooming (default: true) */
67
+ zoomEnabled?: boolean;
68
+ /** Minimum zoom level (default: 0.1) */
69
+ zoomMin?: number;
70
+ /** Maximum zoom level (default: 5) */
71
+ zoomMax?: number;
72
+ /** Zoom speed multiplier (default: 0.001) */
73
+ zoomSpeed?: number;
74
+ /** Enable element dragging (default: true) */
75
+ dragEnabled?: boolean;
76
+ /** Enable snap-to-grid during drag (default: false) */
77
+ snapEnabled?: boolean;
78
+ /** Snap grid size in pixels (default: uses cellSize) */
79
+ snapGridSize?: number;
80
+ /** Toolbar configuration (renders toolbar inside grid) */
81
+ toolbar?: GridToolbarConfig;
82
+ /** Show loading overlay (default: false) */
83
+ loading?: boolean;
84
+ }
85
+ /**
86
+ * Configuration for the grid's integrated toolbar
87
+ */
88
+ interface GridToolbarConfig {
89
+ /** Position of the toolbar within the grid */
90
+ position?: ToolbarPosition;
91
+ /** Show default zoom controls (default: true) */
92
+ showZoomControls?: boolean;
93
+ /** Show reset view button (default: true) */
94
+ showResetView?: boolean;
95
+ /** Additional custom buttons */
96
+ customButtons?: ToolbarButton[];
97
+ }
98
+ /**
99
+ * Viewport state representing pan and zoom
100
+ */
101
+ interface ViewportState {
102
+ /** X offset (pan) */
103
+ x: number;
104
+ /** Y offset (pan) */
105
+ y: number;
106
+ /** Zoom level (1 = 100%) */
107
+ zoom: number;
108
+ }
109
+ /**
110
+ * Definition for an element to render on the grid
111
+ * @template T Type of the data passed to the component
112
+ */
113
+ interface GridElement<T = unknown> {
114
+ /** Unique identifier for this element */
115
+ id: string;
116
+ /** Angular component class to render */
117
+ component: Type<unknown>;
118
+ /**
119
+ * Data to pass to the component via GRID_ELEMENT_DATA injection token.
120
+ * Can be a plain value or a Signal for reactive updates.
121
+ * When using Signal<T>, the component can reactively respond to data changes.
122
+ */
123
+ data?: ReactiveData<T>;
124
+ /** X coordinate in world space */
125
+ x: number;
126
+ /** Y coordinate in world space */
127
+ y: number;
128
+ }
129
+ /**
130
+ * Rendered element with tracked dimensions
131
+ */
132
+ interface RenderedElement {
133
+ /** Element ID */
134
+ id: string;
135
+ /** X coordinate in world space */
136
+ x: number;
137
+ /** Y coordinate in world space */
138
+ y: number;
139
+ /** Rendered width in pixels */
140
+ width: number;
141
+ /** Rendered height in pixels */
142
+ height: number;
143
+ }
144
+ /**
145
+ * Event emitted when an element position changes during drag
146
+ */
147
+ interface ElementPositionChange {
148
+ /** Element ID being dragged */
149
+ id: string;
150
+ /** New X coordinate in world space */
151
+ x: number;
152
+ /** New Y coordinate in world space */
153
+ y: number;
154
+ /** Previous X coordinate */
155
+ previousX: number;
156
+ /** Previous Y coordinate */
157
+ previousY: number;
158
+ }
159
+ /** Default cell size in pixels */
160
+ declare const DEFAULT_CELL_SIZE = 20;
161
+ /** Default background pattern color */
162
+ declare const DEFAULT_PATTERN_COLOR = "#3a3a5a";
163
+ /** Default minimum zoom level */
164
+ declare const DEFAULT_ZOOM_MIN = 0.1;
165
+ /** Default maximum zoom level */
166
+ declare const DEFAULT_ZOOM_MAX = 5;
167
+ /** Default zoom speed multiplier */
168
+ declare const DEFAULT_ZOOM_SPEED = 0.001;
169
+ /** Default background color */
170
+ declare const DEFAULT_BACKGROUND_COLOR = "#1a1a2e";
171
+ /**
172
+ * Default grid configuration
173
+ */
174
+ declare const DEFAULT_GRID_CONFIG: GridConfig;
175
+ /**
176
+ * Default viewport state
177
+ */
178
+ declare const DEFAULT_VIEWPORT_STATE: ViewportState;
179
+ /**
180
+ * Position for the floating toolbar
181
+ */
182
+ type ToolbarPosition = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
183
+ /**
184
+ * Configuration for a toolbar button
185
+ */
186
+ interface ToolbarButton {
187
+ /** Unique identifier for the button */
188
+ id: string;
189
+ /** Button label text (used as tooltip if icon is provided) */
190
+ label: string;
191
+ /** Optional icon (SVG string or icon name) */
192
+ icon?: string;
193
+ /** Whether the button is currently active/toggled */
194
+ active?: boolean;
195
+ /** Whether the button is disabled */
196
+ disabled?: boolean;
197
+ /** Callback function when button is clicked */
198
+ onClick: () => void;
199
+ }
200
+ /**
201
+ * Configuration for the toolbar
202
+ */
203
+ interface ToolbarConfig {
204
+ /** Position of the toolbar within the grid */
205
+ position: ToolbarPosition;
206
+ /** Array of button configurations */
207
+ buttons: ToolbarButton[];
208
+ /** Optional CSS class to apply to the toolbar */
209
+ className?: string;
210
+ }
211
+
212
+ declare class GridComponent implements AfterViewInit, OnDestroy {
213
+ private readonly elementRef;
214
+ private readonly injector;
215
+ private readonly destroyRef;
216
+ /** Grid configuration */
217
+ config: _angular_core.InputSignal<GridConfig>;
218
+ /** Elements to render on the grid */
219
+ elements: _angular_core.InputSignal<GridElement<unknown>[]>;
220
+ /** Current viewport state (pan offset and zoom) */
221
+ viewport: _angular_core.WritableSignal<ViewportState>;
222
+ /** Emits when viewport changes */
223
+ viewportChange: _angular_core.OutputEmitterRef<ViewportState>;
224
+ /** Emits when element dimensions are measured or change */
225
+ elementsRendered: _angular_core.OutputEmitterRef<RenderedElement[]>;
226
+ /** Emits when an element is dragged to a new position */
227
+ elementPositionChange: _angular_core.OutputEmitterRef<ElementPositionChange>;
228
+ /** Map of element IDs to their DOM elements for dimension tracking */
229
+ private elementRefs;
230
+ /** ResizeObserver for tracking element dimension changes */
231
+ private resizeObserver;
232
+ /** Debounce timer for batching dimension updates */
233
+ private dimensionUpdateTimer;
234
+ /** Internal state for pan tracking */
235
+ private isPanning;
236
+ private panStartX;
237
+ private panStartY;
238
+ private panStartViewportX;
239
+ private panStartViewportY;
240
+ /** Internal state for element drag tracking */
241
+ private isDraggingElement;
242
+ private draggingElementId;
243
+ private dragStartX;
244
+ private dragStartY;
245
+ private dragStartElementX;
246
+ private dragStartElementY;
247
+ /** Internal copy of element positions for drag updates */
248
+ private elementPositions;
249
+ /** Track if we're currently dragging to avoid overwriting drag position */
250
+ private syncPositionsFromInput;
251
+ constructor();
252
+ /** Computed container styles based on config */
253
+ containerStyles: _angular_core.Signal<Record<string, string>>;
254
+ /** Computed background styles for the pattern layer */
255
+ backgroundStyles: _angular_core.Signal<Record<string, string>>;
256
+ /** Computed transform styles for the viewport layer (contains all elements) */
257
+ viewportTransform: _angular_core.Signal<string>;
258
+ /** Whether the integrated toolbar should be shown */
259
+ showToolbar: _angular_core.Signal<boolean>;
260
+ /** Whether the loading overlay should be shown */
261
+ isLoading: _angular_core.Signal<boolean>;
262
+ /** Computed toolbar configuration for the integrated toolbar */
263
+ integratedToolbarConfig: _angular_core.Signal<ToolbarConfig | null>;
264
+ /** Get screen position styles for an element */
265
+ getElementStyles(element: GridElement): Record<string, string>;
266
+ /** Create an injector for passing data to a dynamically rendered component */
267
+ createElementInjector(element: GridElement): Injector;
268
+ /** Handle mouse down to start panning */
269
+ onMouseDown(event: MouseEvent): void;
270
+ /** Handle mouse move during panning */
271
+ private onMouseMove;
272
+ /** Handle mouse up to stop panning */
273
+ private onMouseUp;
274
+ /** Handle mouse down on an element to start dragging */
275
+ onElementMouseDown(event: MouseEvent, element: GridElement): void;
276
+ /** Handle mouse move during element dragging */
277
+ private onElementMouseMove;
278
+ /** Handle mouse up to stop element dragging */
279
+ private onElementMouseUp;
280
+ /** Reset viewport to default position */
281
+ resetViewport(): void;
282
+ /**
283
+ * Fit all content to view
284
+ * Centers content in the viewport, optionally zooming out to fit everything
285
+ * @param fitZoom If true, zooms out if needed to fit all content (never zooms in beyond 1.0)
286
+ * @param padding Padding around content in pixels (default: 40)
287
+ */
288
+ fitToView(fitZoom?: boolean, padding?: number): void;
289
+ /**
290
+ * Check if an element is fully visible in the viewport
291
+ * @param elementId The element ID to check
292
+ * @param padding Padding from viewport edges (default: 0)
293
+ * @returns true if element is fully visible, false otherwise
294
+ */
295
+ isElementVisible(elementId: string, padding?: number): boolean;
296
+ /**
297
+ * Center viewport on a specific element (no zoom change)
298
+ * @param elementId The element ID to center on
299
+ */
300
+ centerOnElement(elementId: string): void;
301
+ /**
302
+ * Scroll element into view with minimal pan
303
+ * Only pans if element is not fully visible
304
+ * @param elementId The element ID to scroll into view
305
+ * @param padding Padding from viewport edges (default: 40)
306
+ */
307
+ scrollToElement(elementId: string, padding?: number): void;
308
+ /**
309
+ * Get bounds of a specific element
310
+ * @param elementId The element ID
311
+ * @returns Element bounds in world coordinates, or null if not found
312
+ */
313
+ private getElementBounds;
314
+ /**
315
+ * Calculate the bounding box of all elements
316
+ * @returns Bounding box in world coordinates, or null if no elements
317
+ */
318
+ private calculateContentBounds;
319
+ /** Zoom in by a factor (default 1.25x) */
320
+ zoomIn(factor?: number): void;
321
+ /** Zoom out by a factor (default 1.25x) */
322
+ zoomOut(factor?: number): void;
323
+ /** Handle mouse wheel for zooming */
324
+ onWheel(event: WheelEvent): void;
325
+ /** Initialize ResizeObserver after view is ready */
326
+ ngAfterViewInit(): void;
327
+ /** Clean up resources */
328
+ ngOnDestroy(): void;
329
+ /** Register an element for dimension tracking */
330
+ registerElement(elementId: string, element: HTMLElement): void;
331
+ /** Unregister an element from dimension tracking */
332
+ unregisterElement(elementId: string): void;
333
+ /** Set up the ResizeObserver to track element dimension changes */
334
+ private setupResizeObserver;
335
+ /** Clean up the ResizeObserver */
336
+ private cleanupResizeObserver;
337
+ /** Schedule a debounced dimension update */
338
+ private scheduleDimensionUpdate;
339
+ /** Collect and emit all rendered element dimensions */
340
+ private emitRenderedElements;
341
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<GridComponent, never>;
342
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<GridComponent, "ngx-grid", never, { "config": { "alias": "config"; "required": false; "isSignal": true; }; "elements": { "alias": "elements"; "required": false; "isSignal": true; }; }, { "viewportChange": "viewportChange"; "elementsRendered": "elementsRendered"; "elementPositionChange": "elementPositionChange"; }, never, never, true, never>;
343
+ }
344
+
345
+ declare class ToolbarComponent {
346
+ private readonly sanitizer;
347
+ /** Toolbar configuration */
348
+ config: _angular_core.InputSignal<ToolbarConfig>;
349
+ /** Computed host classes based on position */
350
+ hostClasses: _angular_core.Signal<string>;
351
+ /** Computed classes for the toolbar div */
352
+ toolbarClasses: _angular_core.Signal<string>;
353
+ /** Sanitize HTML for safe rendering of SVG icons */
354
+ sanitizeHtml(html: string): SafeHtml;
355
+ /** Handle button click */
356
+ onButtonClick(button: ToolbarButton, event: MouseEvent): void;
357
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ToolbarComponent, never>;
358
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<ToolbarComponent, "ngx-grid-toolbar", never, { "config": { "alias": "config"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
359
+ }
360
+
361
+ export { DEFAULT_BACKGROUND_COLOR, DEFAULT_CELL_SIZE, DEFAULT_GRID_CONFIG, DEFAULT_PATTERN_COLOR, DEFAULT_VIEWPORT_STATE, DEFAULT_ZOOM_MAX, DEFAULT_ZOOM_MIN, DEFAULT_ZOOM_SPEED, GRID_ELEMENT_DATA, GridComponent, ToolbarComponent };
362
+ export type { BackgroundMode, DimensionMode, ElementPositionChange, GridConfig, GridElement, GridToolbarConfig, ReactiveData, RenderedElement, ToolbarButton, ToolbarConfig, ToolbarPosition, ViewportState };
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@ngx-km/grid",
3
+ "version": "0.0.1",
4
+ "peerDependencies": {
5
+ "@angular/common": ">=19.0.0",
6
+ "@angular/core": ">=19.0.0",
7
+ "@angular/platform-browser": ">=19.0.0"
8
+ },
9
+ "sideEffects": false,
10
+ "module": "fesm2022/ngx-km-grid.mjs",
11
+ "typings": "index.d.ts",
12
+ "exports": {
13
+ "./package.json": {
14
+ "default": "./package.json"
15
+ },
16
+ ".": {
17
+ "types": "./index.d.ts",
18
+ "default": "./fesm2022/ngx-km-grid.mjs"
19
+ }
20
+ },
21
+ "dependencies": {
22
+ "tslib": "^2.3.0"
23
+ }
24
+ }