@dragonworks/ngx-dashboard 21.1.0 → 21.1.2

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.
@@ -23,7 +23,7 @@ import { isPlatformBrowser } from '@angular/common';
23
23
 
24
24
  // Auto-generated by scripts/generate-versions.js
25
25
  // Do not edit manually
26
- const NGX_DASHBOARD_VERSION = '21.1.0';
26
+ const NGX_DASHBOARD_VERSION = '21.1.2';
27
27
 
28
28
  /**
29
29
  * Maximum number of columns supported by the grid.
@@ -232,8 +232,8 @@ class UnknownWidgetComponent {
232
232
  };
233
233
  state = signal({
234
234
  originalWidgetTypeid: 'unknown',
235
- }, ...(ngDevMode ? [{ debugName: "state" }] : []));
236
- tooltipText = computed(() => `${this.state().originalWidgetTypeid}`, ...(ngDevMode ? [{ debugName: "tooltipText" }] : []));
235
+ }, ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
236
+ tooltipText = computed(() => `${this.state().originalWidgetTypeid}`, ...(ngDevMode ? [{ debugName: "tooltipText" }] : /* istanbul ignore next */ []));
237
237
  dashboardSetState(state) {
238
238
  if (state && typeof state === 'object' && 'originalWidgetTypeid' in state) {
239
239
  this.state.set(state);
@@ -242,14 +242,14 @@ class UnknownWidgetComponent {
242
242
  dashboardGetState() {
243
243
  return this.state();
244
244
  }
245
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: UnknownWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
246
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: UnknownWidgetComponent, isStandalone: true, selector: "lib-unknown-widget", ngImport: i0, template: `
245
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: UnknownWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
246
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.10", type: UnknownWidgetComponent, isStandalone: true, selector: "lib-unknown-widget", ngImport: i0, template: `
247
247
  <div class="unknown-widget-container" [matTooltip]="tooltipText()">
248
248
  <mat-icon class="unknown-widget-icon">error_outline</mat-icon>
249
249
  </div>
250
250
  `, isInline: true, styles: [".unknown-widget-container{display:flex;align-items:center;justify-content:center;width:100%;height:100%;background-color:var(--mat-sys-error);border-radius:8px;container-type:size}.unknown-widget-icon{color:var(--mat-sys-on-error);font-size:clamp(12px,75cqmin,68px);width:clamp(12px,75cqmin,68px);height:clamp(12px,75cqmin,68px)}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
251
251
  }
252
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: UnknownWidgetComponent, decorators: [{
252
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: UnknownWidgetComponent, decorators: [{
253
253
  type: Component,
254
254
  args: [{ selector: 'lib-unknown-widget', imports: [MatIconModule, MatTooltipModule], template: `
255
255
  <div class="unknown-widget-container" [matTooltip]="tooltipText()">
@@ -260,9 +260,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImpor
260
260
 
261
261
  // dashboard.service.ts
262
262
  class DashboardService {
263
- #widgetTypes = signal([], ...(ngDevMode ? [{ debugName: "#widgetTypes" }] : []));
263
+ #widgetTypes = signal([], ...(ngDevMode ? [{ debugName: "#widgetTypes" }] : /* istanbul ignore next */ []));
264
264
  #widgetFactoryMap = new Map();
265
265
  #sharedStateProviders = new Map();
266
+ #pendingSharedStates = new Map();
266
267
  #unknownWidgetFactory = createFactoryFromComponent(UnknownWidgetComponent);
267
268
  widgetTypes = this.#widgetTypes.asReadonly(); // make the widget list available as a readonly signal
268
269
  registerWidgetType(widget, sharedStateProvider) {
@@ -276,6 +277,13 @@ class DashboardService {
276
277
  if (sharedStateProvider) {
277
278
  const provider = this.#resolveProvider(sharedStateProvider);
278
279
  this.#sharedStateProviders.set(widgetTypeid, provider);
280
+ // Drain any buffered shared state from a prior loadDashboard that ran
281
+ // before this widget type was registered (e.g. lazy-loaded modules).
282
+ if (this.#pendingSharedStates.has(widgetTypeid)) {
283
+ const registered = this.#sharedStateProviders.get(widgetTypeid);
284
+ registered.setSharedState(this.#pendingSharedStates.get(widgetTypeid));
285
+ this.#pendingSharedStates.delete(widgetTypeid);
286
+ }
279
287
  }
280
288
  this.#widgetTypes.set([...this.#widgetTypes(), widget]);
281
289
  }
@@ -345,13 +353,19 @@ class DashboardService {
345
353
  const provider = this.#sharedStateProviders.get(widgetTypeid);
346
354
  if (provider) {
347
355
  provider.setSharedState(state);
356
+ this.#pendingSharedStates.delete(widgetTypeid);
357
+ }
358
+ else {
359
+ // Buffer for a widget type that hasn't been registered yet. Replaces
360
+ // any prior buffered value so a second loadDashboard wins.
361
+ this.#pendingSharedStates.set(widgetTypeid, state);
348
362
  }
349
363
  }
350
364
  }
351
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DashboardService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
352
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DashboardService, providedIn: 'root' });
365
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DashboardService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
366
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DashboardService, providedIn: 'root' });
353
367
  }
354
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DashboardService, decorators: [{
368
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DashboardService, decorators: [{
355
369
  type: Injectable,
356
370
  args: [{
357
371
  providedIn: 'root',
@@ -1073,8 +1087,14 @@ withMethods((store) => ({
1073
1087
  };
1074
1088
  widgetsById[WidgetIdUtils.toString(widgetId)] = cell;
1075
1089
  });
1090
+ // Adopt the incoming dashboardId only on the initial load (when the
1091
+ // store's id is still empty). On subsequent imperative imports the
1092
+ // existing id is preserved so that bridge registration stays stable
1093
+ // and Export→Import across dashboards "just works" without requiring
1094
+ // consumers to rewrite the id in the file.
1095
+ const currentId = store.dashboardId();
1076
1096
  patchState(store, {
1077
- dashboardId: data.dashboardId,
1097
+ ...(currentId ? {} : { dashboardId: data.dashboardId }),
1078
1098
  rows: data.rows,
1079
1099
  columns: data.columns,
1080
1100
  gutterSize: data.gutterSize,
@@ -1123,8 +1143,8 @@ class CellSettingsDialogComponent {
1123
1143
  };
1124
1144
  this.dialogRef.close(newData);
1125
1145
  }
1126
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CellSettingsDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1127
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: CellSettingsDialogComponent, isStandalone: true, selector: "lib-cell-settings-dialog", ngImport: i0, template: `
1146
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CellSettingsDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1147
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.10", type: CellSettingsDialogComponent, isStandalone: true, selector: "lib-cell-settings-dialog", ngImport: i0, template: `
1128
1148
  <h2 mat-dialog-title i18n="@@ngx.dashboard.cell.settings.title">
1129
1149
  Cell Display Settings
1130
1150
  </h2>
@@ -1190,7 +1210,7 @@ class CellSettingsDialogComponent {
1190
1210
  </mat-dialog-actions>
1191
1211
  `, isInline: true, styles: ["mat-dialog-content{display:block;overflow-y:auto;overflow-x:hidden;padding-top:.5rem}.cell-info{margin:0 0 1.5rem;padding-bottom:1rem}.radio-group{width:100%}mat-radio-group{display:block}mat-radio-button{width:100%;display:block;margin-bottom:1rem}mat-radio-button:last-child{margin-bottom:0}.radio-option{margin-left:.75rem;padding:.25rem 0}.option-title{display:block;margin-bottom:.25rem}.option-description{display:block}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i2$2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i2$2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i2$2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatRadioModule }, { kind: "directive", type: i4$1.MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: i4$1.MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1192
1212
  }
1193
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CellSettingsDialogComponent, decorators: [{
1213
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CellSettingsDialogComponent, decorators: [{
1194
1214
  type: Component,
1195
1215
  args: [{ selector: 'lib-cell-settings-dialog', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
1196
1216
  FormsModule,
@@ -1281,10 +1301,10 @@ class DefaultCellSettingsDialogProvider extends CellSettingsDialogProvider {
1281
1301
  const result = await firstValueFrom(dialogRef.afterClosed());
1282
1302
  return result;
1283
1303
  }
1284
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DefaultCellSettingsDialogProvider, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
1285
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DefaultCellSettingsDialogProvider, providedIn: 'root' });
1304
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DefaultCellSettingsDialogProvider, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
1305
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DefaultCellSettingsDialogProvider, providedIn: 'root' });
1286
1306
  }
1287
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DefaultCellSettingsDialogProvider, decorators: [{
1307
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DefaultCellSettingsDialogProvider, decorators: [{
1288
1308
  type: Injectable,
1289
1309
  args: [{
1290
1310
  providedIn: 'root',
@@ -1308,7 +1328,7 @@ const CELL_SETTINGS_DIALOG_PROVIDER = new InjectionToken('CellSettingsDialogProv
1308
1328
  });
1309
1329
 
1310
1330
  class CellContextMenuService {
1311
- #activeMenu = signal(null, ...(ngDevMode ? [{ debugName: "#activeMenu" }] : []));
1331
+ #activeMenu = signal(null, ...(ngDevMode ? [{ debugName: "#activeMenu" }] : /* istanbul ignore next */ []));
1312
1332
  activeMenu = this.#activeMenu.asReadonly();
1313
1333
  show(x, y, items) {
1314
1334
  this.#activeMenu.set({ x, y, items });
@@ -1316,26 +1336,26 @@ class CellContextMenuService {
1316
1336
  hide() {
1317
1337
  this.#activeMenu.set(null);
1318
1338
  }
1319
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CellContextMenuService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1320
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CellContextMenuService });
1339
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CellContextMenuService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1340
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CellContextMenuService });
1321
1341
  }
1322
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CellContextMenuService, decorators: [{
1342
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CellContextMenuService, decorators: [{
1323
1343
  type: Injectable
1324
1344
  }] });
1325
1345
 
1326
1346
  // cell.component.ts
1327
1347
  class CellComponent {
1328
- widgetId = input.required(...(ngDevMode ? [{ debugName: "widgetId" }] : [])); // Unique widget instance identifier
1329
- cellId = input.required(...(ngDevMode ? [{ debugName: "cellId" }] : [])); // Current grid position
1330
- widgetFactory = input(undefined, ...(ngDevMode ? [{ debugName: "widgetFactory" }] : []));
1331
- widgetState = input(undefined, ...(ngDevMode ? [{ debugName: "widgetState" }] : []));
1332
- isEditMode = input(false, ...(ngDevMode ? [{ debugName: "isEditMode" }] : []));
1333
- flat = input(undefined, ...(ngDevMode ? [{ debugName: "flat" }] : []));
1334
- row = model.required(...(ngDevMode ? [{ debugName: "row" }] : []));
1335
- column = model.required(...(ngDevMode ? [{ debugName: "column" }] : []));
1336
- rowSpan = input(1, ...(ngDevMode ? [{ debugName: "rowSpan" }] : []));
1337
- colSpan = input(1, ...(ngDevMode ? [{ debugName: "colSpan" }] : []));
1338
- draggable = input(false, ...(ngDevMode ? [{ debugName: "draggable" }] : []));
1348
+ widgetId = input.required(...(ngDevMode ? [{ debugName: "widgetId" }] : /* istanbul ignore next */ [])); // Unique widget instance identifier
1349
+ cellId = input.required(...(ngDevMode ? [{ debugName: "cellId" }] : /* istanbul ignore next */ [])); // Current grid position
1350
+ widgetFactory = input(undefined, ...(ngDevMode ? [{ debugName: "widgetFactory" }] : /* istanbul ignore next */ []));
1351
+ widgetState = input(undefined, ...(ngDevMode ? [{ debugName: "widgetState" }] : /* istanbul ignore next */ []));
1352
+ isEditMode = input(false, ...(ngDevMode ? [{ debugName: "isEditMode" }] : /* istanbul ignore next */ []));
1353
+ flat = input(undefined, ...(ngDevMode ? [{ debugName: "flat" }] : /* istanbul ignore next */ []));
1354
+ row = model.required(...(ngDevMode ? [{ debugName: "row" }] : /* istanbul ignore next */ []));
1355
+ column = model.required(...(ngDevMode ? [{ debugName: "column" }] : /* istanbul ignore next */ []));
1356
+ rowSpan = input(1, ...(ngDevMode ? [{ debugName: "rowSpan" }] : /* istanbul ignore next */ []));
1357
+ colSpan = input(1, ...(ngDevMode ? [{ debugName: "colSpan" }] : /* istanbul ignore next */ []));
1358
+ draggable = input(false, ...(ngDevMode ? [{ debugName: "draggable" }] : /* istanbul ignore next */ []));
1339
1359
  dragStart = output();
1340
1360
  dragEnd = output();
1341
1361
  edit = output();
@@ -1356,20 +1376,20 @@ class CellComponent {
1356
1376
  // Document event listeners cleanup function
1357
1377
  // Performance: Only created when actively resizing, not for every cell
1358
1378
  #documentListeners;
1359
- isDragging = signal(false, ...(ngDevMode ? [{ debugName: "isDragging" }] : []));
1360
- gridRowStyle = computed(() => `${this.row()} / span ${this.rowSpan()}`, ...(ngDevMode ? [{ debugName: "gridRowStyle" }] : []));
1361
- gridColumnStyle = computed(() => `${this.column()} / span ${this.colSpan()}`, ...(ngDevMode ? [{ debugName: "gridColumnStyle" }] : []));
1379
+ isDragging = signal(false, ...(ngDevMode ? [{ debugName: "isDragging" }] : /* istanbul ignore next */ []));
1380
+ gridRowStyle = computed(() => `${this.row()} / span ${this.rowSpan()}`, ...(ngDevMode ? [{ debugName: "gridRowStyle" }] : /* istanbul ignore next */ []));
1381
+ gridColumnStyle = computed(() => `${this.column()} / span ${this.colSpan()}`, ...(ngDevMode ? [{ debugName: "gridColumnStyle" }] : /* istanbul ignore next */ []));
1362
1382
  isResizing = computed(() => {
1363
1383
  const resizeData = this.#store.resizeData();
1364
1384
  return resizeData
1365
1385
  ? CellIdUtils.equals(resizeData.cellId, this.cellId())
1366
1386
  : false;
1367
- }, ...(ngDevMode ? [{ debugName: "isResizing" }] : []));
1368
- isDragActive = computed(() => !!this.#store.dragData(), ...(ngDevMode ? [{ debugName: "isDragActive" }] : []));
1387
+ }, ...(ngDevMode ? [{ debugName: "isResizing" }] : /* istanbul ignore next */ []));
1388
+ isDragActive = computed(() => !!this.#store.dragData(), ...(ngDevMode ? [{ debugName: "isDragActive" }] : /* istanbul ignore next */ []));
1369
1389
  resizeData = this.#store.resizeData;
1370
1390
  gridCellDimensions = this.#store.gridCellDimensions;
1371
- resizeDirection = signal(null, ...(ngDevMode ? [{ debugName: "resizeDirection" }] : []));
1372
- resizeStartPos = signal({ x: 0, y: 0 }, ...(ngDevMode ? [{ debugName: "resizeStartPos" }] : []));
1391
+ resizeDirection = signal(null, ...(ngDevMode ? [{ debugName: "resizeDirection" }] : /* istanbul ignore next */ []));
1392
+ resizeStartPos = signal({ x: 0, y: 0 }, ...(ngDevMode ? [{ debugName: "resizeStartPos" }] : /* istanbul ignore next */ []));
1373
1393
  constructor() {
1374
1394
  // widget creation - triggers when factory or state changes
1375
1395
  effect(() => {
@@ -1604,10 +1624,10 @@ class CellComponent {
1604
1624
  // Fall back to stored state if widget doesn't implement dashboardGetState
1605
1625
  return this.widgetState();
1606
1626
  }
1607
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1608
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: CellComponent, isStandalone: true, selector: "lib-cell", inputs: { widgetId: { classPropertyName: "widgetId", publicName: "widgetId", isSignal: true, isRequired: true, transformFunction: null }, cellId: { classPropertyName: "cellId", publicName: "cellId", isSignal: true, isRequired: true, transformFunction: null }, widgetFactory: { classPropertyName: "widgetFactory", publicName: "widgetFactory", isSignal: true, isRequired: false, transformFunction: null }, widgetState: { classPropertyName: "widgetState", publicName: "widgetState", isSignal: true, isRequired: false, transformFunction: null }, isEditMode: { classPropertyName: "isEditMode", publicName: "isEditMode", isSignal: true, isRequired: false, transformFunction: null }, flat: { classPropertyName: "flat", publicName: "flat", isSignal: true, isRequired: false, transformFunction: null }, row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: true, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, rowSpan: { classPropertyName: "rowSpan", publicName: "rowSpan", isSignal: true, isRequired: false, transformFunction: null }, colSpan: { classPropertyName: "colSpan", publicName: "colSpan", isSignal: true, isRequired: false, transformFunction: null }, draggable: { classPropertyName: "draggable", publicName: "draggable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { row: "rowChange", column: "columnChange", dragStart: "dragStart", dragEnd: "dragEnd", edit: "edit", delete: "delete", settings: "settings", resizeStart: "resizeStart", resizeMove: "resizeMove", resizeEnd: "resizeEnd" }, host: { properties: { "style.grid-row": "gridRowStyle()", "style.grid-column": "gridColumnStyle()", "class.is-dragging": "isDragging()", "class.drag-active": "isDragActive()", "class.flat": "flat() === true" } }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: "<!-- cell.component.html -->\n<div\n class=\"cell\"\n [class.is-resizing]=\"isResizing()\"\n [class.flat]=\"flat() === true\"\n [draggable]=\"draggable()\"\n (dragstart)=\"onDragStart($event)\"\n (dragend)=\"onDragEnd()\"\n (contextmenu)=\"onContextMenu($event)\"\n>\n <div class=\"content-area\">\n <ng-template #container></ng-template>\n </div>\n @if (isEditMode() && !isDragging()) {\n <!-- Right resize handle -->\n <div\n class=\"resize-handle resize-handle--right\"\n (mousedown)=\"onResizeStart($event, 'horizontal')\"\n >\n <div class=\"resize-handle-line\"></div>\n </div>\n <!-- Bottom resize handle -->\n <div\n class=\"resize-handle resize-handle--bottom\"\n (mousedown)=\"onResizeStart($event, 'vertical')\"\n >\n <div class=\"resize-handle-line\"></div>\n </div>\n }\n</div>\n\n@if (isResizing()) {\n<div class=\"resize-preview\" i18n=\"@@ngx.dashboard.cell.resize.dimensions\">\n {{ resizeData()?.previewColSpan ?? colSpan() }} \u00D7\n {{ resizeData()?.previewRowSpan ?? rowSpan() }}\n</div>\n}\n", styles: [":host{display:block;width:100%;height:100%;position:relative;z-index:1;container-type:inline-size}:host(.drag-active):not(.is-dragging){pointer-events:none}:host(.is-dragging){z-index:100;opacity:.5;pointer-events:none}:host(.is-dragging) .content-area{pointer-events:none}:host(:hover) .resize-handle{opacity:1}.cell{width:100%;height:100%;border-radius:4px;box-shadow:0 2px 6px #0000001a;padding:0;box-sizing:border-box;overflow:hidden;position:relative;container-type:inline-size}.cell:hover{box-shadow:0 4px 10px #00000026;transform:translateY(-2px)}.cell.flat{box-shadow:none;border:none}.cell.flat:hover{box-shadow:none;transform:none;border-color:#bdbdbd}.cell.resizing{-webkit-user-select:none;user-select:none}.content-area{width:100%;height:100%;overflow:auto;pointer-events:auto;position:relative;z-index:1}.content-area:hover{transform:initial}:host(:not(.is-dragging)) .cell.flat .content-area{pointer-events:auto}:host(:not(.is-dragging)) .cell.flat .content-area:hover{transform:initial}.resize-handle{position:absolute;z-index:20}.resize-handle--right{cursor:col-resize;width:16px;height:100%;right:-8px;top:0;display:flex;align-items:center;justify-content:center;opacity:0}.resize-handle--right:hover{opacity:1}.resize-handle--right:hover .resize-handle-line{background-color:var(--mat-sys-primary-container)}.resize-handle--bottom{cursor:row-resize;width:100%;height:16px;bottom:-8px;left:0;display:flex;align-items:center;justify-content:center;opacity:0}.resize-handle--bottom:hover{opacity:1}.resize-handle--bottom:hover .resize-handle-line{background-color:var(--mat-sys-primary-container)}.resize-handle-line{background-color:#0000001a}.resize-handle--right .resize-handle-line{width:8px;height:40px;border-radius:2px}.resize-handle--bottom .resize-handle-line{width:40px;height:8px;border-radius:2px}.resize-preview{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background-color:var(--mat-sys-primary);color:var(--mat-sys-on-primary);padding:4px 12px;border-radius:4px;font-size:14px;font-weight:500;pointer-events:none;z-index:30}.cell.is-resizing{opacity:.6}.cell.is-resizing .resize-handle{background-color:#2196f380}:root .cursor-col-resize{cursor:col-resize!important}:root .cursor-row-resize{cursor:row-resize!important}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1627
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1628
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: CellComponent, isStandalone: true, selector: "lib-cell", inputs: { widgetId: { classPropertyName: "widgetId", publicName: "widgetId", isSignal: true, isRequired: true, transformFunction: null }, cellId: { classPropertyName: "cellId", publicName: "cellId", isSignal: true, isRequired: true, transformFunction: null }, widgetFactory: { classPropertyName: "widgetFactory", publicName: "widgetFactory", isSignal: true, isRequired: false, transformFunction: null }, widgetState: { classPropertyName: "widgetState", publicName: "widgetState", isSignal: true, isRequired: false, transformFunction: null }, isEditMode: { classPropertyName: "isEditMode", publicName: "isEditMode", isSignal: true, isRequired: false, transformFunction: null }, flat: { classPropertyName: "flat", publicName: "flat", isSignal: true, isRequired: false, transformFunction: null }, row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: true, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, rowSpan: { classPropertyName: "rowSpan", publicName: "rowSpan", isSignal: true, isRequired: false, transformFunction: null }, colSpan: { classPropertyName: "colSpan", publicName: "colSpan", isSignal: true, isRequired: false, transformFunction: null }, draggable: { classPropertyName: "draggable", publicName: "draggable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { row: "rowChange", column: "columnChange", dragStart: "dragStart", dragEnd: "dragEnd", edit: "edit", delete: "delete", settings: "settings", resizeStart: "resizeStart", resizeMove: "resizeMove", resizeEnd: "resizeEnd" }, host: { properties: { "style.grid-row": "gridRowStyle()", "style.grid-column": "gridColumnStyle()", "class.is-dragging": "isDragging()", "class.drag-active": "isDragActive()", "class.flat": "flat() === true" } }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: "<!-- cell.component.html -->\n<div\n class=\"cell\"\n [class.is-resizing]=\"isResizing()\"\n [class.flat]=\"flat() === true\"\n [draggable]=\"draggable()\"\n (dragstart)=\"onDragStart($event)\"\n (dragend)=\"onDragEnd()\"\n (contextmenu)=\"onContextMenu($event)\"\n>\n <div class=\"content-area\">\n <ng-template #container></ng-template>\n </div>\n @if (isEditMode() && !isDragging()) {\n <!-- Right resize handle -->\n <div\n class=\"resize-handle resize-handle--right\"\n (mousedown)=\"onResizeStart($event, 'horizontal')\"\n >\n <div class=\"resize-handle-line\"></div>\n </div>\n <!-- Bottom resize handle -->\n <div\n class=\"resize-handle resize-handle--bottom\"\n (mousedown)=\"onResizeStart($event, 'vertical')\"\n >\n <div class=\"resize-handle-line\"></div>\n </div>\n }\n</div>\n\n@if (isResizing()) {\n<div class=\"resize-preview\" i18n=\"@@ngx.dashboard.cell.resize.dimensions\">\n {{ resizeData()?.previewColSpan ?? colSpan() }} \u00D7\n {{ resizeData()?.previewRowSpan ?? rowSpan() }}\n</div>\n}\n", styles: [":host{display:block;width:100%;height:100%;position:relative;z-index:1;container-type:inline-size}:host(.drag-active):not(.is-dragging){pointer-events:none}:host(.is-dragging){z-index:100;opacity:.5;pointer-events:none}:host(.is-dragging) .content-area{pointer-events:none}:host(:hover) .resize-handle{opacity:1}.cell{width:100%;height:100%;border-radius:4px;box-shadow:0 2px 6px #0000001a;padding:0;box-sizing:border-box;overflow:hidden;position:relative;container-type:inline-size}.cell:hover{box-shadow:0 4px 10px #00000026;transform:translateY(-2px)}.cell.flat{box-shadow:none;border:none}.cell.flat:hover{box-shadow:none;transform:none;border-color:#bdbdbd}.cell.resizing{-webkit-user-select:none;user-select:none}.content-area{width:100%;height:100%;overflow:auto;pointer-events:auto;position:relative;z-index:1}.content-area:hover{transform:initial}:host(:not(.is-dragging)) .cell.flat .content-area{pointer-events:auto}:host(:not(.is-dragging)) .cell.flat .content-area:hover{transform:initial}.resize-handle{position:absolute;z-index:20}.resize-handle--right{cursor:col-resize;width:16px;height:100%;right:-8px;top:0;display:flex;align-items:center;justify-content:center;opacity:0}.resize-handle--right:hover{opacity:1}.resize-handle--right:hover .resize-handle-line{background-color:var(--mat-sys-primary-container)}.resize-handle--bottom{cursor:row-resize;width:100%;height:16px;bottom:-8px;left:0;display:flex;align-items:center;justify-content:center;opacity:0}.resize-handle--bottom:hover{opacity:1}.resize-handle--bottom:hover .resize-handle-line{background-color:var(--mat-sys-primary-container)}.resize-handle-line{background-color:#0000001a}.resize-handle--right .resize-handle-line{width:8px;height:40px;border-radius:2px}.resize-handle--bottom .resize-handle-line{width:40px;height:8px;border-radius:2px}.resize-preview{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background-color:var(--mat-sys-primary);color:var(--mat-sys-on-primary);padding:4px 12px;border-radius:4px;font-size:14px;font-weight:500;pointer-events:none;z-index:30}.cell.is-resizing{opacity:.6}.cell.is-resizing .resize-handle{background-color:#2196f380}:root .cursor-col-resize{cursor:col-resize!important}:root .cursor-row-resize{cursor:row-resize!important}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1609
1629
  }
1610
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CellComponent, decorators: [{
1630
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CellComponent, decorators: [{
1611
1631
  type: Component,
1612
1632
  args: [{ selector: 'lib-cell', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, host: {
1613
1633
  '[style.grid-row]': 'gridRowStyle()',
@@ -1622,21 +1642,21 @@ class DashboardViewerComponent {
1622
1642
  #store = inject(DashboardStore);
1623
1643
  #renderer = inject(Renderer2);
1624
1644
  #destroyRef = inject(DestroyRef);
1625
- cellComponents = viewChildren(CellComponent, ...(ngDevMode ? [{ debugName: "cellComponents" }] : []));
1626
- gridElement = viewChild('gridElement', ...(ngDevMode ? [{ debugName: "gridElement" }] : []));
1627
- rows = input.required(...(ngDevMode ? [{ debugName: "rows" }] : []));
1628
- columns = input.required(...(ngDevMode ? [{ debugName: "columns" }] : []));
1629
- gutterSize = input('1em', ...(ngDevMode ? [{ debugName: "gutterSize" }] : []));
1630
- gutters = computed(() => this.columns() + 1, ...(ngDevMode ? [{ debugName: "gutters" }] : []));
1645
+ cellComponents = viewChildren(CellComponent, ...(ngDevMode ? [{ debugName: "cellComponents" }] : /* istanbul ignore next */ []));
1646
+ gridElement = viewChild('gridElement', ...(ngDevMode ? [{ debugName: "gridElement" }] : /* istanbul ignore next */ []));
1647
+ rows = input.required(...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
1648
+ columns = input.required(...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
1649
+ gutterSize = input('1em', ...(ngDevMode ? [{ debugName: "gutterSize" }] : /* istanbul ignore next */ []));
1650
+ gutters = computed(() => this.columns() + 1, ...(ngDevMode ? [{ debugName: "gutters" }] : /* istanbul ignore next */ []));
1631
1651
  // Selection feature
1632
- enableSelection = input(false, ...(ngDevMode ? [{ debugName: "enableSelection" }] : []));
1652
+ enableSelection = input(false, ...(ngDevMode ? [{ debugName: "enableSelection" }] : /* istanbul ignore next */ []));
1633
1653
  selectionComplete = output();
1634
1654
  // store signals - read-only
1635
1655
  cells = this.#store.cells;
1636
1656
  // Selection state
1637
- isSelecting = signal(false, ...(ngDevMode ? [{ debugName: "isSelecting" }] : []));
1638
- selectionStart = signal(null, ...(ngDevMode ? [{ debugName: "selectionStart" }] : []));
1639
- selectionCurrent = signal(null, ...(ngDevMode ? [{ debugName: "selectionCurrent" }] : []));
1657
+ isSelecting = signal(false, ...(ngDevMode ? [{ debugName: "isSelecting" }] : /* istanbul ignore next */ []));
1658
+ selectionStart = signal(null, ...(ngDevMode ? [{ debugName: "selectionStart" }] : /* istanbul ignore next */ []));
1659
+ selectionCurrent = signal(null, ...(ngDevMode ? [{ debugName: "selectionCurrent" }] : /* istanbul ignore next */ []));
1640
1660
  // Computed selection bounds (normalized)
1641
1661
  selectionBounds = computed(() => {
1642
1662
  const start = this.selectionStart();
@@ -1649,10 +1669,10 @@ class DashboardViewerComponent {
1649
1669
  startCol: Math.min(start.col, current.col),
1650
1670
  endCol: Math.max(start.col, current.col),
1651
1671
  };
1652
- }, ...(ngDevMode ? [{ debugName: "selectionBounds" }] : []));
1672
+ }, ...(ngDevMode ? [{ debugName: "selectionBounds" }] : /* istanbul ignore next */ []));
1653
1673
  // Generate array for template iteration
1654
- rowNumbers = computed(() => Array.from({ length: this.rows() }, (_, i) => i + 1), ...(ngDevMode ? [{ debugName: "rowNumbers" }] : []));
1655
- colNumbers = computed(() => Array.from({ length: this.columns() }, (_, i) => i + 1), ...(ngDevMode ? [{ debugName: "colNumbers" }] : []));
1674
+ rowNumbers = computed(() => Array.from({ length: this.rows() }, (_, i) => i + 1), ...(ngDevMode ? [{ debugName: "rowNumbers" }] : /* istanbul ignore next */ []));
1675
+ colNumbers = computed(() => Array.from({ length: this.columns() }, (_, i) => i + 1), ...(ngDevMode ? [{ debugName: "colNumbers" }] : /* istanbul ignore next */ []));
1656
1676
  // Document-level event listeners (cleanup needed)
1657
1677
  #mouseMoveListener;
1658
1678
  #mouseUpListener;
@@ -1758,10 +1778,10 @@ class DashboardViewerComponent {
1758
1778
  this.#mouseUpListener = undefined;
1759
1779
  }
1760
1780
  }
1761
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DashboardViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1762
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: DashboardViewerComponent, isStandalone: true, selector: "ngx-dashboard-viewer", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, gutterSize: { classPropertyName: "gutterSize", publicName: "gutterSize", isSignal: true, isRequired: false, transformFunction: null }, enableSelection: { classPropertyName: "enableSelection", publicName: "enableSelection", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionComplete: "selectionComplete" }, host: { properties: { "style.--rows": "rows()", "style.--columns": "columns()", "style.--gutter-size": "gutterSize()", "style.--gutters": "gutters()" } }, viewQueries: [{ propertyName: "cellComponents", predicate: CellComponent, descendants: true, isSignal: true }, { propertyName: "gridElement", first: true, predicate: ["gridElement"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Dashboard viewer - read-only grid -->\n<div class=\"grid top-grid\" #gridElement>\n @for (cell of cells(); track cell.widgetId) {\n <lib-cell\n class=\"grid-cell\"\n [widgetId]=\"cell.widgetId\"\n [cellId]=\"cell.cellId\"\n [isEditMode]=\"false\"\n [draggable]=\"false\"\n [row]=\"cell.row\"\n [column]=\"cell.col\"\n [rowSpan]=\"cell.rowSpan\"\n [colSpan]=\"cell.colSpan\"\n [flat]=\"cell.flat\"\n [widgetFactory]=\"cell.widgetFactory\"\n [widgetState]=\"cell.widgetState\"\n >\n </lib-cell>\n }\n</div>\n\n<!-- Selection overlay grid - mirror of main grid for cell selection -->\n@if (enableSelection()) {\n <div class=\"selection-overlay-grid\">\n @for (row of rowNumbers(); track row) {\n @for (col of colNumbers(); track col) {\n <div\n class=\"selection-ghost-cell\"\n [class.selected]=\"isCellSelected(row, col)\"\n [class.selecting]=\"isSelecting()\"\n [style.grid-row]=\"row\"\n [style.grid-column]=\"col\"\n (mousedown)=\"onGhostCellMouseDown($event, row, col)\"\n (mouseenter)=\"onGhostCellMouseEnter(row, col)\"\n ></div>\n }\n }\n </div>\n}\n", styles: ["@charset \"UTF-8\";:host{--cell-size: calc( 100cqi / var(--columns) - var(--gutter-size) * var(--gutters) / var(--columns) );--tile-size: calc(var(--cell-size) + var(--gutter-size));--tile-offset: calc( var(--gutter-size) + var(--cell-size) + var(--gutter-size) / 2 );display:block;container-type:inline-size;box-sizing:border-box;aspect-ratio:var(--columns)/var(--rows);width:100%;height:auto;position:relative;background-color:var(--mat-sys-surface-container)}.grid{display:grid;gap:var(--gutter-size);padding:var(--gutter-size);width:100%;height:100%;box-sizing:border-box;grid-template-columns:repeat(var(--columns),var(--cell-size));grid-template-rows:repeat(var(--rows),var(--cell-size))}.grid-cell{pointer-events:none}.grid-cell:not(.flat){pointer-events:auto;cursor:default}.grid-cell:not(.flat) .content-area{pointer-events:none}.top-grid{z-index:2;pointer-events:none}.selection-overlay-grid{position:absolute;top:0;left:0;width:100%;height:100%;display:grid;gap:var(--gutter-size);padding:var(--gutter-size);grid-template-columns:repeat(var(--columns),var(--cell-size));grid-template-rows:repeat(var(--rows),var(--cell-size));z-index:5;pointer-events:auto;-webkit-user-select:none;user-select:none}.selection-ghost-cell{cursor:crosshair;transition:background-color .1s ease,border-radius .1s ease;border-radius:2px}.selection-ghost-cell:hover:not(.selecting){background-color:var(--mat-sys-primary);opacity:.08}.selection-ghost-cell.selected{background-color:var(--mat-sys-primary);opacity:.25;border-radius:4px}.selection-ghost-cell.selecting{cursor:crosshair}\n"], dependencies: [{ kind: "component", type: CellComponent, selector: "lib-cell", inputs: ["widgetId", "cellId", "widgetFactory", "widgetState", "isEditMode", "flat", "row", "column", "rowSpan", "colSpan", "draggable"], outputs: ["rowChange", "columnChange", "dragStart", "dragEnd", "edit", "delete", "settings", "resizeStart", "resizeMove", "resizeEnd"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1781
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DashboardViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1782
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: DashboardViewerComponent, isStandalone: true, selector: "ngx-dashboard-viewer", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, gutterSize: { classPropertyName: "gutterSize", publicName: "gutterSize", isSignal: true, isRequired: false, transformFunction: null }, enableSelection: { classPropertyName: "enableSelection", publicName: "enableSelection", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionComplete: "selectionComplete" }, host: { properties: { "style.--rows": "rows()", "style.--columns": "columns()", "style.--gutter-size": "gutterSize()", "style.--gutters": "gutters()" } }, viewQueries: [{ propertyName: "cellComponents", predicate: CellComponent, descendants: true, isSignal: true }, { propertyName: "gridElement", first: true, predicate: ["gridElement"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Dashboard viewer - read-only grid -->\n<div class=\"grid top-grid\" #gridElement>\n @for (cell of cells(); track cell.widgetId) {\n <lib-cell\n class=\"grid-cell\"\n [widgetId]=\"cell.widgetId\"\n [cellId]=\"cell.cellId\"\n [isEditMode]=\"false\"\n [draggable]=\"false\"\n [row]=\"cell.row\"\n [column]=\"cell.col\"\n [rowSpan]=\"cell.rowSpan\"\n [colSpan]=\"cell.colSpan\"\n [flat]=\"cell.flat\"\n [widgetFactory]=\"cell.widgetFactory\"\n [widgetState]=\"cell.widgetState\"\n >\n </lib-cell>\n }\n</div>\n\n<!-- Selection overlay grid - mirror of main grid for cell selection -->\n@if (enableSelection()) {\n <div class=\"selection-overlay-grid\">\n @for (row of rowNumbers(); track row) {\n @for (col of colNumbers(); track col) {\n <div\n class=\"selection-ghost-cell\"\n [class.selected]=\"isCellSelected(row, col)\"\n [class.selecting]=\"isSelecting()\"\n [style.grid-row]=\"row\"\n [style.grid-column]=\"col\"\n (mousedown)=\"onGhostCellMouseDown($event, row, col)\"\n (mouseenter)=\"onGhostCellMouseEnter(row, col)\"\n ></div>\n }\n }\n </div>\n}\n", styles: ["@charset \"UTF-8\";:host{--cell-size: calc( 100cqi / var(--columns) - var(--gutter-size) * var(--gutters) / var(--columns) );--tile-size: calc(var(--cell-size) + var(--gutter-size));--tile-offset: calc( var(--gutter-size) + var(--cell-size) + var(--gutter-size) / 2 );display:block;container-type:inline-size;box-sizing:border-box;aspect-ratio:var(--columns)/var(--rows);width:100%;height:auto;position:relative;background-color:var(--mat-sys-surface-container)}.grid{display:grid;gap:var(--gutter-size);padding:var(--gutter-size);width:100%;height:100%;box-sizing:border-box;grid-template-columns:repeat(var(--columns),var(--cell-size));grid-template-rows:repeat(var(--rows),var(--cell-size))}.grid-cell{pointer-events:none}.grid-cell:not(.flat){pointer-events:auto;cursor:default}.grid-cell:not(.flat) .content-area{pointer-events:none}.top-grid{z-index:2;pointer-events:none}.selection-overlay-grid{position:absolute;top:0;left:0;width:100%;height:100%;display:grid;gap:var(--gutter-size);padding:var(--gutter-size);grid-template-columns:repeat(var(--columns),var(--cell-size));grid-template-rows:repeat(var(--rows),var(--cell-size));z-index:5;pointer-events:auto;-webkit-user-select:none;user-select:none}.selection-ghost-cell{cursor:crosshair;transition:background-color .1s ease,border-radius .1s ease;border-radius:2px}.selection-ghost-cell:hover:not(.selecting){background-color:var(--mat-sys-primary);opacity:.08}.selection-ghost-cell.selected{background-color:var(--mat-sys-primary);opacity:.25;border-radius:4px}.selection-ghost-cell.selecting{cursor:crosshair}\n"], dependencies: [{ kind: "component", type: CellComponent, selector: "lib-cell", inputs: ["widgetId", "cellId", "widgetFactory", "widgetState", "isEditMode", "flat", "row", "column", "rowSpan", "colSpan", "draggable"], outputs: ["rowChange", "columnChange", "dragStart", "dragEnd", "edit", "delete", "settings", "resizeStart", "resizeMove", "resizeEnd"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1763
1783
  }
1764
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DashboardViewerComponent, decorators: [{
1784
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DashboardViewerComponent, decorators: [{
1765
1785
  type: Component,
1766
1786
  args: [{ selector: 'ngx-dashboard-viewer', standalone: true, imports: [CellComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
1767
1787
  '[style.--rows]': 'rows()',
@@ -1779,11 +1799,11 @@ class CellContextMenuComponent {
1779
1799
  menuPosition = computed(() => {
1780
1800
  const menu = this.menuService.activeMenu();
1781
1801
  return menu ? { left: `${menu.x}px`, top: `${menu.y}px` } : { left: '0px', top: '0px' };
1782
- }, ...(ngDevMode ? [{ debugName: "menuPosition" }] : []));
1802
+ }, ...(ngDevMode ? [{ debugName: "menuPosition" }] : /* istanbul ignore next */ []));
1783
1803
  menuItems = computed(() => {
1784
1804
  const menu = this.menuService.activeMenu();
1785
1805
  return menu?.items || [];
1786
- }, ...(ngDevMode ? [{ debugName: "menuItems" }] : []));
1806
+ }, ...(ngDevMode ? [{ debugName: "menuItems" }] : /* istanbul ignore next */ []));
1787
1807
  constructor() {
1788
1808
  // Material Menu has a backdrop that blocks events from reaching other elements.
1789
1809
  // When any right-click occurs while menu is open, we need to:
@@ -1844,8 +1864,8 @@ class CellContextMenuComponent {
1844
1864
  this.menuService.hide();
1845
1865
  }
1846
1866
  }
1847
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CellContextMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1848
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: CellContextMenuComponent, isStandalone: true, selector: "lib-cell-context-menu", viewQueries: [{ propertyName: "menuTrigger", first: true, predicate: ["menuTrigger"], descendants: true, read: MatMenuTrigger, isSignal: true }], ngImport: i0, template: `
1867
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CellContextMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1868
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: CellContextMenuComponent, isStandalone: true, selector: "lib-cell-context-menu", viewQueries: [{ propertyName: "menuTrigger", first: true, predicate: ["menuTrigger"], descendants: true, read: MatMenuTrigger, isSignal: true }], ngImport: i0, template: `
1849
1869
  <!-- Hidden trigger for menu positioned at exact mouse coordinates
1850
1870
 
1851
1871
  IMPORTANT: Angular Material applies its own positioning logic to menus,
@@ -1899,7 +1919,7 @@ class CellContextMenuComponent {
1899
1919
  </mat-menu>
1900
1920
  `, isInline: true, styles: [":host{display:contents}\n"], dependencies: [{ kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i1$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i1$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i1$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i3.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1901
1921
  }
1902
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CellContextMenuComponent, decorators: [{
1922
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: CellContextMenuComponent, decorators: [{
1903
1923
  type: Component,
1904
1924
  args: [{ selector: 'lib-cell-context-menu', standalone: true, imports: [MatMenuModule, MatIconModule, MatDividerModule, MatButtonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
1905
1925
  <!-- Hidden trigger for menu positioned at exact mouse coordinates
@@ -1990,10 +2010,10 @@ class DefaultEmptyCellContextProvider extends EmptyCellContextProvider {
1990
2010
  handleEmptyCellContext() {
1991
2011
  // Default behavior: do nothing
1992
2012
  }
1993
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DefaultEmptyCellContextProvider, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
1994
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DefaultEmptyCellContextProvider, providedIn: 'root' });
2013
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DefaultEmptyCellContextProvider, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
2014
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DefaultEmptyCellContextProvider, providedIn: 'root' });
1995
2015
  }
1996
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DefaultEmptyCellContextProvider, decorators: [{
2016
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DefaultEmptyCellContextProvider, decorators: [{
1997
2017
  type: Injectable,
1998
2018
  args: [{
1999
2019
  providedIn: 'root',
@@ -2028,8 +2048,8 @@ const EMPTY_CELL_CONTEXT_PROVIDER = new InjectionToken('EmptyCellContextProvider
2028
2048
  * of the context menu that appears when right-clicking on empty dashboard cells.
2029
2049
  */
2030
2050
  class EmptyCellContextMenuService {
2031
- #activeMenu = signal(null, ...(ngDevMode ? [{ debugName: "#activeMenu" }] : []));
2032
- #lastSelectedWidgetTypeId = signal(null, ...(ngDevMode ? [{ debugName: "#lastSelectedWidgetTypeId" }] : []));
2051
+ #activeMenu = signal(null, ...(ngDevMode ? [{ debugName: "#activeMenu" }] : /* istanbul ignore next */ []));
2052
+ #lastSelectedWidgetTypeId = signal(null, ...(ngDevMode ? [{ debugName: "#lastSelectedWidgetTypeId" }] : /* istanbul ignore next */ []));
2033
2053
  activeMenu = this.#activeMenu.asReadonly();
2034
2054
  lastSelectedWidgetTypeId = this.#lastSelectedWidgetTypeId.asReadonly();
2035
2055
  /**
@@ -2057,10 +2077,10 @@ class EmptyCellContextMenuService {
2057
2077
  setLastSelection(widgetTypeId) {
2058
2078
  this.#lastSelectedWidgetTypeId.set(widgetTypeId);
2059
2079
  }
2060
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: EmptyCellContextMenuService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2061
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: EmptyCellContextMenuService, providedIn: 'root' });
2080
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: EmptyCellContextMenuService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2081
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: EmptyCellContextMenuService, providedIn: 'root' });
2062
2082
  }
2063
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: EmptyCellContextMenuService, decorators: [{
2083
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: EmptyCellContextMenuService, decorators: [{
2064
2084
  type: Injectable,
2065
2085
  args: [{
2066
2086
  providedIn: 'root',
@@ -2175,37 +2195,37 @@ class WidgetListContextMenuProvider extends EmptyCellContextProvider {
2175
2195
  'Ensure you are using a compatible version of the dashboard component.');
2176
2196
  }
2177
2197
  }
2178
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: WidgetListContextMenuProvider, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
2179
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: WidgetListContextMenuProvider });
2198
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: WidgetListContextMenuProvider, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
2199
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: WidgetListContextMenuProvider });
2180
2200
  }
2181
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: WidgetListContextMenuProvider, decorators: [{
2201
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: WidgetListContextMenuProvider, decorators: [{
2182
2202
  type: Injectable
2183
2203
  }] });
2184
2204
 
2185
2205
  // drop-zone.component.ts
2186
2206
  class DropZoneComponent {
2187
2207
  // Required inputs
2188
- row = input.required(...(ngDevMode ? [{ debugName: "row" }] : []));
2189
- col = input.required(...(ngDevMode ? [{ debugName: "col" }] : []));
2190
- index = input.required(...(ngDevMode ? [{ debugName: "index" }] : []));
2208
+ row = input.required(...(ngDevMode ? [{ debugName: "row" }] : /* istanbul ignore next */ []));
2209
+ col = input.required(...(ngDevMode ? [{ debugName: "col" }] : /* istanbul ignore next */ []));
2210
+ index = input.required(...(ngDevMode ? [{ debugName: "index" }] : /* istanbul ignore next */ []));
2191
2211
  // Optional inputs with defaults
2192
- highlight = input(false, ...(ngDevMode ? [{ debugName: "highlight" }] : []));
2193
- highlightInvalid = input(false, ...(ngDevMode ? [{ debugName: "highlightInvalid" }] : []));
2194
- highlightResize = input(false, ...(ngDevMode ? [{ debugName: "highlightResize" }] : []));
2195
- editMode = input(false, ...(ngDevMode ? [{ debugName: "editMode" }] : []));
2212
+ highlight = input(false, ...(ngDevMode ? [{ debugName: "highlight" }] : /* istanbul ignore next */ []));
2213
+ highlightInvalid = input(false, ...(ngDevMode ? [{ debugName: "highlightInvalid" }] : /* istanbul ignore next */ []));
2214
+ highlightResize = input(false, ...(ngDevMode ? [{ debugName: "highlightResize" }] : /* istanbul ignore next */ []));
2215
+ editMode = input(false, ...(ngDevMode ? [{ debugName: "editMode" }] : /* istanbul ignore next */ []));
2196
2216
  // Outputs
2197
2217
  dragEnter = output();
2198
2218
  dragExit = output();
2199
2219
  dragOver = output();
2200
2220
  dragDrop = output();
2201
2221
  // Computed properties
2202
- dropZoneId = computed(() => `drop-zone-${this.row()}-${this.col()}`, ...(ngDevMode ? [{ debugName: "dropZoneId" }] : []));
2222
+ dropZoneId = computed(() => `drop-zone-${this.row()}-${this.col()}`, ...(ngDevMode ? [{ debugName: "dropZoneId" }] : /* istanbul ignore next */ []));
2203
2223
  dropData = computed(() => ({
2204
2224
  row: this.row(),
2205
2225
  col: this.col(),
2206
- }), ...(ngDevMode ? [{ debugName: "dropData" }] : []));
2226
+ }), ...(ngDevMode ? [{ debugName: "dropData" }] : /* istanbul ignore next */ []));
2207
2227
  // Abstract drag state from store
2208
- dragData = computed(() => this.#store.dragData(), ...(ngDevMode ? [{ debugName: "dragData" }] : []));
2228
+ dragData = computed(() => this.#store.dragData(), ...(ngDevMode ? [{ debugName: "dragData" }] : /* istanbul ignore next */ []));
2209
2229
  // Computed drop effect based on drag data and validity
2210
2230
  dropEffect = computed(() => {
2211
2231
  const data = this.dragData();
@@ -2213,7 +2233,7 @@ class DropZoneComponent {
2213
2233
  return 'none';
2214
2234
  }
2215
2235
  return data.kind === 'cell' ? 'move' : 'copy';
2216
- }, ...(ngDevMode ? [{ debugName: "dropEffect" }] : []));
2236
+ }, ...(ngDevMode ? [{ debugName: "dropEffect" }] : /* istanbul ignore next */ []));
2217
2237
  #store = inject(DashboardStore);
2218
2238
  #elementRef = inject(ElementRef);
2219
2239
  #dashboardService = inject(DashboardService);
@@ -2291,10 +2311,10 @@ class DropZoneComponent {
2291
2311
  });
2292
2312
  }
2293
2313
  }
2294
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DropZoneComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2295
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: DropZoneComponent, isStandalone: true, selector: "lib-drop-zone", inputs: { row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: true, transformFunction: null }, col: { classPropertyName: "col", publicName: "col", isSignal: true, isRequired: true, transformFunction: null }, index: { classPropertyName: "index", publicName: "index", isSignal: true, isRequired: true, transformFunction: null }, highlight: { classPropertyName: "highlight", publicName: "highlight", isSignal: true, isRequired: false, transformFunction: null }, highlightInvalid: { classPropertyName: "highlightInvalid", publicName: "highlightInvalid", isSignal: true, isRequired: false, transformFunction: null }, highlightResize: { classPropertyName: "highlightResize", publicName: "highlightResize", isSignal: true, isRequired: false, transformFunction: null }, editMode: { classPropertyName: "editMode", publicName: "editMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dragEnter: "dragEnter", dragExit: "dragExit", dragOver: "dragOver", dragDrop: "dragDrop" }, ngImport: i0, template: "<!-- drop-zone.component.html -->\n<div\n class=\"drop-zone\"\n [class.drop-zone--highlight]=\"highlight() && !highlightInvalid()\"\n [class.drop-zone--invalid]=\"highlightInvalid()\"\n [class.drop-zone--resize]=\"highlightResize()\"\n [style.grid-row]=\"row()\"\n [style.grid-column]=\"col()\"\n (dragenter)=\"onDragEnter($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n (contextmenu)=\"onContextMenu($event)\"\n>\n @if (editMode()) {\n <div class=\"edit-mode-cell-number\">\n {{ index() }}<br />\n {{ row() }},{{ col() }}\n </div>\n }\n</div>\n", styles: [".drop-zone{width:100%;height:100%;z-index:0;align-self:stretch;justify-self:stretch;display:block;box-sizing:border-box}.drop-zone--active,.drop-zone--highlight{background-color:#80808080}.drop-zone--invalid{background-color:light-dark(color-mix(in srgb,var(--mat-sys-error) 40%,white),color-mix(in srgb,var(--mat-sys-error) 80%,black))}.drop-zone--resize{background-color:#2196f34d;outline:1px solid rgba(33,150,243,.6)}.edit-mode-cell-number{font-size:10px;line-height:1.1;color:#64646499;pointer-events:none;-webkit-user-select:none;user-select:none;z-index:-1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;width:100%;height:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2314
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DropZoneComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2315
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: DropZoneComponent, isStandalone: true, selector: "lib-drop-zone", inputs: { row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: true, transformFunction: null }, col: { classPropertyName: "col", publicName: "col", isSignal: true, isRequired: true, transformFunction: null }, index: { classPropertyName: "index", publicName: "index", isSignal: true, isRequired: true, transformFunction: null }, highlight: { classPropertyName: "highlight", publicName: "highlight", isSignal: true, isRequired: false, transformFunction: null }, highlightInvalid: { classPropertyName: "highlightInvalid", publicName: "highlightInvalid", isSignal: true, isRequired: false, transformFunction: null }, highlightResize: { classPropertyName: "highlightResize", publicName: "highlightResize", isSignal: true, isRequired: false, transformFunction: null }, editMode: { classPropertyName: "editMode", publicName: "editMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dragEnter: "dragEnter", dragExit: "dragExit", dragOver: "dragOver", dragDrop: "dragDrop" }, ngImport: i0, template: "<!-- drop-zone.component.html -->\n<div\n class=\"drop-zone\"\n [class.drop-zone--highlight]=\"highlight() && !highlightInvalid()\"\n [class.drop-zone--invalid]=\"highlightInvalid()\"\n [class.drop-zone--resize]=\"highlightResize()\"\n [style.grid-row]=\"row()\"\n [style.grid-column]=\"col()\"\n (dragenter)=\"onDragEnter($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n (contextmenu)=\"onContextMenu($event)\"\n>\n @if (editMode()) {\n <div class=\"edit-mode-cell-number\">\n {{ index() }}<br />\n {{ row() }},{{ col() }}\n </div>\n }\n</div>\n", styles: [".drop-zone{width:100%;height:100%;z-index:0;align-self:stretch;justify-self:stretch;display:block;box-sizing:border-box}.drop-zone--active,.drop-zone--highlight{background-color:#80808080}.drop-zone--invalid{background-color:light-dark(color-mix(in srgb,var(--mat-sys-error) 40%,white),color-mix(in srgb,var(--mat-sys-error) 80%,black))}.drop-zone--resize{background-color:#2196f34d;outline:1px solid rgba(33,150,243,.6)}.edit-mode-cell-number{font-size:10px;line-height:1.1;color:#64646499;pointer-events:none;-webkit-user-select:none;user-select:none;z-index:-1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;width:100%;height:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2296
2316
  }
2297
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DropZoneComponent, decorators: [{
2317
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DropZoneComponent, decorators: [{
2298
2318
  type: Component,
2299
2319
  args: [{ selector: 'lib-drop-zone', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- drop-zone.component.html -->\n<div\n class=\"drop-zone\"\n [class.drop-zone--highlight]=\"highlight() && !highlightInvalid()\"\n [class.drop-zone--invalid]=\"highlightInvalid()\"\n [class.drop-zone--resize]=\"highlightResize()\"\n [style.grid-row]=\"row()\"\n [style.grid-column]=\"col()\"\n (dragenter)=\"onDragEnter($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n (contextmenu)=\"onContextMenu($event)\"\n>\n @if (editMode()) {\n <div class=\"edit-mode-cell-number\">\n {{ index() }}<br />\n {{ row() }},{{ col() }}\n </div>\n }\n</div>\n", styles: [".drop-zone{width:100%;height:100%;z-index:0;align-self:stretch;justify-self:stretch;display:block;box-sizing:border-box}.drop-zone--active,.drop-zone--highlight{background-color:#80808080}.drop-zone--invalid{background-color:light-dark(color-mix(in srgb,var(--mat-sys-error) 40%,white),color-mix(in srgb,var(--mat-sys-error) 80%,black))}.drop-zone--resize{background-color:#2196f34d;outline:1px solid rgba(33,150,243,.6)}.edit-mode-cell-number{font-size:10px;line-height:1.1;color:#64646499;pointer-events:none;-webkit-user-select:none;user-select:none;z-index:-1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;width:100%;height:100%}\n"] }]
2300
2320
  }], propDecorators: { row: [{ type: i0.Input, args: [{ isSignal: true, alias: "row", required: true }] }], col: [{ type: i0.Input, args: [{ isSignal: true, alias: "col", required: true }] }], index: [{ type: i0.Input, args: [{ isSignal: true, alias: "index", required: true }] }], highlight: [{ type: i0.Input, args: [{ isSignal: true, alias: "highlight", required: false }] }], highlightInvalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "highlightInvalid", required: false }] }], highlightResize: [{ type: i0.Input, args: [{ isSignal: true, alias: "highlightResize", required: false }] }], editMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "editMode", required: false }] }], dragEnter: [{ type: i0.Output, args: ["dragEnter"] }], dragExit: [{ type: i0.Output, args: ["dragExit"] }], dragOver: [{ type: i0.Output, args: ["dragOver"] }], dragDrop: [{ type: i0.Output, args: ["dragDrop"] }] } });
@@ -2319,11 +2339,11 @@ class EmptyCellContextMenuComponent {
2319
2339
  return menu
2320
2340
  ? { left: `${menu.x}px`, top: `${menu.y}px` }
2321
2341
  : { left: '0px', top: '0px' };
2322
- }, ...(ngDevMode ? [{ debugName: "menuPosition" }] : []));
2342
+ }, ...(ngDevMode ? [{ debugName: "menuPosition" }] : /* istanbul ignore next */ []));
2323
2343
  menuItems = computed(() => {
2324
2344
  const menu = this.menuService.activeMenu();
2325
2345
  return menu?.items || [];
2326
- }, ...(ngDevMode ? [{ debugName: "menuItems" }] : []));
2346
+ }, ...(ngDevMode ? [{ debugName: "menuItems" }] : /* istanbul ignore next */ []));
2327
2347
  constructor() {
2328
2348
  // Material Menu has a backdrop that blocks events from reaching other elements.
2329
2349
  // When any right-click occurs while menu is open, we need to:
@@ -2395,8 +2415,8 @@ class EmptyCellContextMenuComponent {
2395
2415
  sanitizeSvg(svg) {
2396
2416
  return this.#sanitizer.bypassSecurityTrustHtml(svg);
2397
2417
  }
2398
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: EmptyCellContextMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2399
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: EmptyCellContextMenuComponent, isStandalone: true, selector: "lib-empty-cell-context-menu", viewQueries: [{ propertyName: "menuTrigger", first: true, predicate: ["menuTrigger"], descendants: true, read: MatMenuTrigger, isSignal: true }], ngImport: i0, template: `
2418
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: EmptyCellContextMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2419
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: EmptyCellContextMenuComponent, isStandalone: true, selector: "lib-empty-cell-context-menu", viewQueries: [{ propertyName: "menuTrigger", first: true, predicate: ["menuTrigger"], descendants: true, read: MatMenuTrigger, isSignal: true }], ngImport: i0, template: `
2400
2420
  <!-- Hidden trigger for menu positioned at exact mouse coordinates
2401
2421
 
2402
2422
  IMPORTANT: Angular Material applies its own positioning logic to menus,
@@ -2456,7 +2476,7 @@ class EmptyCellContextMenuComponent {
2456
2476
  </mat-menu>
2457
2477
  `, isInline: true, styles: [":host{display:contents}.empty-cell-widget-menu{max-height:400px;overflow-y:auto}.widget-icon{width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;vertical-align:middle}.widget-icon :deep(svg){width:20px;height:20px;fill:currentColor}\n"], dependencies: [{ kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i1$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i1$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i1$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i3.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2458
2478
  }
2459
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: EmptyCellContextMenuComponent, decorators: [{
2479
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: EmptyCellContextMenuComponent, decorators: [{
2460
2480
  type: Component,
2461
2481
  args: [{ selector: 'lib-empty-cell-context-menu', standalone: true, imports: [
2462
2482
  MatMenuModule,
@@ -2527,15 +2547,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImpor
2527
2547
  // dashboard-editor.component.ts
2528
2548
  class DashboardEditorComponent {
2529
2549
  bottomGridRef = viewChild.required('bottomGrid');
2530
- dropZones = viewChildren(DropZoneComponent, ...(ngDevMode ? [{ debugName: "dropZones" }] : []));
2531
- cellComponents = viewChildren(CellComponent, ...(ngDevMode ? [{ debugName: "cellComponents" }] : []));
2550
+ dropZones = viewChildren(DropZoneComponent, ...(ngDevMode ? [{ debugName: "dropZones" }] : /* istanbul ignore next */ []));
2551
+ cellComponents = viewChildren(CellComponent, ...(ngDevMode ? [{ debugName: "cellComponents" }] : /* istanbul ignore next */ []));
2532
2552
  #store = inject(DashboardStore);
2533
2553
  #destroyRef = inject(DestroyRef);
2534
2554
  #resizeObserver;
2535
- rows = input.required(...(ngDevMode ? [{ debugName: "rows" }] : []));
2536
- columns = input.required(...(ngDevMode ? [{ debugName: "columns" }] : []));
2537
- gutterSize = input('1em', ...(ngDevMode ? [{ debugName: "gutterSize" }] : []));
2538
- gutters = computed(() => this.columns() + 1, ...(ngDevMode ? [{ debugName: "gutters" }] : []));
2555
+ rows = input.required(...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
2556
+ columns = input.required(...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
2557
+ gutterSize = input('1em', ...(ngDevMode ? [{ debugName: "gutterSize" }] : /* istanbul ignore next */ []));
2558
+ gutters = computed(() => this.columns() + 1, ...(ngDevMode ? [{ debugName: "gutters" }] : /* istanbul ignore next */ []));
2539
2559
  // store signals
2540
2560
  cells = this.#store.cells;
2541
2561
  highlightedZones = this.#store.highlightedZones;
@@ -2557,7 +2577,7 @@ class DashboardEditorComponent {
2557
2577
  }
2558
2578
  }
2559
2579
  return positions;
2560
- }, ...(ngDevMode ? [{ debugName: "dropzonePositions" }] : []));
2580
+ }, ...(ngDevMode ? [{ debugName: "dropzonePositions" }] : /* istanbul ignore next */ []));
2561
2581
  // Helper method for template
2562
2582
  createCellId(row, col) {
2563
2583
  return CellIdUtils.create(row, col);
@@ -2629,12 +2649,12 @@ class DashboardEditorComponent {
2629
2649
  this.#store.handleDrop(event.data, event.target);
2630
2650
  // Note: Store handles all validation and error handling internally
2631
2651
  }
2632
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DashboardEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2633
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: DashboardEditorComponent, isStandalone: true, selector: "ngx-dashboard-editor", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, gutterSize: { classPropertyName: "gutterSize", publicName: "gutterSize", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.--rows": "rows()", "style.--columns": "columns()", "style.--gutter-size": "gutterSize()", "style.--gutters": "gutters()", "class.is-edit-mode": "true" } }, providers: [
2652
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DashboardEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2653
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: DashboardEditorComponent, isStandalone: true, selector: "ngx-dashboard-editor", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, gutterSize: { classPropertyName: "gutterSize", publicName: "gutterSize", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.--rows": "rows()", "style.--columns": "columns()", "style.--gutter-size": "gutterSize()", "style.--gutters": "gutters()", "class.is-edit-mode": "true" } }, providers: [
2634
2654
  CellContextMenuService,
2635
2655
  ], viewQueries: [{ propertyName: "bottomGridRef", first: true, predicate: ["bottomGrid"], descendants: true, isSignal: true }, { propertyName: "dropZones", predicate: DropZoneComponent, descendants: true, isSignal: true }, { propertyName: "cellComponents", predicate: CellComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<!-- dashboard-editor.component.html -->\n<div class=\"grid-container\">\n <!-- Bottom grid with drop zones -->\n <div class=\"grid\" id=\"bottom-grid\" #bottomGrid>\n @for (position of dropzonePositions(); track position.id) {\n <lib-drop-zone\n class=\"drop-zone\"\n [row]=\"position.row\"\n [col]=\"position.col\"\n [index]=\"position.index\"\n [highlight]=\"highlightMap().has(createCellId(position.row, position.col))\"\n [highlightInvalid]=\"\n invalidHighlightMap().has(createCellId(position.row, position.col))\n \"\n [highlightResize]=\"\n resizePreviewMap().has(createCellId(position.row, position.col))\n \"\n [editMode]=\"true\"\n (dragEnter)=\"onDragEnter($event)\"\n (dragExit)=\"onDragExit()\"\n (dragOver)=\"onDragOver($event)\"\n (dragDrop)=\"onDragDrop($event)\"\n ></lib-drop-zone>\n }\n </div>\n\n <!-- Top grid with interactive cells -->\n <div class=\"grid\" id=\"top-grid\">\n @for (cell of cells(); track cell.widgetId) {\n <lib-cell\n class=\"grid-cell\"\n [widgetId]=\"cell.widgetId\"\n [cellId]=\"cell.cellId\"\n [isEditMode]=\"true\"\n [draggable]=\"true\"\n [row]=\"cell.row\"\n [column]=\"cell.col\"\n [rowSpan]=\"cell.rowSpan\"\n [colSpan]=\"cell.colSpan\"\n [flat]=\"cell.flat\"\n [widgetFactory]=\"cell.widgetFactory\"\n [widgetState]=\"cell.widgetState\"\n (dragStart)=\"onCellDragStart($event)\"\n (dragEnd)=\"dragEnd()\"\n (delete)=\"onCellDelete($event)\"\n (settings)=\"onCellSettings($event)\"\n (resizeStart)=\"onCellResizeStart($event)\"\n (resizeMove)=\"onCellResizeMove($event)\"\n (resizeEnd)=\"onCellResizeEnd($event)\"\n >\n </lib-cell>\n }\n </div>\n</div>\n\n<!-- Context menus -->\n<lib-cell-context-menu></lib-cell-context-menu>\n<lib-empty-cell-context-menu></lib-empty-cell-context-menu>\n", styles: ["@charset \"UTF-8\";:host{--cell-size: calc( 100cqi / var(--columns) - var(--gutter-size) * var(--gutters) / var(--columns) );--tile-size: calc(var(--cell-size) + var(--gutter-size));--tile-offset: calc( var(--gutter-size) + var(--cell-size) + var(--gutter-size) / 2 );display:block;container-type:inline-size;box-sizing:border-box;aspect-ratio:var(--columns)/var(--rows);width:100%;height:auto}:host .grid{background-image:linear-gradient(to right,rgba(100,100,100,.12) 1px,transparent 1px),linear-gradient(to bottom,rgba(100,100,100,.12) 1px,transparent 1px),linear-gradient(to bottom,rgba(100,100,100,.12) 1px,transparent 1px);background-size:var(--tile-size) var(--tile-size),var(--tile-size) var(--tile-size),100% 1px;background-position:var(--tile-offset) var(--tile-offset),var(--tile-offset) var(--tile-offset),bottom;background-repeat:repeat,repeat,no-repeat}.grid-container{position:relative;width:100%;height:100%}.grid{display:grid;gap:var(--gutter-size);padding:var(--gutter-size);position:absolute;inset:0;width:100%;height:100%;box-sizing:border-box;align-items:stretch;justify-items:stretch;grid-template-columns:repeat(var(--columns),var(--cell-size));grid-template-rows:repeat(var(--rows),var(--cell-size))}#bottom-grid{z-index:1}#top-grid{z-index:2;pointer-events:none}.grid-cell{pointer-events:auto}.grid-cell.is-dragging{pointer-events:none;opacity:.5}\n"], dependencies: [{ kind: "component", type: CellComponent, selector: "lib-cell", inputs: ["widgetId", "cellId", "widgetFactory", "widgetState", "isEditMode", "flat", "row", "column", "rowSpan", "colSpan", "draggable"], outputs: ["rowChange", "columnChange", "dragStart", "dragEnd", "edit", "delete", "settings", "resizeStart", "resizeMove", "resizeEnd"] }, { kind: "component", type: DropZoneComponent, selector: "lib-drop-zone", inputs: ["row", "col", "index", "highlight", "highlightInvalid", "highlightResize", "editMode"], outputs: ["dragEnter", "dragExit", "dragOver", "dragDrop"] }, { kind: "component", type: CellContextMenuComponent, selector: "lib-cell-context-menu" }, { kind: "component", type: EmptyCellContextMenuComponent, selector: "lib-empty-cell-context-menu" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2636
2656
  }
2637
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DashboardEditorComponent, decorators: [{
2657
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DashboardEditorComponent, decorators: [{
2638
2658
  type: Component,
2639
2659
  args: [{ selector: 'ngx-dashboard-editor', standalone: true, imports: [
2640
2660
  CellComponent,
@@ -2661,7 +2681,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImpor
2661
2681
  */
2662
2682
  class DashboardBridgeService {
2663
2683
  // Map of registered dashboard instances with their reactive dimensions
2664
- dashboards = signal(new Map(), ...(ngDevMode ? [{ debugName: "dashboards" }] : []));
2684
+ dashboards = signal(new Map(), ...(ngDevMode ? [{ debugName: "dashboards" }] : /* istanbul ignore next */ []));
2665
2685
  /**
2666
2686
  * Register a dashboard store instance using its dashboard ID
2667
2687
  */
@@ -2712,7 +2732,7 @@ class DashboardBridgeService {
2712
2732
  }
2713
2733
  // Return dimensions from first available dashboard with fallback for undefined
2714
2734
  return dashboardEntries[0].dimensions() || { width: 100, height: 100 };
2715
- }, ...(ngDevMode ? [{ debugName: "availableDimensions" }] : []));
2735
+ }, ...(ngDevMode ? [{ debugName: "availableDimensions" }] : /* istanbul ignore next */ []));
2716
2736
  /**
2717
2737
  * Start drag operation on the first available dashboard
2718
2738
  * (Widget lists need some dashboard to coordinate with during drag)
@@ -2735,15 +2755,15 @@ class DashboardBridgeService {
2735
2755
  /**
2736
2756
  * Get all registered dashboard IDs
2737
2757
  */
2738
- registeredDashboards = computed(() => Array.from(this.dashboards().keys()), ...(ngDevMode ? [{ debugName: "registeredDashboards" }] : []));
2758
+ registeredDashboards = computed(() => Array.from(this.dashboards().keys()), ...(ngDevMode ? [{ debugName: "registeredDashboards" }] : /* istanbul ignore next */ []));
2739
2759
  /**
2740
2760
  * Get the number of registered dashboards
2741
2761
  */
2742
- dashboardCount = computed(() => this.dashboards().size, ...(ngDevMode ? [{ debugName: "dashboardCount" }] : []));
2762
+ dashboardCount = computed(() => this.dashboards().size, ...(ngDevMode ? [{ debugName: "dashboardCount" }] : /* istanbul ignore next */ []));
2743
2763
  /**
2744
2764
  * Check if any dashboards are registered
2745
2765
  */
2746
- hasDashboards = computed(() => this.dashboards().size > 0, ...(ngDevMode ? [{ debugName: "hasDashboards" }] : []));
2766
+ hasDashboards = computed(() => this.dashboards().size > 0, ...(ngDevMode ? [{ debugName: "hasDashboards" }] : /* istanbul ignore next */ []));
2747
2767
  /**
2748
2768
  * Update registration for a dashboard store when its ID becomes available
2749
2769
  */
@@ -2778,10 +2798,10 @@ class DashboardBridgeService {
2778
2798
  getAllDashboards() {
2779
2799
  return this.dashboards();
2780
2800
  }
2781
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DashboardBridgeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2782
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DashboardBridgeService, providedIn: 'root' });
2801
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DashboardBridgeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2802
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DashboardBridgeService, providedIn: 'root' });
2783
2803
  }
2784
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DashboardBridgeService, decorators: [{
2804
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DashboardBridgeService, decorators: [{
2785
2805
  type: Injectable,
2786
2806
  args: [{ providedIn: 'root' }]
2787
2807
  }] });
@@ -2796,8 +2816,8 @@ class DashboardViewportService {
2796
2816
  platformId = inject(PLATFORM_ID);
2797
2817
  destroyRef = inject(DestroyRef);
2798
2818
  store = inject(DashboardStore);
2799
- viewportSize = signal({ width: 0, height: 0 }, ...(ngDevMode ? [{ debugName: "viewportSize" }] : []));
2800
- reservedSpace = signal(DEFAULT_RESERVED_SPACE, ...(ngDevMode ? [{ debugName: "reservedSpace" }] : []));
2819
+ viewportSize = signal({ width: 0, height: 0 }, ...(ngDevMode ? [{ debugName: "viewportSize" }] : /* istanbul ignore next */ []));
2820
+ reservedSpace = signal(DEFAULT_RESERVED_SPACE, ...(ngDevMode ? [{ debugName: "reservedSpace" }] : /* istanbul ignore next */ []));
2801
2821
  resizeObserver = null;
2802
2822
  constructor() {
2803
2823
  if (isPlatformBrowser(this.platformId)) {
@@ -2855,7 +2875,7 @@ class DashboardViewportService {
2855
2875
  width: Math.max(0, viewport.width - reserved.left - reserved.right),
2856
2876
  height: Math.max(0, viewport.height - reserved.top - reserved.bottom)
2857
2877
  };
2858
- }, ...(ngDevMode ? [{ debugName: "availableSpace" }] : []));
2878
+ }, ...(ngDevMode ? [{ debugName: "availableSpace" }] : /* istanbul ignore next */ []));
2859
2879
  /**
2860
2880
  * Calculate dashboard constraints for this dashboard instance
2861
2881
  */
@@ -2896,11 +2916,11 @@ class DashboardViewportService {
2896
2916
  maxHeight: Math.max(0, maxHeight),
2897
2917
  constrainedBy
2898
2918
  };
2899
- }, ...(ngDevMode ? [{ debugName: "constraints" }] : []));
2900
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DashboardViewportService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2901
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DashboardViewportService });
2919
+ }, ...(ngDevMode ? [{ debugName: "constraints" }] : /* istanbul ignore next */ []));
2920
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DashboardViewportService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2921
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DashboardViewportService });
2902
2922
  }
2903
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DashboardViewportService, decorators: [{
2923
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DashboardViewportService, decorators: [{
2904
2924
  type: Injectable
2905
2925
  }], ctorParameters: () => [] });
2906
2926
 
@@ -2918,17 +2938,17 @@ class DashboardComponent {
2918
2938
  store = this.#store;
2919
2939
  viewport = this.#viewport;
2920
2940
  // Component inputs
2921
- dashboardData = input.required(...(ngDevMode ? [{ debugName: "dashboardData" }] : []));
2922
- editMode = input(false, ...(ngDevMode ? [{ debugName: "editMode" }] : []));
2923
- reservedSpace = input(...(ngDevMode ? [undefined, { debugName: "reservedSpace" }] : []));
2924
- enableSelection = input(false, ...(ngDevMode ? [{ debugName: "enableSelection" }] : []));
2941
+ dashboardData = input.required(...(ngDevMode ? [{ debugName: "dashboardData" }] : /* istanbul ignore next */ []));
2942
+ editMode = input(false, ...(ngDevMode ? [{ debugName: "editMode" }] : /* istanbul ignore next */ []));
2943
+ reservedSpace = input(...(ngDevMode ? [undefined, { debugName: "reservedSpace" }] : /* istanbul ignore next */ []));
2944
+ enableSelection = input(false, ...(ngDevMode ? [{ debugName: "enableSelection" }] : /* istanbul ignore next */ []));
2925
2945
  // Component outputs
2926
2946
  selectionComplete = output();
2927
2947
  // Store signals - shared by both child components
2928
2948
  cells = this.#store.cells;
2929
2949
  // ViewChild references for export/import functionality
2930
- dashboardEditor = viewChild(DashboardEditorComponent, ...(ngDevMode ? [{ debugName: "dashboardEditor" }] : []));
2931
- dashboardViewer = viewChild(DashboardViewerComponent, ...(ngDevMode ? [{ debugName: "dashboardViewer" }] : []));
2950
+ dashboardEditor = viewChild(DashboardEditorComponent, ...(ngDevMode ? [{ debugName: "dashboardEditor" }] : /* istanbul ignore next */ []));
2951
+ dashboardViewer = viewChild(DashboardViewerComponent, ...(ngDevMode ? [{ debugName: "dashboardViewer" }] : /* istanbul ignore next */ []));
2932
2952
  // Track if we're in the middle of preserving states
2933
2953
  #isPreservingStates = false;
2934
2954
  // Track if component has been initialized
@@ -2938,10 +2958,12 @@ class DashboardComponent {
2938
2958
  this.#destroyRef.onDestroy(() => {
2939
2959
  this.#bridge.unregisterDashboard(this.#store);
2940
2960
  });
2941
- // Initialize from dashboardData
2961
+ // Initialize from dashboardData. Only applies the first emission so that
2962
+ // subsequent re-emissions (e.g. from toSignal() on an HTTP observable)
2963
+ // don't silently overwrite an imperative loadDashboard() call.
2942
2964
  effect(() => {
2943
2965
  const data = this.dashboardData();
2944
- if (data) {
2966
+ if (data && !this.#isInitialized) {
2945
2967
  this.#store.loadDashboard(data);
2946
2968
  // Register with bridge service after dashboard ID is set
2947
2969
  this.#bridge.updateDashboardRegistration(this.#store);
@@ -3056,10 +3078,10 @@ class DashboardComponent {
3056
3078
  this.#isPreservingStates = false;
3057
3079
  }
3058
3080
  }
3059
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DashboardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3060
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: DashboardComponent, isStandalone: true, selector: "ngx-dashboard", inputs: { dashboardData: { classPropertyName: "dashboardData", publicName: "dashboardData", isSignal: true, isRequired: true, transformFunction: null }, editMode: { classPropertyName: "editMode", publicName: "editMode", isSignal: true, isRequired: false, transformFunction: null }, reservedSpace: { classPropertyName: "reservedSpace", publicName: "reservedSpace", isSignal: true, isRequired: false, transformFunction: null }, enableSelection: { classPropertyName: "enableSelection", publicName: "enableSelection", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionComplete: "selectionComplete" }, host: { properties: { "style.--rows": "store.rows()", "style.--columns": "store.columns()", "style.--gutter-size": "store.gutterSize()", "style.--gutters": "store.columns() + 1", "class.is-edit-mode": "editMode()", "style.max-width.px": "viewport.constraints().maxWidth", "style.max-height.px": "viewport.constraints().maxHeight" } }, providers: [DashboardStore, DashboardViewportService], viewQueries: [{ propertyName: "dashboardEditor", first: true, predicate: DashboardEditorComponent, descendants: true, isSignal: true }, { propertyName: "dashboardViewer", first: true, predicate: DashboardViewerComponent, descendants: true, isSignal: true }], usesOnChanges: true, ngImport: i0, template: "<!-- dashboard.component.html -->\n<div class=\"grid-container\">\n @if (editMode()) {\n <!-- Full editor with drag & drop capabilities -->\n <ngx-dashboard-editor\n [rows]=\"store.rows()\"\n [columns]=\"store.columns()\"\n [gutterSize]=\"store.gutterSize()\"\n ></ngx-dashboard-editor>\n } @else {\n <!-- Read-only viewer -->\n <ngx-dashboard-viewer\n [rows]=\"store.rows()\"\n [columns]=\"store.columns()\"\n [gutterSize]=\"store.gutterSize()\"\n [enableSelection]=\"enableSelection()\"\n (selectionComplete)=\"selectionComplete.emit($event)\"\n ></ngx-dashboard-viewer>\n }\n</div>\n", styles: [":host{display:block;container-type:inline-size;box-sizing:border-box;aspect-ratio:var(--columns)/var(--rows);width:100%;height:auto}.grid-container{position:relative;width:100%;height:100%}\n"], dependencies: [{ kind: "component", type: DashboardViewerComponent, selector: "ngx-dashboard-viewer", inputs: ["rows", "columns", "gutterSize", "enableSelection"], outputs: ["selectionComplete"] }, { kind: "component", type: DashboardEditorComponent, selector: "ngx-dashboard-editor", inputs: ["rows", "columns", "gutterSize"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3081
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DashboardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3082
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: DashboardComponent, isStandalone: true, selector: "ngx-dashboard", inputs: { dashboardData: { classPropertyName: "dashboardData", publicName: "dashboardData", isSignal: true, isRequired: true, transformFunction: null }, editMode: { classPropertyName: "editMode", publicName: "editMode", isSignal: true, isRequired: false, transformFunction: null }, reservedSpace: { classPropertyName: "reservedSpace", publicName: "reservedSpace", isSignal: true, isRequired: false, transformFunction: null }, enableSelection: { classPropertyName: "enableSelection", publicName: "enableSelection", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionComplete: "selectionComplete" }, host: { properties: { "style.--rows": "store.rows()", "style.--columns": "store.columns()", "style.--gutter-size": "store.gutterSize()", "style.--gutters": "store.columns() + 1", "class.is-edit-mode": "editMode()", "style.max-width.px": "viewport.constraints().maxWidth", "style.max-height.px": "viewport.constraints().maxHeight" } }, providers: [DashboardStore, DashboardViewportService], viewQueries: [{ propertyName: "dashboardEditor", first: true, predicate: DashboardEditorComponent, descendants: true, isSignal: true }, { propertyName: "dashboardViewer", first: true, predicate: DashboardViewerComponent, descendants: true, isSignal: true }], usesOnChanges: true, ngImport: i0, template: "<!-- dashboard.component.html -->\n<div class=\"grid-container\">\n @if (editMode()) {\n <!-- Full editor with drag & drop capabilities -->\n <ngx-dashboard-editor\n [rows]=\"store.rows()\"\n [columns]=\"store.columns()\"\n [gutterSize]=\"store.gutterSize()\"\n ></ngx-dashboard-editor>\n } @else {\n <!-- Read-only viewer -->\n <ngx-dashboard-viewer\n [rows]=\"store.rows()\"\n [columns]=\"store.columns()\"\n [gutterSize]=\"store.gutterSize()\"\n [enableSelection]=\"enableSelection()\"\n (selectionComplete)=\"selectionComplete.emit($event)\"\n ></ngx-dashboard-viewer>\n }\n</div>\n", styles: [":host{display:block;container-type:inline-size;box-sizing:border-box;aspect-ratio:var(--columns)/var(--rows);width:100%;height:auto}.grid-container{position:relative;width:100%;height:100%}\n"], dependencies: [{ kind: "component", type: DashboardViewerComponent, selector: "ngx-dashboard-viewer", inputs: ["rows", "columns", "gutterSize", "enableSelection"], outputs: ["selectionComplete"] }, { kind: "component", type: DashboardEditorComponent, selector: "ngx-dashboard-editor", inputs: ["rows", "columns", "gutterSize"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3061
3083
  }
3062
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DashboardComponent, decorators: [{
3084
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DashboardComponent, decorators: [{
3063
3085
  type: Component,
3064
3086
  args: [{ selector: 'ngx-dashboard', standalone: true, imports: [DashboardViewerComponent, DashboardEditorComponent], providers: [DashboardStore, DashboardViewportService], changeDetection: ChangeDetectionStrategy.OnPush, host: {
3065
3087
  '[style.--rows]': 'store.rows()',
@@ -3079,14 +3101,14 @@ class WidgetListComponent {
3079
3101
  #renderer = inject(Renderer2);
3080
3102
  #bridge = inject(DashboardBridgeService);
3081
3103
  // Input to track collapsed state for tooltip display
3082
- collapsed = input(false, ...(ngDevMode ? [{ debugName: "collapsed" }] : []));
3083
- activeWidget = signal(null, ...(ngDevMode ? [{ debugName: "activeWidget" }] : []));
3104
+ collapsed = input(false, ...(ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []));
3105
+ activeWidget = signal(null, ...(ngDevMode ? [{ debugName: "activeWidget" }] : /* istanbul ignore next */ []));
3084
3106
  // Get grid cell dimensions from bridge service (uses first available dashboard)
3085
3107
  gridCellDimensions = this.#bridge.availableDimensions;
3086
3108
  widgets = computed(() => this.#service.widgetTypes().map((w) => ({
3087
3109
  ...w.metadata,
3088
3110
  safeSvgIcon: this.#sanitizer.bypassSecurityTrustHtml(w.metadata.svgIcon),
3089
- })), ...(ngDevMode ? [{ debugName: "widgets" }] : []));
3111
+ })), ...(ngDevMode ? [{ debugName: "widgets" }] : /* istanbul ignore next */ []));
3090
3112
  onDragStart(event, widget) {
3091
3113
  if (!event.dataTransfer)
3092
3114
  return;
@@ -3138,10 +3160,10 @@ class WidgetListComponent {
3138
3160
  // Using $localize for the template pattern
3139
3161
  return $localize `:@@ngx.dashboard.widget.list.item.ariaLabel:${widget.name} widget: ${widget.description}`;
3140
3162
  }
3141
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: WidgetListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3142
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: WidgetListComponent, isStandalone: true, selector: "ngx-dashboard-widget-list", inputs: { collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<!-- widget-list.component.html -->\n<div\n class=\"widget-list\"\n role=\"list\"\n i18n-aria-label=\"@@ngx.dashboard.widget.list.available\"\n aria-label=\"Available widgets\"\n>\n @for (widget of widgets(); track widget.widgetTypeid) {\n <div\n class=\"widget-list-item\"\n [class.active]=\"activeWidget() === widget.widgetTypeid\"\n draggable=\"true\"\n (dragstart)=\"onDragStart($event, widget)\"\n (dragend)=\"onDragEnd()\"\n role=\"listitem\"\n [attr.aria-grabbed]=\"activeWidget() === widget.widgetTypeid\"\n [attr.aria-label]=\"getWidgetAriaLabel(widget)\"\n [matTooltip]=\"widget.description\"\n [matTooltipDisabled]=\"!collapsed()\"\n matTooltipPosition=\"right\"\n tabindex=\"0\"\n >\n <div class=\"icon\" [innerHTML]=\"widget.safeSvgIcon\" aria-hidden=\"true\"></div>\n <div class=\"content\">\n <strong>{{ widget.name }}</strong>\n <small>{{ widget.description }}</small>\n </div>\n </div>\n }\n</div>\n", styles: [":host{background-color:var(--mat-sys-surface-container, #f5f5f5);container-type:inline-size}.widget-list{display:flex;flex-direction:column;gap:var(--mat-sys-spacing-2, 8px)}@container (max-width: 200px){.widget-list{gap:var(--mat-sys-spacing-1, 4px)}}@container (min-width: 400px){.widget-list{gap:var(--mat-sys-spacing-3, 12px)}}.widget-list-item{display:flex;align-items:start;gap:var(--mat-sys-spacing-3, 12px);background-color:var(--mat-sys-surface, #ffffff);border:1px solid var(--mat-sys-outline-variant, #c7c7c7);padding:var(--mat-sys-spacing-3, 12px);border-radius:var(--mat-sys-corner-small, 4px);cursor:grab;transition:background-color var(--mat-sys-motion-duration-medium2, .3s) var(--mat-sys-motion-easing-standard, ease-in-out),border-color var(--mat-sys-motion-duration-medium2, .3s) var(--mat-sys-motion-easing-standard, ease-in-out),box-shadow var(--mat-sys-motion-duration-medium2, .3s) var(--mat-sys-motion-easing-standard, ease-in-out);box-shadow:var(--mat-sys-elevation-level1, 0 1px 2px rgba(0, 0, 0, .05))}@container (max-width: 200px){.widget-list-item{padding:var(--mat-sys-spacing-2, 8px);gap:var(--mat-sys-spacing-2, 8px)}}@container (min-width: 400px){.widget-list-item{padding:var(--mat-sys-spacing-4, 16px);gap:var(--mat-sys-spacing-4, 16px)}}.widget-list-item .icon{width:clamp(20px,4vw,28px);height:clamp(20px,4vw,28px);flex-shrink:0;color:var(--mat-sys-on-surface-variant, #5f5f5f);transition:color var(--mat-sys-motion-duration-short2, .15s) var(--mat-sys-motion-easing-standard, ease-in-out)}.widget-list-item .icon ::ng-deep svg{width:100%;height:100%;display:block}.widget-list-item .content{display:flex;flex-direction:column;line-height:1.2;color:var(--mat-sys-on-surface, #1c1c1c);flex:1;min-width:0}.widget-list-item .content strong{color:var(--mat-sys-on-surface, #1c1c1c);font-weight:500;font-size:clamp(.875rem,2.5vw,1rem);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.widget-list-item .content small{color:var(--mat-sys-on-surface-variant, #5f5f5f);font-size:clamp(.75rem,2vw,.875rem);margin-top:var(--mat-sys-spacing-1, 4px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.widget-list-item:hover{background-color:var(--mat-sys-surface-container-low, #f0f0f0);box-shadow:var(--mat-sys-elevation-level2, 0 2px 4px rgba(0, 0, 0, .1))}.widget-list-item:hover .icon{color:var(--mat-sys-on-surface, #1c1c1c)}.widget-list-item:active{cursor:grabbing;background-color:var(--mat-sys-surface-container, #f5f5f5)}.widget-list-item.active{background-color:var(--mat-sys-primary-container, #e6f2ff);border-color:var(--mat-sys-primary, #1976d2);color:var(--mat-sys-on-primary-container, #004a99)}.widget-list-item.active .content strong{color:var(--mat-sys-on-primary-container, #004a99)}.widget-list-item.active .content small{color:var(--mat-sys-on-primary-container, #004a99);opacity:.8}.widget-list-item.active .icon{color:var(--mat-sys-on-primary-container, #004a99)}.drag-ghost{position:absolute;top:0;left:0;z-index:9999;margin:0;pointer-events:none;display:flex;align-items:center;justify-content:center;box-sizing:border-box;background-color:var(--mat-sys-surface, #ffffff);border:1px solid var(--mat-sys-outline-variant, #c7c7c7);border-radius:var(--mat-sys-corner-small, 4px);box-shadow:var(--mat-sys-elevation-level3, 0 4px 6px rgba(0, 0, 0, .15));opacity:.8}.drag-ghost .icon{display:flex;align-items:center;justify-content:center;color:var(--mat-sys-on-surface-variant, #5f5f5f);opacity:.6}.drag-ghost .icon ::ng-deep svg{display:block}\n"], dependencies: [{ kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3163
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: WidgetListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3164
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: WidgetListComponent, isStandalone: true, selector: "ngx-dashboard-widget-list", inputs: { collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<!-- widget-list.component.html -->\n<div\n class=\"widget-list\"\n role=\"list\"\n i18n-aria-label=\"@@ngx.dashboard.widget.list.available\"\n aria-label=\"Available widgets\"\n>\n @for (widget of widgets(); track widget.widgetTypeid) {\n <div\n class=\"widget-list-item\"\n [class.active]=\"activeWidget() === widget.widgetTypeid\"\n draggable=\"true\"\n (dragstart)=\"onDragStart($event, widget)\"\n (dragend)=\"onDragEnd()\"\n role=\"listitem\"\n [attr.aria-grabbed]=\"activeWidget() === widget.widgetTypeid\"\n [attr.aria-label]=\"getWidgetAriaLabel(widget)\"\n [matTooltip]=\"widget.description\"\n [matTooltipDisabled]=\"!collapsed()\"\n matTooltipPosition=\"right\"\n tabindex=\"0\"\n >\n <div class=\"icon\" [innerHTML]=\"widget.safeSvgIcon\" aria-hidden=\"true\"></div>\n <div class=\"content\">\n <strong>{{ widget.name }}</strong>\n <small>{{ widget.description }}</small>\n </div>\n </div>\n }\n</div>\n", styles: [":host{background-color:var(--mat-sys-surface-container, #f5f5f5);container-type:inline-size}.widget-list{display:flex;flex-direction:column;gap:var(--mat-sys-spacing-2, 8px)}@container (max-width: 200px){.widget-list{gap:var(--mat-sys-spacing-1, 4px)}}@container (min-width: 400px){.widget-list{gap:var(--mat-sys-spacing-3, 12px)}}.widget-list-item{display:flex;align-items:start;gap:var(--mat-sys-spacing-3, 12px);background-color:var(--mat-sys-surface, #ffffff);border:1px solid var(--mat-sys-outline-variant, #c7c7c7);padding:var(--mat-sys-spacing-3, 12px);border-radius:var(--mat-sys-corner-small, 4px);cursor:grab;transition:background-color var(--mat-sys-motion-duration-medium2, .3s) var(--mat-sys-motion-easing-standard, ease-in-out),border-color var(--mat-sys-motion-duration-medium2, .3s) var(--mat-sys-motion-easing-standard, ease-in-out),box-shadow var(--mat-sys-motion-duration-medium2, .3s) var(--mat-sys-motion-easing-standard, ease-in-out);box-shadow:var(--mat-sys-elevation-level1, 0 1px 2px rgba(0, 0, 0, .05))}@container (max-width: 200px){.widget-list-item{padding:var(--mat-sys-spacing-2, 8px);gap:var(--mat-sys-spacing-2, 8px)}}@container (min-width: 400px){.widget-list-item{padding:var(--mat-sys-spacing-4, 16px);gap:var(--mat-sys-spacing-4, 16px)}}.widget-list-item .icon{width:clamp(20px,4vw,28px);height:clamp(20px,4vw,28px);flex-shrink:0;color:var(--mat-sys-on-surface-variant, #5f5f5f);transition:color var(--mat-sys-motion-duration-short2, .15s) var(--mat-sys-motion-easing-standard, ease-in-out)}.widget-list-item .icon ::ng-deep svg{width:100%;height:100%;display:block}.widget-list-item .content{display:flex;flex-direction:column;line-height:1.2;color:var(--mat-sys-on-surface, #1c1c1c);flex:1;min-width:0}.widget-list-item .content strong{color:var(--mat-sys-on-surface, #1c1c1c);font-weight:500;font-size:clamp(.875rem,2.5vw,1rem);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.widget-list-item .content small{color:var(--mat-sys-on-surface-variant, #5f5f5f);font-size:clamp(.75rem,2vw,.875rem);margin-top:var(--mat-sys-spacing-1, 4px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.widget-list-item:hover{background-color:var(--mat-sys-surface-container-low, #f0f0f0);box-shadow:var(--mat-sys-elevation-level2, 0 2px 4px rgba(0, 0, 0, .1))}.widget-list-item:hover .icon{color:var(--mat-sys-on-surface, #1c1c1c)}.widget-list-item:active{cursor:grabbing;background-color:var(--mat-sys-surface-container, #f5f5f5)}.widget-list-item.active{background-color:var(--mat-sys-primary-container, #e6f2ff);border-color:var(--mat-sys-primary, #1976d2);color:var(--mat-sys-on-primary-container, #004a99)}.widget-list-item.active .content strong{color:var(--mat-sys-on-primary-container, #004a99)}.widget-list-item.active .content small{color:var(--mat-sys-on-primary-container, #004a99);opacity:.8}.widget-list-item.active .icon{color:var(--mat-sys-on-primary-container, #004a99)}.drag-ghost{position:absolute;top:0;left:0;z-index:9999;margin:0;pointer-events:none;display:flex;align-items:center;justify-content:center;box-sizing:border-box;background-color:var(--mat-sys-surface, #ffffff);border:1px solid var(--mat-sys-outline-variant, #c7c7c7);border-radius:var(--mat-sys-corner-small, 4px);box-shadow:var(--mat-sys-elevation-level3, 0 4px 6px rgba(0, 0, 0, .15));opacity:.8}.drag-ghost .icon{display:flex;align-items:center;justify-content:center;color:var(--mat-sys-on-surface-variant, #5f5f5f);opacity:.6}.drag-ghost .icon ::ng-deep svg{display:block}\n"], dependencies: [{ kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3143
3165
  }
3144
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: WidgetListComponent, decorators: [{
3166
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: WidgetListComponent, decorators: [{
3145
3167
  type: Component,
3146
3168
  args: [{ selector: 'ngx-dashboard-widget-list', standalone: true, imports: [MatTooltipModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- widget-list.component.html -->\n<div\n class=\"widget-list\"\n role=\"list\"\n i18n-aria-label=\"@@ngx.dashboard.widget.list.available\"\n aria-label=\"Available widgets\"\n>\n @for (widget of widgets(); track widget.widgetTypeid) {\n <div\n class=\"widget-list-item\"\n [class.active]=\"activeWidget() === widget.widgetTypeid\"\n draggable=\"true\"\n (dragstart)=\"onDragStart($event, widget)\"\n (dragend)=\"onDragEnd()\"\n role=\"listitem\"\n [attr.aria-grabbed]=\"activeWidget() === widget.widgetTypeid\"\n [attr.aria-label]=\"getWidgetAriaLabel(widget)\"\n [matTooltip]=\"widget.description\"\n [matTooltipDisabled]=\"!collapsed()\"\n matTooltipPosition=\"right\"\n tabindex=\"0\"\n >\n <div class=\"icon\" [innerHTML]=\"widget.safeSvgIcon\" aria-hidden=\"true\"></div>\n <div class=\"content\">\n <strong>{{ widget.name }}</strong>\n <small>{{ widget.description }}</small>\n </div>\n </div>\n }\n</div>\n", styles: [":host{background-color:var(--mat-sys-surface-container, #f5f5f5);container-type:inline-size}.widget-list{display:flex;flex-direction:column;gap:var(--mat-sys-spacing-2, 8px)}@container (max-width: 200px){.widget-list{gap:var(--mat-sys-spacing-1, 4px)}}@container (min-width: 400px){.widget-list{gap:var(--mat-sys-spacing-3, 12px)}}.widget-list-item{display:flex;align-items:start;gap:var(--mat-sys-spacing-3, 12px);background-color:var(--mat-sys-surface, #ffffff);border:1px solid var(--mat-sys-outline-variant, #c7c7c7);padding:var(--mat-sys-spacing-3, 12px);border-radius:var(--mat-sys-corner-small, 4px);cursor:grab;transition:background-color var(--mat-sys-motion-duration-medium2, .3s) var(--mat-sys-motion-easing-standard, ease-in-out),border-color var(--mat-sys-motion-duration-medium2, .3s) var(--mat-sys-motion-easing-standard, ease-in-out),box-shadow var(--mat-sys-motion-duration-medium2, .3s) var(--mat-sys-motion-easing-standard, ease-in-out);box-shadow:var(--mat-sys-elevation-level1, 0 1px 2px rgba(0, 0, 0, .05))}@container (max-width: 200px){.widget-list-item{padding:var(--mat-sys-spacing-2, 8px);gap:var(--mat-sys-spacing-2, 8px)}}@container (min-width: 400px){.widget-list-item{padding:var(--mat-sys-spacing-4, 16px);gap:var(--mat-sys-spacing-4, 16px)}}.widget-list-item .icon{width:clamp(20px,4vw,28px);height:clamp(20px,4vw,28px);flex-shrink:0;color:var(--mat-sys-on-surface-variant, #5f5f5f);transition:color var(--mat-sys-motion-duration-short2, .15s) var(--mat-sys-motion-easing-standard, ease-in-out)}.widget-list-item .icon ::ng-deep svg{width:100%;height:100%;display:block}.widget-list-item .content{display:flex;flex-direction:column;line-height:1.2;color:var(--mat-sys-on-surface, #1c1c1c);flex:1;min-width:0}.widget-list-item .content strong{color:var(--mat-sys-on-surface, #1c1c1c);font-weight:500;font-size:clamp(.875rem,2.5vw,1rem);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.widget-list-item .content small{color:var(--mat-sys-on-surface-variant, #5f5f5f);font-size:clamp(.75rem,2vw,.875rem);margin-top:var(--mat-sys-spacing-1, 4px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.widget-list-item:hover{background-color:var(--mat-sys-surface-container-low, #f0f0f0);box-shadow:var(--mat-sys-elevation-level2, 0 2px 4px rgba(0, 0, 0, .1))}.widget-list-item:hover .icon{color:var(--mat-sys-on-surface, #1c1c1c)}.widget-list-item:active{cursor:grabbing;background-color:var(--mat-sys-surface-container, #f5f5f5)}.widget-list-item.active{background-color:var(--mat-sys-primary-container, #e6f2ff);border-color:var(--mat-sys-primary, #1976d2);color:var(--mat-sys-on-primary-container, #004a99)}.widget-list-item.active .content strong{color:var(--mat-sys-on-primary-container, #004a99)}.widget-list-item.active .content small{color:var(--mat-sys-on-primary-container, #004a99);opacity:.8}.widget-list-item.active .icon{color:var(--mat-sys-on-primary-container, #004a99)}.drag-ghost{position:absolute;top:0;left:0;z-index:9999;margin:0;pointer-events:none;display:flex;align-items:center;justify-content:center;box-sizing:border-box;background-color:var(--mat-sys-surface, #ffffff);border:1px solid var(--mat-sys-outline-variant, #c7c7c7);border-radius:var(--mat-sys-corner-small, 4px);box-shadow:var(--mat-sys-elevation-level3, 0 4px 6px rgba(0, 0, 0, .15));opacity:.8}.drag-ghost .icon{display:flex;align-items:center;justify-content:center;color:var(--mat-sys-on-surface-variant, #5f5f5f);opacity:.6}.drag-ghost .icon ::ng-deep svg{display:block}\n"] }]
3147
3169
  }], propDecorators: { collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }] } });