UNPKG

135 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/cdk/bidi'), require('@angular/cdk/coercion'), require('@angular/cdk/collections'), require('@angular/cdk/platform'), require('@angular/cdk/scrolling'), require('@angular/common'), require('@angular/core'), require('rxjs'), require('rxjs/operators')) :
3 typeof define === 'function' && define.amd ? define('@angular/cdk/table', ['exports', '@angular/cdk/bidi', '@angular/cdk/coercion', '@angular/cdk/collections', '@angular/cdk/platform', '@angular/cdk/scrolling', '@angular/common', '@angular/core', 'rxjs', 'rxjs/operators'], factory) :
4 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.ng = global.ng || {}, global.ng.cdk = global.ng.cdk || {}, global.ng.cdk.table = {}), global.ng.cdk.bidi, global.ng.cdk.coercion, global.ng.cdk.collections, global.ng.cdk.platform, global.ng.cdk.scrolling, global.ng.common, global.ng.core, global.rxjs, global.rxjs.operators));
5}(this, (function (exports, bidi, coercion, collections, platform, scrolling, common, core, rxjs, operators) { 'use strict';
6
7 /*! *****************************************************************************
8 Copyright (c) Microsoft Corporation.
9
10 Permission to use, copy, modify, and/or distribute this software for any
11 purpose with or without fee is hereby granted.
12
13 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
14 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
16 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
18 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 PERFORMANCE OF THIS SOFTWARE.
20 ***************************************************************************** */
21 /* global Reflect, Promise */
22 var extendStatics = function (d, b) {
23 extendStatics = Object.setPrototypeOf ||
24 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
25 function (d, b) { for (var p in b)
26 if (Object.prototype.hasOwnProperty.call(b, p))
27 d[p] = b[p]; };
28 return extendStatics(d, b);
29 };
30 function __extends(d, b) {
31 if (typeof b !== "function" && b !== null)
32 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
33 extendStatics(d, b);
34 function __() { this.constructor = d; }
35 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
36 }
37 var __assign = function () {
38 __assign = Object.assign || function __assign(t) {
39 for (var s, i = 1, n = arguments.length; i < n; i++) {
40 s = arguments[i];
41 for (var p in s)
42 if (Object.prototype.hasOwnProperty.call(s, p))
43 t[p] = s[p];
44 }
45 return t;
46 };
47 return __assign.apply(this, arguments);
48 };
49 function __rest(s, e) {
50 var t = {};
51 for (var p in s)
52 if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
53 t[p] = s[p];
54 if (s != null && typeof Object.getOwnPropertySymbols === "function")
55 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
56 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
57 t[p[i]] = s[p[i]];
58 }
59 return t;
60 }
61 function __decorate(decorators, target, key, desc) {
62 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
63 if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
64 r = Reflect.decorate(decorators, target, key, desc);
65 else
66 for (var i = decorators.length - 1; i >= 0; i--)
67 if (d = decorators[i])
68 r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
69 return c > 3 && r && Object.defineProperty(target, key, r), r;
70 }
71 function __param(paramIndex, decorator) {
72 return function (target, key) { decorator(target, key, paramIndex); };
73 }
74 function __metadata(metadataKey, metadataValue) {
75 if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
76 return Reflect.metadata(metadataKey, metadataValue);
77 }
78 function __awaiter(thisArg, _arguments, P, generator) {
79 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
80 return new (P || (P = Promise))(function (resolve, reject) {
81 function fulfilled(value) { try {
82 step(generator.next(value));
83 }
84 catch (e) {
85 reject(e);
86 } }
87 function rejected(value) { try {
88 step(generator["throw"](value));
89 }
90 catch (e) {
91 reject(e);
92 } }
93 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
94 step((generator = generator.apply(thisArg, _arguments || [])).next());
95 });
96 }
97 function __generator(thisArg, body) {
98 var _ = { label: 0, sent: function () { if (t[0] & 1)
99 throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
100 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g;
101 function verb(n) { return function (v) { return step([n, v]); }; }
102 function step(op) {
103 if (f)
104 throw new TypeError("Generator is already executing.");
105 while (_)
106 try {
107 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done)
108 return t;
109 if (y = 0, t)
110 op = [op[0] & 2, t.value];
111 switch (op[0]) {
112 case 0:
113 case 1:
114 t = op;
115 break;
116 case 4:
117 _.label++;
118 return { value: op[1], done: false };
119 case 5:
120 _.label++;
121 y = op[1];
122 op = [0];
123 continue;
124 case 7:
125 op = _.ops.pop();
126 _.trys.pop();
127 continue;
128 default:
129 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
130 _ = 0;
131 continue;
132 }
133 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) {
134 _.label = op[1];
135 break;
136 }
137 if (op[0] === 6 && _.label < t[1]) {
138 _.label = t[1];
139 t = op;
140 break;
141 }
142 if (t && _.label < t[2]) {
143 _.label = t[2];
144 _.ops.push(op);
145 break;
146 }
147 if (t[2])
148 _.ops.pop();
149 _.trys.pop();
150 continue;
151 }
152 op = body.call(thisArg, _);
153 }
154 catch (e) {
155 op = [6, e];
156 y = 0;
157 }
158 finally {
159 f = t = 0;
160 }
161 if (op[0] & 5)
162 throw op[1];
163 return { value: op[0] ? op[1] : void 0, done: true };
164 }
165 }
166 var __createBinding = Object.create ? (function (o, m, k, k2) {
167 if (k2 === undefined)
168 k2 = k;
169 Object.defineProperty(o, k2, { enumerable: true, get: function () { return m[k]; } });
170 }) : (function (o, m, k, k2) {
171 if (k2 === undefined)
172 k2 = k;
173 o[k2] = m[k];
174 });
175 function __exportStar(m, o) {
176 for (var p in m)
177 if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p))
178 __createBinding(o, m, p);
179 }
180 function __values(o) {
181 var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
182 if (m)
183 return m.call(o);
184 if (o && typeof o.length === "number")
185 return {
186 next: function () {
187 if (o && i >= o.length)
188 o = void 0;
189 return { value: o && o[i++], done: !o };
190 }
191 };
192 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
193 }
194 function __read(o, n) {
195 var m = typeof Symbol === "function" && o[Symbol.iterator];
196 if (!m)
197 return o;
198 var i = m.call(o), r, ar = [], e;
199 try {
200 while ((n === void 0 || n-- > 0) && !(r = i.next()).done)
201 ar.push(r.value);
202 }
203 catch (error) {
204 e = { error: error };
205 }
206 finally {
207 try {
208 if (r && !r.done && (m = i["return"]))
209 m.call(i);
210 }
211 finally {
212 if (e)
213 throw e.error;
214 }
215 }
216 return ar;
217 }
218 /** @deprecated */
219 function __spread() {
220 for (var ar = [], i = 0; i < arguments.length; i++)
221 ar = ar.concat(__read(arguments[i]));
222 return ar;
223 }
224 /** @deprecated */
225 function __spreadArrays() {
226 for (var s = 0, i = 0, il = arguments.length; i < il; i++)
227 s += arguments[i].length;
228 for (var r = Array(s), k = 0, i = 0; i < il; i++)
229 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
230 r[k] = a[j];
231 return r;
232 }
233 function __spreadArray(to, from, pack) {
234 if (pack || arguments.length === 2)
235 for (var i = 0, l = from.length, ar; i < l; i++) {
236 if (ar || !(i in from)) {
237 if (!ar)
238 ar = Array.prototype.slice.call(from, 0, i);
239 ar[i] = from[i];
240 }
241 }
242 return to.concat(ar || from);
243 }
244 function __await(v) {
245 return this instanceof __await ? (this.v = v, this) : new __await(v);
246 }
247 function __asyncGenerator(thisArg, _arguments, generator) {
248 if (!Symbol.asyncIterator)
249 throw new TypeError("Symbol.asyncIterator is not defined.");
250 var g = generator.apply(thisArg, _arguments || []), i, q = [];
251 return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
252 function verb(n) { if (g[n])
253 i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
254 function resume(n, v) { try {
255 step(g[n](v));
256 }
257 catch (e) {
258 settle(q[0][3], e);
259 } }
260 function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
261 function fulfill(value) { resume("next", value); }
262 function reject(value) { resume("throw", value); }
263 function settle(f, v) { if (f(v), q.shift(), q.length)
264 resume(q[0][0], q[0][1]); }
265 }
266 function __asyncDelegator(o) {
267 var i, p;
268 return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
269 function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
270 }
271 function __asyncValues(o) {
272 if (!Symbol.asyncIterator)
273 throw new TypeError("Symbol.asyncIterator is not defined.");
274 var m = o[Symbol.asyncIterator], i;
275 return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
276 function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
277 function settle(resolve, reject, d, v) { Promise.resolve(v).then(function (v) { resolve({ value: v, done: d }); }, reject); }
278 }
279 function __makeTemplateObject(cooked, raw) {
280 if (Object.defineProperty) {
281 Object.defineProperty(cooked, "raw", { value: raw });
282 }
283 else {
284 cooked.raw = raw;
285 }
286 return cooked;
287 }
288 ;
289 var __setModuleDefault = Object.create ? (function (o, v) {
290 Object.defineProperty(o, "default", { enumerable: true, value: v });
291 }) : function (o, v) {
292 o["default"] = v;
293 };
294 function __importStar(mod) {
295 if (mod && mod.__esModule)
296 return mod;
297 var result = {};
298 if (mod != null)
299 for (var k in mod)
300 if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k))
301 __createBinding(result, mod, k);
302 __setModuleDefault(result, mod);
303 return result;
304 }
305 function __importDefault(mod) {
306 return (mod && mod.__esModule) ? mod : { default: mod };
307 }
308 function __classPrivateFieldGet(receiver, state, kind, f) {
309 if (kind === "a" && !f)
310 throw new TypeError("Private accessor was defined without a getter");
311 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
312 throw new TypeError("Cannot read private member from an object whose class did not declare it");
313 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
314 }
315 function __classPrivateFieldSet(receiver, state, value, kind, f) {
316 if (kind === "m")
317 throw new TypeError("Private method is not writable");
318 if (kind === "a" && !f)
319 throw new TypeError("Private accessor was defined without a setter");
320 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
321 throw new TypeError("Cannot write private member to an object whose class did not declare it");
322 return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
323 }
324
325 /**
326 * Mixin to provide a directive with a function that checks if the sticky input has been
327 * changed since the last time the function was called. Essentially adds a dirty-check to the
328 * sticky value.
329 * @docs-private
330 */
331 function mixinHasStickyInput(base) {
332 return /** @class */ (function (_super) {
333 __extends(class_1, _super);
334 function class_1() {
335 var args = [];
336 for (var _i = 0; _i < arguments.length; _i++) {
337 args[_i] = arguments[_i];
338 }
339 var _this = _super.apply(this, __spreadArray([], __read(args))) || this;
340 _this._sticky = false;
341 /** Whether the sticky input has changed since it was last checked. */
342 _this._hasStickyChanged = false;
343 return _this;
344 }
345 Object.defineProperty(class_1.prototype, "sticky", {
346 /** Whether sticky positioning should be applied. */
347 get: function () { return this._sticky; },
348 set: function (v) {
349 var prevValue = this._sticky;
350 this._sticky = coercion.coerceBooleanProperty(v);
351 this._hasStickyChanged = prevValue !== this._sticky;
352 },
353 enumerable: false,
354 configurable: true
355 });
356 /** Whether the sticky value has changed since this was last called. */
357 class_1.prototype.hasStickyChanged = function () {
358 var hasStickyChanged = this._hasStickyChanged;
359 this._hasStickyChanged = false;
360 return hasStickyChanged;
361 };
362 /** Resets the dirty check for cases where the sticky state has been used without checking. */
363 class_1.prototype.resetStickyChanged = function () {
364 this._hasStickyChanged = false;
365 };
366 return class_1;
367 }(base));
368 }
369
370 /**
371 * @license
372 * Copyright Google LLC All Rights Reserved.
373 *
374 * Use of this source code is governed by an MIT-style license that can be
375 * found in the LICENSE file at https://angular.io/license
376 */
377 /**
378 * Used to provide a table to some of the sub-components without causing a circular dependency.
379 * @docs-private
380 */
381 var CDK_TABLE = new core.InjectionToken('CDK_TABLE');
382 /** Injection token that can be used to specify the text column options. */
383 var TEXT_COLUMN_OPTIONS = new core.InjectionToken('text-column-options');
384
385 /**
386 * Cell definition for a CDK table.
387 * Captures the template of a column's data row cell as well as cell-specific properties.
388 */
389 var CdkCellDef = /** @class */ (function () {
390 function CdkCellDef(/** @docs-private */ template) {
391 this.template = template;
392 }
393 return CdkCellDef;
394 }());
395 CdkCellDef.decorators = [
396 { type: core.Directive, args: [{ selector: '[cdkCellDef]' },] }
397 ];
398 CdkCellDef.ctorParameters = function () { return [
399 { type: core.TemplateRef }
400 ]; };
401 /**
402 * Header cell definition for a CDK table.
403 * Captures the template of a column's header cell and as well as cell-specific properties.
404 */
405 var CdkHeaderCellDef = /** @class */ (function () {
406 function CdkHeaderCellDef(/** @docs-private */ template) {
407 this.template = template;
408 }
409 return CdkHeaderCellDef;
410 }());
411 CdkHeaderCellDef.decorators = [
412 { type: core.Directive, args: [{ selector: '[cdkHeaderCellDef]' },] }
413 ];
414 CdkHeaderCellDef.ctorParameters = function () { return [
415 { type: core.TemplateRef }
416 ]; };
417 /**
418 * Footer cell definition for a CDK table.
419 * Captures the template of a column's footer cell and as well as cell-specific properties.
420 */
421 var CdkFooterCellDef = /** @class */ (function () {
422 function CdkFooterCellDef(/** @docs-private */ template) {
423 this.template = template;
424 }
425 return CdkFooterCellDef;
426 }());
427 CdkFooterCellDef.decorators = [
428 { type: core.Directive, args: [{ selector: '[cdkFooterCellDef]' },] }
429 ];
430 CdkFooterCellDef.ctorParameters = function () { return [
431 { type: core.TemplateRef }
432 ]; };
433 // Boilerplate for applying mixins to CdkColumnDef.
434 /** @docs-private */
435 var CdkColumnDefBase = /** @class */ (function () {
436 function CdkColumnDefBase() {
437 }
438 return CdkColumnDefBase;
439 }());
440 var _CdkColumnDefBase = mixinHasStickyInput(CdkColumnDefBase);
441 /**
442 * Column definition for the CDK table.
443 * Defines a set of cells available for a table column.
444 */
445 var CdkColumnDef = /** @class */ (function (_super) {
446 __extends(CdkColumnDef, _super);
447 function CdkColumnDef(_table) {
448 var _this = _super.call(this) || this;
449 _this._table = _table;
450 _this._stickyEnd = false;
451 return _this;
452 }
453 Object.defineProperty(CdkColumnDef.prototype, "name", {
454 /** Unique name for this column. */
455 get: function () { return this._name; },
456 set: function (name) { this._setNameInput(name); },
457 enumerable: false,
458 configurable: true
459 });
460 Object.defineProperty(CdkColumnDef.prototype, "stickyEnd", {
461 /**
462 * Whether this column should be sticky positioned on the end of the row. Should make sure
463 * that it mimics the `CanStick` mixin such that `_hasStickyChanged` is set to true if the value
464 * has been changed.
465 */
466 get: function () {
467 return this._stickyEnd;
468 },
469 set: function (v) {
470 var prevValue = this._stickyEnd;
471 this._stickyEnd = coercion.coerceBooleanProperty(v);
472 this._hasStickyChanged = prevValue !== this._stickyEnd;
473 },
474 enumerable: false,
475 configurable: true
476 });
477 /**
478 * Overridable method that sets the css classes that will be added to every cell in this
479 * column.
480 * In the future, columnCssClassName will change from type string[] to string and this
481 * will set a single string value.
482 * @docs-private
483 */
484 CdkColumnDef.prototype._updateColumnCssClassName = function () {
485 this._columnCssClassName = ["cdk-column-" + this.cssClassFriendlyName];
486 };
487 /**
488 * This has been extracted to a util because of TS 4 and VE.
489 * View Engine doesn't support property rename inheritance.
490 * TS 4.0 doesn't allow properties to override accessors or vice-versa.
491 * @docs-private
492 */
493 CdkColumnDef.prototype._setNameInput = function (value) {
494 // If the directive is set without a name (updated programmatically), then this setter will
495 // trigger with an empty string and should not overwrite the programmatically set value.
496 if (value) {
497 this._name = value;
498 this.cssClassFriendlyName = value.replace(/[^a-z0-9_-]/ig, '-');
499 this._updateColumnCssClassName();
500 }
501 };
502 return CdkColumnDef;
503 }(_CdkColumnDefBase));
504 CdkColumnDef.decorators = [
505 { type: core.Directive, args: [{
506 selector: '[cdkColumnDef]',
507 inputs: ['sticky'],
508 providers: [{ provide: 'MAT_SORT_HEADER_COLUMN_DEF', useExisting: CdkColumnDef }],
509 },] }
510 ];
511 CdkColumnDef.ctorParameters = function () { return [
512 { type: undefined, decorators: [{ type: core.Inject, args: [CDK_TABLE,] }, { type: core.Optional }] }
513 ]; };
514 CdkColumnDef.propDecorators = {
515 name: [{ type: core.Input, args: ['cdkColumnDef',] }],
516 stickyEnd: [{ type: core.Input, args: ['stickyEnd',] }],
517 cell: [{ type: core.ContentChild, args: [CdkCellDef,] }],
518 headerCell: [{ type: core.ContentChild, args: [CdkHeaderCellDef,] }],
519 footerCell: [{ type: core.ContentChild, args: [CdkFooterCellDef,] }]
520 };
521 /** Base class for the cells. Adds a CSS classname that identifies the column it renders in. */
522 var BaseCdkCell = /** @class */ (function () {
523 function BaseCdkCell(columnDef, elementRef) {
524 var e_1, _b;
525 // If IE 11 is dropped before we switch to setting a single class name, change to multi param
526 // with destructuring.
527 var classList = elementRef.nativeElement.classList;
528 try {
529 for (var _c = __values(columnDef._columnCssClassName), _d = _c.next(); !_d.done; _d = _c.next()) {
530 var className = _d.value;
531 classList.add(className);
532 }
533 }
534 catch (e_1_1) { e_1 = { error: e_1_1 }; }
535 finally {
536 try {
537 if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
538 }
539 finally { if (e_1) throw e_1.error; }
540 }
541 }
542 return BaseCdkCell;
543 }());
544 /** Header cell template container that adds the right classes and role. */
545 var CdkHeaderCell = /** @class */ (function (_super) {
546 __extends(CdkHeaderCell, _super);
547 function CdkHeaderCell(columnDef, elementRef) {
548 return _super.call(this, columnDef, elementRef) || this;
549 }
550 return CdkHeaderCell;
551 }(BaseCdkCell));
552 CdkHeaderCell.decorators = [
553 { type: core.Directive, args: [{
554 selector: 'cdk-header-cell, th[cdk-header-cell]',
555 host: {
556 'class': 'cdk-header-cell',
557 'role': 'columnheader',
558 },
559 },] }
560 ];
561 CdkHeaderCell.ctorParameters = function () { return [
562 { type: CdkColumnDef },
563 { type: core.ElementRef }
564 ]; };
565 /** Footer cell template container that adds the right classes and role. */
566 var CdkFooterCell = /** @class */ (function (_super) {
567 __extends(CdkFooterCell, _super);
568 function CdkFooterCell(columnDef, elementRef) {
569 var _this = this;
570 var _a;
571 _this = _super.call(this, columnDef, elementRef) || this;
572 if (((_a = columnDef._table) === null || _a === void 0 ? void 0 : _a._elementRef.nativeElement.nodeType) === 1) {
573 var tableRole = columnDef._table._elementRef.nativeElement
574 .getAttribute('role');
575 var role = (tableRole === 'grid' || tableRole === 'treegrid') ? 'gridcell' : 'cell';
576 elementRef.nativeElement.setAttribute('role', role);
577 }
578 return _this;
579 }
580 return CdkFooterCell;
581 }(BaseCdkCell));
582 CdkFooterCell.decorators = [
583 { type: core.Directive, args: [{
584 selector: 'cdk-footer-cell, td[cdk-footer-cell]',
585 host: {
586 'class': 'cdk-footer-cell',
587 },
588 },] }
589 ];
590 CdkFooterCell.ctorParameters = function () { return [
591 { type: CdkColumnDef },
592 { type: core.ElementRef }
593 ]; };
594 /** Cell template container that adds the right classes and role. */
595 var CdkCell = /** @class */ (function (_super) {
596 __extends(CdkCell, _super);
597 function CdkCell(columnDef, elementRef) {
598 var _this = this;
599 var _a;
600 _this = _super.call(this, columnDef, elementRef) || this;
601 if (((_a = columnDef._table) === null || _a === void 0 ? void 0 : _a._elementRef.nativeElement.nodeType) === 1) {
602 var tableRole = columnDef._table._elementRef.nativeElement
603 .getAttribute('role');
604 var role = (tableRole === 'grid' || tableRole === 'treegrid') ? 'gridcell' : 'cell';
605 elementRef.nativeElement.setAttribute('role', role);
606 }
607 return _this;
608 }
609 return CdkCell;
610 }(BaseCdkCell));
611 CdkCell.decorators = [
612 { type: core.Directive, args: [{
613 selector: 'cdk-cell, td[cdk-cell]',
614 host: {
615 'class': 'cdk-cell',
616 },
617 },] }
618 ];
619 CdkCell.ctorParameters = function () { return [
620 { type: CdkColumnDef },
621 { type: core.ElementRef }
622 ]; };
623
624 /**
625 * @docs-private
626 */
627 var _Schedule = /** @class */ (function () {
628 function _Schedule() {
629 this.tasks = [];
630 this.endTasks = [];
631 }
632 return _Schedule;
633 }());
634 /** Injection token used to provide a coalesced style scheduler. */
635 var _COALESCED_STYLE_SCHEDULER = new core.InjectionToken('_COALESCED_STYLE_SCHEDULER');
636 /**
637 * Allows grouping up CSSDom mutations after the current execution context.
638 * This can significantly improve performance when separate consecutive functions are
639 * reading from the CSSDom and then mutating it.
640 *
641 * @docs-private
642 */
643 var _CoalescedStyleScheduler = /** @class */ (function () {
644 function _CoalescedStyleScheduler(_ngZone) {
645 this._ngZone = _ngZone;
646 this._currentSchedule = null;
647 this._destroyed = new rxjs.Subject();
648 }
649 /**
650 * Schedules the specified task to run at the end of the current VM turn.
651 */
652 _CoalescedStyleScheduler.prototype.schedule = function (task) {
653 this._createScheduleIfNeeded();
654 this._currentSchedule.tasks.push(task);
655 };
656 /**
657 * Schedules the specified task to run after other scheduled tasks at the end of the current
658 * VM turn.
659 */
660 _CoalescedStyleScheduler.prototype.scheduleEnd = function (task) {
661 this._createScheduleIfNeeded();
662 this._currentSchedule.endTasks.push(task);
663 };
664 /** Prevent any further tasks from running. */
665 _CoalescedStyleScheduler.prototype.ngOnDestroy = function () {
666 this._destroyed.next();
667 this._destroyed.complete();
668 };
669 _CoalescedStyleScheduler.prototype._createScheduleIfNeeded = function () {
670 var _this = this;
671 if (this._currentSchedule) {
672 return;
673 }
674 this._currentSchedule = new _Schedule();
675 this._getScheduleObservable().pipe(operators.takeUntil(this._destroyed)).subscribe(function () {
676 var e_1, _a, e_2, _b;
677 while (_this._currentSchedule.tasks.length || _this._currentSchedule.endTasks.length) {
678 var schedule = _this._currentSchedule;
679 // Capture new tasks scheduled by the current set of tasks.
680 _this._currentSchedule = new _Schedule();
681 try {
682 for (var _c = (e_1 = void 0, __values(schedule.tasks)), _d = _c.next(); !_d.done; _d = _c.next()) {
683 var task = _d.value;
684 task();
685 }
686 }
687 catch (e_1_1) { e_1 = { error: e_1_1 }; }
688 finally {
689 try {
690 if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
691 }
692 finally { if (e_1) throw e_1.error; }
693 }
694 try {
695 for (var _e = (e_2 = void 0, __values(schedule.endTasks)), _f = _e.next(); !_f.done; _f = _e.next()) {
696 var task = _f.value;
697 task();
698 }
699 }
700 catch (e_2_1) { e_2 = { error: e_2_1 }; }
701 finally {
702 try {
703 if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
704 }
705 finally { if (e_2) throw e_2.error; }
706 }
707 }
708 _this._currentSchedule = null;
709 });
710 };
711 _CoalescedStyleScheduler.prototype._getScheduleObservable = function () {
712 // Use onStable when in the context of an ongoing change detection cycle so that we
713 // do not accidentally trigger additional cycles.
714 return this._ngZone.isStable ?
715 rxjs.from(Promise.resolve(undefined)) :
716 this._ngZone.onStable.pipe(operators.take(1));
717 };
718 return _CoalescedStyleScheduler;
719 }());
720 _CoalescedStyleScheduler.decorators = [
721 { type: core.Injectable }
722 ];
723 _CoalescedStyleScheduler.ctorParameters = function () { return [
724 { type: core.NgZone }
725 ]; };
726
727 /**
728 * The row template that can be used by the mat-table. Should not be used outside of the
729 * material library.
730 */
731 var CDK_ROW_TEMPLATE = "<ng-container cdkCellOutlet></ng-container>";
732 /**
733 * Base class for the CdkHeaderRowDef and CdkRowDef that handles checking their columns inputs
734 * for changes and notifying the table.
735 */
736 var BaseRowDef = /** @class */ (function () {
737 function BaseRowDef(
738 /** @docs-private */ template, _differs) {
739 this.template = template;
740 this._differs = _differs;
741 }
742 BaseRowDef.prototype.ngOnChanges = function (changes) {
743 // Create a new columns differ if one does not yet exist. Initialize it based on initial value
744 // of the columns property or an empty array if none is provided.
745 if (!this._columnsDiffer) {
746 var columns = (changes['columns'] && changes['columns'].currentValue) || [];
747 this._columnsDiffer = this._differs.find(columns).create();
748 this._columnsDiffer.diff(columns);
749 }
750 };
751 /**
752 * Returns the difference between the current columns and the columns from the last diff, or null
753 * if there is no difference.
754 */
755 BaseRowDef.prototype.getColumnsDiff = function () {
756 return this._columnsDiffer.diff(this.columns);
757 };
758 /** Gets this row def's relevant cell template from the provided column def. */
759 BaseRowDef.prototype.extractCellTemplate = function (column) {
760 if (this instanceof CdkHeaderRowDef) {
761 return column.headerCell.template;
762 }
763 if (this instanceof CdkFooterRowDef) {
764 return column.footerCell.template;
765 }
766 else {
767 return column.cell.template;
768 }
769 };
770 return BaseRowDef;
771 }());
772 BaseRowDef.decorators = [
773 { type: core.Directive }
774 ];
775 BaseRowDef.ctorParameters = function () { return [
776 { type: core.TemplateRef },
777 { type: core.IterableDiffers }
778 ]; };
779 // Boilerplate for applying mixins to CdkHeaderRowDef.
780 /** @docs-private */
781 var CdkHeaderRowDefBase = /** @class */ (function (_super) {
782 __extends(CdkHeaderRowDefBase, _super);
783 function CdkHeaderRowDefBase() {
784 return _super !== null && _super.apply(this, arguments) || this;
785 }
786 return CdkHeaderRowDefBase;
787 }(BaseRowDef));
788 var _CdkHeaderRowDefBase = mixinHasStickyInput(CdkHeaderRowDefBase);
789 /**
790 * Header row definition for the CDK table.
791 * Captures the header row's template and other header properties such as the columns to display.
792 */
793 var CdkHeaderRowDef = /** @class */ (function (_super) {
794 __extends(CdkHeaderRowDef, _super);
795 function CdkHeaderRowDef(template, _differs, _table) {
796 var _this = _super.call(this, template, _differs) || this;
797 _this._table = _table;
798 return _this;
799 }
800 // Prerender fails to recognize that ngOnChanges in a part of this class through inheritance.
801 // Explicitly define it so that the method is called as part of the Angular lifecycle.
802 CdkHeaderRowDef.prototype.ngOnChanges = function (changes) {
803 _super.prototype.ngOnChanges.call(this, changes);
804 };
805 return CdkHeaderRowDef;
806 }(_CdkHeaderRowDefBase));
807 CdkHeaderRowDef.decorators = [
808 { type: core.Directive, args: [{
809 selector: '[cdkHeaderRowDef]',
810 inputs: ['columns: cdkHeaderRowDef', 'sticky: cdkHeaderRowDefSticky'],
811 },] }
812 ];
813 CdkHeaderRowDef.ctorParameters = function () { return [
814 { type: core.TemplateRef },
815 { type: core.IterableDiffers },
816 { type: undefined, decorators: [{ type: core.Inject, args: [CDK_TABLE,] }, { type: core.Optional }] }
817 ]; };
818 // Boilerplate for applying mixins to CdkFooterRowDef.
819 /** @docs-private */
820 var CdkFooterRowDefBase = /** @class */ (function (_super) {
821 __extends(CdkFooterRowDefBase, _super);
822 function CdkFooterRowDefBase() {
823 return _super !== null && _super.apply(this, arguments) || this;
824 }
825 return CdkFooterRowDefBase;
826 }(BaseRowDef));
827 var _CdkFooterRowDefBase = mixinHasStickyInput(CdkFooterRowDefBase);
828 /**
829 * Footer row definition for the CDK table.
830 * Captures the footer row's template and other footer properties such as the columns to display.
831 */
832 var CdkFooterRowDef = /** @class */ (function (_super) {
833 __extends(CdkFooterRowDef, _super);
834 function CdkFooterRowDef(template, _differs, _table) {
835 var _this = _super.call(this, template, _differs) || this;
836 _this._table = _table;
837 return _this;
838 }
839 // Prerender fails to recognize that ngOnChanges in a part of this class through inheritance.
840 // Explicitly define it so that the method is called as part of the Angular lifecycle.
841 CdkFooterRowDef.prototype.ngOnChanges = function (changes) {
842 _super.prototype.ngOnChanges.call(this, changes);
843 };
844 return CdkFooterRowDef;
845 }(_CdkFooterRowDefBase));
846 CdkFooterRowDef.decorators = [
847 { type: core.Directive, args: [{
848 selector: '[cdkFooterRowDef]',
849 inputs: ['columns: cdkFooterRowDef', 'sticky: cdkFooterRowDefSticky'],
850 },] }
851 ];
852 CdkFooterRowDef.ctorParameters = function () { return [
853 { type: core.TemplateRef },
854 { type: core.IterableDiffers },
855 { type: undefined, decorators: [{ type: core.Inject, args: [CDK_TABLE,] }, { type: core.Optional }] }
856 ]; };
857 /**
858 * Data row definition for the CDK table.
859 * Captures the header row's template and other row properties such as the columns to display and
860 * a when predicate that describes when this row should be used.
861 */
862 var CdkRowDef = /** @class */ (function (_super) {
863 __extends(CdkRowDef, _super);
864 // TODO(andrewseguin): Add an input for providing a switch function to determine
865 // if this template should be used.
866 function CdkRowDef(template, _differs, _table) {
867 var _this = _super.call(this, template, _differs) || this;
868 _this._table = _table;
869 return _this;
870 }
871 return CdkRowDef;
872 }(BaseRowDef));
873 CdkRowDef.decorators = [
874 { type: core.Directive, args: [{
875 selector: '[cdkRowDef]',
876 inputs: ['columns: cdkRowDefColumns', 'when: cdkRowDefWhen'],
877 },] }
878 ];
879 CdkRowDef.ctorParameters = function () { return [
880 { type: core.TemplateRef },
881 { type: core.IterableDiffers },
882 { type: undefined, decorators: [{ type: core.Inject, args: [CDK_TABLE,] }, { type: core.Optional }] }
883 ]; };
884 /**
885 * Outlet for rendering cells inside of a row or header row.
886 * @docs-private
887 */
888 var CdkCellOutlet = /** @class */ (function () {
889 function CdkCellOutlet(_viewContainer) {
890 this._viewContainer = _viewContainer;
891 CdkCellOutlet.mostRecentCellOutlet = this;
892 }
893 CdkCellOutlet.prototype.ngOnDestroy = function () {
894 // If this was the last outlet being rendered in the view, remove the reference
895 // from the static property after it has been destroyed to avoid leaking memory.
896 if (CdkCellOutlet.mostRecentCellOutlet === this) {
897 CdkCellOutlet.mostRecentCellOutlet = null;
898 }
899 };
900 return CdkCellOutlet;
901 }());
902 /**
903 * Static property containing the latest constructed instance of this class.
904 * Used by the CDK table when each CdkHeaderRow and CdkRow component is created using
905 * createEmbeddedView. After one of these components are created, this property will provide
906 * a handle to provide that component's cells and context. After init, the CdkCellOutlet will
907 * construct the cells with the provided context.
908 */
909 CdkCellOutlet.mostRecentCellOutlet = null;
910 CdkCellOutlet.decorators = [
911 { type: core.Directive, args: [{ selector: '[cdkCellOutlet]' },] }
912 ];
913 CdkCellOutlet.ctorParameters = function () { return [
914 { type: core.ViewContainerRef }
915 ]; };
916 /** Header template container that contains the cell outlet. Adds the right class and role. */
917 var CdkHeaderRow = /** @class */ (function () {
918 function CdkHeaderRow() {
919 }
920 return CdkHeaderRow;
921 }());
922 CdkHeaderRow.decorators = [
923 { type: core.Component, args: [{
924 selector: 'cdk-header-row, tr[cdk-header-row]',
925 template: CDK_ROW_TEMPLATE,
926 host: {
927 'class': 'cdk-header-row',
928 'role': 'row',
929 },
930 // See note on CdkTable for explanation on why this uses the default change detection strategy.
931 // tslint:disable-next-line:validate-decorators
932 changeDetection: core.ChangeDetectionStrategy.Default,
933 encapsulation: core.ViewEncapsulation.None
934 },] }
935 ];
936 /** Footer template container that contains the cell outlet. Adds the right class and role. */
937 var CdkFooterRow = /** @class */ (function () {
938 function CdkFooterRow() {
939 }
940 return CdkFooterRow;
941 }());
942 CdkFooterRow.decorators = [
943 { type: core.Component, args: [{
944 selector: 'cdk-footer-row, tr[cdk-footer-row]',
945 template: CDK_ROW_TEMPLATE,
946 host: {
947 'class': 'cdk-footer-row',
948 'role': 'row',
949 },
950 // See note on CdkTable for explanation on why this uses the default change detection strategy.
951 // tslint:disable-next-line:validate-decorators
952 changeDetection: core.ChangeDetectionStrategy.Default,
953 encapsulation: core.ViewEncapsulation.None
954 },] }
955 ];
956 /** Data row template container that contains the cell outlet. Adds the right class and role. */
957 var CdkRow = /** @class */ (function () {
958 function CdkRow() {
959 }
960 return CdkRow;
961 }());
962 CdkRow.decorators = [
963 { type: core.Component, args: [{
964 selector: 'cdk-row, tr[cdk-row]',
965 template: CDK_ROW_TEMPLATE,
966 host: {
967 'class': 'cdk-row',
968 'role': 'row',
969 },
970 // See note on CdkTable for explanation on why this uses the default change detection strategy.
971 // tslint:disable-next-line:validate-decorators
972 changeDetection: core.ChangeDetectionStrategy.Default,
973 encapsulation: core.ViewEncapsulation.None
974 },] }
975 ];
976 /** Row that can be used to display a message when no data is shown in the table. */
977 var CdkNoDataRow = /** @class */ (function () {
978 function CdkNoDataRow(templateRef) {
979 this.templateRef = templateRef;
980 }
981 return CdkNoDataRow;
982 }());
983 CdkNoDataRow.decorators = [
984 { type: core.Directive, args: [{
985 selector: 'ng-template[cdkNoDataRow]'
986 },] }
987 ];
988 CdkNoDataRow.ctorParameters = function () { return [
989 { type: core.TemplateRef }
990 ]; };
991
992 /**
993 * @license
994 * Copyright Google LLC All Rights Reserved.
995 *
996 * Use of this source code is governed by an MIT-style license that can be
997 * found in the LICENSE file at https://angular.io/license
998 */
999 /**
1000 * List of all possible directions that can be used for sticky positioning.
1001 * @docs-private
1002 */
1003 var STICKY_DIRECTIONS = ['top', 'bottom', 'left', 'right'];
1004 /**
1005 * Applies and removes sticky positioning styles to the `CdkTable` rows and columns cells.
1006 * @docs-private
1007 */
1008 var StickyStyler = /** @class */ (function () {
1009 /**
1010 * @param _isNativeHtmlTable Whether the sticky logic should be based on a table
1011 * that uses the native `<table>` element.
1012 * @param _stickCellCss The CSS class that will be applied to every row/cell that has
1013 * sticky positioning applied.
1014 * @param direction The directionality context of the table (ltr/rtl); affects column positioning
1015 * by reversing left/right positions.
1016 * @param _isBrowser Whether the table is currently being rendered on the server or the client.
1017 * @param _needsPositionStickyOnElement Whether we need to specify position: sticky on cells
1018 * using inline styles. If false, it is assumed that position: sticky is included in
1019 * the component stylesheet for _stickCellCss.
1020 * @param _positionListener A listener that is notified of changes to sticky rows/columns
1021 * and their dimensions.
1022 */
1023 function StickyStyler(_isNativeHtmlTable, _stickCellCss, direction, _coalescedStyleScheduler, _isBrowser, _needsPositionStickyOnElement, _positionListener) {
1024 if (_isBrowser === void 0) { _isBrowser = true; }
1025 if (_needsPositionStickyOnElement === void 0) { _needsPositionStickyOnElement = true; }
1026 this._isNativeHtmlTable = _isNativeHtmlTable;
1027 this._stickCellCss = _stickCellCss;
1028 this.direction = direction;
1029 this._coalescedStyleScheduler = _coalescedStyleScheduler;
1030 this._isBrowser = _isBrowser;
1031 this._needsPositionStickyOnElement = _needsPositionStickyOnElement;
1032 this._positionListener = _positionListener;
1033 this._cachedCellWidths = [];
1034 this._borderCellCss = {
1035 'top': _stickCellCss + "-border-elem-top",
1036 'bottom': _stickCellCss + "-border-elem-bottom",
1037 'left': _stickCellCss + "-border-elem-left",
1038 'right': _stickCellCss + "-border-elem-right",
1039 };
1040 }
1041 /**
1042 * Clears the sticky positioning styles from the row and its cells by resetting the `position`
1043 * style, setting the zIndex to 0, and unsetting each provided sticky direction.
1044 * @param rows The list of rows that should be cleared from sticking in the provided directions
1045 * @param stickyDirections The directions that should no longer be set as sticky on the rows.
1046 */
1047 StickyStyler.prototype.clearStickyPositioning = function (rows, stickyDirections) {
1048 var e_1, _c;
1049 var _this = this;
1050 var elementsToClear = [];
1051 try {
1052 for (var rows_1 = __values(rows), rows_1_1 = rows_1.next(); !rows_1_1.done; rows_1_1 = rows_1.next()) {
1053 var row = rows_1_1.value;
1054 // If the row isn't an element (e.g. if it's an `ng-container`),
1055 // it won't have inline styles or `children` so we skip it.
1056 if (row.nodeType !== row.ELEMENT_NODE) {
1057 continue;
1058 }
1059 elementsToClear.push(row);
1060 for (var i = 0; i < row.children.length; i++) {
1061 elementsToClear.push(row.children[i]);
1062 }
1063 }
1064 }
1065 catch (e_1_1) { e_1 = { error: e_1_1 }; }
1066 finally {
1067 try {
1068 if (rows_1_1 && !rows_1_1.done && (_c = rows_1.return)) _c.call(rows_1);
1069 }
1070 finally { if (e_1) throw e_1.error; }
1071 }
1072 // Coalesce with sticky row/column updates (and potentially other changes like column resize).
1073 this._coalescedStyleScheduler.schedule(function () {
1074 var e_2, _c;
1075 try {
1076 for (var elementsToClear_1 = __values(elementsToClear), elementsToClear_1_1 = elementsToClear_1.next(); !elementsToClear_1_1.done; elementsToClear_1_1 = elementsToClear_1.next()) {
1077 var element = elementsToClear_1_1.value;
1078 _this._removeStickyStyle(element, stickyDirections);
1079 }
1080 }
1081 catch (e_2_1) { e_2 = { error: e_2_1 }; }
1082 finally {
1083 try {
1084 if (elementsToClear_1_1 && !elementsToClear_1_1.done && (_c = elementsToClear_1.return)) _c.call(elementsToClear_1);
1085 }
1086 finally { if (e_2) throw e_2.error; }
1087 }
1088 });
1089 };
1090 /**
1091 * Applies sticky left and right positions to the cells of each row according to the sticky
1092 * states of the rendered column definitions.
1093 * @param rows The rows that should have its set of cells stuck according to the sticky states.
1094 * @param stickyStartStates A list of boolean states where each state represents whether the cell
1095 * in this index position should be stuck to the start of the row.
1096 * @param stickyEndStates A list of boolean states where each state represents whether the cell
1097 * in this index position should be stuck to the end of the row.
1098 * @param recalculateCellWidths Whether the sticky styler should recalculate the width of each
1099 * column cell. If `false` cached widths will be used instead.
1100 */
1101 StickyStyler.prototype.updateStickyColumns = function (rows, stickyStartStates, stickyEndStates, recalculateCellWidths) {
1102 var _this = this;
1103 if (recalculateCellWidths === void 0) { recalculateCellWidths = true; }
1104 if (!rows.length || !this._isBrowser || !(stickyStartStates.some(function (state) { return state; }) ||
1105 stickyEndStates.some(function (state) { return state; }))) {
1106 if (this._positionListener) {
1107 this._positionListener.stickyColumnsUpdated({ sizes: [] });
1108 this._positionListener.stickyEndColumnsUpdated({ sizes: [] });
1109 }
1110 return;
1111 }
1112 var firstRow = rows[0];
1113 var numCells = firstRow.children.length;
1114 var cellWidths = this._getCellWidths(firstRow, recalculateCellWidths);
1115 var startPositions = this._getStickyStartColumnPositions(cellWidths, stickyStartStates);
1116 var endPositions = this._getStickyEndColumnPositions(cellWidths, stickyEndStates);
1117 var lastStickyStart = stickyStartStates.lastIndexOf(true);
1118 var firstStickyEnd = stickyEndStates.indexOf(true);
1119 // Coalesce with sticky row updates (and potentially other changes like column resize).
1120 this._coalescedStyleScheduler.schedule(function () {
1121 var e_3, _c;
1122 var isRtl = _this.direction === 'rtl';
1123 var start = isRtl ? 'right' : 'left';
1124 var end = isRtl ? 'left' : 'right';
1125 try {
1126 for (var rows_2 = __values(rows), rows_2_1 = rows_2.next(); !rows_2_1.done; rows_2_1 = rows_2.next()) {
1127 var row = rows_2_1.value;
1128 for (var i = 0; i < numCells; i++) {
1129 var cell = row.children[i];
1130 if (stickyStartStates[i]) {
1131 _this._addStickyStyle(cell, start, startPositions[i], i === lastStickyStart);
1132 }
1133 if (stickyEndStates[i]) {
1134 _this._addStickyStyle(cell, end, endPositions[i], i === firstStickyEnd);
1135 }
1136 }
1137 }
1138 }
1139 catch (e_3_1) { e_3 = { error: e_3_1 }; }
1140 finally {
1141 try {
1142 if (rows_2_1 && !rows_2_1.done && (_c = rows_2.return)) _c.call(rows_2);
1143 }
1144 finally { if (e_3) throw e_3.error; }
1145 }
1146 if (_this._positionListener) {
1147 _this._positionListener.stickyColumnsUpdated({
1148 sizes: lastStickyStart === -1 ?
1149 [] :
1150 cellWidths
1151 .slice(0, lastStickyStart + 1)
1152 .map(function (width, index) { return stickyStartStates[index] ? width : null; })
1153 });
1154 _this._positionListener.stickyEndColumnsUpdated({
1155 sizes: firstStickyEnd === -1 ?
1156 [] :
1157 cellWidths
1158 .slice(firstStickyEnd)
1159 .map(function (width, index) { return stickyEndStates[index + firstStickyEnd] ? width : null; })
1160 .reverse()
1161 });
1162 }
1163 });
1164 };
1165 /**
1166 * Applies sticky positioning to the row's cells if using the native table layout, and to the
1167 * row itself otherwise.
1168 * @param rowsToStick The list of rows that should be stuck according to their corresponding
1169 * sticky state and to the provided top or bottom position.
1170 * @param stickyStates A list of boolean states where each state represents whether the row
1171 * should be stuck in the particular top or bottom position.
1172 * @param position The position direction in which the row should be stuck if that row should be
1173 * sticky.
1174 *
1175 */
1176 StickyStyler.prototype.stickRows = function (rowsToStick, stickyStates, position) {
1177 var _this = this;
1178 // Since we can't measure the rows on the server, we can't stick the rows properly.
1179 if (!this._isBrowser) {
1180 return;
1181 }
1182 // If positioning the rows to the bottom, reverse their order when evaluating the sticky
1183 // position such that the last row stuck will be "bottom: 0px" and so on. Note that the
1184 // sticky states need to be reversed as well.
1185 var rows = position === 'bottom' ? rowsToStick.slice().reverse() : rowsToStick;
1186 var states = position === 'bottom' ? stickyStates.slice().reverse() : stickyStates;
1187 // Measure row heights all at once before adding sticky styles to reduce layout thrashing.
1188 var stickyOffsets = [];
1189 var stickyCellHeights = [];
1190 var elementsToStick = [];
1191 for (var rowIndex = 0, stickyOffset = 0; rowIndex < rows.length; rowIndex++) {
1192 if (!states[rowIndex]) {
1193 continue;
1194 }
1195 stickyOffsets[rowIndex] = stickyOffset;
1196 var row = rows[rowIndex];
1197 elementsToStick[rowIndex] = this._isNativeHtmlTable ?
1198 Array.from(row.children) : [row];
1199 var height = row.getBoundingClientRect().height;
1200 stickyOffset += height;
1201 stickyCellHeights[rowIndex] = height;
1202 }
1203 var borderedRowIndex = states.lastIndexOf(true);
1204 // Coalesce with other sticky row updates (top/bottom), sticky columns updates
1205 // (and potentially other changes like column resize).
1206 this._coalescedStyleScheduler.schedule(function () {
1207 var e_4, _c;
1208 var _a, _b;
1209 for (var rowIndex = 0; rowIndex < rows.length; rowIndex++) {
1210 if (!states[rowIndex]) {
1211 continue;
1212 }
1213 var offset = stickyOffsets[rowIndex];
1214 var isBorderedRowIndex = rowIndex === borderedRowIndex;
1215 try {
1216 for (var _d = (e_4 = void 0, __values(elementsToStick[rowIndex])), _e = _d.next(); !_e.done; _e = _d.next()) {
1217 var element = _e.value;
1218 _this._addStickyStyle(element, position, offset, isBorderedRowIndex);
1219 }
1220 }
1221 catch (e_4_1) { e_4 = { error: e_4_1 }; }
1222 finally {
1223 try {
1224 if (_e && !_e.done && (_c = _d.return)) _c.call(_d);
1225 }
1226 finally { if (e_4) throw e_4.error; }
1227 }
1228 }
1229 if (position === 'top') {
1230 (_a = _this._positionListener) === null || _a === void 0 ? void 0 : _a.stickyHeaderRowsUpdated({ sizes: stickyCellHeights, offsets: stickyOffsets, elements: elementsToStick });
1231 }
1232 else {
1233 (_b = _this._positionListener) === null || _b === void 0 ? void 0 : _b.stickyFooterRowsUpdated({ sizes: stickyCellHeights, offsets: stickyOffsets, elements: elementsToStick });
1234 }
1235 });
1236 };
1237 /**
1238 * When using the native table in Safari, sticky footer cells do not stick. The only way to stick
1239 * footer rows is to apply sticky styling to the tfoot container. This should only be done if
1240 * all footer rows are sticky. If not all footer rows are sticky, remove sticky positioning from
1241 * the tfoot element.
1242 */
1243 StickyStyler.prototype.updateStickyFooterContainer = function (tableElement, stickyStates) {
1244 var _this = this;
1245 if (!this._isNativeHtmlTable) {
1246 return;
1247 }
1248 var tfoot = tableElement.querySelector('tfoot');
1249 // Coalesce with other sticky updates (and potentially other changes like column resize).
1250 this._coalescedStyleScheduler.schedule(function () {
1251 if (stickyStates.some(function (state) { return !state; })) {
1252 _this._removeStickyStyle(tfoot, ['bottom']);
1253 }
1254 else {
1255 _this._addStickyStyle(tfoot, 'bottom', 0, false);
1256 }
1257 });
1258 };
1259 /**
1260 * Removes the sticky style on the element by removing the sticky cell CSS class, re-evaluating
1261 * the zIndex, removing each of the provided sticky directions, and removing the
1262 * sticky position if there are no more directions.
1263 */
1264 StickyStyler.prototype._removeStickyStyle = function (element, stickyDirections) {
1265 var e_5, _c;
1266 try {
1267 for (var stickyDirections_1 = __values(stickyDirections), stickyDirections_1_1 = stickyDirections_1.next(); !stickyDirections_1_1.done; stickyDirections_1_1 = stickyDirections_1.next()) {
1268 var dir = stickyDirections_1_1.value;
1269 element.style[dir] = '';
1270 element.classList.remove(this._borderCellCss[dir]);
1271 }
1272 }
1273 catch (e_5_1) { e_5 = { error: e_5_1 }; }
1274 finally {
1275 try {
1276 if (stickyDirections_1_1 && !stickyDirections_1_1.done && (_c = stickyDirections_1.return)) _c.call(stickyDirections_1);
1277 }
1278 finally { if (e_5) throw e_5.error; }
1279 }
1280 // If the element no longer has any more sticky directions, remove sticky positioning and
1281 // the sticky CSS class.
1282 // Short-circuit checking element.style[dir] for stickyDirections as they
1283 // were already removed above.
1284 var hasDirection = STICKY_DIRECTIONS.some(function (dir) { return stickyDirections.indexOf(dir) === -1 && element.style[dir]; });
1285 if (hasDirection) {
1286 element.style.zIndex = this._getCalculatedZIndex(element);
1287 }
1288 else {
1289 // When not hasDirection, _getCalculatedZIndex will always return ''.
1290 element.style.zIndex = '';
1291 if (this._needsPositionStickyOnElement) {
1292 element.style.position = '';
1293 }
1294 element.classList.remove(this._stickCellCss);
1295 }
1296 };
1297 /**
1298 * Adds the sticky styling to the element by adding the sticky style class, changing position
1299 * to be sticky (and -webkit-sticky), setting the appropriate zIndex, and adding a sticky
1300 * direction and value.
1301 */
1302 StickyStyler.prototype._addStickyStyle = function (element, dir, dirValue, isBorderElement) {
1303 element.classList.add(this._stickCellCss);
1304 if (isBorderElement) {
1305 element.classList.add(this._borderCellCss[dir]);
1306 }
1307 element.style[dir] = dirValue + "px";
1308 element.style.zIndex = this._getCalculatedZIndex(element);
1309 if (this._needsPositionStickyOnElement) {
1310 element.style.cssText += 'position: -webkit-sticky; position: sticky; ';
1311 }
1312 };
1313 /**
1314 * Calculate what the z-index should be for the element, depending on what directions (top,
1315 * bottom, left, right) have been set. It should be true that elements with a top direction
1316 * should have the highest index since these are elements like a table header. If any of those
1317 * elements are also sticky in another direction, then they should appear above other elements
1318 * that are only sticky top (e.g. a sticky column on a sticky header). Bottom-sticky elements
1319 * (e.g. footer rows) should then be next in the ordering such that they are below the header
1320 * but above any non-sticky elements. Finally, left/right sticky elements (e.g. sticky columns)
1321 * should minimally increment so that they are above non-sticky elements but below top and bottom
1322 * elements.
1323 */
1324 StickyStyler.prototype._getCalculatedZIndex = function (element) {
1325 var e_6, _c;
1326 var zIndexIncrements = {
1327 top: 100,
1328 bottom: 10,
1329 left: 1,
1330 right: 1,
1331 };
1332 var zIndex = 0;
1333 try {
1334 // Use `Iterable` instead of `Array` because TypeScript, as of 3.6.3,
1335 // loses the array generic type in the `for of`. But we *also* have to use `Array` because
1336 // typescript won't iterate over an `Iterable` unless you compile with `--downlevelIteration`
1337 for (var STICKY_DIRECTIONS_1 = __values(STICKY_DIRECTIONS), STICKY_DIRECTIONS_1_1 = STICKY_DIRECTIONS_1.next(); !STICKY_DIRECTIONS_1_1.done; STICKY_DIRECTIONS_1_1 = STICKY_DIRECTIONS_1.next()) {
1338 var dir = STICKY_DIRECTIONS_1_1.value;
1339 if (element.style[dir]) {
1340 zIndex += zIndexIncrements[dir];
1341 }
1342 }
1343 }
1344 catch (e_6_1) { e_6 = { error: e_6_1 }; }
1345 finally {
1346 try {
1347 if (STICKY_DIRECTIONS_1_1 && !STICKY_DIRECTIONS_1_1.done && (_c = STICKY_DIRECTIONS_1.return)) _c.call(STICKY_DIRECTIONS_1);
1348 }
1349 finally { if (e_6) throw e_6.error; }
1350 }
1351 return zIndex ? "" + zIndex : '';
1352 };
1353 /** Gets the widths for each cell in the provided row. */
1354 StickyStyler.prototype._getCellWidths = function (row, recalculateCellWidths) {
1355 if (recalculateCellWidths === void 0) { recalculateCellWidths = true; }
1356 if (!recalculateCellWidths && this._cachedCellWidths.length) {
1357 return this._cachedCellWidths;
1358 }
1359 var cellWidths = [];
1360 var firstRowCells = row.children;
1361 for (var i = 0; i < firstRowCells.length; i++) {
1362 var cell = firstRowCells[i];
1363 cellWidths.push(cell.getBoundingClientRect().width);
1364 }
1365 this._cachedCellWidths = cellWidths;
1366 return cellWidths;
1367 };
1368 /**
1369 * Determines the left and right positions of each sticky column cell, which will be the
1370 * accumulation of all sticky column cell widths to the left and right, respectively.
1371 * Non-sticky cells do not need to have a value set since their positions will not be applied.
1372 */
1373 StickyStyler.prototype._getStickyStartColumnPositions = function (widths, stickyStates) {
1374 var positions = [];
1375 var nextPosition = 0;
1376 for (var i = 0; i < widths.length; i++) {
1377 if (stickyStates[i]) {
1378 positions[i] = nextPosition;
1379 nextPosition += widths[i];
1380 }
1381 }
1382 return positions;
1383 };
1384 /**
1385 * Determines the left and right positions of each sticky column cell, which will be the
1386 * accumulation of all sticky column cell widths to the left and right, respectively.
1387 * Non-sticky cells do not need to have a value set since their positions will not be applied.
1388 */
1389 StickyStyler.prototype._getStickyEndColumnPositions = function (widths, stickyStates) {
1390 var positions = [];
1391 var nextPosition = 0;
1392 for (var i = widths.length; i > 0; i--) {
1393 if (stickyStates[i]) {
1394 positions[i] = nextPosition;
1395 nextPosition += widths[i];
1396 }
1397 }
1398 return positions;
1399 };
1400 return StickyStyler;
1401 }());
1402
1403 /**
1404 * @license
1405 * Copyright Google LLC All Rights Reserved.
1406 *
1407 * Use of this source code is governed by an MIT-style license that can be
1408 * found in the LICENSE file at https://angular.io/license
1409 */
1410 /**
1411 * Returns an error to be thrown when attempting to find an unexisting column.
1412 * @param id Id whose lookup failed.
1413 * @docs-private
1414 */
1415 function getTableUnknownColumnError(id) {
1416 return Error("Could not find column with id \"" + id + "\".");
1417 }
1418 /**
1419 * Returns an error to be thrown when two column definitions have the same name.
1420 * @docs-private
1421 */
1422 function getTableDuplicateColumnNameError(name) {
1423 return Error("Duplicate column definition name provided: \"" + name + "\".");
1424 }
1425 /**
1426 * Returns an error to be thrown when there are multiple rows that are missing a when function.
1427 * @docs-private
1428 */
1429 function getTableMultipleDefaultRowDefsError() {
1430 return Error("There can only be one default row without a when predicate function.");
1431 }
1432 /**
1433 * Returns an error to be thrown when there are no matching row defs for a particular set of data.
1434 * @docs-private
1435 */
1436 function getTableMissingMatchingRowDefError(data) {
1437 return Error("Could not find a matching row definition for the" +
1438 ("provided row data: " + JSON.stringify(data)));
1439 }
1440 /**
1441 * Returns an error to be thrown when there is no row definitions present in the content.
1442 * @docs-private
1443 */
1444 function getTableMissingRowDefsError() {
1445 return Error('Missing definitions for header, footer, and row; ' +
1446 'cannot determine which columns should be rendered.');
1447 }
1448 /**
1449 * Returns an error to be thrown when the data source does not match the compatible types.
1450 * @docs-private
1451 */
1452 function getTableUnknownDataSourceError() {
1453 return Error("Provided data source did not match an array, Observable, or DataSource");
1454 }
1455 /**
1456 * Returns an error to be thrown when the text column cannot find a parent table to inject.
1457 * @docs-private
1458 */
1459 function getTableTextColumnMissingParentTableError() {
1460 return Error("Text column could not find a parent table for registration.");
1461 }
1462 /**
1463 * Returns an error to be thrown when a table text column doesn't have a name.
1464 * @docs-private
1465 */
1466 function getTableTextColumnMissingNameError() {
1467 return Error("Table text column must have a name.");
1468 }
1469
1470 /**
1471 * @license
1472 * Copyright Google LLC All Rights Reserved.
1473 *
1474 * Use of this source code is governed by an MIT-style license that can be
1475 * found in the LICENSE file at https://angular.io/license
1476 */
1477 /** The injection token used to specify the StickyPositioningListener. */
1478 var STICKY_POSITIONING_LISTENER = new core.InjectionToken('CDK_SPL');
1479
1480 /**
1481 * Enables the recycle view repeater strategy, which reduces rendering latency. Not compatible with
1482 * tables that animate rows.
1483 */
1484 var CdkRecycleRows = /** @class */ (function () {
1485 function CdkRecycleRows() {
1486 }
1487 return CdkRecycleRows;
1488 }());
1489 CdkRecycleRows.decorators = [
1490 { type: core.Directive, args: [{
1491 selector: 'cdk-table[recycleRows], table[cdk-table][recycleRows]',
1492 providers: [
1493 { provide: collections._VIEW_REPEATER_STRATEGY, useClass: collections._RecycleViewRepeaterStrategy },
1494 ],
1495 },] }
1496 ];
1497 /**
1498 * Provides a handle for the table to grab the view container's ng-container to insert data rows.
1499 * @docs-private
1500 */
1501 var DataRowOutlet = /** @class */ (function () {
1502 function DataRowOutlet(viewContainer, elementRef) {
1503 this.viewContainer = viewContainer;
1504 this.elementRef = elementRef;
1505 }
1506 return DataRowOutlet;
1507 }());
1508 DataRowOutlet.decorators = [
1509 { type: core.Directive, args: [{ selector: '[rowOutlet]' },] }
1510 ];
1511 DataRowOutlet.ctorParameters = function () { return [
1512 { type: core.ViewContainerRef },
1513 { type: core.ElementRef }
1514 ]; };
1515 /**
1516 * Provides a handle for the table to grab the view container's ng-container to insert the header.
1517 * @docs-private
1518 */
1519 var HeaderRowOutlet = /** @class */ (function () {
1520 function HeaderRowOutlet(viewContainer, elementRef) {
1521 this.viewContainer = viewContainer;
1522 this.elementRef = elementRef;
1523 }
1524 return HeaderRowOutlet;
1525 }());
1526 HeaderRowOutlet.decorators = [
1527 { type: core.Directive, args: [{ selector: '[headerRowOutlet]' },] }
1528 ];
1529 HeaderRowOutlet.ctorParameters = function () { return [
1530 { type: core.ViewContainerRef },
1531 { type: core.ElementRef }
1532 ]; };
1533 /**
1534 * Provides a handle for the table to grab the view container's ng-container to insert the footer.
1535 * @docs-private
1536 */
1537 var FooterRowOutlet = /** @class */ (function () {
1538 function FooterRowOutlet(viewContainer, elementRef) {
1539 this.viewContainer = viewContainer;
1540 this.elementRef = elementRef;
1541 }
1542 return FooterRowOutlet;
1543 }());
1544 FooterRowOutlet.decorators = [
1545 { type: core.Directive, args: [{ selector: '[footerRowOutlet]' },] }
1546 ];
1547 FooterRowOutlet.ctorParameters = function () { return [
1548 { type: core.ViewContainerRef },
1549 { type: core.ElementRef }
1550 ]; };
1551 /**
1552 * Provides a handle for the table to grab the view
1553 * container's ng-container to insert the no data row.
1554 * @docs-private
1555 */
1556 var NoDataRowOutlet = /** @class */ (function () {
1557 function NoDataRowOutlet(viewContainer, elementRef) {
1558 this.viewContainer = viewContainer;
1559 this.elementRef = elementRef;
1560 }
1561 return NoDataRowOutlet;
1562 }());
1563 NoDataRowOutlet.decorators = [
1564 { type: core.Directive, args: [{ selector: '[noDataRowOutlet]' },] }
1565 ];
1566 NoDataRowOutlet.ctorParameters = function () { return [
1567 { type: core.ViewContainerRef },
1568 { type: core.ElementRef }
1569 ]; };
1570 /**
1571 * The table template that can be used by the mat-table. Should not be used outside of the
1572 * material library.
1573 * @docs-private
1574 */
1575 var CDK_TABLE_TEMPLATE =
1576 // Note that according to MDN, the `caption` element has to be projected as the **first**
1577 // element in the table. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/caption
1578 "\n <ng-content select=\"caption\"></ng-content>\n <ng-content select=\"colgroup, col\"></ng-content>\n <ng-container headerRowOutlet></ng-container>\n <ng-container rowOutlet></ng-container>\n <ng-container noDataRowOutlet></ng-container>\n <ng-container footerRowOutlet></ng-container>\n";
1579 /**
1580 * Class used to conveniently type the embedded view ref for rows with a context.
1581 * @docs-private
1582 */
1583 var RowViewRef = /** @class */ (function (_super) {
1584 __extends(RowViewRef, _super);
1585 function RowViewRef() {
1586 return _super !== null && _super.apply(this, arguments) || this;
1587 }
1588 return RowViewRef;
1589 }(core.EmbeddedViewRef));
1590 /**
1591 * A data table that can render a header row, data rows, and a footer row.
1592 * Uses the dataSource input to determine the data to be rendered. The data can be provided either
1593 * as a data array, an Observable stream that emits the data array to render, or a DataSource with a
1594 * connect function that will return an Observable stream that emits the data array to render.
1595 */
1596 var CdkTable = /** @class */ (function () {
1597 function CdkTable(_differs, _changeDetectorRef, _elementRef, role, _dir, _document, _platform, _viewRepeater, _coalescedStyleScheduler, _viewportRuler,
1598 /**
1599 * @deprecated `_stickyPositioningListener` parameter to become required.
1600 * @breaking-change 13.0.0
1601 */
1602 _stickyPositioningListener) {
1603 this._differs = _differs;
1604 this._changeDetectorRef = _changeDetectorRef;
1605 this._elementRef = _elementRef;
1606 this._dir = _dir;
1607 this._platform = _platform;
1608 this._viewRepeater = _viewRepeater;
1609 this._coalescedStyleScheduler = _coalescedStyleScheduler;
1610 this._viewportRuler = _viewportRuler;
1611 this._stickyPositioningListener = _stickyPositioningListener;
1612 /** Subject that emits when the component has been destroyed. */
1613 this._onDestroy = new rxjs.Subject();
1614 /**
1615 * Map of all the user's defined columns (header, data, and footer cell template) identified by
1616 * name. Collection populated by the column definitions gathered by `ContentChildren` as well as
1617 * any custom column definitions added to `_customColumnDefs`.
1618 */
1619 this._columnDefsByName = new Map();
1620 /**
1621 * Column definitions that were defined outside of the direct content children of the table.
1622 * These will be defined when, e.g., creating a wrapper around the cdkTable that has
1623 * column definitions as *its* content child.
1624 */
1625 this._customColumnDefs = new Set();
1626 /**
1627 * Data row definitions that were defined outside of the direct content children of the table.
1628 * These will be defined when, e.g., creating a wrapper around the cdkTable that has
1629 * built-in data rows as *its* content child.
1630 */
1631 this._customRowDefs = new Set();
1632 /**
1633 * Header row definitions that were defined outside of the direct content children of the table.
1634 * These will be defined when, e.g., creating a wrapper around the cdkTable that has
1635 * built-in header rows as *its* content child.
1636 */
1637 this._customHeaderRowDefs = new Set();
1638 /**
1639 * Footer row definitions that were defined outside of the direct content children of the table.
1640 * These will be defined when, e.g., creating a wrapper around the cdkTable that has a
1641 * built-in footer row as *its* content child.
1642 */
1643 this._customFooterRowDefs = new Set();
1644 /**
1645 * Whether the header row definition has been changed. Triggers an update to the header row after
1646 * content is checked. Initialized as true so that the table renders the initial set of rows.
1647 */
1648 this._headerRowDefChanged = true;
1649 /**
1650 * Whether the footer row definition has been changed. Triggers an update to the footer row after
1651 * content is checked. Initialized as true so that the table renders the initial set of rows.
1652 */
1653 this._footerRowDefChanged = true;
1654 /**
1655 * Whether the sticky column styles need to be updated. Set to `true` when the visible columns
1656 * change.
1657 */
1658 this._stickyColumnStylesNeedReset = true;
1659 /**
1660 * Whether the sticky styler should recalculate cell widths when applying sticky styles. If
1661 * `false`, cached values will be used instead. This is only applicable to tables with
1662 * {@link fixedLayout} enabled. For other tables, cell widths will always be recalculated.
1663 */
1664 this._forceRecalculateCellWidths = true;
1665 /**
1666 * Cache of the latest rendered `RenderRow` objects as a map for easy retrieval when constructing
1667 * a new list of `RenderRow` objects for rendering rows. Since the new list is constructed with
1668 * the cached `RenderRow` objects when possible, the row identity is preserved when the data
1669 * and row template matches, which allows the `IterableDiffer` to check rows by reference
1670 * and understand which rows are added/moved/removed.
1671 *
1672 * Implemented as a map of maps where the first key is the `data: T` object and the second is the
1673 * `CdkRowDef<T>` object. With the two keys, the cache points to a `RenderRow<T>` object that
1674 * contains an array of created pairs. The array is necessary to handle cases where the data
1675 * array contains multiple duplicate data objects and each instantiated `RenderRow` must be
1676 * stored.
1677 */
1678 this._cachedRenderRowsMap = new Map();
1679 /**
1680 * CSS class added to any row or cell that has sticky positioning applied. May be overriden by
1681 * table subclasses.
1682 */
1683 this.stickyCssClass = 'cdk-table-sticky';
1684 /**
1685 * Whether to manually add positon: sticky to all sticky cell elements. Not needed if
1686 * the position is set in a selector associated with the value of stickyCssClass. May be
1687 * overridden by table subclasses
1688 */
1689 this.needsPositionStickyOnElement = true;
1690 /** Whether the no data row is currently showing anything. */
1691 this._isShowingNoDataRow = false;
1692 this._multiTemplateDataRows = false;
1693 this._fixedLayout = false;
1694 /**
1695 * Emits when the table completes rendering a set of data rows based on the latest data from the
1696 * data source, even if the set of rows is empty.
1697 */
1698 this.contentChanged = new core.EventEmitter();
1699 // TODO(andrewseguin): Remove max value as the end index
1700 // and instead calculate the view on init and scroll.
1701 /**
1702 * Stream containing the latest information on what rows are being displayed on screen.
1703 * Can be used by the data source to as a heuristic of what data should be provided.
1704 *
1705 * @docs-private
1706 */
1707 this.viewChange = new rxjs.BehaviorSubject({ start: 0, end: Number.MAX_VALUE });
1708 if (!role) {
1709 this._elementRef.nativeElement.setAttribute('role', 'table');
1710 }
1711 this._document = _document;
1712 this._isNativeHtmlTable = this._elementRef.nativeElement.nodeName === 'TABLE';
1713 }
1714 Object.defineProperty(CdkTable.prototype, "trackBy", {
1715 /**
1716 * Tracking function that will be used to check the differences in data changes. Used similarly
1717 * to `ngFor` `trackBy` function. Optimize row operations by identifying a row based on its data
1718 * relative to the function to know if a row should be added/removed/moved.
1719 * Accepts a function that takes two parameters, `index` and `item`.
1720 */
1721 get: function () {
1722 return this._trackByFn;
1723 },
1724 set: function (fn) {
1725 if ((typeof ngDevMode === 'undefined' || ngDevMode) && fn != null && typeof fn !== 'function') {
1726 console.warn("trackBy must be a function, but received " + JSON.stringify(fn) + ".");
1727 }
1728 this._trackByFn = fn;
1729 },
1730 enumerable: false,
1731 configurable: true
1732 });
1733 Object.defineProperty(CdkTable.prototype, "dataSource", {
1734 /**
1735 * The table's source of data, which can be provided in three ways (in order of complexity):
1736 * - Simple data array (each object represents one table row)
1737 * - Stream that emits a data array each time the array changes
1738 * - `DataSource` object that implements the connect/disconnect interface.
1739 *
1740 * If a data array is provided, the table must be notified when the array's objects are
1741 * added, removed, or moved. This can be done by calling the `renderRows()` function which will
1742 * render the diff since the last table render. If the data array reference is changed, the table
1743 * will automatically trigger an update to the rows.
1744 *
1745 * When providing an Observable stream, the table will trigger an update automatically when the
1746 * stream emits a new array of data.
1747 *
1748 * Finally, when providing a `DataSource` object, the table will use the Observable stream
1749 * provided by the connect function and trigger updates when that stream emits new data array
1750 * values. During the table's ngOnDestroy or when the data source is removed from the table, the
1751 * table will call the DataSource's `disconnect` function (may be useful for cleaning up any
1752 * subscriptions registered during the connect process).
1753 */
1754 get: function () {
1755 return this._dataSource;
1756 },
1757 set: function (dataSource) {
1758 if (this._dataSource !== dataSource) {
1759 this._switchDataSource(dataSource);
1760 }
1761 },
1762 enumerable: false,
1763 configurable: true
1764 });
1765 Object.defineProperty(CdkTable.prototype, "multiTemplateDataRows", {
1766 /**
1767 * Whether to allow multiple rows per data object by evaluating which rows evaluate their 'when'
1768 * predicate to true. If `multiTemplateDataRows` is false, which is the default value, then each
1769 * dataobject will render the first row that evaluates its when predicate to true, in the order
1770 * defined in the table, or otherwise the default row which does not have a when predicate.
1771 */
1772 get: function () {
1773 return this._multiTemplateDataRows;
1774 },
1775 set: function (v) {
1776 this._multiTemplateDataRows = coercion.coerceBooleanProperty(v);
1777 // In Ivy if this value is set via a static attribute (e.g. <table multiTemplateDataRows>),
1778 // this setter will be invoked before the row outlet has been defined hence the null check.
1779 if (this._rowOutlet && this._rowOutlet.viewContainer.length) {
1780 this._forceRenderDataRows();
1781 this.updateStickyColumnStyles();
1782 }
1783 },
1784 enumerable: false,
1785 configurable: true
1786 });
1787 Object.defineProperty(CdkTable.prototype, "fixedLayout", {
1788 /**
1789 * Whether to use a fixed table layout. Enabling this option will enforce consistent column widths
1790 * and optimize rendering sticky styles for native tables. No-op for flex tables.
1791 */
1792 get: function () {
1793 return this._fixedLayout;
1794 },
1795 set: function (v) {
1796 this._fixedLayout = coercion.coerceBooleanProperty(v);
1797 // Toggling `fixedLayout` may change column widths. Sticky column styles should be recalculated.
1798 this._forceRecalculateCellWidths = true;
1799 this._stickyColumnStylesNeedReset = true;
1800 },
1801 enumerable: false,
1802 configurable: true
1803 });
1804 CdkTable.prototype.ngOnInit = function () {
1805 var _this = this;
1806 this._setupStickyStyler();
1807 if (this._isNativeHtmlTable) {
1808 this._applyNativeTableSections();
1809 }
1810 // Set up the trackBy function so that it uses the `RenderRow` as its identity by default. If
1811 // the user has provided a custom trackBy, return the result of that function as evaluated
1812 // with the values of the `RenderRow`'s data and index.
1813 this._dataDiffer = this._differs.find([]).create(function (_i, dataRow) {
1814 return _this.trackBy ? _this.trackBy(dataRow.dataIndex, dataRow.data) : dataRow;
1815 });
1816 this._viewportRuler.change().pipe(operators.takeUntil(this._onDestroy)).subscribe(function () {
1817 _this._forceRecalculateCellWidths = true;
1818 });
1819 };
1820 CdkTable.prototype.ngAfterContentChecked = function () {
1821 // Cache the row and column definitions gathered by ContentChildren and programmatic injection.
1822 this._cacheRowDefs();
1823 this._cacheColumnDefs();
1824 // Make sure that the user has at least added header, footer, or data row def.
1825 if (!this._headerRowDefs.length && !this._footerRowDefs.length && !this._rowDefs.length &&
1826 (typeof ngDevMode === 'undefined' || ngDevMode)) {
1827 throw getTableMissingRowDefsError();
1828 }
1829 // Render updates if the list of columns have been changed for the header, row, or footer defs.
1830 var columnsChanged = this._renderUpdatedColumns();
1831 var rowDefsChanged = columnsChanged || this._headerRowDefChanged || this._footerRowDefChanged;
1832 // Ensure sticky column styles are reset if set to `true` elsewhere.
1833 this._stickyColumnStylesNeedReset = this._stickyColumnStylesNeedReset || rowDefsChanged;
1834 this._forceRecalculateCellWidths = rowDefsChanged;
1835 // If the header row definition has been changed, trigger a render to the header row.
1836 if (this._headerRowDefChanged) {
1837 this._forceRenderHeaderRows();
1838 this._headerRowDefChanged = false;
1839 }
1840 // If the footer row definition has been changed, trigger a render to the footer row.
1841 if (this._footerRowDefChanged) {
1842 this._forceRenderFooterRows();
1843 this._footerRowDefChanged = false;
1844 }
1845 // If there is a data source and row definitions, connect to the data source unless a
1846 // connection has already been made.
1847 if (this.dataSource && this._rowDefs.length > 0 && !this._renderChangeSubscription) {
1848 this._observeRenderChanges();
1849 }
1850 else if (this._stickyColumnStylesNeedReset) {
1851 // In the above case, _observeRenderChanges will result in updateStickyColumnStyles being
1852 // called when it row data arrives. Otherwise, we need to call it proactively.
1853 this.updateStickyColumnStyles();
1854 }
1855 this._checkStickyStates();
1856 };
1857 CdkTable.prototype.ngOnDestroy = function () {
1858 this._rowOutlet.viewContainer.clear();
1859 this._noDataRowOutlet.viewContainer.clear();
1860 this._headerRowOutlet.viewContainer.clear();
1861 this._footerRowOutlet.viewContainer.clear();
1862 this._cachedRenderRowsMap.clear();
1863 this._onDestroy.next();
1864 this._onDestroy.complete();
1865 if (collections.isDataSource(this.dataSource)) {
1866 this.dataSource.disconnect(this);
1867 }
1868 };
1869 /**
1870 * Renders rows based on the table's latest set of data, which was either provided directly as an
1871 * input or retrieved through an Observable stream (directly or from a DataSource).
1872 * Checks for differences in the data since the last diff to perform only the necessary
1873 * changes (add/remove/move rows).
1874 *
1875 * If the table's data source is a DataSource or Observable, this will be invoked automatically
1876 * each time the provided Observable stream emits a new data array. Otherwise if your data is
1877 * an array, this function will need to be called to render any changes.
1878 */
1879 CdkTable.prototype.renderRows = function () {
1880 var _this = this;
1881 this._renderRows = this._getAllRenderRows();
1882 var changes = this._dataDiffer.diff(this._renderRows);
1883 if (!changes) {
1884 this._updateNoDataRow();
1885 this.contentChanged.next();
1886 return;
1887 }
1888 var viewContainer = this._rowOutlet.viewContainer;
1889 this._viewRepeater.applyChanges(changes, viewContainer, function (record, _adjustedPreviousIndex, currentIndex) { return _this._getEmbeddedViewArgs(record.item, currentIndex); }, function (record) { return record.item.data; }, function (change) {
1890 if (change.operation === 1 /* INSERTED */ && change.context) {
1891 _this._renderCellTemplateForItem(change.record.item.rowDef, change.context);
1892 }
1893 });
1894 // Update the meta context of a row's context data (index, count, first, last, ...)
1895 this._updateRowIndexContext();
1896 // Update rows that did not get added/removed/moved but may have had their identity changed,
1897 // e.g. if trackBy matched data on some property but the actual data reference changed.
1898 changes.forEachIdentityChange(function (record) {
1899 var rowView = viewContainer.get(record.currentIndex);
1900 rowView.context.$implicit = record.item.data;
1901 });
1902 this._updateNoDataRow();
1903 this.updateStickyColumnStyles();
1904 this.contentChanged.next();
1905 };
1906 /** Adds a column definition that was not included as part of the content children. */
1907 CdkTable.prototype.addColumnDef = function (columnDef) {
1908 this._customColumnDefs.add(columnDef);
1909 };
1910 /** Removes a column definition that was not included as part of the content children. */
1911 CdkTable.prototype.removeColumnDef = function (columnDef) {
1912 this._customColumnDefs.delete(columnDef);
1913 };
1914 /** Adds a row definition that was not included as part of the content children. */
1915 CdkTable.prototype.addRowDef = function (rowDef) {
1916 this._customRowDefs.add(rowDef);
1917 };
1918 /** Removes a row definition that was not included as part of the content children. */
1919 CdkTable.prototype.removeRowDef = function (rowDef) {
1920 this._customRowDefs.delete(rowDef);
1921 };
1922 /** Adds a header row definition that was not included as part of the content children. */
1923 CdkTable.prototype.addHeaderRowDef = function (headerRowDef) {
1924 this._customHeaderRowDefs.add(headerRowDef);
1925 this._headerRowDefChanged = true;
1926 };
1927 /** Removes a header row definition that was not included as part of the content children. */
1928 CdkTable.prototype.removeHeaderRowDef = function (headerRowDef) {
1929 this._customHeaderRowDefs.delete(headerRowDef);
1930 this._headerRowDefChanged = true;
1931 };
1932 /** Adds a footer row definition that was not included as part of the content children. */
1933 CdkTable.prototype.addFooterRowDef = function (footerRowDef) {
1934 this._customFooterRowDefs.add(footerRowDef);
1935 this._footerRowDefChanged = true;
1936 };
1937 /** Removes a footer row definition that was not included as part of the content children. */
1938 CdkTable.prototype.removeFooterRowDef = function (footerRowDef) {
1939 this._customFooterRowDefs.delete(footerRowDef);
1940 this._footerRowDefChanged = true;
1941 };
1942 /** Sets a no data row definition that was not included as a part of the content children. */
1943 CdkTable.prototype.setNoDataRow = function (noDataRow) {
1944 this._customNoDataRow = noDataRow;
1945 };
1946 /**
1947 * Updates the header sticky styles. First resets all applied styles with respect to the cells
1948 * sticking to the top. Then, evaluating which cells need to be stuck to the top. This is
1949 * automatically called when the header row changes its displayed set of columns, or if its
1950 * sticky input changes. May be called manually for cases where the cell content changes outside
1951 * of these events.
1952 */
1953 CdkTable.prototype.updateStickyHeaderRowStyles = function () {
1954 var headerRows = this._getRenderedRows(this._headerRowOutlet);
1955 var tableElement = this._elementRef.nativeElement;
1956 // Hide the thead element if there are no header rows. This is necessary to satisfy
1957 // overzealous a11y checkers that fail because the `rowgroup` element does not contain
1958 // required child `row`.
1959 var thead = tableElement.querySelector('thead');
1960 if (thead) {
1961 thead.style.display = headerRows.length ? '' : 'none';
1962 }
1963 var stickyStates = this._headerRowDefs.map(function (def) { return def.sticky; });
1964 this._stickyStyler.clearStickyPositioning(headerRows, ['top']);
1965 this._stickyStyler.stickRows(headerRows, stickyStates, 'top');
1966 // Reset the dirty state of the sticky input change since it has been used.
1967 this._headerRowDefs.forEach(function (def) { return def.resetStickyChanged(); });
1968 };
1969 /**
1970 * Updates the footer sticky styles. First resets all applied styles with respect to the cells
1971 * sticking to the bottom. Then, evaluating which cells need to be stuck to the bottom. This is
1972 * automatically called when the footer row changes its displayed set of columns, or if its
1973 * sticky input changes. May be called manually for cases where the cell content changes outside
1974 * of these events.
1975 */
1976 CdkTable.prototype.updateStickyFooterRowStyles = function () {
1977 var footerRows = this._getRenderedRows(this._footerRowOutlet);
1978 var tableElement = this._elementRef.nativeElement;
1979 // Hide the tfoot element if there are no footer rows. This is necessary to satisfy
1980 // overzealous a11y checkers that fail because the `rowgroup` element does not contain
1981 // required child `row`.
1982 var tfoot = tableElement.querySelector('tfoot');
1983 if (tfoot) {
1984 tfoot.style.display = footerRows.length ? '' : 'none';
1985 }
1986 var stickyStates = this._footerRowDefs.map(function (def) { return def.sticky; });
1987 this._stickyStyler.clearStickyPositioning(footerRows, ['bottom']);
1988 this._stickyStyler.stickRows(footerRows, stickyStates, 'bottom');
1989 this._stickyStyler.updateStickyFooterContainer(this._elementRef.nativeElement, stickyStates);
1990 // Reset the dirty state of the sticky input change since it has been used.
1991 this._footerRowDefs.forEach(function (def) { return def.resetStickyChanged(); });
1992 };
1993 /**
1994 * Updates the column sticky styles. First resets all applied styles with respect to the cells
1995 * sticking to the left and right. Then sticky styles are added for the left and right according
1996 * to the column definitions for each cell in each row. This is automatically called when
1997 * the data source provides a new set of data or when a column definition changes its sticky
1998 * input. May be called manually for cases where the cell content changes outside of these events.
1999 */
2000 CdkTable.prototype.updateStickyColumnStyles = function () {
2001 var _this = this;
2002 var headerRows = this._getRenderedRows(this._headerRowOutlet);
2003 var dataRows = this._getRenderedRows(this._rowOutlet);
2004 var footerRows = this._getRenderedRows(this._footerRowOutlet);
2005 // For tables not using a fixed layout, the column widths may change when new rows are rendered.
2006 // In a table using a fixed layout, row content won't affect column width, so sticky styles
2007 // don't need to be cleared unless either the sticky column config changes or one of the row
2008 // defs change.
2009 if ((this._isNativeHtmlTable && !this._fixedLayout)
2010 || this._stickyColumnStylesNeedReset) {
2011 // Clear the left and right positioning from all columns in the table across all rows since
2012 // sticky columns span across all table sections (header, data, footer)
2013 this._stickyStyler.clearStickyPositioning(__spreadArray(__spreadArray(__spreadArray([], __read(headerRows)), __read(dataRows)), __read(footerRows)), ['left', 'right']);
2014 this._stickyColumnStylesNeedReset = false;
2015 }
2016 // Update the sticky styles for each header row depending on the def's sticky state
2017 headerRows.forEach(function (headerRow, i) {
2018 _this._addStickyColumnStyles([headerRow], _this._headerRowDefs[i]);
2019 });
2020 // Update the sticky styles for each data row depending on its def's sticky state
2021 this._rowDefs.forEach(function (rowDef) {
2022 // Collect all the rows rendered with this row definition.
2023 var rows = [];
2024 for (var i = 0; i < dataRows.length; i++) {
2025 if (_this._renderRows[i].rowDef === rowDef) {
2026 rows.push(dataRows[i]);
2027 }
2028 }
2029 _this._addStickyColumnStyles(rows, rowDef);
2030 });
2031 // Update the sticky styles for each footer row depending on the def's sticky state
2032 footerRows.forEach(function (footerRow, i) {
2033 _this._addStickyColumnStyles([footerRow], _this._footerRowDefs[i]);
2034 });
2035 // Reset the dirty state of the sticky input change since it has been used.
2036 Array.from(this._columnDefsByName.values()).forEach(function (def) { return def.resetStickyChanged(); });
2037 };
2038 /**
2039 * Get the list of RenderRow objects to render according to the current list of data and defined
2040 * row definitions. If the previous list already contained a particular pair, it should be reused
2041 * so that the differ equates their references.
2042 */
2043 CdkTable.prototype._getAllRenderRows = function () {
2044 var renderRows = [];
2045 // Store the cache and create a new one. Any re-used RenderRow objects will be moved into the
2046 // new cache while unused ones can be picked up by garbage collection.
2047 var prevCachedRenderRows = this._cachedRenderRowsMap;
2048 this._cachedRenderRowsMap = new Map();
2049 // For each data object, get the list of rows that should be rendered, represented by the
2050 // respective `RenderRow` object which is the pair of `data` and `CdkRowDef`.
2051 for (var i = 0; i < this._data.length; i++) {
2052 var data = this._data[i];
2053 var renderRowsForData = this._getRenderRowsForData(data, i, prevCachedRenderRows.get(data));
2054 if (!this._cachedRenderRowsMap.has(data)) {
2055 this._cachedRenderRowsMap.set(data, new WeakMap());
2056 }
2057 for (var j = 0; j < renderRowsForData.length; j++) {
2058 var renderRow = renderRowsForData[j];
2059 var cache = this._cachedRenderRowsMap.get(renderRow.data);
2060 if (cache.has(renderRow.rowDef)) {
2061 cache.get(renderRow.rowDef).push(renderRow);
2062 }
2063 else {
2064 cache.set(renderRow.rowDef, [renderRow]);
2065 }
2066 renderRows.push(renderRow);
2067 }
2068 }
2069 return renderRows;
2070 };
2071 /**
2072 * Gets a list of `RenderRow<T>` for the provided data object and any `CdkRowDef` objects that
2073 * should be rendered for this data. Reuses the cached RenderRow objects if they match the same
2074 * `(T, CdkRowDef)` pair.
2075 */
2076 CdkTable.prototype._getRenderRowsForData = function (data, dataIndex, cache) {
2077 var rowDefs = this._getRowDefs(data, dataIndex);
2078 return rowDefs.map(function (rowDef) {
2079 var cachedRenderRows = (cache && cache.has(rowDef)) ? cache.get(rowDef) : [];
2080 if (cachedRenderRows.length) {
2081 var dataRow = cachedRenderRows.shift();
2082 dataRow.dataIndex = dataIndex;
2083 return dataRow;
2084 }
2085 else {
2086 return { data: data, rowDef: rowDef, dataIndex: dataIndex };
2087 }
2088 });
2089 };
2090 /** Update the map containing the content's column definitions. */
2091 CdkTable.prototype._cacheColumnDefs = function () {
2092 var _this = this;
2093 this._columnDefsByName.clear();
2094 var columnDefs = mergeArrayAndSet(this._getOwnDefs(this._contentColumnDefs), this._customColumnDefs);
2095 columnDefs.forEach(function (columnDef) {
2096 if (_this._columnDefsByName.has(columnDef.name) &&
2097 (typeof ngDevMode === 'undefined' || ngDevMode)) {
2098 throw getTableDuplicateColumnNameError(columnDef.name);
2099 }
2100 _this._columnDefsByName.set(columnDef.name, columnDef);
2101 });
2102 };
2103 /** Update the list of all available row definitions that can be used. */
2104 CdkTable.prototype._cacheRowDefs = function () {
2105 this._headerRowDefs = mergeArrayAndSet(this._getOwnDefs(this._contentHeaderRowDefs), this._customHeaderRowDefs);
2106 this._footerRowDefs = mergeArrayAndSet(this._getOwnDefs(this._contentFooterRowDefs), this._customFooterRowDefs);
2107 this._rowDefs = mergeArrayAndSet(this._getOwnDefs(this._contentRowDefs), this._customRowDefs);
2108 // After all row definitions are determined, find the row definition to be considered default.
2109 var defaultRowDefs = this._rowDefs.filter(function (def) { return !def.when; });
2110 if (!this.multiTemplateDataRows && defaultRowDefs.length > 1 &&
2111 (typeof ngDevMode === 'undefined' || ngDevMode)) {
2112 throw getTableMultipleDefaultRowDefsError();
2113 }
2114 this._defaultRowDef = defaultRowDefs[0];
2115 };
2116 /**
2117 * Check if the header, data, or footer rows have changed what columns they want to display or
2118 * whether the sticky states have changed for the header or footer. If there is a diff, then
2119 * re-render that section.
2120 */
2121 CdkTable.prototype._renderUpdatedColumns = function () {
2122 var columnsDiffReducer = function (acc, def) { return acc || !!def.getColumnsDiff(); };
2123 // Force re-render data rows if the list of column definitions have changed.
2124 var dataColumnsChanged = this._rowDefs.reduce(columnsDiffReducer, false);
2125 if (dataColumnsChanged) {
2126 this._forceRenderDataRows();
2127 }
2128 // Force re-render header/footer rows if the list of column definitions have changed.
2129 var headerColumnsChanged = this._headerRowDefs.reduce(columnsDiffReducer, false);
2130 if (headerColumnsChanged) {
2131 this._forceRenderHeaderRows();
2132 }
2133 var footerColumnsChanged = this._footerRowDefs.reduce(columnsDiffReducer, false);
2134 if (footerColumnsChanged) {
2135 this._forceRenderFooterRows();
2136 }
2137 return dataColumnsChanged || headerColumnsChanged || footerColumnsChanged;
2138 };
2139 /**
2140 * Switch to the provided data source by resetting the data and unsubscribing from the current
2141 * render change subscription if one exists. If the data source is null, interpret this by
2142 * clearing the row outlet. Otherwise start listening for new data.
2143 */
2144 CdkTable.prototype._switchDataSource = function (dataSource) {
2145 this._data = [];
2146 if (collections.isDataSource(this.dataSource)) {
2147 this.dataSource.disconnect(this);
2148 }
2149 // Stop listening for data from the previous data source.
2150 if (this._renderChangeSubscription) {
2151 this._renderChangeSubscription.unsubscribe();
2152 this._renderChangeSubscription = null;
2153 }
2154 if (!dataSource) {
2155 if (this._dataDiffer) {
2156 this._dataDiffer.diff([]);
2157 }
2158 this._rowOutlet.viewContainer.clear();
2159 }
2160 this._dataSource = dataSource;
2161 };
2162 /** Set up a subscription for the data provided by the data source. */
2163 CdkTable.prototype._observeRenderChanges = function () {
2164 var _this = this;
2165 // If no data source has been set, there is nothing to observe for changes.
2166 if (!this.dataSource) {
2167 return;
2168 }
2169 var dataStream;
2170 if (collections.isDataSource(this.dataSource)) {
2171 dataStream = this.dataSource.connect(this);
2172 }
2173 else if (rxjs.isObservable(this.dataSource)) {
2174 dataStream = this.dataSource;
2175 }
2176 else if (Array.isArray(this.dataSource)) {
2177 dataStream = rxjs.of(this.dataSource);
2178 }
2179 if (dataStream === undefined && (typeof ngDevMode === 'undefined' || ngDevMode)) {
2180 throw getTableUnknownDataSourceError();
2181 }
2182 this._renderChangeSubscription = dataStream.pipe(operators.takeUntil(this._onDestroy))
2183 .subscribe(function (data) {
2184 _this._data = data || [];
2185 _this.renderRows();
2186 });
2187 };
2188 /**
2189 * Clears any existing content in the header row outlet and creates a new embedded view
2190 * in the outlet using the header row definition.
2191 */
2192 CdkTable.prototype._forceRenderHeaderRows = function () {
2193 var _this = this;
2194 // Clear the header row outlet if any content exists.
2195 if (this._headerRowOutlet.viewContainer.length > 0) {
2196 this._headerRowOutlet.viewContainer.clear();
2197 }
2198 this._headerRowDefs.forEach(function (def, i) { return _this._renderRow(_this._headerRowOutlet, def, i); });
2199 this.updateStickyHeaderRowStyles();
2200 };
2201 /**
2202 * Clears any existing content in the footer row outlet and creates a new embedded view
2203 * in the outlet using the footer row definition.
2204 */
2205 CdkTable.prototype._forceRenderFooterRows = function () {
2206 var _this = this;
2207 // Clear the footer row outlet if any content exists.
2208 if (this._footerRowOutlet.viewContainer.length > 0) {
2209 this._footerRowOutlet.viewContainer.clear();
2210 }
2211 this._footerRowDefs.forEach(function (def, i) { return _this._renderRow(_this._footerRowOutlet, def, i); });
2212 this.updateStickyFooterRowStyles();
2213 };
2214 /** Adds the sticky column styles for the rows according to the columns' stick states. */
2215 CdkTable.prototype._addStickyColumnStyles = function (rows, rowDef) {
2216 var _this = this;
2217 var columnDefs = Array.from(rowDef.columns || []).map(function (columnName) {
2218 var columnDef = _this._columnDefsByName.get(columnName);
2219 if (!columnDef && (typeof ngDevMode === 'undefined' || ngDevMode)) {
2220 throw getTableUnknownColumnError(columnName);
2221 }
2222 return columnDef;
2223 });
2224 var stickyStartStates = columnDefs.map(function (columnDef) { return columnDef.sticky; });
2225 var stickyEndStates = columnDefs.map(function (columnDef) { return columnDef.stickyEnd; });
2226 this._stickyStyler.updateStickyColumns(rows, stickyStartStates, stickyEndStates, !this._fixedLayout || this._forceRecalculateCellWidths);
2227 };
2228 /** Gets the list of rows that have been rendered in the row outlet. */
2229 CdkTable.prototype._getRenderedRows = function (rowOutlet) {
2230 var renderedRows = [];
2231 for (var i = 0; i < rowOutlet.viewContainer.length; i++) {
2232 var viewRef = rowOutlet.viewContainer.get(i);
2233 renderedRows.push(viewRef.rootNodes[0]);
2234 }
2235 return renderedRows;
2236 };
2237 /**
2238 * Get the matching row definitions that should be used for this row data. If there is only
2239 * one row definition, it is returned. Otherwise, find the row definitions that has a when
2240 * predicate that returns true with the data. If none return true, return the default row
2241 * definition.
2242 */
2243 CdkTable.prototype._getRowDefs = function (data, dataIndex) {
2244 if (this._rowDefs.length == 1) {
2245 return [this._rowDefs[0]];
2246 }
2247 var rowDefs = [];
2248 if (this.multiTemplateDataRows) {
2249 rowDefs = this._rowDefs.filter(function (def) { return !def.when || def.when(dataIndex, data); });
2250 }
2251 else {
2252 var rowDef = this._rowDefs.find(function (def) { return def.when && def.when(dataIndex, data); }) || this._defaultRowDef;
2253 if (rowDef) {
2254 rowDefs.push(rowDef);
2255 }
2256 }
2257 if (!rowDefs.length && (typeof ngDevMode === 'undefined' || ngDevMode)) {
2258 throw getTableMissingMatchingRowDefError(data);
2259 }
2260 return rowDefs;
2261 };
2262 CdkTable.prototype._getEmbeddedViewArgs = function (renderRow, index) {
2263 var rowDef = renderRow.rowDef;
2264 var context = { $implicit: renderRow.data };
2265 return {
2266 templateRef: rowDef.template,
2267 context: context,
2268 index: index,
2269 };
2270 };
2271 /**
2272 * Creates a new row template in the outlet and fills it with the set of cell templates.
2273 * Optionally takes a context to provide to the row and cells, as well as an optional index
2274 * of where to place the new row template in the outlet.
2275 */
2276 CdkTable.prototype._renderRow = function (outlet, rowDef, index, context) {
2277 if (context === void 0) { context = {}; }
2278 // TODO(andrewseguin): enforce that one outlet was instantiated from createEmbeddedView
2279 var view = outlet.viewContainer.createEmbeddedView(rowDef.template, context, index);
2280 this._renderCellTemplateForItem(rowDef, context);
2281 return view;
2282 };
2283 CdkTable.prototype._renderCellTemplateForItem = function (rowDef, context) {
2284 var e_1, _a;
2285 try {
2286 for (var _b = __values(this._getCellTemplates(rowDef)), _c = _b.next(); !_c.done; _c = _b.next()) {
2287 var cellTemplate = _c.value;
2288 if (CdkCellOutlet.mostRecentCellOutlet) {
2289 CdkCellOutlet.mostRecentCellOutlet._viewContainer.createEmbeddedView(cellTemplate, context);
2290 }
2291 }
2292 }
2293 catch (e_1_1) { e_1 = { error: e_1_1 }; }
2294 finally {
2295 try {
2296 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
2297 }
2298 finally { if (e_1) throw e_1.error; }
2299 }
2300 this._changeDetectorRef.markForCheck();
2301 };
2302 /**
2303 * Updates the index-related context for each row to reflect any changes in the index of the rows,
2304 * e.g. first/last/even/odd.
2305 */
2306 CdkTable.prototype._updateRowIndexContext = function () {
2307 var viewContainer = this._rowOutlet.viewContainer;
2308 for (var renderIndex = 0, count = viewContainer.length; renderIndex < count; renderIndex++) {
2309 var viewRef = viewContainer.get(renderIndex);
2310 var context = viewRef.context;
2311 context.count = count;
2312 context.first = renderIndex === 0;
2313 context.last = renderIndex === count - 1;
2314 context.even = renderIndex % 2 === 0;
2315 context.odd = !context.even;
2316 if (this.multiTemplateDataRows) {
2317 context.dataIndex = this._renderRows[renderIndex].dataIndex;
2318 context.renderIndex = renderIndex;
2319 }
2320 else {
2321 context.index = this._renderRows[renderIndex].dataIndex;
2322 }
2323 }
2324 };
2325 /** Gets the column definitions for the provided row def. */
2326 CdkTable.prototype._getCellTemplates = function (rowDef) {
2327 var _this = this;
2328 if (!rowDef || !rowDef.columns) {
2329 return [];
2330 }
2331 return Array.from(rowDef.columns, function (columnId) {
2332 var column = _this._columnDefsByName.get(columnId);
2333 if (!column && (typeof ngDevMode === 'undefined' || ngDevMode)) {
2334 throw getTableUnknownColumnError(columnId);
2335 }
2336 return rowDef.extractCellTemplate(column);
2337 });
2338 };
2339 /** Adds native table sections (e.g. tbody) and moves the row outlets into them. */
2340 CdkTable.prototype._applyNativeTableSections = function () {
2341 var e_2, _a, e_3, _b;
2342 var documentFragment = this._document.createDocumentFragment();
2343 var sections = [
2344 { tag: 'thead', outlets: [this._headerRowOutlet] },
2345 { tag: 'tbody', outlets: [this._rowOutlet, this._noDataRowOutlet] },
2346 { tag: 'tfoot', outlets: [this._footerRowOutlet] },
2347 ];
2348 try {
2349 for (var sections_1 = __values(sections), sections_1_1 = sections_1.next(); !sections_1_1.done; sections_1_1 = sections_1.next()) {
2350 var section = sections_1_1.value;
2351 var element = this._document.createElement(section.tag);
2352 element.setAttribute('role', 'rowgroup');
2353 try {
2354 for (var _c = (e_3 = void 0, __values(section.outlets)), _d = _c.next(); !_d.done; _d = _c.next()) {
2355 var outlet = _d.value;
2356 element.appendChild(outlet.elementRef.nativeElement);
2357 }
2358 }
2359 catch (e_3_1) { e_3 = { error: e_3_1 }; }
2360 finally {
2361 try {
2362 if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
2363 }
2364 finally { if (e_3) throw e_3.error; }
2365 }
2366 documentFragment.appendChild(element);
2367 }
2368 }
2369 catch (e_2_1) { e_2 = { error: e_2_1 }; }
2370 finally {
2371 try {
2372 if (sections_1_1 && !sections_1_1.done && (_a = sections_1.return)) _a.call(sections_1);
2373 }
2374 finally { if (e_2) throw e_2.error; }
2375 }
2376 // Use a DocumentFragment so we don't hit the DOM on each iteration.
2377 this._elementRef.nativeElement.appendChild(documentFragment);
2378 };
2379 /**
2380 * Forces a re-render of the data rows. Should be called in cases where there has been an input
2381 * change that affects the evaluation of which rows should be rendered, e.g. toggling
2382 * `multiTemplateDataRows` or adding/removing row definitions.
2383 */
2384 CdkTable.prototype._forceRenderDataRows = function () {
2385 this._dataDiffer.diff([]);
2386 this._rowOutlet.viewContainer.clear();
2387 this.renderRows();
2388 };
2389 /**
2390 * Checks if there has been a change in sticky states since last check and applies the correct
2391 * sticky styles. Since checking resets the "dirty" state, this should only be performed once
2392 * during a change detection and after the inputs are settled (after content check).
2393 */
2394 CdkTable.prototype._checkStickyStates = function () {
2395 var stickyCheckReducer = function (acc, d) {
2396 return acc || d.hasStickyChanged();
2397 };
2398 // Note that the check needs to occur for every definition since it notifies the definition
2399 // that it can reset its dirty state. Using another operator like `some` may short-circuit
2400 // remaining definitions and leave them in an unchecked state.
2401 if (this._headerRowDefs.reduce(stickyCheckReducer, false)) {
2402 this.updateStickyHeaderRowStyles();
2403 }
2404 if (this._footerRowDefs.reduce(stickyCheckReducer, false)) {
2405 this.updateStickyFooterRowStyles();
2406 }
2407 if (Array.from(this._columnDefsByName.values()).reduce(stickyCheckReducer, false)) {
2408 this._stickyColumnStylesNeedReset = true;
2409 this.updateStickyColumnStyles();
2410 }
2411 };
2412 /**
2413 * Creates the sticky styler that will be used for sticky rows and columns. Listens
2414 * for directionality changes and provides the latest direction to the styler. Re-applies column
2415 * stickiness when directionality changes.
2416 */
2417 CdkTable.prototype._setupStickyStyler = function () {
2418 var _this = this;
2419 var direction = this._dir ? this._dir.value : 'ltr';
2420 this._stickyStyler = new StickyStyler(this._isNativeHtmlTable, this.stickyCssClass, direction, this._coalescedStyleScheduler, this._platform.isBrowser, this.needsPositionStickyOnElement, this._stickyPositioningListener);
2421 (this._dir ? this._dir.change : rxjs.of())
2422 .pipe(operators.takeUntil(this._onDestroy))
2423 .subscribe(function (value) {
2424 _this._stickyStyler.direction = value;
2425 _this.updateStickyColumnStyles();
2426 });
2427 };
2428 /** Filters definitions that belong to this table from a QueryList. */
2429 CdkTable.prototype._getOwnDefs = function (items) {
2430 var _this = this;
2431 return items.filter(function (item) { return !item._table || item._table === _this; });
2432 };
2433 /** Creates or removes the no data row, depending on whether any data is being shown. */
2434 CdkTable.prototype._updateNoDataRow = function () {
2435 var noDataRow = this._customNoDataRow || this._noDataRow;
2436 if (noDataRow) {
2437 var shouldShow = this._rowOutlet.viewContainer.length === 0;
2438 if (shouldShow !== this._isShowingNoDataRow) {
2439 var container = this._noDataRowOutlet.viewContainer;
2440 shouldShow ? container.createEmbeddedView(noDataRow.templateRef) : container.clear();
2441 this._isShowingNoDataRow = shouldShow;
2442 }
2443 }
2444 };
2445 return CdkTable;
2446 }());
2447 CdkTable.decorators = [
2448 { type: core.Component, args: [{
2449 selector: 'cdk-table, table[cdk-table]',
2450 exportAs: 'cdkTable',
2451 template: CDK_TABLE_TEMPLATE,
2452 host: {
2453 'class': 'cdk-table',
2454 '[class.cdk-table-fixed-layout]': 'fixedLayout',
2455 },
2456 encapsulation: core.ViewEncapsulation.None,
2457 // The "OnPush" status for the `MatTable` component is effectively a noop, so we are removing it.
2458 // The view for `MatTable` consists entirely of templates declared in other views. As they are
2459 // declared elsewhere, they are checked when their declaration points are checked.
2460 // tslint:disable-next-line:validate-decorators
2461 changeDetection: core.ChangeDetectionStrategy.Default,
2462 providers: [
2463 { provide: CDK_TABLE, useExisting: CdkTable },
2464 { provide: collections._VIEW_REPEATER_STRATEGY, useClass: collections._DisposeViewRepeaterStrategy },
2465 { provide: _COALESCED_STYLE_SCHEDULER, useClass: _CoalescedStyleScheduler },
2466 // Prevent nested tables from seeing this table's StickyPositioningListener.
2467 { provide: STICKY_POSITIONING_LISTENER, useValue: null },
2468 ],
2469 styles: [".cdk-table-fixed-layout{table-layout:fixed}\n"]
2470 },] }
2471 ];
2472 CdkTable.ctorParameters = function () { return [
2473 { type: core.IterableDiffers },
2474 { type: core.ChangeDetectorRef },
2475 { type: core.ElementRef },
2476 { type: String, decorators: [{ type: core.Attribute, args: ['role',] }] },
2477 { type: bidi.Directionality, decorators: [{ type: core.Optional }] },
2478 { type: undefined, decorators: [{ type: core.Inject, args: [common.DOCUMENT,] }] },
2479 { type: platform.Platform },
2480 { type: undefined, decorators: [{ type: core.Inject, args: [collections._VIEW_REPEATER_STRATEGY,] }] },
2481 { type: _CoalescedStyleScheduler, decorators: [{ type: core.Inject, args: [_COALESCED_STYLE_SCHEDULER,] }] },
2482 { type: scrolling.ViewportRuler },
2483 { type: undefined, decorators: [{ type: core.Optional }, { type: core.SkipSelf }, { type: core.Inject, args: [STICKY_POSITIONING_LISTENER,] }] }
2484 ]; };
2485 CdkTable.propDecorators = {
2486 trackBy: [{ type: core.Input }],
2487 dataSource: [{ type: core.Input }],
2488 multiTemplateDataRows: [{ type: core.Input }],
2489 fixedLayout: [{ type: core.Input }],
2490 contentChanged: [{ type: core.Output }],
2491 _rowOutlet: [{ type: core.ViewChild, args: [DataRowOutlet, { static: true },] }],
2492 _headerRowOutlet: [{ type: core.ViewChild, args: [HeaderRowOutlet, { static: true },] }],
2493 _footerRowOutlet: [{ type: core.ViewChild, args: [FooterRowOutlet, { static: true },] }],
2494 _noDataRowOutlet: [{ type: core.ViewChild, args: [NoDataRowOutlet, { static: true },] }],
2495 _contentColumnDefs: [{ type: core.ContentChildren, args: [CdkColumnDef, { descendants: true },] }],
2496 _contentRowDefs: [{ type: core.ContentChildren, args: [CdkRowDef, { descendants: true },] }],
2497 _contentHeaderRowDefs: [{ type: core.ContentChildren, args: [CdkHeaderRowDef, {
2498 descendants: true
2499 },] }],
2500 _contentFooterRowDefs: [{ type: core.ContentChildren, args: [CdkFooterRowDef, {
2501 descendants: true
2502 },] }],
2503 _noDataRow: [{ type: core.ContentChild, args: [CdkNoDataRow,] }]
2504 };
2505 /** Utility function that gets a merged list of the entries in an array and values of a Set. */
2506 function mergeArrayAndSet(array, set) {
2507 return array.concat(Array.from(set));
2508 }
2509
2510 /**
2511 * @license
2512 * Copyright Google LLC All Rights Reserved.
2513 *
2514 * Use of this source code is governed by an MIT-style license that can be
2515 * found in the LICENSE file at https://angular.io/license
2516 */
2517 /**
2518 * Column that simply shows text content for the header and row cells. Assumes that the table
2519 * is using the native table implementation (`<table>`).
2520 *
2521 * By default, the name of this column will be the header text and data property accessor.
2522 * The header text can be overridden with the `headerText` input. Cell values can be overridden with
2523 * the `dataAccessor` input. Change the text justification to the start or end using the `justify`
2524 * input.
2525 */
2526 var CdkTextColumn = /** @class */ (function () {
2527 function CdkTextColumn(
2528 // `CdkTextColumn` is always requiring a table, but we just assert it manually
2529 // for better error reporting.
2530 // tslint:disable-next-line: lightweight-tokens
2531 _table, _options) {
2532 this._table = _table;
2533 this._options = _options;
2534 /** Alignment of the cell values. */
2535 this.justify = 'start';
2536 this._options = _options || {};
2537 }
2538 Object.defineProperty(CdkTextColumn.prototype, "name", {
2539 /** Column name that should be used to reference this column. */
2540 get: function () {
2541 return this._name;
2542 },
2543 set: function (name) {
2544 this._name = name;
2545 // With Ivy, inputs can be initialized before static query results are
2546 // available. In that case, we defer the synchronization until "ngOnInit" fires.
2547 this._syncColumnDefName();
2548 },
2549 enumerable: false,
2550 configurable: true
2551 });
2552 CdkTextColumn.prototype.ngOnInit = function () {
2553 this._syncColumnDefName();
2554 if (this.headerText === undefined) {
2555 this.headerText = this._createDefaultHeaderText();
2556 }
2557 if (!this.dataAccessor) {
2558 this.dataAccessor =
2559 this._options.defaultDataAccessor || (function (data, name) { return data[name]; });
2560 }
2561 if (this._table) {
2562 // Provide the cell and headerCell directly to the table with the static `ViewChild` query,
2563 // since the columnDef will not pick up its content by the time the table finishes checking
2564 // its content and initializing the rows.
2565 this.columnDef.cell = this.cell;
2566 this.columnDef.headerCell = this.headerCell;
2567 this._table.addColumnDef(this.columnDef);
2568 }
2569 else if (typeof ngDevMode === 'undefined' || ngDevMode) {
2570 throw getTableTextColumnMissingParentTableError();
2571 }
2572 };
2573 CdkTextColumn.prototype.ngOnDestroy = function () {
2574 if (this._table) {
2575 this._table.removeColumnDef(this.columnDef);
2576 }
2577 };
2578 /**
2579 * Creates a default header text. Use the options' header text transformation function if one
2580 * has been provided. Otherwise simply capitalize the column name.
2581 */
2582 CdkTextColumn.prototype._createDefaultHeaderText = function () {
2583 var name = this.name;
2584 if (!name && (typeof ngDevMode === 'undefined' || ngDevMode)) {
2585 throw getTableTextColumnMissingNameError();
2586 }
2587 if (this._options && this._options.defaultHeaderTextTransform) {
2588 return this._options.defaultHeaderTextTransform(name);
2589 }
2590 return name[0].toUpperCase() + name.slice(1);
2591 };
2592 /** Synchronizes the column definition name with the text column name. */
2593 CdkTextColumn.prototype._syncColumnDefName = function () {
2594 if (this.columnDef) {
2595 this.columnDef.name = this.name;
2596 }
2597 };
2598 return CdkTextColumn;
2599 }());
2600 CdkTextColumn.decorators = [
2601 { type: core.Component, args: [{
2602 selector: 'cdk-text-column',
2603 template: "\n <ng-container cdkColumnDef>\n <th cdk-header-cell *cdkHeaderCellDef [style.text-align]=\"justify\">\n {{headerText}}\n </th>\n <td cdk-cell *cdkCellDef=\"let data\" [style.text-align]=\"justify\">\n {{dataAccessor(data, name)}}\n </td>\n </ng-container>\n ",
2604 encapsulation: core.ViewEncapsulation.None,
2605 // Change detection is intentionally not set to OnPush. This component's template will be provided
2606 // to the table to be inserted into its view. This is problematic when change detection runs since
2607 // the bindings in this template will be evaluated _after_ the table's view is evaluated, which
2608 // mean's the template in the table's view will not have the updated value (and in fact will cause
2609 // an ExpressionChangedAfterItHasBeenCheckedError).
2610 // tslint:disable-next-line:validate-decorators
2611 changeDetection: core.ChangeDetectionStrategy.Default
2612 },] }
2613 ];
2614 CdkTextColumn.ctorParameters = function () { return [
2615 { type: CdkTable, decorators: [{ type: core.Optional }] },
2616 { type: undefined, decorators: [{ type: core.Optional }, { type: core.Inject, args: [TEXT_COLUMN_OPTIONS,] }] }
2617 ]; };
2618 CdkTextColumn.propDecorators = {
2619 name: [{ type: core.Input }],
2620 headerText: [{ type: core.Input }],
2621 dataAccessor: [{ type: core.Input }],
2622 justify: [{ type: core.Input }],
2623 columnDef: [{ type: core.ViewChild, args: [CdkColumnDef, { static: true },] }],
2624 cell: [{ type: core.ViewChild, args: [CdkCellDef, { static: true },] }],
2625 headerCell: [{ type: core.ViewChild, args: [CdkHeaderCellDef, { static: true },] }]
2626 };
2627
2628 /**
2629 * @license
2630 * Copyright Google LLC All Rights Reserved.
2631 *
2632 * Use of this source code is governed by an MIT-style license that can be
2633 * found in the LICENSE file at https://angular.io/license
2634 */
2635 var EXPORTED_DECLARATIONS = [
2636 CdkTable,
2637 CdkRowDef,
2638 CdkCellDef,
2639 CdkCellOutlet,
2640 CdkHeaderCellDef,
2641 CdkFooterCellDef,
2642 CdkColumnDef,
2643 CdkCell,
2644 CdkRow,
2645 CdkHeaderCell,
2646 CdkFooterCell,
2647 CdkHeaderRow,
2648 CdkHeaderRowDef,
2649 CdkFooterRow,
2650 CdkFooterRowDef,
2651 DataRowOutlet,
2652 HeaderRowOutlet,
2653 FooterRowOutlet,
2654 CdkTextColumn,
2655 CdkNoDataRow,
2656 CdkRecycleRows,
2657 NoDataRowOutlet,
2658 ];
2659 var CdkTableModule = /** @class */ (function () {
2660 function CdkTableModule() {
2661 }
2662 return CdkTableModule;
2663 }());
2664 CdkTableModule.decorators = [
2665 { type: core.NgModule, args: [{
2666 exports: EXPORTED_DECLARATIONS,
2667 declarations: EXPORTED_DECLARATIONS,
2668 imports: [scrolling.ScrollingModule]
2669 },] }
2670 ];
2671
2672 /**
2673 * @license
2674 * Copyright Google LLC All Rights Reserved.
2675 *
2676 * Use of this source code is governed by an MIT-style license that can be
2677 * found in the LICENSE file at https://angular.io/license
2678 */
2679
2680 /**
2681 * Generated bundle index. Do not edit.
2682 */
2683
2684 Object.defineProperty(exports, 'DataSource', {
2685 enumerable: true,
2686 get: function () {
2687 return collections.DataSource;
2688 }
2689 });
2690 exports.BaseCdkCell = BaseCdkCell;
2691 exports.BaseRowDef = BaseRowDef;
2692 exports.CDK_ROW_TEMPLATE = CDK_ROW_TEMPLATE;
2693 exports.CDK_TABLE = CDK_TABLE;
2694 exports.CDK_TABLE_TEMPLATE = CDK_TABLE_TEMPLATE;
2695 exports.CdkCell = CdkCell;
2696 exports.CdkCellDef = CdkCellDef;
2697 exports.CdkCellOutlet = CdkCellOutlet;
2698 exports.CdkColumnDef = CdkColumnDef;
2699 exports.CdkFooterCell = CdkFooterCell;
2700 exports.CdkFooterCellDef = CdkFooterCellDef;
2701 exports.CdkFooterRow = CdkFooterRow;
2702 exports.CdkFooterRowDef = CdkFooterRowDef;
2703 exports.CdkHeaderCell = CdkHeaderCell;
2704 exports.CdkHeaderCellDef = CdkHeaderCellDef;
2705 exports.CdkHeaderRow = CdkHeaderRow;
2706 exports.CdkHeaderRowDef = CdkHeaderRowDef;
2707 exports.CdkNoDataRow = CdkNoDataRow;
2708 exports.CdkRecycleRows = CdkRecycleRows;
2709 exports.CdkRow = CdkRow;
2710 exports.CdkRowDef = CdkRowDef;
2711 exports.CdkTable = CdkTable;
2712 exports.CdkTableModule = CdkTableModule;
2713 exports.CdkTextColumn = CdkTextColumn;
2714 exports.DataRowOutlet = DataRowOutlet;
2715 exports.FooterRowOutlet = FooterRowOutlet;
2716 exports.HeaderRowOutlet = HeaderRowOutlet;
2717 exports.NoDataRowOutlet = NoDataRowOutlet;
2718 exports.STICKY_DIRECTIONS = STICKY_DIRECTIONS;
2719 exports.STICKY_POSITIONING_LISTENER = STICKY_POSITIONING_LISTENER;
2720 exports.StickyStyler = StickyStyler;
2721 exports.TEXT_COLUMN_OPTIONS = TEXT_COLUMN_OPTIONS;
2722 exports._COALESCED_STYLE_SCHEDULER = _COALESCED_STYLE_SCHEDULER;
2723 exports._CoalescedStyleScheduler = _CoalescedStyleScheduler;
2724 exports._Schedule = _Schedule;
2725 exports.mixinHasStickyInput = mixinHasStickyInput;
2726
2727 Object.defineProperty(exports, '__esModule', { value: true });
2728
2729})));
2730//# sourceMappingURL=cdk-table.umd.js.map