ngx-mat-table-multi-sort 19.6.0 → 20.0.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.
package/README.md CHANGED
@@ -14,7 +14,7 @@ An Angular library that adds multi-sort capability to the Angular Material table
14
14
  - Extend the Angular Material Table to support multiple sorting
15
15
  - Extend the Angular Material Table to allow the user to re-order columns and toggle their visibility.
16
16
  - Support persisting the configuration in local, session or custom storage implementations.
17
- - Supports Angular 18 and 19. Supporting all actively supported Angular versions is planned (see [#5](https://github.com/pgerke/ngx-mat-table-multi-sort/issues/5))
17
+ - Supports all actively supported versions of Angular. Currently that is versions 18, 19 and 20.
18
18
  - Batteries included: The repository contains a demo application that can help you integrate the library with your project
19
19
  - 100% covered by automated unit tests and secured by static code analysis
20
20
 
@@ -1,20 +1,19 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, EventEmitter, signal, effect, Output, Optional, Inject, Directive, Injectable, Component, HostListener, inject, ViewEncapsulation, ANIMATION_MODULE_TYPE, Input } from '@angular/core';
2
+ import { InjectionToken, inject, EventEmitter, signal, effect, Output, Directive, Injectable, Component, ElementRef, ViewContainerRef, HostListener, ViewEncapsulation, ANIMATION_MODULE_TYPE, Input } from '@angular/core';
3
3
  import { moveItemInArray, CdkDropList, CdkDrag } from '@angular/cdk/drag-drop';
4
4
  import { MatSort, MAT_SORT_DEFAULT_OPTIONS, MatSortHeader } from '@angular/material/sort';
5
+ import { Overlay } from '@angular/cdk/overlay';
5
6
  import { ComponentPortal } from '@angular/cdk/portal';
6
- import * as i2 from '@angular/material/button';
7
+ import * as i1 from '@angular/material/button';
7
8
  import { MatButtonModule } from '@angular/material/button';
8
- import * as i3 from '@angular/material/checkbox';
9
+ import * as i2 from '@angular/material/checkbox';
9
10
  import { MatCheckboxModule } from '@angular/material/checkbox';
10
- import * as i4 from '@angular/material/icon';
11
+ import * as i3 from '@angular/material/icon';
11
12
  import { MatIconModule } from '@angular/material/icon';
12
- import * as i5 from '@angular/material/tooltip';
13
+ import * as i4 from '@angular/material/tooltip';
13
14
  import { MatTooltipModule } from '@angular/material/tooltip';
14
15
  import { BehaviorSubject } from 'rxjs';
15
- import * as i1 from '@angular/cdk/overlay';
16
16
  import { MatTableDataSource } from '@angular/material/table';
17
- import { NgIf } from '@angular/common';
18
17
  import * as i1$1 from '@angular/material/chips';
19
18
  import { MatChipsModule } from '@angular/material/chips';
20
19
 
@@ -78,11 +77,33 @@ const SORT_PERSISTENCE_ENABLED = new InjectionToken("SORT_PERSISTENCE_ENABLED");
78
77
  */
79
78
  const SORT_PERSISTENCE_KEY = new InjectionToken("SORT_PERSISTENCE_KEY");
80
79
  class MatMultiSortDirective extends MatSort {
81
- isPersistenceEnabled;
82
- initialKey;
83
- storage;
80
+ storage = inject(SORT_PERSISTENCE_STORAGE, { optional: true }) ??
81
+ localStorage;
82
+ persistenceKey = inject(SORT_PERSISTENCE_KEY, { optional: true }) ??
83
+ "mat-table-persistence-sort";
84
+ isPersistenceEnabled = inject(SORT_PERSISTENCE_ENABLED, { optional: true }) ?? true;
85
+ /**
86
+ * Event emitter that fires when the persistence state changes.
87
+ *
88
+ * This output emits an array of Sort objects whenever the sorting state
89
+ * is persisted or restored from storage. This can be useful for components
90
+ * that need to react to changes in the persisted sorting configuration.
91
+ *
92
+ * @example
93
+ * ```html
94
+ * <table mat-table [dataSource]="dataSource" matMultiSort
95
+ * (persistenceChanged)="onPersistenceChanged($event)">
96
+ * ```
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * onPersistenceChanged(sorts: Sort[]): void {
101
+ * console.log('Sorting state changed:', sorts);
102
+ * // Handle the updated sorting configuration
103
+ * }
104
+ * ```
105
+ */
84
106
  persistenceChanged = new EventEmitter();
85
- _key;
86
107
  /**
87
108
  * A writable signal that holds an array of Sort objects.
88
109
  * This signal is used to manage the sorting state of the table.
@@ -96,16 +117,13 @@ class MatMultiSortDirective extends MatSort {
96
117
  * @returns {string} The key used for column configuration persistence.
97
118
  */
98
119
  get key() {
99
- return this._key;
120
+ return this.persistenceKey;
100
121
  }
101
- constructor(isPersistenceEnabled, initialKey, storage, defaultOptions) {
122
+ constructor() {
123
+ const defaultOptions = inject(MAT_SORT_DEFAULT_OPTIONS, {
124
+ optional: true,
125
+ }) ?? undefined;
102
126
  super(defaultOptions);
103
- this.isPersistenceEnabled = isPersistenceEnabled;
104
- this.initialKey = initialKey;
105
- this.storage = storage;
106
- this.isPersistenceEnabled ??= true;
107
- this._key = initialKey ?? "mat-table-persistence-sort";
108
- this.storage ??= localStorage;
109
127
  if (this.isPersistenceEnabled) {
110
128
  const sortsSerialized = this.storage.getItem(this.key);
111
129
  this._sorts.set(sortsSerialized ? JSON.parse(sortsSerialized) : []);
@@ -238,7 +256,7 @@ class MatMultiSortDirective extends MatSort {
238
256
  * @returns void
239
257
  */
240
258
  setPersistenceKey(key, overwritePersistedValue = false) {
241
- this._key = key;
259
+ this.persistenceKey = key;
242
260
  if (overwritePersistedValue) {
243
261
  this.persistSortSettings();
244
262
  return;
@@ -246,10 +264,10 @@ class MatMultiSortDirective extends MatSort {
246
264
  const sortsSerialized = this.storage.getItem(this.key);
247
265
  this._sorts.set(sortsSerialized ? JSON.parse(sortsSerialized) : []);
248
266
  }
249
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: MatMultiSortDirective, deps: [{ token: SORT_PERSISTENCE_ENABLED, optional: true }, { token: SORT_PERSISTENCE_KEY, optional: true }, { token: SORT_PERSISTENCE_STORAGE, optional: true }, { token: MAT_SORT_DEFAULT_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
250
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.14", type: MatMultiSortDirective, isStandalone: true, selector: "[matMultiSort]", outputs: { persistenceChanged: "persistenceChanged" }, host: { classAttribute: "mat-sort" }, exportAs: ["matMultiSort"], usesInheritance: true, ngImport: i0 });
267
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: MatMultiSortDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
268
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.5", type: MatMultiSortDirective, isStandalone: true, selector: "[matMultiSort]", outputs: { persistenceChanged: "persistenceChanged" }, host: { classAttribute: "mat-sort" }, exportAs: ["matMultiSort"], usesInheritance: true, ngImport: i0 });
251
269
  }
252
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: MatMultiSortDirective, decorators: [{
270
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: MatMultiSortDirective, decorators: [{
253
271
  type: Directive,
254
272
  args: [{
255
273
  selector: "[matMultiSort]",
@@ -258,36 +276,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
258
276
  class: "mat-sort",
259
277
  },
260
278
  }]
261
- }], ctorParameters: () => [{ type: undefined, decorators: [{
262
- type: Optional
263
- }, {
264
- type: Inject,
265
- args: [SORT_PERSISTENCE_ENABLED]
266
- }] }, { type: undefined, decorators: [{
267
- type: Optional
268
- }, {
269
- type: Inject,
270
- args: [SORT_PERSISTENCE_KEY]
271
- }] }, { type: Storage, decorators: [{
272
- type: Optional
273
- }, {
274
- type: Inject,
275
- args: [SORT_PERSISTENCE_STORAGE]
276
- }] }, { type: undefined, decorators: [{
277
- type: Optional
278
- }, {
279
- type: Inject,
280
- args: [MAT_SORT_DEFAULT_OPTIONS]
281
- }] }], propDecorators: { persistenceChanged: [{
279
+ }], ctorParameters: () => [], propDecorators: { persistenceChanged: [{
282
280
  type: Output
283
281
  }] } });
284
282
 
285
283
  class MatTableColumnConfigPersistenceService {
286
- isPersistenceEnabled;
287
- initialKey;
288
- storage;
289
284
  columns$ = new BehaviorSubject([]);
290
- _key;
285
+ storage = inject(COLUMN_CONFIG_PERSISTENCE_STORAGE, { optional: true }) ??
286
+ localStorage;
287
+ persistenceKey = inject(COLUMN_CONFIG_PERSISTENCE_KEY, { optional: true }) ??
288
+ "mat-table-persistence-column-config";
289
+ isPersistenceEnabled = inject(COLUMN_CONFIG_PERSISTENCE_ENABLED, { optional: true }) ?? true;
291
290
  /**
292
291
  * Gets the current table columns configuration.
293
292
  *
@@ -311,19 +310,13 @@ class MatTableColumnConfigPersistenceService {
311
310
  * @returns {string} The key used for column configuration persistence.
312
311
  */
313
312
  get key() {
314
- return this._key;
315
- }
316
- constructor(isPersistenceEnabled, initialKey, storage) {
317
- this.isPersistenceEnabled = isPersistenceEnabled;
318
- this.initialKey = initialKey;
319
- this.storage = storage;
320
- this.isPersistenceEnabled ??= true;
321
- this._key = initialKey ?? "mat-table-persistence-column-config";
322
- this.storage ??= localStorage;
323
- if (this.isPersistenceEnabled) {
324
- const columnsSerialized = this.storage.getItem(this.key);
325
- this.columns$.next(columnsSerialized ? JSON.parse(columnsSerialized) : []);
326
- }
313
+ return this.persistenceKey;
314
+ }
315
+ constructor() {
316
+ if (!this.isPersistenceEnabled)
317
+ return;
318
+ const columnsSerialized = this.storage.getItem(this.key);
319
+ this.columns$.next(columnsSerialized ? JSON.parse(columnsSerialized) : []);
327
320
  }
328
321
  /**
329
322
  * Retrieves an observable stream of table columns.
@@ -336,7 +329,7 @@ class MatTableColumnConfigPersistenceService {
336
329
  persistColumnConfig(columns) {
337
330
  if (!this.isPersistenceEnabled)
338
331
  return;
339
- this.storage.setItem(this.key, JSON.stringify(columns));
332
+ this.storage.setItem(this.persistenceKey, JSON.stringify(columns));
340
333
  }
341
334
  /**
342
335
  * Sets the persistence key for storing column configurations.
@@ -349,46 +342,28 @@ class MatTableColumnConfigPersistenceService {
349
342
  * @returns void
350
343
  */
351
344
  setPersistenceKey(key, overwritePersistedValue = false) {
352
- this._key = key;
345
+ this.persistenceKey = key;
353
346
  if (overwritePersistedValue) {
354
347
  this.persistColumnConfig(this.columns);
355
348
  return;
356
349
  }
357
- const columnsSerialized = this.storage.getItem(this.key);
350
+ const columnsSerialized = this.storage.getItem(this.persistenceKey);
358
351
  this.columns$.next(columnsSerialized ? JSON.parse(columnsSerialized) : []);
359
352
  }
360
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: MatTableColumnConfigPersistenceService, deps: [{ token: COLUMN_CONFIG_PERSISTENCE_ENABLED, optional: true }, { token: COLUMN_CONFIG_PERSISTENCE_KEY, optional: true }, { token: COLUMN_CONFIG_PERSISTENCE_STORAGE, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
361
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: MatTableColumnConfigPersistenceService, providedIn: "root" });
353
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: MatTableColumnConfigPersistenceService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
354
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: MatTableColumnConfigPersistenceService, providedIn: "root" });
362
355
  }
363
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: MatTableColumnConfigPersistenceService, decorators: [{
356
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: MatTableColumnConfigPersistenceService, decorators: [{
364
357
  type: Injectable,
365
358
  args: [{
366
359
  providedIn: "root",
367
360
  }]
368
- }], ctorParameters: () => [{ type: undefined, decorators: [{
369
- type: Optional
370
- }, {
371
- type: Inject,
372
- args: [COLUMN_CONFIG_PERSISTENCE_ENABLED]
373
- }] }, { type: undefined, decorators: [{
374
- type: Optional
375
- }, {
376
- type: Inject,
377
- args: [COLUMN_CONFIG_PERSISTENCE_KEY]
378
- }] }, { type: Storage, decorators: [{
379
- type: Optional
380
- }, {
381
- type: Inject,
382
- args: [COLUMN_CONFIG_PERSISTENCE_STORAGE]
383
- }] }] });
361
+ }], ctorParameters: () => [] });
384
362
 
385
363
  class MatTableColumnConfigComponent {
386
- persistenceService;
364
+ persistenceService = inject(MatTableColumnConfigPersistenceService);
387
365
  subscription;
388
366
  columns = [];
389
- constructor(persistenceService) {
390
- this.persistenceService = persistenceService;
391
- }
392
367
  ngOnInit() {
393
368
  this.subscription = this.persistenceService
394
369
  .getColumns()
@@ -460,10 +435,10 @@ class MatTableColumnConfigComponent {
460
435
  }
461
436
  this.persistenceService.columns = this.columns;
462
437
  }
463
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: MatTableColumnConfigComponent, deps: [{ token: MatTableColumnConfigPersistenceService }], target: i0.ɵɵFactoryTarget.Component });
464
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: MatTableColumnConfigComponent, isStandalone: true, selector: "mat-table-column-config", ngImport: i0, template: "<div class=\"container mat-elevation-z4\">\n <div class=\"toolbar\">\n <button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Select all columns\"\n (click)=\"selectAllColumns()\">\n <mat-icon>select_all</mat-icon>\n </button>\n <button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Deselect all columns\"\n (click)=\"deselectAllColumns()\">\n <mat-icon>deselect</mat-icon>\n </button>\n <button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Invert selection\"\n (click)=\"invertColumnSelection()\">\n <mat-icon>flip</mat-icon>\n </button>\n </div>\n <hr />\n <div\n cdkDropList\n class=\"table-column-list\"\n cdkDropListOrientation=\"vertical\"\n (cdkDropListDropped)=\"onColumnDropped($event)\">\n @for (column of columns; track column.id) {\n <div cdkDrag class=\"table-column\">\n <mat-icon cdkDragHandle>drag_indicator</mat-icon>\n <mat-checkbox\n [checked]=\"column.visible\"\n (change)=\"onColumnVisibilityChanged(column.id)\"\n >{{ column.label }}</mat-checkbox\n >\n </div>\n }\n </div>\n</div>\n", styles: [".cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .15s cubic-bezier(0,0,.2,1)}.cdk-drag-preview{box-sizing:border-box;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;overflow:hidden}div.container{background:var(--mat-sys-surface, #ffffff);color:var(--mat-sys-on-surface, rgba(0, 0, 0, .87))}div.container>hr{border-color:var(--mat-inverse-on-surface, rgba(0, 0, 0, .87))}div.container>div.toolbar{display:inline}.table-column-list{background-color:var(--mat-sys-surface-container, #eeeeee);max-height:65vh;overflow:auto}.table-column{background:var(--mat-sys-surface, #ffffff);display:flex;justify-content:flex-start;align-items:center;height:48px;padding:0 16px 0 8px}.table-column mat-icon{margin-right:16px}.table-column mat-checkbox{line-height:48px;color:#000000de;font-size:14px;font-weight:400}.table-column:last-child{border:none}.cdk-drop-list-dragging .table-column:not(.cdk-drag-placeholder){transition:transform .15s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i3.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
438
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: MatTableColumnConfigComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
439
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.5", type: MatTableColumnConfigComponent, isStandalone: true, selector: "mat-table-column-config", ngImport: i0, template: "<div class=\"container mat-elevation-z4\">\n <div class=\"toolbar\">\n <button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Select all columns\"\n (click)=\"selectAllColumns()\">\n <mat-icon>select_all</mat-icon>\n </button>\n <button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Deselect all columns\"\n (click)=\"deselectAllColumns()\">\n <mat-icon>deselect</mat-icon>\n </button>\n <button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Invert selection\"\n (click)=\"invertColumnSelection()\">\n <mat-icon>flip</mat-icon>\n </button>\n </div>\n <hr />\n <div\n cdkDropList\n class=\"table-column-list\"\n cdkDropListOrientation=\"vertical\"\n (cdkDropListDropped)=\"onColumnDropped($event)\">\n @for (column of columns; track column.id) {\n <div cdkDrag class=\"table-column\">\n <mat-icon cdkDragHandle>drag_indicator</mat-icon>\n <mat-checkbox\n [checked]=\"column.visible\"\n (change)=\"onColumnVisibilityChanged(column.id)\"\n >{{ column.label }}</mat-checkbox\n >\n </div>\n }\n </div>\n</div>\n", styles: [".cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .15s cubic-bezier(0,0,.2,1)}.cdk-drag-preview{box-sizing:border-box;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;overflow:hidden}div.container{background:var(--mat-sys-surface, #ffffff);color:var(--mat-sys-on-surface, rgba(0, 0, 0, .87))}div.container>hr{border-color:var(--mat-inverse-on-surface, rgba(0, 0, 0, .87))}div.container>div.toolbar{display:inline}.table-column-list{background-color:var(--mat-sys-surface-container, #eeeeee);max-height:65vh;overflow:auto}.table-column{background:var(--mat-sys-surface, #ffffff);display:flex;justify-content:flex-start;align-items:center;height:48px;padding:0 16px 0 8px}.table-column mat-icon{margin-right:16px}.table-column mat-checkbox{line-height:48px;color:#000000de;font-size:14px;font-weight:400}.table-column:last-child{border:none}.cdk-drop-list-dragging .table-column:not(.cdk-drag-placeholder){transition:transform .15s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i2.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
465
440
  }
466
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: MatTableColumnConfigComponent, decorators: [{
441
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: MatTableColumnConfigComponent, decorators: [{
467
442
  type: Component,
468
443
  args: [{ selector: "mat-table-column-config", imports: [
469
444
  CdkDropList,
@@ -473,12 +448,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
473
448
  MatIconModule,
474
449
  MatTooltipModule,
475
450
  ], template: "<div class=\"container mat-elevation-z4\">\n <div class=\"toolbar\">\n <button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Select all columns\"\n (click)=\"selectAllColumns()\">\n <mat-icon>select_all</mat-icon>\n </button>\n <button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Deselect all columns\"\n (click)=\"deselectAllColumns()\">\n <mat-icon>deselect</mat-icon>\n </button>\n <button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Invert selection\"\n (click)=\"invertColumnSelection()\">\n <mat-icon>flip</mat-icon>\n </button>\n </div>\n <hr />\n <div\n cdkDropList\n class=\"table-column-list\"\n cdkDropListOrientation=\"vertical\"\n (cdkDropListDropped)=\"onColumnDropped($event)\">\n @for (column of columns; track column.id) {\n <div cdkDrag class=\"table-column\">\n <mat-icon cdkDragHandle>drag_indicator</mat-icon>\n <mat-checkbox\n [checked]=\"column.visible\"\n (change)=\"onColumnVisibilityChanged(column.id)\"\n >{{ column.label }}</mat-checkbox\n >\n </div>\n }\n </div>\n</div>\n", styles: [".cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .15s cubic-bezier(0,0,.2,1)}.cdk-drag-preview{box-sizing:border-box;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;overflow:hidden}div.container{background:var(--mat-sys-surface, #ffffff);color:var(--mat-sys-on-surface, rgba(0, 0, 0, .87))}div.container>hr{border-color:var(--mat-inverse-on-surface, rgba(0, 0, 0, .87))}div.container>div.toolbar{display:inline}.table-column-list{background-color:var(--mat-sys-surface-container, #eeeeee);max-height:65vh;overflow:auto}.table-column{background:var(--mat-sys-surface, #ffffff);display:flex;justify-content:flex-start;align-items:center;height:48px;padding:0 16px 0 8px}.table-column mat-icon{margin-right:16px}.table-column mat-checkbox{line-height:48px;color:#000000de;font-size:14px;font-weight:400}.table-column:last-child{border:none}.cdk-drop-list-dragging .table-column:not(.cdk-drag-placeholder){transition:transform .15s cubic-bezier(0,0,.2,1)}\n"] }]
476
- }], ctorParameters: () => [{ type: MatTableColumnConfigPersistenceService }] });
451
+ }] });
477
452
 
478
453
  class MatTableColumnConfigTriggerDirective {
479
- elementRef;
480
- overlay;
481
- viewContainerRef;
454
+ elementRef = inject(ElementRef);
455
+ overlay = inject(Overlay);
456
+ viewContainerRef = inject(ViewContainerRef);
482
457
  _componentRef = null;
483
458
  /**
484
459
  * Gets the reference to the MatTableColumnConfigComponent.
@@ -489,11 +464,6 @@ class MatTableColumnConfigTriggerDirective {
489
464
  get componentRef() {
490
465
  return this._componentRef;
491
466
  }
492
- constructor(elementRef, overlay, viewContainerRef) {
493
- this.elementRef = elementRef;
494
- this.overlay = overlay;
495
- this.viewContainerRef = viewContainerRef;
496
- }
497
467
  onClick() {
498
468
  // Create the component portal
499
469
  const positionStrategy = this.overlay
@@ -524,16 +494,16 @@ class MatTableColumnConfigTriggerDirective {
524
494
  this._componentRef = null;
525
495
  });
526
496
  }
527
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: MatTableColumnConfigTriggerDirective, deps: [{ token: i0.ElementRef }, { token: i1.Overlay }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
528
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.14", type: MatTableColumnConfigTriggerDirective, isStandalone: true, selector: "[matTableColumnConfigTrigger]", host: { listeners: { "click": "onClick()" } }, exportAs: ["matTableColumnConfigTrigger"], ngImport: i0 });
497
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: MatTableColumnConfigTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
498
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.5", type: MatTableColumnConfigTriggerDirective, isStandalone: true, selector: "[matTableColumnConfigTrigger]", host: { listeners: { "click": "onClick()" } }, exportAs: ["matTableColumnConfigTrigger"], ngImport: i0 });
529
499
  }
530
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: MatTableColumnConfigTriggerDirective, decorators: [{
500
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: MatTableColumnConfigTriggerDirective, decorators: [{
531
501
  type: Directive,
532
502
  args: [{
533
503
  selector: "[matTableColumnConfigTrigger]",
534
504
  exportAs: "matTableColumnConfigTrigger",
535
505
  }]
536
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.Overlay }, { type: i0.ViewContainerRef }], propDecorators: { onClick: [{
506
+ }], propDecorators: { onClick: [{
537
507
  type: HostListener,
538
508
  args: ["click"]
539
509
  }] } });
@@ -636,12 +606,12 @@ class MatMultiSortHeaderComponent extends MatSortHeader {
636
606
  this._sort.sort(this);
637
607
  this._recentlyCleared.set(wasSorted && !this._isSorted() ? prevDirection : null);
638
608
  }
639
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: MatMultiSortHeaderComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
640
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: MatMultiSortHeaderComponent, isStandalone: true, selector: "[mat-multi-sort-header]", providers: [{ provide: MatSort, useExisting: MatMultiSortDirective }], exportAs: ["matMultiSortHeader"], usesInheritance: true, ngImport: i0, template: "<!--\n We set the `tabindex` on an element inside the table header, rather than the header itself,\n because of a bug in NVDA where having a `tabindex` on a `th` breaks keyboard navigation in the\n table (see https://github.com/nvaccess/nvda/issues/7718). This allows for the header to both\n be focusable, and have screen readers read out its `aria-sort` state. We prefer this approach\n over having a button with an `aria-label` inside the header, because the button's `aria-label`\n will be read out as the user is navigating the table's cell (see #13012).\n\n The approach is based off of: https://dequeuniversity.com/library/aria/tables/sf-sortable-grid\n-->\n<div\n class=\"mat-sort-header-container mat-focus-indicator\"\n [class.mat-sort-header-sorted]=\"_isSorted()\"\n [class.mat-sort-header-position-before]=\"arrowPosition === 'before'\"\n [class.mat-sort-header-descending]=\"sortDirection === 'desc'\"\n [class.mat-sort-header-ascending]=\"sortDirection === 'asc'\"\n [class.mat-sort-header-recently-cleared-ascending]=\"\n _recentlyCleared() === 'asc'\n \"\n [class.mat-sort-header-recently-cleared-descending]=\"\n _recentlyCleared() === 'desc'\n \"\n [class.mat-sort-header-animations-disabled]=\"\n _animationModule === 'NoopAnimations'\n \"\n [attr.tabindex]=\"_isDisabled() ? null : 0\"\n [attr.role]=\"_isDisabled() ? null : 'button'\">\n <!--\n TODO(crisbeto): this div isn't strictly necessary, but we have to keep it due to a large\n number of screenshot diff failures. It should be removed eventually. Note that the difference\n isn't visible with a shorter header, but once it breaks up into multiple lines, this element\n causes it to be center-aligned, whereas removing it will keep the text to the left.\n -->\n <div class=\"mat-sort-header-content\">\n <ng-content></ng-content>\n </div>\n\n <!-- Disable animations while a current animation is running -->\n @if (_renderArrow()) {\n <div class=\"mat-sort-header-arrow\">\n <svg viewBox=\"0 -960 960 960\" focusable=\"false\" aria-hidden=\"true\">\n <path\n d=\"M440-240v-368L296-464l-56-56 240-240 240 240-56 56-144-144v368h-80Z\" />\n </svg>\n </div>\n }\n <div *ngIf=\"_isSorted()\" class=\"mat-sort-header-counter\">\n {{ sortIndex + 1 }}\n </div>\n</div>\n", styles: [".mat-sort-header-container{display:flex;cursor:pointer;align-items:center;letter-spacing:normal;outline:0}[mat-sort-header].cdk-keyboard-focused .mat-sort-header-container,[mat-sort-header].cdk-program-focused .mat-sort-header-container{border-bottom:solid 1px currentColor}.mat-sort-header-disabled .mat-sort-header-container{cursor:default}.mat-sort-header-container:before{margin:calc(calc(var(--mat-focus-indicator-border-width, 3px) + 2px) * -1)}.mat-sort-header-content{display:flex;align-items:center}.mat-sort-header-position-before{flex-direction:row-reverse}@keyframes _mat-sort-header-recently-cleared-ascending{0%{transform:translateY(0);opacity:1}to{transform:translateY(-25%);opacity:0}}@keyframes _mat-sort-header-recently-cleared-descending{0%{transform:translateY(0) rotate(180deg);opacity:1}to{transform:translateY(25%) rotate(180deg);opacity:0}}.mat-sort-header-arrow{height:12px;width:12px;position:relative;transition:transform 225ms cubic-bezier(.4,0,.2,1),opacity 225ms cubic-bezier(.4,0,.2,1);opacity:0;overflow:visible;color:var(--mat-sort-arrow-color, var(--mat-sys-on-surface))}.mat-sort-header.cdk-keyboard-focused .mat-sort-header-arrow,.mat-sort-header.cdk-program-focused .mat-sort-header-arrow,.mat-sort-header:hover .mat-sort-header-arrow{opacity:.54}.mat-sort-header .mat-sort-header-sorted .mat-sort-header-arrow{opacity:1}.mat-sort-header-descending .mat-sort-header-arrow{transform:rotate(180deg)}.mat-sort-header-recently-cleared-ascending .mat-sort-header-arrow{transform:translateY(-25%);transition:none;animation:_mat-sort-header-recently-cleared-ascending 225ms cubic-bezier(.4,0,.2,1) forwards}.mat-sort-header-animations-disabled .mat-sort-header-arrow{transition-duration:0ms;animation-duration:0ms}.mat-sort-header-arrow svg{width:24px;height:24px;fill:currentColor;position:absolute;top:50%;left:50%;margin:-12px 0 0 -12px;transform:translateZ(0)}.mat-sort-header-arrow,[dir=rtl] .mat-sort-header-position-before .mat-sort-header-arrow{margin:0 0 0 6px}.mat-sort-header-position-before .mat-sort-header-arrow,[dir=rtl] .mat-sort-header-arrow{margin:0 6px 0 0}.mat-sort-header-counter{color:var(--mat-sort-arrow-color, var(--mat-sys-on-surface))}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], encapsulation: i0.ViewEncapsulation.None });
609
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: MatMultiSortHeaderComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
610
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.5", type: MatMultiSortHeaderComponent, isStandalone: true, selector: "[mat-multi-sort-header]", providers: [{ provide: MatSort, useExisting: MatMultiSortDirective }], exportAs: ["matMultiSortHeader"], usesInheritance: true, ngImport: i0, template: "<!--\n We set the `tabindex` on an element inside the table header, rather than the header itself,\n because of a bug in NVDA where having a `tabindex` on a `th` breaks keyboard navigation in the\n table (see https://github.com/nvaccess/nvda/issues/7718). This allows for the header to both\n be focusable, and have screen readers read out its `aria-sort` state. We prefer this approach\n over having a button with an `aria-label` inside the header, because the button's `aria-label`\n will be read out as the user is navigating the table's cell (see #13012).\n\n The approach is based off of: https://dequeuniversity.com/library/aria/tables/sf-sortable-grid\n-->\n<div\n class=\"mat-sort-header-container mat-focus-indicator\"\n [class.mat-sort-header-sorted]=\"_isSorted()\"\n [class.mat-sort-header-position-before]=\"arrowPosition === 'before'\"\n [class.mat-sort-header-descending]=\"sortDirection === 'desc'\"\n [class.mat-sort-header-ascending]=\"sortDirection === 'asc'\"\n [class.mat-sort-header-recently-cleared-ascending]=\"\n _recentlyCleared() === 'asc'\n \"\n [class.mat-sort-header-recently-cleared-descending]=\"\n _recentlyCleared() === 'desc'\n \"\n [class.mat-sort-header-animations-disabled]=\"_animationsDisabled\"\n [attr.tabindex]=\"_isDisabled() ? null : 0\"\n [attr.role]=\"_isDisabled() ? null : 'button'\">\n <!--\n TODO(crisbeto): this div isn't strictly necessary, but we have to keep it due to a large\n number of screenshot diff failures. It should be removed eventually. Note that the difference\n isn't visible with a shorter header, but once it breaks up into multiple lines, this element\n causes it to be center-aligned, whereas removing it will keep the text to the left.\n -->\n <div class=\"mat-sort-header-content\">\n <ng-content></ng-content>\n </div>\n\n <!-- Disable animations while a current animation is running -->\n @if (_renderArrow()) {\n <div class=\"mat-sort-header-arrow\">\n <svg viewBox=\"0 -960 960 960\" focusable=\"false\" aria-hidden=\"true\">\n <path\n d=\"M440-240v-368L296-464l-56-56 240-240 240 240-56 56-144-144v368h-80Z\" />\n </svg>\n </div>\n }\n @if (_isSorted()) {\n <div class=\"mat-sort-header-counter\">\n {{ sortIndex + 1 }}\n </div>\n }\n</div>\n", styles: [".mat-sort-header{cursor:pointer}.mat-sort-header-disabled{cursor:default}.mat-sort-header-container{display:flex;align-items:center;letter-spacing:normal;outline:0}[mat-sort-header].cdk-keyboard-focused .mat-sort-header-container,[mat-sort-header].cdk-program-focused .mat-sort-header-container{border-bottom:solid 1px currentColor}.mat-sort-header-container:before{margin:calc(calc(var(--mat-focus-indicator-border-width, 3px) + 2px) * -1)}.mat-sort-header-content{display:flex;align-items:center}.mat-sort-header-position-before{flex-direction:row-reverse}@keyframes _mat-sort-header-recently-cleared-ascending{0%{transform:translateY(0);opacity:1}to{transform:translateY(-25%);opacity:0}}@keyframes _mat-sort-header-recently-cleared-descending{0%{transform:translateY(0) rotate(180deg);opacity:1}to{transform:translateY(25%) rotate(180deg);opacity:0}}.mat-sort-header-arrow{height:12px;width:12px;position:relative;transition:transform 225ms cubic-bezier(.4,0,.2,1),opacity 225ms cubic-bezier(.4,0,.2,1);opacity:0;overflow:visible;color:var(--mat-sort-arrow-color, var(--mat-sys-on-surface))}.mat-sort-header.cdk-keyboard-focused .mat-sort-header-arrow,.mat-sort-header.cdk-program-focused .mat-sort-header-arrow,.mat-sort-header:hover .mat-sort-header-arrow{opacity:.54}.mat-sort-header .mat-sort-header-sorted .mat-sort-header-arrow{opacity:1}.mat-sort-header-descending .mat-sort-header-arrow{transform:rotate(180deg)}.mat-sort-header-recently-cleared-ascending .mat-sort-header-arrow{transform:translateY(-25%);transition:none;animation:_mat-sort-header-recently-cleared-ascending 225ms cubic-bezier(.4,0,.2,1) forwards}.mat-sort-header-recently-cleared-descending .mat-sort-header-arrow{transition:none;animation:_mat-sort-header-recently-cleared-descending 225ms cubic-bezier(.4,0,.2,1) forwards}.mat-sort-header-animations-disabled .mat-sort-header-arrow{transition-duration:0ms;animation-duration:0ms}.mat-sort-header-arrow svg{width:24px;height:24px;fill:currentColor;position:absolute;top:50%;left:50%;margin:-12px 0 0 -12px;transform:translateZ(0)}.mat-sort-header-arrow,[dir=rtl] .mat-sort-header-position-before .mat-sort-header-arrow{margin:0 0 0 6px}.mat-sort-header-position-before .mat-sort-header-arrow,[dir=rtl] .mat-sort-header-arrow{margin:0 6px 0 0}.mat-sort-header-counter{color:var(--mat-sort-arrow-color, var(--mat-sys-on-surface))}\n"], encapsulation: i0.ViewEncapsulation.None });
641
611
  }
642
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: MatMultiSortHeaderComponent, decorators: [{
612
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: MatMultiSortHeaderComponent, decorators: [{
643
613
  type: Component,
644
- args: [{ selector: "[mat-multi-sort-header]", exportAs: "matMultiSortHeader", imports: [NgIf], providers: [{ provide: MatSort, useExisting: MatMultiSortDirective }], encapsulation: ViewEncapsulation.None, template: "<!--\n We set the `tabindex` on an element inside the table header, rather than the header itself,\n because of a bug in NVDA where having a `tabindex` on a `th` breaks keyboard navigation in the\n table (see https://github.com/nvaccess/nvda/issues/7718). This allows for the header to both\n be focusable, and have screen readers read out its `aria-sort` state. We prefer this approach\n over having a button with an `aria-label` inside the header, because the button's `aria-label`\n will be read out as the user is navigating the table's cell (see #13012).\n\n The approach is based off of: https://dequeuniversity.com/library/aria/tables/sf-sortable-grid\n-->\n<div\n class=\"mat-sort-header-container mat-focus-indicator\"\n [class.mat-sort-header-sorted]=\"_isSorted()\"\n [class.mat-sort-header-position-before]=\"arrowPosition === 'before'\"\n [class.mat-sort-header-descending]=\"sortDirection === 'desc'\"\n [class.mat-sort-header-ascending]=\"sortDirection === 'asc'\"\n [class.mat-sort-header-recently-cleared-ascending]=\"\n _recentlyCleared() === 'asc'\n \"\n [class.mat-sort-header-recently-cleared-descending]=\"\n _recentlyCleared() === 'desc'\n \"\n [class.mat-sort-header-animations-disabled]=\"\n _animationModule === 'NoopAnimations'\n \"\n [attr.tabindex]=\"_isDisabled() ? null : 0\"\n [attr.role]=\"_isDisabled() ? null : 'button'\">\n <!--\n TODO(crisbeto): this div isn't strictly necessary, but we have to keep it due to a large\n number of screenshot diff failures. It should be removed eventually. Note that the difference\n isn't visible with a shorter header, but once it breaks up into multiple lines, this element\n causes it to be center-aligned, whereas removing it will keep the text to the left.\n -->\n <div class=\"mat-sort-header-content\">\n <ng-content></ng-content>\n </div>\n\n <!-- Disable animations while a current animation is running -->\n @if (_renderArrow()) {\n <div class=\"mat-sort-header-arrow\">\n <svg viewBox=\"0 -960 960 960\" focusable=\"false\" aria-hidden=\"true\">\n <path\n d=\"M440-240v-368L296-464l-56-56 240-240 240 240-56 56-144-144v368h-80Z\" />\n </svg>\n </div>\n }\n <div *ngIf=\"_isSorted()\" class=\"mat-sort-header-counter\">\n {{ sortIndex + 1 }}\n </div>\n</div>\n", styles: [".mat-sort-header-container{display:flex;cursor:pointer;align-items:center;letter-spacing:normal;outline:0}[mat-sort-header].cdk-keyboard-focused .mat-sort-header-container,[mat-sort-header].cdk-program-focused .mat-sort-header-container{border-bottom:solid 1px currentColor}.mat-sort-header-disabled .mat-sort-header-container{cursor:default}.mat-sort-header-container:before{margin:calc(calc(var(--mat-focus-indicator-border-width, 3px) + 2px) * -1)}.mat-sort-header-content{display:flex;align-items:center}.mat-sort-header-position-before{flex-direction:row-reverse}@keyframes _mat-sort-header-recently-cleared-ascending{0%{transform:translateY(0);opacity:1}to{transform:translateY(-25%);opacity:0}}@keyframes _mat-sort-header-recently-cleared-descending{0%{transform:translateY(0) rotate(180deg);opacity:1}to{transform:translateY(25%) rotate(180deg);opacity:0}}.mat-sort-header-arrow{height:12px;width:12px;position:relative;transition:transform 225ms cubic-bezier(.4,0,.2,1),opacity 225ms cubic-bezier(.4,0,.2,1);opacity:0;overflow:visible;color:var(--mat-sort-arrow-color, var(--mat-sys-on-surface))}.mat-sort-header.cdk-keyboard-focused .mat-sort-header-arrow,.mat-sort-header.cdk-program-focused .mat-sort-header-arrow,.mat-sort-header:hover .mat-sort-header-arrow{opacity:.54}.mat-sort-header .mat-sort-header-sorted .mat-sort-header-arrow{opacity:1}.mat-sort-header-descending .mat-sort-header-arrow{transform:rotate(180deg)}.mat-sort-header-recently-cleared-ascending .mat-sort-header-arrow{transform:translateY(-25%);transition:none;animation:_mat-sort-header-recently-cleared-ascending 225ms cubic-bezier(.4,0,.2,1) forwards}.mat-sort-header-animations-disabled .mat-sort-header-arrow{transition-duration:0ms;animation-duration:0ms}.mat-sort-header-arrow svg{width:24px;height:24px;fill:currentColor;position:absolute;top:50%;left:50%;margin:-12px 0 0 -12px;transform:translateZ(0)}.mat-sort-header-arrow,[dir=rtl] .mat-sort-header-position-before .mat-sort-header-arrow{margin:0 0 0 6px}.mat-sort-header-position-before .mat-sort-header-arrow,[dir=rtl] .mat-sort-header-arrow{margin:0 6px 0 0}.mat-sort-header-counter{color:var(--mat-sort-arrow-color, var(--mat-sys-on-surface))}\n"] }]
614
+ args: [{ selector: "[mat-multi-sort-header]", exportAs: "matMultiSortHeader", providers: [{ provide: MatSort, useExisting: MatMultiSortDirective }], encapsulation: ViewEncapsulation.None, template: "<!--\n We set the `tabindex` on an element inside the table header, rather than the header itself,\n because of a bug in NVDA where having a `tabindex` on a `th` breaks keyboard navigation in the\n table (see https://github.com/nvaccess/nvda/issues/7718). This allows for the header to both\n be focusable, and have screen readers read out its `aria-sort` state. We prefer this approach\n over having a button with an `aria-label` inside the header, because the button's `aria-label`\n will be read out as the user is navigating the table's cell (see #13012).\n\n The approach is based off of: https://dequeuniversity.com/library/aria/tables/sf-sortable-grid\n-->\n<div\n class=\"mat-sort-header-container mat-focus-indicator\"\n [class.mat-sort-header-sorted]=\"_isSorted()\"\n [class.mat-sort-header-position-before]=\"arrowPosition === 'before'\"\n [class.mat-sort-header-descending]=\"sortDirection === 'desc'\"\n [class.mat-sort-header-ascending]=\"sortDirection === 'asc'\"\n [class.mat-sort-header-recently-cleared-ascending]=\"\n _recentlyCleared() === 'asc'\n \"\n [class.mat-sort-header-recently-cleared-descending]=\"\n _recentlyCleared() === 'desc'\n \"\n [class.mat-sort-header-animations-disabled]=\"_animationsDisabled\"\n [attr.tabindex]=\"_isDisabled() ? null : 0\"\n [attr.role]=\"_isDisabled() ? null : 'button'\">\n <!--\n TODO(crisbeto): this div isn't strictly necessary, but we have to keep it due to a large\n number of screenshot diff failures. It should be removed eventually. Note that the difference\n isn't visible with a shorter header, but once it breaks up into multiple lines, this element\n causes it to be center-aligned, whereas removing it will keep the text to the left.\n -->\n <div class=\"mat-sort-header-content\">\n <ng-content></ng-content>\n </div>\n\n <!-- Disable animations while a current animation is running -->\n @if (_renderArrow()) {\n <div class=\"mat-sort-header-arrow\">\n <svg viewBox=\"0 -960 960 960\" focusable=\"false\" aria-hidden=\"true\">\n <path\n d=\"M440-240v-368L296-464l-56-56 240-240 240 240-56 56-144-144v368h-80Z\" />\n </svg>\n </div>\n }\n @if (_isSorted()) {\n <div class=\"mat-sort-header-counter\">\n {{ sortIndex + 1 }}\n </div>\n }\n</div>\n", styles: [".mat-sort-header{cursor:pointer}.mat-sort-header-disabled{cursor:default}.mat-sort-header-container{display:flex;align-items:center;letter-spacing:normal;outline:0}[mat-sort-header].cdk-keyboard-focused .mat-sort-header-container,[mat-sort-header].cdk-program-focused .mat-sort-header-container{border-bottom:solid 1px currentColor}.mat-sort-header-container:before{margin:calc(calc(var(--mat-focus-indicator-border-width, 3px) + 2px) * -1)}.mat-sort-header-content{display:flex;align-items:center}.mat-sort-header-position-before{flex-direction:row-reverse}@keyframes _mat-sort-header-recently-cleared-ascending{0%{transform:translateY(0);opacity:1}to{transform:translateY(-25%);opacity:0}}@keyframes _mat-sort-header-recently-cleared-descending{0%{transform:translateY(0) rotate(180deg);opacity:1}to{transform:translateY(25%) rotate(180deg);opacity:0}}.mat-sort-header-arrow{height:12px;width:12px;position:relative;transition:transform 225ms cubic-bezier(.4,0,.2,1),opacity 225ms cubic-bezier(.4,0,.2,1);opacity:0;overflow:visible;color:var(--mat-sort-arrow-color, var(--mat-sys-on-surface))}.mat-sort-header.cdk-keyboard-focused .mat-sort-header-arrow,.mat-sort-header.cdk-program-focused .mat-sort-header-arrow,.mat-sort-header:hover .mat-sort-header-arrow{opacity:.54}.mat-sort-header .mat-sort-header-sorted .mat-sort-header-arrow{opacity:1}.mat-sort-header-descending .mat-sort-header-arrow{transform:rotate(180deg)}.mat-sort-header-recently-cleared-ascending .mat-sort-header-arrow{transform:translateY(-25%);transition:none;animation:_mat-sort-header-recently-cleared-ascending 225ms cubic-bezier(.4,0,.2,1) forwards}.mat-sort-header-recently-cleared-descending .mat-sort-header-arrow{transition:none;animation:_mat-sort-header-recently-cleared-descending 225ms cubic-bezier(.4,0,.2,1) forwards}.mat-sort-header-animations-disabled .mat-sort-header-arrow{transition-duration:0ms;animation-duration:0ms}.mat-sort-header-arrow svg{width:24px;height:24px;fill:currentColor;position:absolute;top:50%;left:50%;margin:-12px 0 0 -12px;transform:translateZ(0)}.mat-sort-header-arrow,[dir=rtl] .mat-sort-header-position-before .mat-sort-header-arrow{margin:0 0 0 6px}.mat-sort-header-position-before .mat-sort-header-arrow,[dir=rtl] .mat-sort-header-arrow{margin:0 6px 0 0}.mat-sort-header-counter{color:var(--mat-sort-arrow-color, var(--mat-sys-on-surface))}\n"] }]
645
615
  }] });
646
616
 
647
617
  class MatMultiSortControlComponent {
@@ -712,10 +682,10 @@ class MatMultiSortControlComponent {
712
682
  onDrop(event) {
713
683
  this.sort?.reorderSortLevel(event.previousIndex, event.currentIndex);
714
684
  }
715
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: MatMultiSortControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
716
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: MatMultiSortControlComponent, isStandalone: true, selector: "mat-multi-sort-control", inputs: { orientation: "orientation", sort: "sort" }, ngImport: i0, template: "<mat-chip-listbox\n cdkDropList\n [cdkDropListOrientation]=\"orientation\"\n (cdkDropListDropped)=\"onDrop($event)\">\n <mat-chip\n [disabled]=\"!sorts.length\"\n [highlighted]=\"true\"\n (click)=\"onClearClick()\"\n ><mat-icon matChipAvatar fontIcon=\"clear_all\"></mat-icon\n ><span i18n>Clear All</span></mat-chip\n >\n @for (column of sorts; track $index) {\n <mat-chip\n class=\"mat-sort-header\"\n cdkDrag\n (click)=\"onChipClick(column.active)\"\n (removed)=\"onChipRemoved(column.active)\">\n <div\n matChipAvatar\n class=\"mat-sort-header-container mat-sort-header-sorted mat-focus-indicator\"\n [class.mat-sort-header-descending]=\"column.direction === 'desc'\"\n [class.mat-sort-header-ascending]=\"column.direction === 'asc'\"\n [class.mat-sort-header-animations-disabled]=\"\n _animationModule === 'NoopAnimations'\n \">\n <div class=\"mat-sort-header-arrow\">\n <svg viewBox=\"0 -960 960 960\" focusable=\"false\" aria-hidden=\"true\">\n <path\n d=\"M440-240v-368L296-464l-56-56 240-240 240 240-56 56-144-144v368h-80Z\" />\n </svg>\n </div>\n </div>\n {{ column.active }}\n <button matChipRemove i18n-matTooltip matTooltip=\"Clear column sorting\">\n <mat-icon>clear</mat-icon>\n </button>\n </mat-chip>\n }\n</mat-chip-listbox>\n", styles: [".cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .15s cubic-bezier(0,0,.2,1)}.cdk-drag-preview{box-sizing:border-box;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;overflow:hidden}.mat-mdc-chip.mat-sort-header{background-color:var(--mat-sys-surface, #ffffff);transition:background-color .1s cubic-bezier(0,0,.2,1),box-shadow .1s cubic-bezier(0,0,.2,1)}.mat-mdc-chip.mat-sort-header:hover{cursor:move}.mat-mdc-chip.mat-sort-header:hover:after{opacity:0}.mat-mdc-chip.mat-sort-header:focus:after{opacity:0}.mat-mdc-chip.mat-sort-header:active{box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drop-list-dragging .mat-sort-header:not(.cdk-drag-placeholder){background-color:var(--mat-sys-surface-dim, #ffffff);transition:transform .15s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i1$1.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "directive", type: i1$1.MatChipAvatar, selector: "mat-chip-avatar, [matChipAvatar]" }, { kind: "component", type: i1$1.MatChipListbox, selector: "mat-chip-listbox", inputs: ["multiple", "aria-orientation", "selectable", "compareWith", "required", "hideSingleSelectionIndicator", "value"], outputs: ["change"] }, { kind: "directive", type: i1$1.MatChipRemove, selector: "[matChipRemove]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
685
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: MatMultiSortControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
686
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.5", type: MatMultiSortControlComponent, isStandalone: true, selector: "mat-multi-sort-control", inputs: { orientation: "orientation", sort: "sort" }, ngImport: i0, template: "<mat-chip-listbox\n cdkDropList\n [cdkDropListOrientation]=\"orientation\"\n (cdkDropListDropped)=\"onDrop($event)\">\n <mat-chip\n [disabled]=\"!sorts.length\"\n [highlighted]=\"true\"\n (click)=\"onClearClick()\"\n ><mat-icon matChipAvatar fontIcon=\"clear_all\"></mat-icon\n ><span i18n>Clear All</span></mat-chip\n >\n @for (column of sorts; track $index) {\n <mat-chip\n class=\"mat-sort-header\"\n cdkDrag\n (click)=\"onChipClick(column.active)\"\n (removed)=\"onChipRemoved(column.active)\">\n <div\n matChipAvatar\n class=\"mat-sort-header-container mat-sort-header-sorted mat-focus-indicator\"\n [class.mat-sort-header-descending]=\"column.direction === 'desc'\"\n [class.mat-sort-header-ascending]=\"column.direction === 'asc'\"\n [class.mat-sort-header-animations-disabled]=\"\n _animationModule === 'NoopAnimations'\n \">\n <div class=\"mat-sort-header-arrow\">\n <svg viewBox=\"0 -960 960 960\" focusable=\"false\" aria-hidden=\"true\">\n <path\n d=\"M440-240v-368L296-464l-56-56 240-240 240 240-56 56-144-144v368h-80Z\" />\n </svg>\n </div>\n </div>\n {{ column.active }}\n <button matChipRemove i18n-matTooltip matTooltip=\"Clear column sorting\">\n <mat-icon>clear</mat-icon>\n </button>\n </mat-chip>\n }\n</mat-chip-listbox>\n", styles: [".cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .15s cubic-bezier(0,0,.2,1)}.cdk-drag-preview{box-sizing:border-box;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;overflow:hidden}.mat-mdc-chip.mat-sort-header{background-color:var(--mat-sys-surface, #ffffff);transition:background-color .1s cubic-bezier(0,0,.2,1),box-shadow .1s cubic-bezier(0,0,.2,1)}.mat-mdc-chip.mat-sort-header:hover{cursor:move}.mat-mdc-chip.mat-sort-header:hover:after{opacity:0}.mat-mdc-chip.mat-sort-header:focus:after{opacity:0}.mat-mdc-chip.mat-sort-header:active{box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drop-list-dragging .mat-sort-header:not(.cdk-drag-placeholder){background-color:var(--mat-sys-surface-dim, #ffffff);transition:transform .15s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i1$1.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "directive", type: i1$1.MatChipAvatar, selector: "mat-chip-avatar, [matChipAvatar]" }, { kind: "component", type: i1$1.MatChipListbox, selector: "mat-chip-listbox", inputs: ["multiple", "aria-orientation", "selectable", "compareWith", "required", "hideSingleSelectionIndicator", "value"], outputs: ["change"] }, { kind: "directive", type: i1$1.MatChipRemove, selector: "[matChipRemove]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
717
687
  }
718
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: MatMultiSortControlComponent, decorators: [{
688
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: MatMultiSortControlComponent, decorators: [{
719
689
  type: Component,
720
690
  args: [{ selector: "mat-multi-sort-control", imports: [CdkDropList, CdkDrag, MatChipsModule, MatIconModule], template: "<mat-chip-listbox\n cdkDropList\n [cdkDropListOrientation]=\"orientation\"\n (cdkDropListDropped)=\"onDrop($event)\">\n <mat-chip\n [disabled]=\"!sorts.length\"\n [highlighted]=\"true\"\n (click)=\"onClearClick()\"\n ><mat-icon matChipAvatar fontIcon=\"clear_all\"></mat-icon\n ><span i18n>Clear All</span></mat-chip\n >\n @for (column of sorts; track $index) {\n <mat-chip\n class=\"mat-sort-header\"\n cdkDrag\n (click)=\"onChipClick(column.active)\"\n (removed)=\"onChipRemoved(column.active)\">\n <div\n matChipAvatar\n class=\"mat-sort-header-container mat-sort-header-sorted mat-focus-indicator\"\n [class.mat-sort-header-descending]=\"column.direction === 'desc'\"\n [class.mat-sort-header-ascending]=\"column.direction === 'asc'\"\n [class.mat-sort-header-animations-disabled]=\"\n _animationModule === 'NoopAnimations'\n \">\n <div class=\"mat-sort-header-arrow\">\n <svg viewBox=\"0 -960 960 960\" focusable=\"false\" aria-hidden=\"true\">\n <path\n d=\"M440-240v-368L296-464l-56-56 240-240 240 240-56 56-144-144v368h-80Z\" />\n </svg>\n </div>\n </div>\n {{ column.active }}\n <button matChipRemove i18n-matTooltip matTooltip=\"Clear column sorting\">\n <mat-icon>clear</mat-icon>\n </button>\n </mat-chip>\n }\n</mat-chip-listbox>\n", styles: [".cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .15s cubic-bezier(0,0,.2,1)}.cdk-drag-preview{box-sizing:border-box;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;overflow:hidden}.mat-mdc-chip.mat-sort-header{background-color:var(--mat-sys-surface, #ffffff);transition:background-color .1s cubic-bezier(0,0,.2,1),box-shadow .1s cubic-bezier(0,0,.2,1)}.mat-mdc-chip.mat-sort-header:hover{cursor:move}.mat-mdc-chip.mat-sort-header:hover:after{opacity:0}.mat-mdc-chip.mat-sort-header:focus:after{opacity:0}.mat-mdc-chip.mat-sort-header:active{box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drop-list-dragging .mat-sort-header:not(.cdk-drag-placeholder){background-color:var(--mat-sys-surface-dim, #ffffff);transition:transform .15s cubic-bezier(0,0,.2,1)}\n"] }]
721
691
  }], propDecorators: { orientation: [{