@dragonworks/ngx-dashboard 20.1.6 → 20.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -218,8 +218,8 @@ function createFactoryFromComponent(component) {
218
218
  class UnknownWidgetComponent {
219
219
  static metadata = {
220
220
  widgetTypeid: '__internal/unknown-widget',
221
- name: 'Unknown Widget',
222
- description: 'Fallback widget for unknown widget types',
221
+ name: $localize `:@@ngx.dashboard.unknown.widget.name:Unknown Widget`,
222
+ description: $localize `:@@ngx.dashboard.unknown.widget.description:Fallback widget for unknown widget types`,
223
223
  svgIcon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="currentColor"><path d="M480-280q17 0 28.5-11.5T520-320q0-17-11.5-28.5T480-360q-17 0-28.5 11.5T440-320q0 17 11.5 28.5T480-280Zm-40-160h80v-240h-80v240Zm40 360q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Z"/></svg>',
224
224
  };
225
225
  state = signal({
@@ -904,40 +904,72 @@ class CellSettingsDialogComponent {
904
904
  save() {
905
905
  const newData = {
906
906
  ...this.data,
907
- flat: this.selectedMode === 'flat'
907
+ flat: this.selectedMode === 'flat',
908
908
  };
909
909
  this.dialogRef.close(newData);
910
910
  }
911
911
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: CellSettingsDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
912
912
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.1", type: CellSettingsDialogComponent, isStandalone: true, selector: "lib-cell-settings-dialog", ngImport: i0, template: `
913
- <h2 mat-dialog-title>Cell Display Settings</h2>
913
+ <h2 mat-dialog-title i18n="@@ngx.dashboard.cell.settings.title">
914
+ Cell Display Settings
915
+ </h2>
914
916
  <mat-dialog-content>
915
- <p class="cell-info">Cell ID: <strong>{{ data.id }}</strong></p>
916
-
917
+ <p class="cell-info" i18n="@@ngx.dashboard.cell.settings.cellId">
918
+ Cell ID: <strong>{{ data.id }}</strong>
919
+ </p>
920
+
917
921
  <div class="radio-group">
918
922
  <mat-radio-group [(ngModel)]="selectedMode" name="displayMode">
919
923
  <mat-radio-button value="normal">
920
924
  <div class="radio-option">
921
- <div class="option-title">Normal</div>
922
- <div class="option-description">Standard cell display with full content visibility</div>
925
+ <div
926
+ class="option-title"
927
+ i18n="@@ngx.dashboard.cell.settings.mode.normal"
928
+ >
929
+ Normal
930
+ </div>
931
+ <div
932
+ class="option-description"
933
+ i18n="@@ngx.dashboard.cell.settings.mode.normal.description"
934
+ >
935
+ Standard cell display with full content visibility
936
+ </div>
923
937
  </div>
924
938
  </mat-radio-button>
925
-
939
+
926
940
  <mat-radio-button value="flat">
927
941
  <div class="radio-option">
928
- <div class="option-title">Flat</div>
929
- <div class="option-description">Simplified display with reduced visual emphasis</div>
942
+ <div
943
+ class="option-title"
944
+ i18n="@@ngx.dashboard.cell.settings.mode.flat"
945
+ >
946
+ Flat
947
+ </div>
948
+ <div
949
+ class="option-description"
950
+ i18n="@@ngx.dashboard.cell.settings.mode.flat.description"
951
+ >
952
+ Simplified display with reduced visual emphasis
953
+ </div>
930
954
  </div>
931
955
  </mat-radio-button>
932
956
  </mat-radio-group>
933
957
  </div>
934
958
  </mat-dialog-content>
935
959
  <mat-dialog-actions align="end">
936
- <button mat-button (click)="onCancel()">Cancel</button>
937
- <button
938
- mat-flat-button
960
+ <button
961
+ mat-button
962
+ (click)="onCancel()"
963
+ i18n="@@ngx.dashboard.common.cancel"
964
+ >
965
+ Cancel
966
+ </button>
967
+ <button
968
+ mat-flat-button
939
969
  (click)="save()"
940
- [disabled]="selectedMode === currentMode">
970
+ [disabled]="selectedMode === currentMode"
971
+ i18n="@@ngx.dashboard.common.apply"
972
+ >
941
973
  Apply
942
974
  </button>
943
975
  </mat-dialog-actions>
@@ -952,34 +984,66 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
952
984
  MatButtonModule,
953
985
  MatRadioModule,
954
986
  ], template: `
955
- <h2 mat-dialog-title>Cell Display Settings</h2>
987
+ <h2 mat-dialog-title i18n="@@ngx.dashboard.cell.settings.title">
988
+ Cell Display Settings
989
+ </h2>
956
990
  <mat-dialog-content>
957
- <p class="cell-info">Cell ID: <strong>{{ data.id }}</strong></p>
958
-
991
+ <p class="cell-info" i18n="@@ngx.dashboard.cell.settings.cellId">
992
+ Cell ID: <strong>{{ data.id }}</strong>
993
+ </p>
994
+
959
995
  <div class="radio-group">
960
996
  <mat-radio-group [(ngModel)]="selectedMode" name="displayMode">
961
997
  <mat-radio-button value="normal">
962
998
  <div class="radio-option">
963
- <div class="option-title">Normal</div>
964
- <div class="option-description">Standard cell display with full content visibility</div>
999
+ <div
1000
+ class="option-title"
1001
+ i18n="@@ngx.dashboard.cell.settings.mode.normal"
1002
+ >
1003
+ Normal
1004
+ </div>
1005
+ <div
1006
+ class="option-description"
1007
+ i18n="@@ngx.dashboard.cell.settings.mode.normal.description"
1008
+ >
1009
+ Standard cell display with full content visibility
1010
+ </div>
965
1011
  </div>
966
1012
  </mat-radio-button>
967
-
1013
+
968
1014
  <mat-radio-button value="flat">
969
1015
  <div class="radio-option">
970
- <div class="option-title">Flat</div>
971
- <div class="option-description">Simplified display with reduced visual emphasis</div>
1016
+ <div
1017
+ class="option-title"
1018
+ i18n="@@ngx.dashboard.cell.settings.mode.flat"
1019
+ >
1020
+ Flat
1021
+ </div>
1022
+ <div
1023
+ class="option-description"
1024
+ i18n="@@ngx.dashboard.cell.settings.mode.flat.description"
1025
+ >
1026
+ Simplified display with reduced visual emphasis
1027
+ </div>
972
1028
  </div>
973
1029
  </mat-radio-button>
974
1030
  </mat-radio-group>
975
1031
  </div>
976
1032
  </mat-dialog-content>
977
1033
  <mat-dialog-actions align="end">
978
- <button mat-button (click)="onCancel()">Cancel</button>
979
- <button
980
- mat-flat-button
1034
+ <button
1035
+ mat-button
1036
+ (click)="onCancel()"
1037
+ i18n="@@ngx.dashboard.common.cancel"
1038
+ >
1039
+ Cancel
1040
+ </button>
1041
+ <button
1042
+ mat-flat-button
981
1043
  (click)="save()"
982
- [disabled]="selectedMode === currentMode">
1044
+ [disabled]="selectedMode === currentMode"
1045
+ i18n="@@ngx.dashboard.common.apply"
1046
+ >
983
1047
  Apply
984
1048
  </button>
985
1049
  </mat-dialog-actions>
@@ -1165,7 +1229,8 @@ class CellComponent {
1165
1229
  };
1166
1230
  const content = { kind: 'cell', content: cell };
1167
1231
  this.dragStart.emit(content);
1168
- this.isDragging.set(true);
1232
+ event.dataTransfer.setData('text/plain', 'cell'); // helps firefox
1233
+ requestAnimationFrame(() => this.isDragging.set(true)); // defer to next frame to avoid immediate dragend event in some instances
1169
1234
  }
1170
1235
  onDragEnd( /*_: DragEvent*/) {
1171
1236
  this.isDragging.set(false);
@@ -1183,19 +1248,19 @@ class CellComponent {
1183
1248
  event.stopPropagation();
1184
1249
  const items = [
1185
1250
  {
1186
- label: 'Edit Widget',
1251
+ label: $localize `:@@ngx.dashboard.cell.menu.edit:Edit Widget`,
1187
1252
  icon: 'edit',
1188
1253
  action: () => this.onEdit(),
1189
1254
  disabled: !this.canEdit(),
1190
1255
  },
1191
1256
  {
1192
- label: 'Settings',
1257
+ label: $localize `:@@ngx.dashboard.cell.menu.settings:Settings`,
1193
1258
  icon: 'settings',
1194
1259
  action: () => this.onSettings(),
1195
1260
  },
1196
1261
  { divider: true },
1197
1262
  {
1198
- label: 'Delete',
1263
+ label: $localize `:@@ngx.dashboard.cell.menu.delete:Delete`,
1199
1264
  icon: 'delete',
1200
1265
  action: () => this.onDelete(),
1201
1266
  },
@@ -1267,12 +1332,20 @@ class CellComponent {
1267
1332
  if (direction === 'horizontal') {
1268
1333
  const deltaX = event.clientX - startPos.x;
1269
1334
  const deltaSpan = Math.round(deltaX / cellSize.width);
1270
- this.resizeMove.emit({ cellId: this.cellId(), direction, delta: deltaSpan });
1335
+ this.resizeMove.emit({
1336
+ cellId: this.cellId(),
1337
+ direction,
1338
+ delta: deltaSpan,
1339
+ });
1271
1340
  }
1272
1341
  else {
1273
1342
  const deltaY = event.clientY - startPos.y;
1274
1343
  const deltaSpan = Math.round(deltaY / cellSize.height);
1275
- this.resizeMove.emit({ cellId: this.cellId(), direction, delta: deltaSpan });
1344
+ this.resizeMove.emit({
1345
+ cellId: this.cellId(),
1346
+ direction,
1347
+ delta: deltaSpan,
1348
+ });
1276
1349
  }
1277
1350
  }
1278
1351
  /**
@@ -1304,7 +1377,7 @@ class CellComponent {
1304
1377
  return this.widgetState();
1305
1378
  }
1306
1379
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: CellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1307
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.1", 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 -->\r\n<div\r\n class=\"cell\"\r\n [class.is-resizing]=\"isResizing()\"\r\n [class.flat]=\"flat() === true\"\r\n [draggable]=\"draggable()\"\r\n (dragstart)=\"onDragStart($event)\"\r\n (dragend)=\"onDragEnd()\"\r\n (contextmenu)=\"onContextMenu($event)\"\r\n>\r\n <div class=\"content-area\">\r\n <ng-template #container></ng-template>\r\n </div>\r\n @if (isEditMode() && !isDragging()) {\r\n <!-- Right resize handle -->\r\n <div\r\n class=\"resize-handle resize-handle--right\"\r\n (mousedown)=\"onResizeStart($event, 'horizontal')\"\r\n >\r\n <div class=\"resize-handle-line\"></div>\r\n </div>\r\n <!-- Bottom resize handle -->\r\n <div\r\n class=\"resize-handle resize-handle--bottom\"\r\n (mousedown)=\"onResizeStart($event, 'vertical')\"\r\n >\r\n <div class=\"resize-handle-line\"></div>\r\n </div>\r\n }\r\n</div>\r\n\r\n@if (isResizing()) {\r\n<div class=\"resize-preview\">\r\n {{ resizeData()?.previewColSpan ?? colSpan() }} \u00D7\r\n {{ resizeData()?.previewRowSpan ?? rowSpan() }}\r\n</div>\r\n}\r\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"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1380
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.1", 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 -->\r\n<div\r\n class=\"cell\"\r\n [class.is-resizing]=\"isResizing()\"\r\n [class.flat]=\"flat() === true\"\r\n [draggable]=\"draggable()\"\r\n (dragstart)=\"onDragStart($event)\"\r\n (dragend)=\"onDragEnd()\"\r\n (contextmenu)=\"onContextMenu($event)\"\r\n>\r\n <div class=\"content-area\">\r\n <ng-template #container></ng-template>\r\n </div>\r\n @if (isEditMode() && !isDragging()) {\r\n <!-- Right resize handle -->\r\n <div\r\n class=\"resize-handle resize-handle--right\"\r\n (mousedown)=\"onResizeStart($event, 'horizontal')\"\r\n >\r\n <div class=\"resize-handle-line\"></div>\r\n </div>\r\n <!-- Bottom resize handle -->\r\n <div\r\n class=\"resize-handle resize-handle--bottom\"\r\n (mousedown)=\"onResizeStart($event, 'vertical')\"\r\n >\r\n <div class=\"resize-handle-line\"></div>\r\n </div>\r\n }\r\n</div>\r\n\r\n@if (isResizing()) {\r\n<div class=\"resize-preview\" i18n=\"@@ngx.dashboard.cell.resize.dimensions\">\r\n {{ resizeData()?.previewColSpan ?? colSpan() }} \u00D7\r\n {{ resizeData()?.previewRowSpan ?? rowSpan() }}\r\n</div>\r\n}\r\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"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1308
1381
  }
1309
1382
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: CellComponent, decorators: [{
1310
1383
  type: Component,
@@ -1314,7 +1387,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
1314
1387
  '[class.is-dragging]': 'isDragging()',
1315
1388
  '[class.drag-active]': 'isDragActive()',
1316
1389
  '[class.flat]': 'flat() === true',
1317
- }, template: "<!-- cell.component.html -->\r\n<div\r\n class=\"cell\"\r\n [class.is-resizing]=\"isResizing()\"\r\n [class.flat]=\"flat() === true\"\r\n [draggable]=\"draggable()\"\r\n (dragstart)=\"onDragStart($event)\"\r\n (dragend)=\"onDragEnd()\"\r\n (contextmenu)=\"onContextMenu($event)\"\r\n>\r\n <div class=\"content-area\">\r\n <ng-template #container></ng-template>\r\n </div>\r\n @if (isEditMode() && !isDragging()) {\r\n <!-- Right resize handle -->\r\n <div\r\n class=\"resize-handle resize-handle--right\"\r\n (mousedown)=\"onResizeStart($event, 'horizontal')\"\r\n >\r\n <div class=\"resize-handle-line\"></div>\r\n </div>\r\n <!-- Bottom resize handle -->\r\n <div\r\n class=\"resize-handle resize-handle--bottom\"\r\n (mousedown)=\"onResizeStart($event, 'vertical')\"\r\n >\r\n <div class=\"resize-handle-line\"></div>\r\n </div>\r\n }\r\n</div>\r\n\r\n@if (isResizing()) {\r\n<div class=\"resize-preview\">\r\n {{ resizeData()?.previewColSpan ?? colSpan() }} \u00D7\r\n {{ resizeData()?.previewRowSpan ?? rowSpan() }}\r\n</div>\r\n}\r\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"] }]
1390
+ }, template: "<!-- cell.component.html -->\r\n<div\r\n class=\"cell\"\r\n [class.is-resizing]=\"isResizing()\"\r\n [class.flat]=\"flat() === true\"\r\n [draggable]=\"draggable()\"\r\n (dragstart)=\"onDragStart($event)\"\r\n (dragend)=\"onDragEnd()\"\r\n (contextmenu)=\"onContextMenu($event)\"\r\n>\r\n <div class=\"content-area\">\r\n <ng-template #container></ng-template>\r\n </div>\r\n @if (isEditMode() && !isDragging()) {\r\n <!-- Right resize handle -->\r\n <div\r\n class=\"resize-handle resize-handle--right\"\r\n (mousedown)=\"onResizeStart($event, 'horizontal')\"\r\n >\r\n <div class=\"resize-handle-line\"></div>\r\n </div>\r\n <!-- Bottom resize handle -->\r\n <div\r\n class=\"resize-handle resize-handle--bottom\"\r\n (mousedown)=\"onResizeStart($event, 'vertical')\"\r\n >\r\n <div class=\"resize-handle-line\"></div>\r\n </div>\r\n }\r\n</div>\r\n\r\n@if (isResizing()) {\r\n<div class=\"resize-preview\" i18n=\"@@ngx.dashboard.cell.resize.dimensions\">\r\n {{ resizeData()?.previewColSpan ?? colSpan() }} \u00D7\r\n {{ resizeData()?.previewRowSpan ?? rowSpan() }}\r\n</div>\r\n}\r\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"] }]
1318
1391
  }], ctorParameters: () => [] });
1319
1392
 
1320
1393
  class DashboardViewerComponent {
@@ -2229,12 +2302,16 @@ class WidgetListComponent {
2229
2302
  }
2230
2303
  return el;
2231
2304
  }
2305
+ getWidgetAriaLabel(widget) {
2306
+ // Using $localize for the template pattern
2307
+ return $localize `:@@ngx.dashboard.widget.list.item.ariaLabel:${widget.name} widget: ${widget.description}`;
2308
+ }
2232
2309
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: WidgetListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2233
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.1", type: WidgetListComponent, isStandalone: true, selector: "ngx-dashboard-widget-list", ngImport: i0, template: "<!-- widget-list.component.html -->\r\n<div class=\"widget-list\" role=\"list\" aria-label=\"Available widgets\">\r\n @for (widget of widgets(); track widget.widgetTypeid) {\r\n <div\r\n class=\"widget-list-item\"\r\n [class.active]=\"activeWidget() === widget.widgetTypeid\"\r\n draggable=\"true\"\r\n (dragstart)=\"onDragStart($event, widget)\"\r\n (dragend)=\"onDragEnd()\"\r\n role=\"listitem\"\r\n [attr.aria-grabbed]=\"activeWidget() === widget.widgetTypeid\"\r\n [attr.aria-label]=\"widget.name + ' widget: ' + widget.description\"\r\n tabindex=\"0\"\r\n >\r\n <div class=\"icon\" [innerHTML]=\"widget.safeSvgIcon\" aria-hidden=\"true\"></div>\r\n <div class=\"content\">\r\n <strong>{{ widget.name }}</strong>\r\n <small>{{ widget.description }}</small>\r\n </div>\r\n </div>\r\n }\r\n</div>", 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"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2310
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.1", type: WidgetListComponent, isStandalone: true, selector: "ngx-dashboard-widget-list", ngImport: i0, template: "<!-- widget-list.component.html -->\r\n<div\r\n class=\"widget-list\"\r\n role=\"list\"\r\n i18n-aria-label=\"@@ngx.dashboard.widget.list.available\"\r\n aria-label=\"Available widgets\"\r\n>\r\n @for (widget of widgets(); track widget.widgetTypeid) {\r\n <div\r\n class=\"widget-list-item\"\r\n [class.active]=\"activeWidget() === widget.widgetTypeid\"\r\n draggable=\"true\"\r\n (dragstart)=\"onDragStart($event, widget)\"\r\n (dragend)=\"onDragEnd()\"\r\n role=\"listitem\"\r\n [attr.aria-grabbed]=\"activeWidget() === widget.widgetTypeid\"\r\n [attr.aria-label]=\"getWidgetAriaLabel(widget)\"\r\n tabindex=\"0\"\r\n >\r\n <div class=\"icon\" [innerHTML]=\"widget.safeSvgIcon\" aria-hidden=\"true\"></div>\r\n <div class=\"content\">\r\n <strong>{{ widget.name }}</strong>\r\n <small>{{ widget.description }}</small>\r\n </div>\r\n </div>\r\n }\r\n</div>\r\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"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2234
2311
  }
2235
2312
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: WidgetListComponent, decorators: [{
2236
2313
  type: Component,
2237
- args: [{ selector: 'ngx-dashboard-widget-list', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- widget-list.component.html -->\r\n<div class=\"widget-list\" role=\"list\" aria-label=\"Available widgets\">\r\n @for (widget of widgets(); track widget.widgetTypeid) {\r\n <div\r\n class=\"widget-list-item\"\r\n [class.active]=\"activeWidget() === widget.widgetTypeid\"\r\n draggable=\"true\"\r\n (dragstart)=\"onDragStart($event, widget)\"\r\n (dragend)=\"onDragEnd()\"\r\n role=\"listitem\"\r\n [attr.aria-grabbed]=\"activeWidget() === widget.widgetTypeid\"\r\n [attr.aria-label]=\"widget.name + ' widget: ' + widget.description\"\r\n tabindex=\"0\"\r\n >\r\n <div class=\"icon\" [innerHTML]=\"widget.safeSvgIcon\" aria-hidden=\"true\"></div>\r\n <div class=\"content\">\r\n <strong>{{ widget.name }}</strong>\r\n <small>{{ widget.description }}</small>\r\n </div>\r\n </div>\r\n }\r\n</div>", 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"] }]
2314
+ args: [{ selector: 'ngx-dashboard-widget-list', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- widget-list.component.html -->\r\n<div\r\n class=\"widget-list\"\r\n role=\"list\"\r\n i18n-aria-label=\"@@ngx.dashboard.widget.list.available\"\r\n aria-label=\"Available widgets\"\r\n>\r\n @for (widget of widgets(); track widget.widgetTypeid) {\r\n <div\r\n class=\"widget-list-item\"\r\n [class.active]=\"activeWidget() === widget.widgetTypeid\"\r\n draggable=\"true\"\r\n (dragstart)=\"onDragStart($event, widget)\"\r\n (dragend)=\"onDragEnd()\"\r\n role=\"listitem\"\r\n [attr.aria-grabbed]=\"activeWidget() === widget.widgetTypeid\"\r\n [attr.aria-label]=\"getWidgetAriaLabel(widget)\"\r\n tabindex=\"0\"\r\n >\r\n <div class=\"icon\" [innerHTML]=\"widget.safeSvgIcon\" aria-hidden=\"true\"></div>\r\n <div class=\"content\">\r\n <strong>{{ widget.name }}</strong>\r\n <small>{{ widget.description }}</small>\r\n </div>\r\n </div>\r\n }\r\n</div>\r\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"] }]
2238
2315
  }] });
2239
2316
 
2240
2317
  /*