import * as _angular_core from '@angular/core'; import { Type, ViewContainerRef, ComponentRef, OnChanges, SimpleChanges, InjectionToken } from '@angular/core'; import * as _ngrx_signals from '@ngrx/signals'; import * as _dragonworks_ngx_dashboard from '@dragonworks/ngx-dashboard'; import { SafeHtml } from '@angular/platform-browser'; declare const NGX_DASHBOARD_VERSION = "22.2.0"; /** * Branded type for cell identifiers to ensure type safety when working with grid coordinates. * This prevents accidentally mixing up row/column numbers with cell IDs. */ type CellId = number & { __brand: 'CellId'; }; /** * Branded type for widget identifiers to ensure type safety when working with widget instances. * This prevents accidentally mixing up widget IDs with other string values. */ type WidgetId = string & { __brand: 'WidgetId'; }; interface Widget { dashboardGetState?(): unknown; dashboardSetState?(state?: unknown): void; dashboardEditState?(): void; dashboardEditSharedState?(): void; } interface WidgetMetadata { widgetTypeid: string; name: string; description: string; svgIcon: string; /** * Optional group heading for the widget list. Widgets sharing a group are * rendered together under that heading, in the order the groups were first * encountered during registration. Widgets without a group are listed last, * without a heading — so omitting this field everywhere renders a single * unlabelled section, i.e. a flat list. * * The library never translates this value, so callers should pass an already * localized string. Note that the default styling renders the heading * upper-cased. */ group?: string; } interface WidgetComponentClass extends Type { metadata: WidgetMetadata; } interface WidgetFactory { widgetTypeid: string; name: string; description: string; svgIcon: string; createInstance(container: ViewContainerRef, state?: unknown): ComponentRef; } interface CellPosition { row: number; col: number; rowSpan: number; colSpan: number; } interface CellComponentPosition extends CellPosition { cellId: CellId; widgetId: WidgetId; } interface CellData extends CellPosition { widgetId: WidgetId; cellId: CellId; flat?: boolean; widgetTypeid?: string; widgetFactory: WidgetFactory; widgetState: unknown; } /** * Data structure for cell display settings */ interface CellDisplayData { id: string; flat: boolean | undefined; } /** * Which axis a resize handle drives. `'both'` is the corner handle: it * grows/shrinks columns and rows in the same gesture. */ type CellResizeDirection = 'horizontal' | 'vertical' | 'both'; /** * Span delta in whole grid tracks. Producers zero the axis their handle does * not drive, so every consumer reads both fields unconditionally rather than * re-deriving which axis is live from the direction. */ interface CellResizeDelta { columns: number; rows: number; } /** * Serializable data format for dashboard export/import functionality. * This format can be safely converted to/from JSON for persistence. * Corresponds to the persistent state from the dashboard store features. */ interface DashboardDataDto { /** Version for future compatibility and migration support */ version: string; /** * Unique dashboard identifier managed by the client. * Set once when a dashboard is first mounted via `[dashboardData]`. * On subsequent imperative `loadDashboard()` calls this field is treated * as informational metadata (i.e. where the file came from) — the store's * existing id is preserved so that bridge registration stays stable and * Export→Import across dashboards works without rewriting the id. */ dashboardId: string; /** Grid dimensions */ rows: number; columns: number; gutterSize: string; /** Array of serializable cell data */ cells: CellDataDto[]; /** * Shared states for widget families (optional). * Maps widget type ID to shared state object. * This allows widget families to share configuration across all instances. * @since 1.1.0 */ sharedStates?: Record; } /** * Serializable version of CellData that can be safely JSON stringified. * Converts non-serializable types (CellId, WidgetFactory) to serializable equivalents. */ interface CellDataDto { /** Grid position */ row: number; col: number; /** Cell span */ rowSpan: number; colSpan: number; /** Display settings */ flat?: boolean; /** Widget type identifier for factory lookup during import */ widgetTypeid: string; /** Raw widget state (must be JSON serializable) */ widgetState: unknown; } /** * Creates an empty dashboard configuration with the specified dimensions. * This is a convenience function for creating a basic dashboard without any cells. * * @param dashboardId - Unique identifier for the dashboard (managed by client) * @param rows - Number of rows in the dashboard grid * @param columns - Number of columns in the dashboard grid * @param gutterSize - CSS size for the gutter between cells (default: '0.5em') * @returns A DashboardDataDto configured with the specified dimensions and no cells * * @example * // Create an 8x16 dashboard with default gutter * const dashboard = createEmptyDashboard('my-dashboard-1', 8, 16); * * @example * // Create a 5x10 dashboard with custom gutter * const dashboard = createEmptyDashboard('my-dashboard-2', 5, 10, '0.5rem'); */ declare function createEmptyDashboard(dashboardId: string, rows: number, columns: number, gutterSize?: string): DashboardDataDto; /** * Creates a default dashboard configuration with standard dimensions. * This provides a reasonable starting point for most use cases. * * @param dashboardId - Unique identifier for the dashboard (managed by client) * @returns A DashboardDataDto with 8 rows, 16 columns, and 0.5em gutter * * @example * const dashboard = createDefaultDashboard('my-dashboard-id'); */ declare function createDefaultDashboard(dashboardId: string): DashboardDataDto; type DragData = { kind: 'cell'; content: CellComponentPosition; } | { kind: 'widget'; content: WidgetMetadata; }; /** * Committed grid geometry. * * Mirrors the persisted shape in `DashboardDataDto` so a host can round-trip * it without a mapper. Emitted by `DashboardComponent.gridConfigChanged` and * readable at any time from `DashboardComponent.gridConfig()`. */ interface GridConfig { /** Committed row count (never the in-progress drag preview). */ rows: number; /** Committed column count (never the in-progress drag preview). */ columns: number; /** CSS length; always a value that has passed `sanitizeGutterSize()`. */ gutterSize: string; } /** * Upper bound applied to a requested grid size. * * The content floor outranks this ceiling: a dashboard that already exceeds * the cap keeps its size rather than losing widgets. See `clampGridSize()`. */ interface GridSizeLimits { maxRows: number; maxColumns: number; } /** * Default ceiling, overridable per dashboard via `DashboardComponent.maxRows` * / `maxColumns`. * * The editor renders one drop-zone component per cell, so the cap is what * keeps a typed size from materializing an unbounded number of components — * a cliff a drag gesture cannot reach but a number field can. The default is * generous enough that no plausible dashboard hits it. */ declare const DEFAULT_GRID_SIZE_LIMITS: GridSizeLimits; /** * Discrete gutter steps offered by the reference UI in the demo application. * * Consumers are free to ignore these and pass any value that satisfies * `sanitizeGutterSize()`. `0` is deliberately absent: at a zero gutter the * grid loses the outer band the resize handles live in (they fall back to * their 6px floor in `grid-resize-handle.component.scss`) and the handles end * up sitting on top of the last column and row of widgets. */ declare const GUTTER_SIZE_PRESETS: readonly ["0.25em", "0.5em", "0.75em", "1em", "1.5em"]; /** * Returns `value` when it is a CSS length this grid can safely use, otherwise * `fallback`. Surrounding whitespace is trimmed from an accepted value. * * Rejection is silent by design — the caller keeps whatever gutter it already * had, which is always a value that has been through this function. `value` * accepts `undefined` so a partial geometry update can pass the field through * without the caller branching on its presence. * * @example * sanitizeGutterSize('0.5em', '1em'); // '0.5em' * sanitizeGutterSize('8', '1em'); // '1em' (no unit) * sanitizeGutterSize('50%', '1em'); // '1em' (unsupported unit) * sanitizeGutterSize(undefined, '1em'); // '1em' (field omitted) */ declare function sanitizeGutterSize(value: string | undefined, fallback: string): string; /** * Represents a rectangular selection region in the dashboard grid */ interface GridSelection { topLeft: { row: number; col: number; }; bottomRight: { row: number; col: number; }; } /** * Outcome of a grid resize request (e.g. `DashboardComponent.setGridSize()` * or an editor drag-handle commit). * * The dashboard uses a clamp-to-content policy: a requested size that would * push an existing widget outside the grid is snapped up to the smallest size * that still contains every widget's full footprint. A request is also capped * at the configured maximum (`DashboardComponent.maxRows` / `maxColumns`). * The fields below report the size that was actually applied, not the size * that was requested. */ interface GridResizeResult { /** Rows actually applied after clamping. */ rows: number; /** Columns actually applied after clamping. */ columns: number; /** * True when the applied size differs from the requested one — either * snapped up to keep widgets in bounds, or capped at the maximum. */ clamped: boolean; } /** * Defines space that should be reserved around the dashboard component * when calculating viewport constraints. */ interface ReservedSpace { /** Space reserved at the top (e.g., toolbar height) */ top: number; /** Space reserved on the right (e.g., padding, widget list) */ right: number; /** Space reserved at the bottom (e.g., padding) */ bottom: number; /** Space reserved on the left (e.g., padding) */ left: number; } /** * Options for filtering and exporting a selection of the dashboard. * * Used when exporting a subset of the dashboard based on a grid selection. * Provides control over how the selection bounds are calculated and applied. */ interface SelectionFilterOptions { /** * If true, shrink the export bounds to the minimal bounding box containing all widgets. * If false or undefined (default), use the selection bounds as-is. * * When enabled, the exported dashboard will be tightly cropped to only include * the space occupied by widgets, removing any empty cells around the edges. * * @default false * * @example * ```typescript * // Export with minimal bounds (tight crop around widgets) * const data = dashboard.exportDashboard(selection, { useMinimalBounds: true }); * * // Export with full selection bounds (preserve empty space) * const data = dashboard.exportDashboard(selection, { useMinimalBounds: false }); * ``` */ useMinimalBounds?: boolean; /** * Number of cells to add as padding on each side of the export bounds. * * Padding expands the export area by adding empty cells around the selection. * A padding value of 1 adds 1 row above, 1 row below, 1 column to the left, * and 1 column to the right of the bounds. * * When used with `useMinimalBounds: true`, padding is applied AFTER the bounds * are shrunk to the minimal bounding box containing all widgets. * * The minimum row and column values are clamped to 1 (grid coordinates are 1-based), * so padding will not extend below the grid origin. * * @default 0 * * @example * ```typescript * // Export with 1 cell of padding on all sides * const data = dashboard.exportDashboard(selection, { padding: 1 }); * * // Export with minimal bounds and 2 cells of padding * const data = dashboard.exportDashboard(selection, { * useMinimalBounds: true, * padding: 2 * }); * ``` */ padding?: number; } /** * Keyboard modifier that gates drag-to-select. * * When set on `DashboardComponent.selectionModifier`, the selection overlay * is mounted but transparent to pointer events until the modifier is held * (or a drag started while the modifier was held is in progress). */ type SelectionModifier = 'shift' | 'ctrl' | 'alt' | 'meta'; /** * Interface for providing shared state across all instances of a widget type. * * Widget families can implement this interface to manage state that should be * shared across all instances of that widget type (e.g., theme colors, configuration). * * During dashboard serialization, the framework calls getSharedState() once per * widget type (not per instance), and during deserialization, setSharedState() * is called to restore the shared configuration. * * @example * ```typescript * @Injectable({ providedIn: 'root' }) * export class ParkingSpaceSharedState implements WidgetSharedStateProvider { * private state = signal({ color: '#4CAF50', pricePerHour: 5 }); * * getSharedState(): ParkingConfig { * return this.state(); * } * * setSharedState(state: ParkingConfig): void { * this.state.set(state); * } * * readonly config = this.state.asReadonly(); * } * * // Register with dashboard * dashboardService.registerWidgetType(ParkingSpaceWidget, ParkingSpaceSharedState); * ``` */ interface WidgetSharedStateProvider { /** * Gets the current shared state for this widget type. * Called during dashboard export/serialization. * * @returns The current shared state, or undefined if no state should be serialized */ getSharedState(): T | undefined; /** * Sets the shared state for this widget type. * Called during dashboard import/deserialization before widget instances are created. * * @param state The shared state to restore */ setSharedState(state: T): void; } interface ResizeData { cellId: CellId; originalRowSpan: number; originalColSpan: number; previewRowSpan: number; previewColSpan: number; } interface ViewportSize { width: number; height: number; } interface DashboardConstraints { maxWidth: number; maxHeight: number; constrainedBy: 'width' | 'height' | 'none'; } /** * Internal component-scoped service that provides viewport-aware constraints for a single dashboard. * Each dashboard component gets its own instance of this service. * * This service is NOT part of the public API and should remain internal to the library. */ declare class DashboardViewportService { private readonly platformId; private readonly destroyRef; private readonly store; private readonly viewportSize; private readonly reservedSpace; private resizeObserver; constructor(); /** * Initialize viewport size tracking using ResizeObserver on the window */ private initializeViewportTracking; /** * Set reserved space that should be excluded from dashboard calculations * (e.g., toolbar height, widget list width, padding) */ setReservedSpace(space: ReservedSpace): void; /** * Get current viewport size */ readonly currentViewportSize: _angular_core.Signal; /** * Get current reserved space */ readonly currentReservedSpace: _angular_core.Signal; /** * Calculate available space for dashboard after accounting for reserved areas */ readonly availableSpace: _angular_core.Signal; /** * Calculate dashboard constraints for this dashboard instance */ readonly constraints: _angular_core.Signal; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵprov: _angular_core.ɵɵInjectableDeclaration; } declare class DashboardComponent implements OnChanges { #private; protected readonly store: { dashboardId: _angular_core.Signal; rows: _angular_core.Signal; columns: _angular_core.Signal; gutterSize: _angular_core.Signal; gridSizeLimits: _ngrx_signals.DeepSignal<_dragonworks_ngx_dashboard.GridSizeLimits>; isEditMode: _angular_core.Signal; showWidgetNames: _angular_core.Signal; gridCellDimensions: _ngrx_signals.DeepSignal<{ width: number; height: number; }>; widgetsById: _angular_core.Signal>; resizeData: _angular_core.Signal; gridResizePreview: _angular_core.Signal; dragData: _angular_core.Signal; hoveredDropZone: _angular_core.Signal<{ row: number; col: number; } | null>; dashboardService: _dragonworks_ngx_dashboard.DashboardService; cells: _angular_core.Signal; isDragActive: _angular_core.Signal; highlightedZones: _angular_core.Signal<{ row: number; col: number; }[]>; highlightMap: _angular_core.Signal>; effectiveRows: _angular_core.Signal; effectiveColumns: _angular_core.Signal; gridConfig: _angular_core.Signal<{ rows: number; columns: number; gutterSize: string; }>; minGridSize: _angular_core.Signal<{ rows: number; columns: number; }>; invalidHighlightMap: _angular_core.Signal>; isValidPlacement: _angular_core.Signal; resizePreviewCells: _angular_core.Signal<{ row: number; col: number; }[]>; resizePreviewMap: _angular_core.Signal>; setGridConfig: (config: { rows?: number; columns?: number; gutterSize?: string; }) => void; setGridSizeLimits: (limits: _dragonworks_ngx_dashboard.GridSizeLimits) => void; setGridCellDimensions: (width: number, height: number) => void; toggleEditMode: () => void; setEditMode: (isEditMode: boolean) => void; setShowWidgetNames: (showWidgetNames: boolean) => void; setGutterSize: (value: string) => string; addWidget: (cell: CellData) => void; removeWidget: (widgetId: WidgetId) => void; updateWidgetPosition: (widgetId: WidgetId, row: number, col: number) => void; createWidget: (row: number, col: number, widgetFactory: WidgetFactory, widgetState?: string) => void; updateCellSettings: (widgetId: WidgetId, flat: boolean) => void; updateWidgetSpan: (widgetId: WidgetId, rowSpan: number, colSpan: number) => void; updateWidgetState: (widgetId: WidgetId, widgetState: unknown) => void; updateAllWidgetStates: (cellStates: Map) => void; clearDashboard: () => void; clearGridResizePreview: () => void; startDrag: (dragData: DragData) => void; endDrag: () => void; setHoveredDropZone: (zone: { row: number; col: number; } | null) => void; handleDrop: (dragData: DragData, targetPosition: { row: number; col: number; }) => boolean; startResize: (cellId: CellId) => void; updateResizePreview: (direction: CellResizeDirection, delta: CellResizeDelta) => void; endResize: (apply: boolean) => void; setGridSize: (rows: number, columns: number) => GridResizeResult; previewGridResize: (deltaRows: number, deltaColumns: number) => void; exportDashboard: (getCurrentWidgetStates?: () => Map, selection?: GridSelection, selectionOptions?: SelectionFilterOptions) => DashboardDataDto; loadDashboard: (data: DashboardDataDto) => void; endGridResize: (deltaRows: number, deltaColumns: number) => GridResizeResult | null; } & _ngrx_signals.StateSource<{ dashboardId: string; rows: number; columns: number; gutterSize: string; gridSizeLimits: _dragonworks_ngx_dashboard.GridSizeLimits; isEditMode: boolean; showWidgetNames: boolean; gridCellDimensions: { width: number; height: number; }; widgetsById: Record; resizeData: ResizeData | null; gridResizePreview: GridResizeResult | null; dragData: DragData | null; hoveredDropZone: { row: number; col: number; } | null; }>; protected readonly viewport: DashboardViewportService; dashboardData: _angular_core.InputSignal; editMode: _angular_core.InputSignal; reservedSpace: _angular_core.InputSignal; enableSelection: _angular_core.InputSignal; selectionModifier: _angular_core.InputSignal; dragThreshold: _angular_core.InputSignal; /** * Optional CSS length for the gutter between cells (e.g. `'0.5em'`). * * A seed rather than a binding: it pushes into the store when the bound * value changes, and the store remains the single source of truth. A * statically bound value therefore does not fight a later * `loadDashboard()` — the imported dashboard's gutter survives. * * Values that are not a `px`/`em`/`rem` length are ignored and the current * gutter is kept. */ gutterSize: _angular_core.InputSignal; /** * Upper bound for any resize path, typed entry and handle drags alike. * * Every grid cell renders a drop zone component in the editor, so an * unbounded typed size is a performance cliff a drag gesture can't reach. * The content floor still outranks this cap: a dashboard loaded with more * rows than `maxRows` keeps them rather than losing widgets. */ maxRows: _angular_core.InputSignal; maxColumns: _angular_core.InputSignal; /** * Show each widget's type name as a badge in its top-right corner. * * A reading aid for a crowded grid, where a wall of small tiles gives no * clue what each one is. The library ships the badge but no control for it: * the host owns that chrome, and commonly binds it to its own edit mode. * * The input is the only write path — deliberately no imperative setter, in * line with every other view input here (`editMode`, `enableSelection`, * `dragThreshold`, `selectionModifier`). A host holds the flag in its own * signal and binds it. */ showWidgetNames: _angular_core.InputSignal; selectionComplete: _angular_core.OutputEmitterRef; gridResized: _angular_core.OutputEmitterRef; /** * Emits on any committed geometry change — size or gutter, handle-driven or * programmatic. Does not fire for `loadDashboard()`, which the host * initiated itself. * * Broader than `gridResized`, which covers size only but additionally * reports whether the request was clamped. * * Note for autosave: every committed change emits, including the * intermediate states of a host UI that applies as the user edits. Debounce, * or persist on a settled signal, rather than writing on each emission. */ gridConfigChanged: _angular_core.OutputEmitterRef; cells: _angular_core.Signal; /** Committed grid geometry (never the in-progress drag preview). */ readonly gridConfig: _angular_core.Signal<{ rows: number; columns: number; gutterSize: string; }>; /** * Smallest grid size that still contains every widget — the clamp-to-content * floor. Read it to show the limit before a user runs into it. */ readonly minGridSize: _angular_core.Signal<{ rows: number; columns: number; }>; /** * Ceiling currently in force, as set by `maxRows` / `maxColumns`. Read it to * bound a host control without restating the defaults. */ readonly gridSizeLimits: _ngrx_signals.DeepSignal<_dragonworks_ngx_dashboard.GridSizeLimits>; private dashboardEditor; private dashboardViewer; constructor(); ngOnChanges(changes: SimpleChanges): void; /** * Get current widget states from all cell components. * Used during dashboard export to get live widget states. */ private getCurrentWidgetStates; exportDashboard(): DashboardDataDto; exportDashboard(selection: GridSelection, options?: SelectionFilterOptions): DashboardDataDto; loadDashboard(data: DashboardDataDto): void; getCurrentDashboardData(): DashboardDataDto; clearDashboard(): void; /** * Resize the dashboard grid to the given row/column counts. * * Uses a clamp-to-content policy: a size that would push an existing widget * out of bounds is snapped up to the smallest size that still contains every * widget, so shrinking never orphans a widget. The applied size (which may * differ from the request when clamped) is returned and emitted via * `gridResized`. Values below 1 are treated as 1; fractional values are * floored. */ setGridSize(rows: number, columns: number): GridResizeResult; /** * Set the gutter between grid cells. * * Accepts a `px`, `em` or `rem` length. An unusable value is rejected * silently and the current gutter is kept — the returned string is the one * actually applied, mirroring how `setGridSize()` reports the size actually * applied. */ setGutterSize(value: string): string; /** Commit of a grid-resize handle drag, forwarded from the editor. */ protected onEditorGridResized(result: GridResizeResult): void; /** * Forwards to the active viewer. No-op in edit mode. * See `DashboardViewerComponent.clearSelection()`. */ clearSelection(): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵcmp: _angular_core.ɵɵComponentDeclaration; } interface WidgetDisplayItem extends WidgetMetadata { safeSvgIcon?: SafeHtml; } /** * A rendered section of the widget list. `label` is undefined for the trailing * section holding widgets that declare no `WidgetMetadata.group`; that section * is rendered without a heading. */ interface WidgetListGroup { label?: string; widgets: WidgetDisplayItem[]; /** * Derived display state, memoized with the group rather than recomputed per * change-detection pass from the template. */ expanded: boolean; /** Target of the heading button's `aria-controls`. */ sectionId: string; /** The heading button's own id, for the region's `aria-labelledby`. */ headingId: string; } declare class WidgetListComponent { #private; collapsed: _angular_core.InputSignal; enableSearchBox: _angular_core.InputSignal; activeWidget: _angular_core.WritableSignal; /** * Free-text filter over the list. Empty (or whitespace only) means no * filtering. Kept per component instance, like the collapsed group state. */ readonly searchTerm: _angular_core.WritableSignal; /** Whether a filter is currently narrowing the list. */ readonly isFiltering: _angular_core.Signal; /** Whether the search box is rendered: the icon-only rail has no room. */ readonly showSearchBox: _angular_core.Signal; gridCellDimensions: _angular_core.Signal<{ width: number; height: number; }>; /** * The widgets the list renders: every registered widget, or those matching * `searchTerm`. A widget matches when the term is contained in its name, * description or widget type id — the type id so a user who knows what they * registered can search by it directly. Matching is case insensitive. */ widgets: _angular_core.Signal<{ safeSvgIcon: SafeHtml; widgetTypeid: string; name: string; description: string; svgIcon: string; group?: string; }[]>; /** * Widgets bucketed by `WidgetMetadata.group`. Groups keep the order in which * they were first seen in the registration order, widgets keep their * registration order within a group, and ungrouped widgets trail the labelled * groups in a single unlabelled section. With no widget declaring a group the * result is one unlabelled section, i.e. a flat list with no heading. */ widgetGroups: _angular_core.Signal; /** * Whether a group's widgets are shown. Ungrouped widgets have no heading to * toggle, so they are always shown. */ isGroupExpanded(label?: string): boolean; /** Toggles a group open/closed. No-op for the unlabelled group. */ toggleGroup(label?: string): void; /** * Records a group's expanded state. Idempotent, so it is safe to drive from * the expansion panel's `opened`/`closed` outputs. */ setGroupExpanded(label: string | undefined, expanded: boolean): void; /** Clears the filter, restoring the full list. */ clearSearch(): void; onSearchInput(value: string): void; onDragStart(event: DragEvent, widget: WidgetDisplayItem): void; onDragEnd(): void; getWidgetAriaLabel(widget: WidgetDisplayItem): string; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵcmp: _angular_core.ɵɵComponentDeclaration; } declare class DashboardService { #private; readonly widgetTypes: _angular_core.Signal[]>; registerWidgetType(widget: WidgetComponentClass, sharedStateProvider?: WidgetSharedStateProvider | Type>): void; getFactory(widgetTypeid: string): WidgetFactory; /** * Get the shared state provider for a specific widget type. * * @param widgetTypeid The widget type identifier * @returns The shared state provider, or undefined if none is registered */ getSharedStateProvider(widgetTypeid: string): WidgetSharedStateProvider | undefined; /** * Collect shared states for all widget types currently on the dashboard. * Called during dashboard export/serialization. * * @param activeWidgetTypes Set of widget type IDs that are currently in use * @returns Map of widget type IDs to their shared states */ collectSharedStates(activeWidgetTypes: Set): Map; /** * Restore shared states for widget types. * Called during dashboard import/deserialization, before widget instances are created. * * @param states Map of widget type IDs to their shared states */ restoreSharedStates(states: Map): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵprov: _angular_core.ɵɵInjectableDeclaration; } /** * Abstract provider for cell settings dialogs. * Implement this to provide custom dialog solutions. */ declare abstract class CellSettingsDialogProvider { /** * Open a settings dialog for the given cell. * Returns a promise that resolves to the new settings, or undefined if cancelled. */ abstract openCellSettings(data: CellDisplayData): Promise; } /** * Injection token for the cell dialog provider. * Use this to provide your custom dialog implementation. * * @example * ```typescript * providers: [ * { provide: CELL_SETTINGS_DIALOG_PROVIDER, useClass: MyCellSettingsDialogProvider } * ] * ``` */ declare const CELL_SETTINGS_DIALOG_PROVIDER: InjectionToken; /** * Default cell dialog provider that uses Material Design dialogs. * Provides a modern, accessible dialog experience for cell settings. */ declare class DefaultCellSettingsDialogProvider extends CellSettingsDialogProvider { private dialog; openCellSettings(data: CellDisplayData): Promise; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵprov: _angular_core.ɵɵInjectableDeclaration; } /** * Context information about the empty cell that was clicked */ interface EmptyCellContext { /** The row position in the grid (1-indexed) */ row: number; /** The column position in the grid (1-indexed) */ col: number; /** Total number of rows in the dashboard */ totalRows: number; /** Total number of columns in the dashboard */ totalColumns: number; /** The gutter size between cells (e.g., '1em') */ gutterSize: string; /** * Optional callback to create a widget at this position. * When provided, allows the context provider to create widgets directly. * * @param widgetTypeid - The widget type identifier to create * @returns true if widget was created successfully, false otherwise */ createWidget?: (widgetTypeid: string) => boolean; } /** * Abstract provider for handling context menu events on empty dashboard cells. * Implement this to provide custom behavior when users right-click on unoccupied grid spaces. * * @example * ```typescript * @Injectable() * export class CustomEmptyCellProvider extends EmptyCellContextProvider { * handleEmptyCellContext(event: MouseEvent, context: EmptyCellContext): void { * event.preventDefault(); * // Show custom menu, open dialog, etc. * } * } * ``` */ declare abstract class EmptyCellContextProvider { /** * Handle context menu event on an empty dashboard cell. * * @param event - The mouse event from the right-click * @param context - Information about the empty cell and dashboard */ abstract handleEmptyCellContext(event: MouseEvent, context: EmptyCellContext): void; } /** * Injection token for the empty cell context provider. * Use this to provide your custom implementation for handling right-clicks on empty dashboard cells. * * @example * ```typescript * // Provide a custom implementation * providers: [ * { * provide: EMPTY_CELL_CONTEXT_PROVIDER, * useClass: MyCustomEmptyCellProvider * } * ] * ``` */ declare const EMPTY_CELL_CONTEXT_PROVIDER: InjectionToken; /** * Default empty cell context provider that prevents the browser's context menu * and performs no other action. * * This is the default behavior that allows users to right-click on empty dashboard * cells without triggering the browser's default context menu. */ declare class DefaultEmptyCellContextProvider extends EmptyCellContextProvider { /** * Default empty cell context handler. * The browser context menu is already prevented by the component. * No additional action is taken by default. */ handleEmptyCellContext(): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵprov: _angular_core.ɵɵInjectableDeclaration; } /** * Context provider that displays a widget list menu when right-clicking on empty cells. * * This provider shows a Material Design context menu with all available widget types. * When a user clicks on a widget in the menu, it's immediately added to the empty cell. * * @example * ```typescript * // In your component or app config * providers: [ * { * provide: EMPTY_CELL_CONTEXT_PROVIDER, * useClass: WidgetListContextMenuProvider * } * ] * ``` * * @public */ declare class WidgetListContextMenuProvider extends EmptyCellContextProvider { #private; /** * Handle empty cell context menu by showing available widgets. * * @param event - The mouse event from the right-click * @param context - Information about the empty cell and dashboard */ handleEmptyCellContext(event: MouseEvent, context: EmptyCellContext): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵprov: _angular_core.ɵɵInjectableDeclaration; } export { CELL_SETTINGS_DIALOG_PROVIDER, CellSettingsDialogProvider, DEFAULT_GRID_SIZE_LIMITS, DashboardComponent, DashboardService, DefaultCellSettingsDialogProvider, DefaultEmptyCellContextProvider, EMPTY_CELL_CONTEXT_PROVIDER, EmptyCellContextProvider, GUTTER_SIZE_PRESETS, NGX_DASHBOARD_VERSION, WidgetListComponent, WidgetListContextMenuProvider, createDefaultDashboard, createEmptyDashboard, sanitizeGutterSize }; export type { CellDataDto, DashboardDataDto, EmptyCellContext, GridConfig, GridResizeResult, GridSelection, GridSizeLimits, ReservedSpace, SelectionFilterOptions, SelectionModifier, Widget, WidgetMetadata, WidgetSharedStateProvider };