| (function (global, factory) { |
| 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')) : |
| 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) : |
| (global = 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)); |
| }(this, (function (exports, bidi, coercion, collections, platform, scrolling, common, core, rxjs, operators) { 'use strict'; |
| |
| /*! ***************************************************************************** |
| Copyright (c) Microsoft Corporation. |
| |
| Permission to use, copy, modify, and/or distribute this software for any |
| purpose with or without fee is hereby granted. |
| |
| THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH |
| REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
| AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, |
| INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
| LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR |
| OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
| PERFORMANCE OF THIS SOFTWARE. |
| ***************************************************************************** */ |
| /* global Reflect, Promise */ |
| var extendStatics = function (d, b) { |
| extendStatics = Object.setPrototypeOf || |
| ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || |
| function (d, b) { for (var p in b) |
| if (Object.prototype.hasOwnProperty.call(b, p)) |
| d[p] = b[p]; }; |
| return extendStatics(d, b); |
| }; |
| function __extends(d, b) { |
| if (typeof b !== "function" && b !== null) |
| throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); |
| extendStatics(d, b); |
| function __() { this.constructor = d; } |
| d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); |
| } |
| var __assign = function () { |
| __assign = Object.assign || function __assign(t) { |
| for (var s, i = 1, n = arguments.length; i < n; i++) { |
| s = arguments[i]; |
| for (var p in s) |
| if (Object.prototype.hasOwnProperty.call(s, p)) |
| t[p] = s[p]; |
| } |
| return t; |
| }; |
| return __assign.apply(this, arguments); |
| }; |
| function __rest(s, e) { |
| var t = {}; |
| for (var p in s) |
| if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) |
| t[p] = s[p]; |
| if (s != null && typeof Object.getOwnPropertySymbols === "function") |
| for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { |
| if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) |
| t[p[i]] = s[p[i]]; |
| } |
| return t; |
| } |
| function __decorate(decorators, target, key, desc) { |
| var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; |
| if (typeof Reflect === "object" && typeof Reflect.decorate === "function") |
| r = Reflect.decorate(decorators, target, key, desc); |
| else |
| for (var i = decorators.length - 1; i >= 0; i--) |
| if (d = decorators[i]) |
| r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; |
| return c > 3 && r && Object.defineProperty(target, key, r), r; |
| } |
| function __param(paramIndex, decorator) { |
| return function (target, key) { decorator(target, key, paramIndex); }; |
| } |
| function __metadata(metadataKey, metadataValue) { |
| if (typeof Reflect === "object" && typeof Reflect.metadata === "function") |
| return Reflect.metadata(metadataKey, metadataValue); |
| } |
| function __awaiter(thisArg, _arguments, P, generator) { |
| function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } |
| return new (P || (P = Promise))(function (resolve, reject) { |
| function fulfilled(value) { try { |
| step(generator.next(value)); |
| } |
| catch (e) { |
| reject(e); |
| } } |
| function rejected(value) { try { |
| step(generator["throw"](value)); |
| } |
| catch (e) { |
| reject(e); |
| } } |
| function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } |
| step((generator = generator.apply(thisArg, _arguments || [])).next()); |
| }); |
| } |
| function __generator(thisArg, body) { |
| var _ = { label: 0, sent: function () { if (t[0] & 1) |
| throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; |
| return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g; |
| function verb(n) { return function (v) { return step([n, v]); }; } |
| function step(op) { |
| if (f) |
| throw new TypeError("Generator is already executing."); |
| while (_) |
| try { |
| 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) |
| return t; |
| if (y = 0, t) |
| op = [op[0] & 2, t.value]; |
| switch (op[0]) { |
| case 0: |
| case 1: |
| t = op; |
| break; |
| case 4: |
| _.label++; |
| return { value: op[1], done: false }; |
| case 5: |
| _.label++; |
| y = op[1]; |
| op = [0]; |
| continue; |
| case 7: |
| op = _.ops.pop(); |
| _.trys.pop(); |
| continue; |
| default: |
| if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { |
| _ = 0; |
| continue; |
| } |
| if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { |
| _.label = op[1]; |
| break; |
| } |
| if (op[0] === 6 && _.label < t[1]) { |
| _.label = t[1]; |
| t = op; |
| break; |
| } |
| if (t && _.label < t[2]) { |
| _.label = t[2]; |
| _.ops.push(op); |
| break; |
| } |
| if (t[2]) |
| _.ops.pop(); |
| _.trys.pop(); |
| continue; |
| } |
| op = body.call(thisArg, _); |
| } |
| catch (e) { |
| op = [6, e]; |
| y = 0; |
| } |
| finally { |
| f = t = 0; |
| } |
| if (op[0] & 5) |
| throw op[1]; |
| return { value: op[0] ? op[1] : void 0, done: true }; |
| } |
| } |
| var __createBinding = Object.create ? (function (o, m, k, k2) { |
| if (k2 === undefined) |
| k2 = k; |
| Object.defineProperty(o, k2, { enumerable: true, get: function () { return m[k]; } }); |
| }) : (function (o, m, k, k2) { |
| if (k2 === undefined) |
| k2 = k; |
| o[k2] = m[k]; |
| }); |
| function __exportStar(m, o) { |
| for (var p in m) |
| if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) |
| __createBinding(o, m, p); |
| } |
| function __values(o) { |
| var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; |
| if (m) |
| return m.call(o); |
| if (o && typeof o.length === "number") |
| return { |
| next: function () { |
| if (o && i >= o.length) |
| o = void 0; |
| return { value: o && o[i++], done: !o }; |
| } |
| }; |
| throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); |
| } |
| function __read(o, n) { |
| var m = typeof Symbol === "function" && o[Symbol.iterator]; |
| if (!m) |
| return o; |
| var i = m.call(o), r, ar = [], e; |
| try { |
| while ((n === void 0 || n-- > 0) && !(r = i.next()).done) |
| ar.push(r.value); |
| } |
| catch (error) { |
| e = { error: error }; |
| } |
| finally { |
| try { |
| if (r && !r.done && (m = i["return"])) |
| m.call(i); |
| } |
| finally { |
| if (e) |
| throw e.error; |
| } |
| } |
| return ar; |
| } |
| /** @deprecated */ |
| function __spread() { |
| for (var ar = [], i = 0; i < arguments.length; i++) |
| ar = ar.concat(__read(arguments[i])); |
| return ar; |
| } |
| /** @deprecated */ |
| function __spreadArrays() { |
| for (var s = 0, i = 0, il = arguments.length; i < il; i++) |
| s += arguments[i].length; |
| for (var r = Array(s), k = 0, i = 0; i < il; i++) |
| for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) |
| r[k] = a[j]; |
| return r; |
| } |
| function __spreadArray(to, from) { |
| for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) |
| to[j] = from[i]; |
| return to; |
| } |
| function __await(v) { |
| return this instanceof __await ? (this.v = v, this) : new __await(v); |
| } |
| function __asyncGenerator(thisArg, _arguments, generator) { |
| if (!Symbol.asyncIterator) |
| throw new TypeError("Symbol.asyncIterator is not defined."); |
| var g = generator.apply(thisArg, _arguments || []), i, q = []; |
| return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; |
| function verb(n) { if (g[n]) |
| i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } |
| function resume(n, v) { try { |
| step(g[n](v)); |
| } |
| catch (e) { |
| settle(q[0][3], e); |
| } } |
| function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } |
| function fulfill(value) { resume("next", value); } |
| function reject(value) { resume("throw", value); } |
| function settle(f, v) { if (f(v), q.shift(), q.length) |
| resume(q[0][0], q[0][1]); } |
| } |
| function __asyncDelegator(o) { |
| var i, p; |
| return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; |
| 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; } |
| } |
| function __asyncValues(o) { |
| if (!Symbol.asyncIterator) |
| throw new TypeError("Symbol.asyncIterator is not defined."); |
| var m = o[Symbol.asyncIterator], i; |
| 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); |
| 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); }); }; } |
| function settle(resolve, reject, d, v) { Promise.resolve(v).then(function (v) { resolve({ value: v, done: d }); }, reject); } |
| } |
| function __makeTemplateObject(cooked, raw) { |
| if (Object.defineProperty) { |
| Object.defineProperty(cooked, "raw", { value: raw }); |
| } |
| else { |
| cooked.raw = raw; |
| } |
| return cooked; |
| } |
| ; |
| var __setModuleDefault = Object.create ? (function (o, v) { |
| Object.defineProperty(o, "default", { enumerable: true, value: v }); |
| }) : function (o, v) { |
| o["default"] = v; |
| }; |
| function __importStar(mod) { |
| if (mod && mod.__esModule) |
| return mod; |
| var result = {}; |
| if (mod != null) |
| for (var k in mod) |
| if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) |
| __createBinding(result, mod, k); |
| __setModuleDefault(result, mod); |
| return result; |
| } |
| function __importDefault(mod) { |
| return (mod && mod.__esModule) ? mod : { default: mod }; |
| } |
| function __classPrivateFieldGet(receiver, privateMap) { |
| if (!privateMap.has(receiver)) { |
| throw new TypeError("attempted to get private field on non-instance"); |
| } |
| return privateMap.get(receiver); |
| } |
| function __classPrivateFieldSet(receiver, privateMap, value) { |
| if (!privateMap.has(receiver)) { |
| throw new TypeError("attempted to set private field on non-instance"); |
| } |
| privateMap.set(receiver, value); |
| return value; |
| } |
| |
| /** |
| * Mixin to provide a directive with a function that checks if the sticky input has been |
| * changed since the last time the function was called. Essentially adds a dirty-check to the |
| * sticky value. |
| * @docs-private |
| */ |
| function mixinHasStickyInput(base) { |
| return /** @class */ (function (_super) { |
| __extends(class_1, _super); |
| function class_1() { |
| var args = []; |
| for (var _i = 0; _i < arguments.length; _i++) { |
| args[_i] = arguments[_i]; |
| } |
| var _this = _super.apply(this, __spread(args)) || this; |
| _this._sticky = false; |
| /** Whether the sticky input has changed since it was last checked. */ |
| _this._hasStickyChanged = false; |
| return _this; |
| } |
| Object.defineProperty(class_1.prototype, "sticky", { |
| /** Whether sticky positioning should be applied. */ |
| get: function () { return this._sticky; }, |
| set: function (v) { |
| var prevValue = this._sticky; |
| this._sticky = coercion.coerceBooleanProperty(v); |
| this._hasStickyChanged = prevValue !== this._sticky; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| /** Whether the sticky value has changed since this was last called. */ |
| class_1.prototype.hasStickyChanged = function () { |
| var hasStickyChanged = this._hasStickyChanged; |
| this._hasStickyChanged = false; |
| return hasStickyChanged; |
| }; |
| /** Resets the dirty check for cases where the sticky state has been used without checking. */ |
| class_1.prototype.resetStickyChanged = function () { |
| this._hasStickyChanged = false; |
| }; |
| return class_1; |
| }(base)); |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * Used to provide a table to some of the sub-components without causing a circular dependency. |
| * @docs-private |
| */ |
| var CDK_TABLE = new core.InjectionToken('CDK_TABLE'); |
| /** Injection token that can be used to specify the text column options. */ |
| var TEXT_COLUMN_OPTIONS = new core.InjectionToken('text-column-options'); |
| |
| /** |
| * Cell definition for a CDK table. |
| * Captures the template of a column's data row cell as well as cell-specific properties. |
| */ |
| var CdkCellDef = /** @class */ (function () { |
| function CdkCellDef(/** @docs-private */ template) { |
| this.template = template; |
| } |
| return CdkCellDef; |
| }()); |
| CdkCellDef.decorators = [ |
| { type: core.Directive, args: [{ selector: '[cdkCellDef]' },] } |
| ]; |
| CdkCellDef.ctorParameters = function () { return [ |
| { type: core.TemplateRef } |
| ]; }; |
| /** |
| * Header cell definition for a CDK table. |
| * Captures the template of a column's header cell and as well as cell-specific properties. |
| */ |
| var CdkHeaderCellDef = /** @class */ (function () { |
| function CdkHeaderCellDef(/** @docs-private */ template) { |
| this.template = template; |
| } |
| return CdkHeaderCellDef; |
| }()); |
| CdkHeaderCellDef.decorators = [ |
| { type: core.Directive, args: [{ selector: '[cdkHeaderCellDef]' },] } |
| ]; |
| CdkHeaderCellDef.ctorParameters = function () { return [ |
| { type: core.TemplateRef } |
| ]; }; |
| /** |
| * Footer cell definition for a CDK table. |
| * Captures the template of a column's footer cell and as well as cell-specific properties. |
| */ |
| var CdkFooterCellDef = /** @class */ (function () { |
| function CdkFooterCellDef(/** @docs-private */ template) { |
| this.template = template; |
| } |
| return CdkFooterCellDef; |
| }()); |
| CdkFooterCellDef.decorators = [ |
| { type: core.Directive, args: [{ selector: '[cdkFooterCellDef]' },] } |
| ]; |
| CdkFooterCellDef.ctorParameters = function () { return [ |
| { type: core.TemplateRef } |
| ]; }; |
| // Boilerplate for applying mixins to CdkColumnDef. |
| /** @docs-private */ |
| var CdkColumnDefBase = /** @class */ (function () { |
| function CdkColumnDefBase() { |
| } |
| return CdkColumnDefBase; |
| }()); |
| var _CdkColumnDefBase = mixinHasStickyInput(CdkColumnDefBase); |
| /** |
| * Column definition for the CDK table. |
| * Defines a set of cells available for a table column. |
| */ |
| var CdkColumnDef = /** @class */ (function (_super) { |
| __extends(CdkColumnDef, _super); |
| function CdkColumnDef(_table) { |
| var _this = _super.call(this) || this; |
| _this._table = _table; |
| _this._stickyEnd = false; |
| return _this; |
| } |
| Object.defineProperty(CdkColumnDef.prototype, "name", { |
| /** Unique name for this column. */ |
| get: function () { return this._name; }, |
| set: function (name) { this._setNameInput(name); }, |
| enumerable: false, |
| configurable: true |
| }); |
| Object.defineProperty(CdkColumnDef.prototype, "stickyEnd", { |
| /** |
| * Whether this column should be sticky positioned on the end of the row. Should make sure |
| * that it mimics the `CanStick` mixin such that `_hasStickyChanged` is set to true if the value |
| * has been changed. |
| */ |
| get: function () { |
| return this._stickyEnd; |
| }, |
| set: function (v) { |
| var prevValue = this._stickyEnd; |
| this._stickyEnd = coercion.coerceBooleanProperty(v); |
| this._hasStickyChanged = prevValue !== this._stickyEnd; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| /** |
| * Overridable method that sets the css classes that will be added to every cell in this |
| * column. |
| * In the future, columnCssClassName will change from type string[] to string and this |
| * will set a single string value. |
| * @docs-private |
| */ |
| CdkColumnDef.prototype._updateColumnCssClassName = function () { |
| this._columnCssClassName = ["cdk-column-" + this.cssClassFriendlyName]; |
| }; |
| /** |
| * This has been extracted to a util because of TS 4 and VE. |
| * View Engine doesn't support property rename inheritance. |
| * TS 4.0 doesn't allow properties to override accessors or vice-versa. |
| * @docs-private |
| */ |
| CdkColumnDef.prototype._setNameInput = function (value) { |
| // If the directive is set without a name (updated programmatically), then this setter will |
| // trigger with an empty string and should not overwrite the programmatically set value. |
| if (value) { |
| this._name = value; |
| this.cssClassFriendlyName = value.replace(/[^a-z0-9_-]/ig, '-'); |
| this._updateColumnCssClassName(); |
| } |
| }; |
| return CdkColumnDef; |
| }(_CdkColumnDefBase)); |
| CdkColumnDef.decorators = [ |
| { type: core.Directive, args: [{ |
| selector: '[cdkColumnDef]', |
| inputs: ['sticky'], |
| providers: [{ provide: 'MAT_SORT_HEADER_COLUMN_DEF', useExisting: CdkColumnDef }], |
| },] } |
| ]; |
| CdkColumnDef.ctorParameters = function () { return [ |
| { type: undefined, decorators: [{ type: core.Inject, args: [CDK_TABLE,] }, { type: core.Optional }] } |
| ]; }; |
| CdkColumnDef.propDecorators = { |
| name: [{ type: core.Input, args: ['cdkColumnDef',] }], |
| stickyEnd: [{ type: core.Input, args: ['stickyEnd',] }], |
| cell: [{ type: core.ContentChild, args: [CdkCellDef,] }], |
| headerCell: [{ type: core.ContentChild, args: [CdkHeaderCellDef,] }], |
| footerCell: [{ type: core.ContentChild, args: [CdkFooterCellDef,] }] |
| }; |
| /** Base class for the cells. Adds a CSS classname that identifies the column it renders in. */ |
| var BaseCdkCell = /** @class */ (function () { |
| function BaseCdkCell(columnDef, elementRef) { |
| var e_1, _a; |
| // If IE 11 is dropped before we switch to setting a single class name, change to multi param |
| // with destructuring. |
| var classList = elementRef.nativeElement.classList; |
| try { |
| for (var _b = __values(columnDef._columnCssClassName), _c = _b.next(); !_c.done; _c = _b.next()) { |
| var className = _c.value; |
| classList.add(className); |
| } |
| } |
| catch (e_1_1) { e_1 = { error: e_1_1 }; } |
| finally { |
| try { |
| if (_c && !_c.done && (_a = _b.return)) _a.call(_b); |
| } |
| finally { if (e_1) throw e_1.error; } |
| } |
| } |
| return BaseCdkCell; |
| }()); |
| /** Header cell template container that adds the right classes and role. */ |
| var CdkHeaderCell = /** @class */ (function (_super) { |
| __extends(CdkHeaderCell, _super); |
| function CdkHeaderCell(columnDef, elementRef) { |
| return _super.call(this, columnDef, elementRef) || this; |
| } |
| return CdkHeaderCell; |
| }(BaseCdkCell)); |
| CdkHeaderCell.decorators = [ |
| { type: core.Directive, args: [{ |
| selector: 'cdk-header-cell, th[cdk-header-cell]', |
| host: { |
| 'class': 'cdk-header-cell', |
| 'role': 'columnheader', |
| }, |
| },] } |
| ]; |
| CdkHeaderCell.ctorParameters = function () { return [ |
| { type: CdkColumnDef }, |
| { type: core.ElementRef } |
| ]; }; |
| /** Footer cell template container that adds the right classes and role. */ |
| var CdkFooterCell = /** @class */ (function (_super) { |
| __extends(CdkFooterCell, _super); |
| function CdkFooterCell(columnDef, elementRef) { |
| return _super.call(this, columnDef, elementRef) || this; |
| } |
| return CdkFooterCell; |
| }(BaseCdkCell)); |
| CdkFooterCell.decorators = [ |
| { type: core.Directive, args: [{ |
| selector: 'cdk-footer-cell, td[cdk-footer-cell]', |
| host: { |
| 'class': 'cdk-footer-cell', |
| 'role': 'gridcell', |
| }, |
| },] } |
| ]; |
| CdkFooterCell.ctorParameters = function () { return [ |
| { type: CdkColumnDef }, |
| { type: core.ElementRef } |
| ]; }; |
| /** Cell template container that adds the right classes and role. */ |
| var CdkCell = /** @class */ (function (_super) { |
| __extends(CdkCell, _super); |
| function CdkCell(columnDef, elementRef) { |
| return _super.call(this, columnDef, elementRef) || this; |
| } |
| return CdkCell; |
| }(BaseCdkCell)); |
| CdkCell.decorators = [ |
| { type: core.Directive, args: [{ |
| selector: 'cdk-cell, td[cdk-cell]', |
| host: { |
| 'class': 'cdk-cell', |
| 'role': 'gridcell', |
| }, |
| },] } |
| ]; |
| CdkCell.ctorParameters = function () { return [ |
| { type: CdkColumnDef }, |
| { type: core.ElementRef } |
| ]; }; |
| |
| /** |
| * @docs-private |
| */ |
| var _Schedule = /** @class */ (function () { |
| function _Schedule() { |
| this.tasks = []; |
| this.endTasks = []; |
| } |
| return _Schedule; |
| }()); |
| /** Injection token used to provide a coalesced style scheduler. */ |
| var _COALESCED_STYLE_SCHEDULER = new core.InjectionToken('_COALESCED_STYLE_SCHEDULER'); |
| /** |
| * Allows grouping up CSSDom mutations after the current execution context. |
| * This can significantly improve performance when separate consecutive functions are |
| * reading from the CSSDom and then mutating it. |
| * |
| * @docs-private |
| */ |
| var _CoalescedStyleScheduler = /** @class */ (function () { |
| function _CoalescedStyleScheduler(_ngZone) { |
| this._ngZone = _ngZone; |
| this._currentSchedule = null; |
| this._destroyed = new rxjs.Subject(); |
| } |
| /** |
| * Schedules the specified task to run at the end of the current VM turn. |
| */ |
| _CoalescedStyleScheduler.prototype.schedule = function (task) { |
| this._createScheduleIfNeeded(); |
| this._currentSchedule.tasks.push(task); |
| }; |
| /** |
| * Schedules the specified task to run after other scheduled tasks at the end of the current |
| * VM turn. |
| */ |
| _CoalescedStyleScheduler.prototype.scheduleEnd = function (task) { |
| this._createScheduleIfNeeded(); |
| this._currentSchedule.endTasks.push(task); |
| }; |
| /** Prevent any further tasks from running. */ |
| _CoalescedStyleScheduler.prototype.ngOnDestroy = function () { |
| this._destroyed.next(); |
| this._destroyed.complete(); |
| }; |
| _CoalescedStyleScheduler.prototype._createScheduleIfNeeded = function () { |
| var _this = this; |
| if (this._currentSchedule) { |
| return; |
| } |
| this._currentSchedule = new _Schedule(); |
| this._getScheduleObservable().pipe(operators.takeUntil(this._destroyed)).subscribe(function () { |
| var e_1, _a, e_2, _b; |
| while (_this._currentSchedule.tasks.length || _this._currentSchedule.endTasks.length) { |
| var schedule = _this._currentSchedule; |
| // Capture new tasks scheduled by the current set of tasks. |
| _this._currentSchedule = new _Schedule(); |
| try { |
| for (var _c = (e_1 = void 0, __values(schedule.tasks)), _d = _c.next(); !_d.done; _d = _c.next()) { |
| var task = _d.value; |
| task(); |
| } |
| } |
| catch (e_1_1) { e_1 = { error: e_1_1 }; } |
| finally { |
| try { |
| if (_d && !_d.done && (_a = _c.return)) _a.call(_c); |
| } |
| finally { if (e_1) throw e_1.error; } |
| } |
| try { |
| for (var _e = (e_2 = void 0, __values(schedule.endTasks)), _f = _e.next(); !_f.done; _f = _e.next()) { |
| var task = _f.value; |
| task(); |
| } |
| } |
| catch (e_2_1) { e_2 = { error: e_2_1 }; } |
| finally { |
| try { |
| if (_f && !_f.done && (_b = _e.return)) _b.call(_e); |
| } |
| finally { if (e_2) throw e_2.error; } |
| } |
| } |
| _this._currentSchedule = null; |
| }); |
| }; |
| _CoalescedStyleScheduler.prototype._getScheduleObservable = function () { |
| // Use onStable when in the context of an ongoing change detection cycle so that we |
| // do not accidentally trigger additional cycles. |
| return this._ngZone.isStable ? |
| rxjs.from(Promise.resolve(undefined)) : |
| this._ngZone.onStable.pipe(operators.take(1)); |
| }; |
| return _CoalescedStyleScheduler; |
| }()); |
| _CoalescedStyleScheduler.decorators = [ |
| { type: core.Injectable } |
| ]; |
| _CoalescedStyleScheduler.ctorParameters = function () { return [ |
| { type: core.NgZone } |
| ]; }; |
| |
| /** |
| * The row template that can be used by the mat-table. Should not be used outside of the |
| * material library. |
| */ |
| var CDK_ROW_TEMPLATE = "<ng-container cdkCellOutlet></ng-container>"; |
| /** |
| * Base class for the CdkHeaderRowDef and CdkRowDef that handles checking their columns inputs |
| * for changes and notifying the table. |
| */ |
| var BaseRowDef = /** @class */ (function () { |
| function BaseRowDef( |
| /** @docs-private */ template, _differs) { |
| this.template = template; |
| this._differs = _differs; |
| } |
| BaseRowDef.prototype.ngOnChanges = function (changes) { |
| // Create a new columns differ if one does not yet exist. Initialize it based on initial value |
| // of the columns property or an empty array if none is provided. |
| if (!this._columnsDiffer) { |
| var columns = (changes['columns'] && changes['columns'].currentValue) || []; |
| this._columnsDiffer = this._differs.find(columns).create(); |
| this._columnsDiffer.diff(columns); |
| } |
| }; |
| /** |
| * Returns the difference between the current columns and the columns from the last diff, or null |
| * if there is no difference. |
| */ |
| BaseRowDef.prototype.getColumnsDiff = function () { |
| return this._columnsDiffer.diff(this.columns); |
| }; |
| /** Gets this row def's relevant cell template from the provided column def. */ |
| BaseRowDef.prototype.extractCellTemplate = function (column) { |
| if (this instanceof CdkHeaderRowDef) { |
| return column.headerCell.template; |
| } |
| if (this instanceof CdkFooterRowDef) { |
| return column.footerCell.template; |
| } |
| else { |
| return column.cell.template; |
| } |
| }; |
| return BaseRowDef; |
| }()); |
| BaseRowDef.decorators = [ |
| { type: core.Directive } |
| ]; |
| BaseRowDef.ctorParameters = function () { return [ |
| { type: core.TemplateRef }, |
| { type: core.IterableDiffers } |
| ]; }; |
| // Boilerplate for applying mixins to CdkHeaderRowDef. |
| /** @docs-private */ |
| var CdkHeaderRowDefBase = /** @class */ (function (_super) { |
| __extends(CdkHeaderRowDefBase, _super); |
| function CdkHeaderRowDefBase() { |
| return _super !== null && _super.apply(this, arguments) || this; |
| } |
| return CdkHeaderRowDefBase; |
| }(BaseRowDef)); |
| var _CdkHeaderRowDefBase = mixinHasStickyInput(CdkHeaderRowDefBase); |
| /** |
| * Header row definition for the CDK table. |
| * Captures the header row's template and other header properties such as the columns to display. |
| */ |
| var CdkHeaderRowDef = /** @class */ (function (_super) { |
| __extends(CdkHeaderRowDef, _super); |
| function CdkHeaderRowDef(template, _differs, _table) { |
| var _this = _super.call(this, template, _differs) || this; |
| _this._table = _table; |
| return _this; |
| } |
| // Prerender fails to recognize that ngOnChanges in a part of this class through inheritance. |
| // Explicitly define it so that the method is called as part of the Angular lifecycle. |
| CdkHeaderRowDef.prototype.ngOnChanges = function (changes) { |
| _super.prototype.ngOnChanges.call(this, changes); |
| }; |
| return CdkHeaderRowDef; |
| }(_CdkHeaderRowDefBase)); |
| CdkHeaderRowDef.decorators = [ |
| { type: core.Directive, args: [{ |
| selector: '[cdkHeaderRowDef]', |
| inputs: ['columns: cdkHeaderRowDef', 'sticky: cdkHeaderRowDefSticky'], |
| },] } |
| ]; |
| CdkHeaderRowDef.ctorParameters = function () { return [ |
| { type: core.TemplateRef }, |
| { type: core.IterableDiffers }, |
| { type: undefined, decorators: [{ type: core.Inject, args: [CDK_TABLE,] }, { type: core.Optional }] } |
| ]; }; |
| // Boilerplate for applying mixins to CdkFooterRowDef. |
| /** @docs-private */ |
| var CdkFooterRowDefBase = /** @class */ (function (_super) { |
| __extends(CdkFooterRowDefBase, _super); |
| function CdkFooterRowDefBase() { |
| return _super !== null && _super.apply(this, arguments) || this; |
| } |
| return CdkFooterRowDefBase; |
| }(BaseRowDef)); |
| var _CdkFooterRowDefBase = mixinHasStickyInput(CdkFooterRowDefBase); |
| /** |
| * Footer row definition for the CDK table. |
| * Captures the footer row's template and other footer properties such as the columns to display. |
| */ |
| var CdkFooterRowDef = /** @class */ (function (_super) { |
| __extends(CdkFooterRowDef, _super); |
| function CdkFooterRowDef(template, _differs, _table) { |
| var _this = _super.call(this, template, _differs) || this; |
| _this._table = _table; |
| return _this; |
| } |
| // Prerender fails to recognize that ngOnChanges in a part of this class through inheritance. |
| // Explicitly define it so that the method is called as part of the Angular lifecycle. |
| CdkFooterRowDef.prototype.ngOnChanges = function (changes) { |
| _super.prototype.ngOnChanges.call(this, changes); |
| }; |
| return CdkFooterRowDef; |
| }(_CdkFooterRowDefBase)); |
| CdkFooterRowDef.decorators = [ |
| { type: core.Directive, args: [{ |
| selector: '[cdkFooterRowDef]', |
| inputs: ['columns: cdkFooterRowDef', 'sticky: cdkFooterRowDefSticky'], |
| },] } |
| ]; |
| CdkFooterRowDef.ctorParameters = function () { return [ |
| { type: core.TemplateRef }, |
| { type: core.IterableDiffers }, |
| { type: undefined, decorators: [{ type: core.Inject, args: [CDK_TABLE,] }, { type: core.Optional }] } |
| ]; }; |
| /** |
| * Data row definition for the CDK table. |
| * Captures the header row's template and other row properties such as the columns to display and |
| * a when predicate that describes when this row should be used. |
| */ |
| var CdkRowDef = /** @class */ (function (_super) { |
| __extends(CdkRowDef, _super); |
| // TODO(andrewseguin): Add an input for providing a switch function to determine |
| // if this template should be used. |
| function CdkRowDef(template, _differs, _table) { |
| var _this = _super.call(this, template, _differs) || this; |
| _this._table = _table; |
| return _this; |
| } |
| return CdkRowDef; |
| }(BaseRowDef)); |
| CdkRowDef.decorators = [ |
| { type: core.Directive, args: [{ |
| selector: '[cdkRowDef]', |
| inputs: ['columns: cdkRowDefColumns', 'when: cdkRowDefWhen'], |
| },] } |
| ]; |
| CdkRowDef.ctorParameters = function () { return [ |
| { type: core.TemplateRef }, |
| { type: core.IterableDiffers }, |
| { type: undefined, decorators: [{ type: core.Inject, args: [CDK_TABLE,] }, { type: core.Optional }] } |
| ]; }; |
| /** |
| * Outlet for rendering cells inside of a row or header row. |
| * @docs-private |
| */ |
| var CdkCellOutlet = /** @class */ (function () { |
| function CdkCellOutlet(_viewContainer) { |
| this._viewContainer = _viewContainer; |
| CdkCellOutlet.mostRecentCellOutlet = this; |
| } |
| CdkCellOutlet.prototype.ngOnDestroy = function () { |
| // If this was the last outlet being rendered in the view, remove the reference |
| // from the static property after it has been destroyed to avoid leaking memory. |
| if (CdkCellOutlet.mostRecentCellOutlet === this) { |
| CdkCellOutlet.mostRecentCellOutlet = null; |
| } |
| }; |
| return CdkCellOutlet; |
| }()); |
| /** |
| * Static property containing the latest constructed instance of this class. |
| * Used by the CDK table when each CdkHeaderRow and CdkRow component is created using |
| * createEmbeddedView. After one of these components are created, this property will provide |
| * a handle to provide that component's cells and context. After init, the CdkCellOutlet will |
| * construct the cells with the provided context. |
| */ |
| CdkCellOutlet.mostRecentCellOutlet = null; |
| CdkCellOutlet.decorators = [ |
| { type: core.Directive, args: [{ selector: '[cdkCellOutlet]' },] } |
| ]; |
| CdkCellOutlet.ctorParameters = function () { return [ |
| { type: core.ViewContainerRef } |
| ]; }; |
| /** Header template container that contains the cell outlet. Adds the right class and role. */ |
| var CdkHeaderRow = /** @class */ (function () { |
| function CdkHeaderRow() { |
| } |
| return CdkHeaderRow; |
| }()); |
| CdkHeaderRow.decorators = [ |
| { type: core.Component, args: [{ |
| selector: 'cdk-header-row, tr[cdk-header-row]', |
| template: CDK_ROW_TEMPLATE, |
| host: { |
| 'class': 'cdk-header-row', |
| 'role': 'row', |
| }, |
| // See note on CdkTable for explanation on why this uses the default change detection strategy. |
| // tslint:disable-next-line:validate-decorators |
| changeDetection: core.ChangeDetectionStrategy.Default, |
| encapsulation: core.ViewEncapsulation.None |
| },] } |
| ]; |
| /** Footer template container that contains the cell outlet. Adds the right class and role. */ |
| var CdkFooterRow = /** @class */ (function () { |
| function CdkFooterRow() { |
| } |
| return CdkFooterRow; |
| }()); |
| CdkFooterRow.decorators = [ |
| { type: core.Component, args: [{ |
| selector: 'cdk-footer-row, tr[cdk-footer-row]', |
| template: CDK_ROW_TEMPLATE, |
| host: { |
| 'class': 'cdk-footer-row', |
| 'role': 'row', |
| }, |
| // See note on CdkTable for explanation on why this uses the default change detection strategy. |
| // tslint:disable-next-line:validate-decorators |
| changeDetection: core.ChangeDetectionStrategy.Default, |
| encapsulation: core.ViewEncapsulation.None |
| },] } |
| ]; |
| /** Data row template container that contains the cell outlet. Adds the right class and role. */ |
| var CdkRow = /** @class */ (function () { |
| function CdkRow() { |
| } |
| return CdkRow; |
| }()); |
| CdkRow.decorators = [ |
| { type: core.Component, args: [{ |
| selector: 'cdk-row, tr[cdk-row]', |
| template: CDK_ROW_TEMPLATE, |
| host: { |
| 'class': 'cdk-row', |
| 'role': 'row', |
| }, |
| // See note on CdkTable for explanation on why this uses the default change detection strategy. |
| // tslint:disable-next-line:validate-decorators |
| changeDetection: core.ChangeDetectionStrategy.Default, |
| encapsulation: core.ViewEncapsulation.None |
| },] } |
| ]; |
| /** Row that can be used to display a message when no data is shown in the table. */ |
| var CdkNoDataRow = /** @class */ (function () { |
| function CdkNoDataRow(templateRef) { |
| this.templateRef = templateRef; |
| } |
| return CdkNoDataRow; |
| }()); |
| CdkNoDataRow.decorators = [ |
| { type: core.Directive, args: [{ |
| selector: 'ng-template[cdkNoDataRow]' |
| },] } |
| ]; |
| CdkNoDataRow.ctorParameters = function () { return [ |
| { type: core.TemplateRef } |
| ]; }; |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * List of all possible directions that can be used for sticky positioning. |
| * @docs-private |
| */ |
| var STICKY_DIRECTIONS = ['top', 'bottom', 'left', 'right']; |
| /** |
| * Applies and removes sticky positioning styles to the `CdkTable` rows and columns cells. |
| * @docs-private |
| */ |
| var StickyStyler = /** @class */ (function () { |
| /** |
| * @param _isNativeHtmlTable Whether the sticky logic should be based on a table |
| * that uses the native `<table>` element. |
| * @param _stickCellCss The CSS class that will be applied to every row/cell that has |
| * sticky positioning applied. |
| * @param direction The directionality context of the table (ltr/rtl); affects column positioning |
| * by reversing left/right positions. |
| * @param _isBrowser Whether the table is currently being rendered on the server or the client. |
| * @param _needsPositionStickyOnElement Whether we need to specify position: sticky on cells |
| * using inline styles. If false, it is assumed that position: sticky is included in |
| * the component stylesheet for _stickCellCss. |
| * @param _positionListener A listener that is notified of changes to sticky rows/columns |
| * and their dimensions. |
| */ |
| function StickyStyler(_isNativeHtmlTable, _stickCellCss, direction, |
| /** |
| * @deprecated `_coalescedStyleScheduler` parameter to become required. |
| * @breaking-change 11.0.0 |
| */ |
| _coalescedStyleScheduler, _isBrowser, _needsPositionStickyOnElement, _positionListener) { |
| if (_isBrowser === void 0) { _isBrowser = true; } |
| if (_needsPositionStickyOnElement === void 0) { _needsPositionStickyOnElement = true; } |
| this._isNativeHtmlTable = _isNativeHtmlTable; |
| this._stickCellCss = _stickCellCss; |
| this.direction = direction; |
| this._coalescedStyleScheduler = _coalescedStyleScheduler; |
| this._isBrowser = _isBrowser; |
| this._needsPositionStickyOnElement = _needsPositionStickyOnElement; |
| this._positionListener = _positionListener; |
| this._cachedCellWidths = []; |
| this._borderCellCss = { |
| 'top': _stickCellCss + "-border-elem-top", |
| 'bottom': _stickCellCss + "-border-elem-bottom", |
| 'left': _stickCellCss + "-border-elem-left", |
| 'right': _stickCellCss + "-border-elem-right", |
| }; |
| } |
| /** |
| * Clears the sticky positioning styles from the row and its cells by resetting the `position` |
| * style, setting the zIndex to 0, and unsetting each provided sticky direction. |
| * @param rows The list of rows that should be cleared from sticking in the provided directions |
| * @param stickyDirections The directions that should no longer be set as sticky on the rows. |
| */ |
| StickyStyler.prototype.clearStickyPositioning = function (rows, stickyDirections) { |
| var e_1, _c; |
| var _this = this; |
| var elementsToClear = []; |
| try { |
| for (var rows_1 = __values(rows), rows_1_1 = rows_1.next(); !rows_1_1.done; rows_1_1 = rows_1.next()) { |
| var row = rows_1_1.value; |
| // If the row isn't an element (e.g. if it's an `ng-container`), |
| // it won't have inline styles or `children` so we skip it. |
| if (row.nodeType !== row.ELEMENT_NODE) { |
| continue; |
| } |
| elementsToClear.push(row); |
| for (var i = 0; i < row.children.length; i++) { |
| elementsToClear.push(row.children[i]); |
| } |
| } |
| } |
| catch (e_1_1) { e_1 = { error: e_1_1 }; } |
| finally { |
| try { |
| if (rows_1_1 && !rows_1_1.done && (_c = rows_1.return)) _c.call(rows_1); |
| } |
| finally { if (e_1) throw e_1.error; } |
| } |
| // Coalesce with sticky row/column updates (and potentially other changes like column resize). |
| this._scheduleStyleChanges(function () { |
| var e_2, _c; |
| try { |
| for (var elementsToClear_1 = __values(elementsToClear), elementsToClear_1_1 = elementsToClear_1.next(); !elementsToClear_1_1.done; elementsToClear_1_1 = elementsToClear_1.next()) { |
| var element = elementsToClear_1_1.value; |
| _this._removeStickyStyle(element, stickyDirections); |
| } |
| } |
| catch (e_2_1) { e_2 = { error: e_2_1 }; } |
| finally { |
| try { |
| if (elementsToClear_1_1 && !elementsToClear_1_1.done && (_c = elementsToClear_1.return)) _c.call(elementsToClear_1); |
| } |
| finally { if (e_2) throw e_2.error; } |
| } |
| }); |
| }; |
| /** |
| * Applies sticky left and right positions to the cells of each row according to the sticky |
| * states of the rendered column definitions. |
| * @param rows The rows that should have its set of cells stuck according to the sticky states. |
| * @param stickyStartStates A list of boolean states where each state represents whether the cell |
| * in this index position should be stuck to the start of the row. |
| * @param stickyEndStates A list of boolean states where each state represents whether the cell |
| * in this index position should be stuck to the end of the row. |
| * @param recalculateCellWidths Whether the sticky styler should recalculate the width of each |
| * column cell. If `false` cached widths will be used instead. |
| */ |
| StickyStyler.prototype.updateStickyColumns = function (rows, stickyStartStates, stickyEndStates, recalculateCellWidths) { |
| var _this = this; |
| if (recalculateCellWidths === void 0) { recalculateCellWidths = true; } |
| if (!rows.length || !this._isBrowser || !(stickyStartStates.some(function (state) { return state; }) || |
| stickyEndStates.some(function (state) { return state; }))) { |
| if (this._positionListener) { |
| this._positionListener.stickyColumnsUpdated({ sizes: [] }); |
| this._positionListener.stickyEndColumnsUpdated({ sizes: [] }); |
| } |
| return; |
| } |
| var firstRow = rows[0]; |
| var numCells = firstRow.children.length; |
| var cellWidths = this._getCellWidths(firstRow, recalculateCellWidths); |
| var startPositions = this._getStickyStartColumnPositions(cellWidths, stickyStartStates); |
| var endPositions = this._getStickyEndColumnPositions(cellWidths, stickyEndStates); |
| var lastStickyStart = stickyStartStates.lastIndexOf(true); |
| var firstStickyEnd = stickyEndStates.indexOf(true); |
| // Coalesce with sticky row updates (and potentially other changes like column resize). |
| this._scheduleStyleChanges(function () { |
| var e_3, _c; |
| var isRtl = _this.direction === 'rtl'; |
| var start = isRtl ? 'right' : 'left'; |
| var end = isRtl ? 'left' : 'right'; |
| try { |
| for (var rows_2 = __values(rows), rows_2_1 = rows_2.next(); !rows_2_1.done; rows_2_1 = rows_2.next()) { |
| var row = rows_2_1.value; |
| for (var i = 0; i < numCells; i++) { |
| var cell = row.children[i]; |
| if (stickyStartStates[i]) { |
| _this._addStickyStyle(cell, start, startPositions[i], i === lastStickyStart); |
| } |
| if (stickyEndStates[i]) { |
| _this._addStickyStyle(cell, end, endPositions[i], i === firstStickyEnd); |
| } |
| } |
| } |
| } |
| catch (e_3_1) { e_3 = { error: e_3_1 }; } |
| finally { |
| try { |
| if (rows_2_1 && !rows_2_1.done && (_c = rows_2.return)) _c.call(rows_2); |
| } |
| finally { if (e_3) throw e_3.error; } |
| } |
| if (_this._positionListener) { |
| _this._positionListener.stickyColumnsUpdated({ |
| sizes: lastStickyStart === -1 ? |
| [] : |
| cellWidths |
| .slice(0, lastStickyStart + 1) |
| .map(function (width, index) { return stickyStartStates[index] ? width : null; }) |
| }); |
| _this._positionListener.stickyEndColumnsUpdated({ |
| sizes: firstStickyEnd === -1 ? |
| [] : |
| cellWidths |
| .slice(firstStickyEnd) |
| .map(function (width, index) { return stickyEndStates[index + firstStickyEnd] ? width : null; }) |
| .reverse() |
| }); |
| } |
| }); |
| }; |
| /** |
| * Applies sticky positioning to the row's cells if using the native table layout, and to the |
| * row itself otherwise. |
| * @param rowsToStick The list of rows that should be stuck according to their corresponding |
| * sticky state and to the provided top or bottom position. |
| * @param stickyStates A list of boolean states where each state represents whether the row |
| * should be stuck in the particular top or bottom position. |
| * @param position The position direction in which the row should be stuck if that row should be |
| * sticky. |
| * |
| */ |
| StickyStyler.prototype.stickRows = function (rowsToStick, stickyStates, position) { |
| var _this = this; |
| // Since we can't measure the rows on the server, we can't stick the rows properly. |
| if (!this._isBrowser) { |
| return; |
| } |
| // If positioning the rows to the bottom, reverse their order when evaluating the sticky |
| // position such that the last row stuck will be "bottom: 0px" and so on. Note that the |
| // sticky states need to be reversed as well. |
| var rows = position === 'bottom' ? rowsToStick.slice().reverse() : rowsToStick; |
| var states = position === 'bottom' ? stickyStates.slice().reverse() : stickyStates; |
| // Measure row heights all at once before adding sticky styles to reduce layout thrashing. |
| var stickyOffsets = []; |
| var stickyCellHeights = []; |
| var elementsToStick = []; |
| for (var rowIndex = 0, stickyOffset = 0; rowIndex < rows.length; rowIndex++) { |
| stickyOffsets[rowIndex] = stickyOffset; |
| if (!states[rowIndex]) { |
| continue; |
| } |
| var row = rows[rowIndex]; |
| elementsToStick[rowIndex] = this._isNativeHtmlTable ? |
| Array.from(row.children) : [row]; |
| var height = row.getBoundingClientRect().height; |
| stickyOffset += height; |
| stickyCellHeights[rowIndex] = height; |
| } |
| var borderedRowIndex = states.lastIndexOf(true); |
| // Coalesce with other sticky row updates (top/bottom), sticky columns updates |
| // (and potentially other changes like column resize). |
| this._scheduleStyleChanges(function () { |
| var e_4, _c; |
| var _a, _b; |
| for (var rowIndex = 0; rowIndex < rows.length; rowIndex++) { |
| if (!states[rowIndex]) { |
| continue; |
| } |
| var offset = stickyOffsets[rowIndex]; |
| var isBorderedRowIndex = rowIndex === borderedRowIndex; |
| try { |
| for (var _d = (e_4 = void 0, __values(elementsToStick[rowIndex])), _e = _d.next(); !_e.done; _e = _d.next()) { |
| var element = _e.value; |
| _this._addStickyStyle(element, position, offset, isBorderedRowIndex); |
| } |
| } |
| catch (e_4_1) { e_4 = { error: e_4_1 }; } |
| finally { |
| try { |
| if (_e && !_e.done && (_c = _d.return)) _c.call(_d); |
| } |
| finally { if (e_4) throw e_4.error; } |
| } |
| } |
| if (position === 'top') { |
| (_a = _this._positionListener) === null || _a === void 0 ? void 0 : _a.stickyHeaderRowsUpdated({ sizes: stickyCellHeights, elements: elementsToStick }); |
| } |
| else { |
| (_b = _this._positionListener) === null || _b === void 0 ? void 0 : _b.stickyFooterRowsUpdated({ sizes: stickyCellHeights, elements: elementsToStick }); |
| } |
| }); |
| }; |
| /** |
| * When using the native table in Safari, sticky footer cells do not stick. The only way to stick |
| * footer rows is to apply sticky styling to the tfoot container. This should only be done if |
| * all footer rows are sticky. If not all footer rows are sticky, remove sticky positioning from |
| * the tfoot element. |
| */ |
| StickyStyler.prototype.updateStickyFooterContainer = function (tableElement, stickyStates) { |
| var _this = this; |
| if (!this._isNativeHtmlTable) { |
| return; |
| } |
| var tfoot = tableElement.querySelector('tfoot'); |
| // Coalesce with other sticky updates (and potentially other changes like column resize). |
| this._scheduleStyleChanges(function () { |
| if (stickyStates.some(function (state) { return !state; })) { |
| _this._removeStickyStyle(tfoot, ['bottom']); |
| } |
| else { |
| _this._addStickyStyle(tfoot, 'bottom', 0, false); |
| } |
| }); |
| }; |
| /** |
| * Removes the sticky style on the element by removing the sticky cell CSS class, re-evaluating |
| * the zIndex, removing each of the provided sticky directions, and removing the |
| * sticky position if there are no more directions. |
| */ |
| StickyStyler.prototype._removeStickyStyle = function (element, stickyDirections) { |
| var e_5, _c; |
| try { |
| for (var stickyDirections_1 = __values(stickyDirections), stickyDirections_1_1 = stickyDirections_1.next(); !stickyDirections_1_1.done; stickyDirections_1_1 = stickyDirections_1.next()) { |
| var dir = stickyDirections_1_1.value; |
| element.style[dir] = ''; |
| element.classList.remove(this._borderCellCss[dir]); |
| } |
| } |
| catch (e_5_1) { e_5 = { error: e_5_1 }; } |
| finally { |
| try { |
| if (stickyDirections_1_1 && !stickyDirections_1_1.done && (_c = stickyDirections_1.return)) _c.call(stickyDirections_1); |
| } |
| finally { if (e_5) throw e_5.error; } |
| } |
| // If the element no longer has any more sticky directions, remove sticky positioning and |
| // the sticky CSS class. |
| // Short-circuit checking element.style[dir] for stickyDirections as they |
| // were already removed above. |
| var hasDirection = STICKY_DIRECTIONS.some(function (dir) { return stickyDirections.indexOf(dir) === -1 && element.style[dir]; }); |
| if (hasDirection) { |
| element.style.zIndex = this._getCalculatedZIndex(element); |
| } |
| else { |
| // When not hasDirection, _getCalculatedZIndex will always return ''. |
| element.style.zIndex = ''; |
| if (this._needsPositionStickyOnElement) { |
| element.style.position = ''; |
| } |
| element.classList.remove(this._stickCellCss); |
| } |
| }; |
| /** |
| * Adds the sticky styling to the element by adding the sticky style class, changing position |
| * to be sticky (and -webkit-sticky), setting the appropriate zIndex, and adding a sticky |
| * direction and value. |
| */ |
| StickyStyler.prototype._addStickyStyle = function (element, dir, dirValue, isBorderElement) { |
| element.classList.add(this._stickCellCss); |
| if (isBorderElement) { |
| element.classList.add(this._borderCellCss[dir]); |
| } |
| element.style[dir] = dirValue + "px"; |
| element.style.zIndex = this._getCalculatedZIndex(element); |
| if (this._needsPositionStickyOnElement) { |
| element.style.cssText += 'position: -webkit-sticky; position: sticky; '; |
| } |
| }; |
| /** |
| * Calculate what the z-index should be for the element, depending on what directions (top, |
| * bottom, left, right) have been set. It should be true that elements with a top direction |
| * should have the highest index since these are elements like a table header. If any of those |
| * elements are also sticky in another direction, then they should appear above other elements |
| * that are only sticky top (e.g. a sticky column on a sticky header). Bottom-sticky elements |
| * (e.g. footer rows) should then be next in the ordering such that they are below the header |
| * but above any non-sticky elements. Finally, left/right sticky elements (e.g. sticky columns) |
| * should minimally increment so that they are above non-sticky elements but below top and bottom |
| * elements. |
| */ |
| StickyStyler.prototype._getCalculatedZIndex = function (element) { |
| var e_6, _c; |
| var zIndexIncrements = { |
| top: 100, |
| bottom: 10, |
| left: 1, |
| right: 1, |
| }; |
| var zIndex = 0; |
| try { |
| // Use `Iterable` instead of `Array` because TypeScript, as of 3.6.3, |
| // loses the array generic type in the `for of`. But we *also* have to use `Array` because |
| // typescript won't iterate over an `Iterable` unless you compile with `--downlevelIteration` |
| 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()) { |
| var dir = STICKY_DIRECTIONS_1_1.value; |
| if (element.style[dir]) { |
| zIndex += zIndexIncrements[dir]; |
| } |
| } |
| } |
| catch (e_6_1) { e_6 = { error: e_6_1 }; } |
| finally { |
| try { |
| if (STICKY_DIRECTIONS_1_1 && !STICKY_DIRECTIONS_1_1.done && (_c = STICKY_DIRECTIONS_1.return)) _c.call(STICKY_DIRECTIONS_1); |
| } |
| finally { if (e_6) throw e_6.error; } |
| } |
| return zIndex ? "" + zIndex : ''; |
| }; |
| /** Gets the widths for each cell in the provided row. */ |
| StickyStyler.prototype._getCellWidths = function (row, recalculateCellWidths) { |
| if (recalculateCellWidths === void 0) { recalculateCellWidths = true; } |
| if (!recalculateCellWidths && this._cachedCellWidths.length) { |
| return this._cachedCellWidths; |
| } |
| var cellWidths = []; |
| var firstRowCells = row.children; |
| for (var i = 0; i < firstRowCells.length; i++) { |
| var cell = firstRowCells[i]; |
| cellWidths.push(cell.getBoundingClientRect().width); |
| } |
| this._cachedCellWidths = cellWidths; |
| return cellWidths; |
| }; |
| /** |
| * Determines the left and right positions of each sticky column cell, which will be the |
| * accumulation of all sticky column cell widths to the left and right, respectively. |
| * Non-sticky cells do not need to have a value set since their positions will not be applied. |
| */ |
| StickyStyler.prototype._getStickyStartColumnPositions = function (widths, stickyStates) { |
| var positions = []; |
| var nextPosition = 0; |
| for (var i = 0; i < widths.length; i++) { |
| if (stickyStates[i]) { |
| positions[i] = nextPosition; |
| nextPosition += widths[i]; |
| } |
| } |
| return positions; |
| }; |
| /** |
| * Determines the left and right positions of each sticky column cell, which will be the |
| * accumulation of all sticky column cell widths to the left and right, respectively. |
| * Non-sticky cells do not need to have a value set since their positions will not be applied. |
| */ |
| StickyStyler.prototype._getStickyEndColumnPositions = function (widths, stickyStates) { |
| var positions = []; |
| var nextPosition = 0; |
| for (var i = widths.length; i > 0; i--) { |
| if (stickyStates[i]) { |
| positions[i] = nextPosition; |
| nextPosition += widths[i]; |
| } |
| } |
| return positions; |
| }; |
| /** |
| * Schedules styles to be applied when the style scheduler deems appropriate. |
| * @breaking-change 11.0.0 This method can be removed in favor of calling |
| * `CoalescedStyleScheduler.schedule` directly once the scheduler is a required parameter. |
| */ |
| StickyStyler.prototype._scheduleStyleChanges = function (changes) { |
| if (this._coalescedStyleScheduler) { |
| this._coalescedStyleScheduler.schedule(changes); |
| } |
| else { |
| changes(); |
| } |
| }; |
| return StickyStyler; |
| }()); |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * Returns an error to be thrown when attempting to find an unexisting column. |
| * @param id Id whose lookup failed. |
| * @docs-private |
| */ |
| function getTableUnknownColumnError(id) { |
| return Error("Could not find column with id \"" + id + "\"."); |
| } |
| /** |
| * Returns an error to be thrown when two column definitions have the same name. |
| * @docs-private |
| */ |
| function getTableDuplicateColumnNameError(name) { |
| return Error("Duplicate column definition name provided: \"" + name + "\"."); |
| } |
| /** |
| * Returns an error to be thrown when there are multiple rows that are missing a when function. |
| * @docs-private |
| */ |
| function getTableMultipleDefaultRowDefsError() { |
| return Error("There can only be one default row without a when predicate function."); |
| } |
| /** |
| * Returns an error to be thrown when there are no matching row defs for a particular set of data. |
| * @docs-private |
| */ |
| function getTableMissingMatchingRowDefError(data) { |
| return Error("Could not find a matching row definition for the" + |
| ("provided row data: " + JSON.stringify(data))); |
| } |
| /** |
| * Returns an error to be thrown when there is no row definitions present in the content. |
| * @docs-private |
| */ |
| function getTableMissingRowDefsError() { |
| return Error('Missing definitions for header, footer, and row; ' + |
| 'cannot determine which columns should be rendered.'); |
| } |
| /** |
| * Returns an error to be thrown when the data source does not match the compatible types. |
| * @docs-private |
| */ |
| function getTableUnknownDataSourceError() { |
| return Error("Provided data source did not match an array, Observable, or DataSource"); |
| } |
| /** |
| * Returns an error to be thrown when the text column cannot find a parent table to inject. |
| * @docs-private |
| */ |
| function getTableTextColumnMissingParentTableError() { |
| return Error("Text column could not find a parent table for registration."); |
| } |
| /** |
| * Returns an error to be thrown when a table text column doesn't have a name. |
| * @docs-private |
| */ |
| function getTableTextColumnMissingNameError() { |
| return Error("Table text column must have a name."); |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** The injection token used to specify the StickyPositioningListener. */ |
| var STICKY_POSITIONING_LISTENER = new core.InjectionToken('CDK_SPL'); |
| |
| /** |
| * Provides a handle for the table to grab the view container's ng-container to insert data rows. |
| * @docs-private |
| */ |
| var DataRowOutlet = /** @class */ (function () { |
| function DataRowOutlet(viewContainer, elementRef) { |
| this.viewContainer = viewContainer; |
| this.elementRef = elementRef; |
| } |
| return DataRowOutlet; |
| }()); |
| DataRowOutlet.decorators = [ |
| { type: core.Directive, args: [{ selector: '[rowOutlet]' },] } |
| ]; |
| DataRowOutlet.ctorParameters = function () { return [ |
| { type: core.ViewContainerRef }, |
| { type: core.ElementRef } |
| ]; }; |
| /** |
| * Provides a handle for the table to grab the view container's ng-container to insert the header. |
| * @docs-private |
| */ |
| var HeaderRowOutlet = /** @class */ (function () { |
| function HeaderRowOutlet(viewContainer, elementRef) { |
| this.viewContainer = viewContainer; |
| this.elementRef = elementRef; |
| } |
| return HeaderRowOutlet; |
| }()); |
| HeaderRowOutlet.decorators = [ |
| { type: core.Directive, args: [{ selector: '[headerRowOutlet]' },] } |
| ]; |
| HeaderRowOutlet.ctorParameters = function () { return [ |
| { type: core.ViewContainerRef }, |
| { type: core.ElementRef } |
| ]; }; |
| /** |
| * Provides a handle for the table to grab the view container's ng-container to insert the footer. |
| * @docs-private |
| */ |
| var FooterRowOutlet = /** @class */ (function () { |
| function FooterRowOutlet(viewContainer, elementRef) { |
| this.viewContainer = viewContainer; |
| this.elementRef = elementRef; |
| } |
| return FooterRowOutlet; |
| }()); |
| FooterRowOutlet.decorators = [ |
| { type: core.Directive, args: [{ selector: '[footerRowOutlet]' },] } |
| ]; |
| FooterRowOutlet.ctorParameters = function () { return [ |
| { type: core.ViewContainerRef }, |
| { type: core.ElementRef } |
| ]; }; |
| /** |
| * Provides a handle for the table to grab the view |
| * container's ng-container to insert the no data row. |
| * @docs-private |
| */ |
| var NoDataRowOutlet = /** @class */ (function () { |
| function NoDataRowOutlet(viewContainer, elementRef) { |
| this.viewContainer = viewContainer; |
| this.elementRef = elementRef; |
| } |
| return NoDataRowOutlet; |
| }()); |
| NoDataRowOutlet.decorators = [ |
| { type: core.Directive, args: [{ selector: '[noDataRowOutlet]' },] } |
| ]; |
| NoDataRowOutlet.ctorParameters = function () { return [ |
| { type: core.ViewContainerRef }, |
| { type: core.ElementRef } |
| ]; }; |
| /** |
| * The table template that can be used by the mat-table. Should not be used outside of the |
| * material library. |
| * @docs-private |
| */ |
| var CDK_TABLE_TEMPLATE = |
| // Note that according to MDN, the `caption` element has to be projected as the **first** |
| // element in the table. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/caption |
| "\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"; |
| /** |
| * Class used to conveniently type the embedded view ref for rows with a context. |
| * @docs-private |
| */ |
| var RowViewRef = /** @class */ (function (_super) { |
| __extends(RowViewRef, _super); |
| function RowViewRef() { |
| return _super !== null && _super.apply(this, arguments) || this; |
| } |
| return RowViewRef; |
| }(core.EmbeddedViewRef)); |
| /** |
| * A data table that can render a header row, data rows, and a footer row. |
| * Uses the dataSource input to determine the data to be rendered. The data can be provided either |
| * as a data array, an Observable stream that emits the data array to render, or a DataSource with a |
| * connect function that will return an Observable stream that emits the data array to render. |
| */ |
| var CdkTable = /** @class */ (function () { |
| function CdkTable(_differs, _changeDetectorRef, _elementRef, role, _dir, _document, _platform, |
| /** |
| * @deprecated `_coalescedStyleScheduler`, `_viewRepeater` and `_viewportRuler` |
| * parameters to become required. |
| * @breaking-change 11.0.0 |
| */ |
| _viewRepeater, _coalescedStyleScheduler, _stickyPositioningListener, |
| // Optional for backwards compatibility. The viewport ruler is provided in root. Therefore, |
| // this property will never be null. |
| // tslint:disable-next-line: lightweight-tokens |
| _viewportRuler) { |
| this._differs = _differs; |
| this._changeDetectorRef = _changeDetectorRef; |
| this._elementRef = _elementRef; |
| this._dir = _dir; |
| this._platform = _platform; |
| this._viewRepeater = _viewRepeater; |
| this._coalescedStyleScheduler = _coalescedStyleScheduler; |
| this._stickyPositioningListener = _stickyPositioningListener; |
| this._viewportRuler = _viewportRuler; |
| /** Subject that emits when the component has been destroyed. */ |
| this._onDestroy = new rxjs.Subject(); |
| /** |
| * Map of all the user's defined columns (header, data, and footer cell template) identified by |
| * name. Collection populated by the column definitions gathered by `ContentChildren` as well as |
| * any custom column definitions added to `_customColumnDefs`. |
| */ |
| this._columnDefsByName = new Map(); |
| /** |
| * Column definitions that were defined outside of the direct content children of the table. |
| * These will be defined when, e.g., creating a wrapper around the cdkTable that has |
| * column definitions as *its* content child. |
| */ |
| this._customColumnDefs = new Set(); |
| /** |
| * Data row definitions that were defined outside of the direct content children of the table. |
| * These will be defined when, e.g., creating a wrapper around the cdkTable that has |
| * built-in data rows as *its* content child. |
| */ |
| this._customRowDefs = new Set(); |
| /** |
| * Header row definitions that were defined outside of the direct content children of the table. |
| * These will be defined when, e.g., creating a wrapper around the cdkTable that has |
| * built-in header rows as *its* content child. |
| */ |
| this._customHeaderRowDefs = new Set(); |
| /** |
| * Footer row definitions that were defined outside of the direct content children of the table. |
| * These will be defined when, e.g., creating a wrapper around the cdkTable that has a |
| * built-in footer row as *its* content child. |
| */ |
| this._customFooterRowDefs = new Set(); |
| /** |
| * Whether the header row definition has been changed. Triggers an update to the header row after |
| * content is checked. Initialized as true so that the table renders the initial set of rows. |
| */ |
| this._headerRowDefChanged = true; |
| /** |
| * Whether the footer row definition has been changed. Triggers an update to the footer row after |
| * content is checked. Initialized as true so that the table renders the initial set of rows. |
| */ |
| this._footerRowDefChanged = true; |
| /** |
| * Whether the sticky column styles need to be updated. Set to `true` when the visible columns |
| * change. |
| */ |
| this._stickyColumnStylesNeedReset = true; |
| /** |
| * Whether the sticky styler should recalculate cell widths when applying sticky styles. If |
| * `false`, cached values will be used instead. This is only applicable to tables with |
| * {@link fixedLayout} enabled. For other tables, cell widths will always be recalculated. |
| */ |
| this._forceRecalculateCellWidths = true; |
| /** |
| * Cache of the latest rendered `RenderRow` objects as a map for easy retrieval when constructing |
| * a new list of `RenderRow` objects for rendering rows. Since the new list is constructed with |
| * the cached `RenderRow` objects when possible, the row identity is preserved when the data |
| * and row template matches, which allows the `IterableDiffer` to check rows by reference |
| * and understand which rows are added/moved/removed. |
| * |
| * Implemented as a map of maps where the first key is the `data: T` object and the second is the |
| * `CdkRowDef<T>` object. With the two keys, the cache points to a `RenderRow<T>` object that |
| * contains an array of created pairs. The array is necessary to handle cases where the data |
| * array contains multiple duplicate data objects and each instantiated `RenderRow` must be |
| * stored. |
| */ |
| this._cachedRenderRowsMap = new Map(); |
| /** |
| * CSS class added to any row or cell that has sticky positioning applied. May be overriden by |
| * table subclasses. |
| */ |
| this.stickyCssClass = 'cdk-table-sticky'; |
| /** |
| * Whether to manually add positon: sticky to all sticky cell elements. Not needed if |
| * the position is set in a selector associated with the value of stickyCssClass. May be |
| * overridden by table subclasses |
| */ |
| this.needsPositionStickyOnElement = true; |
| /** Whether the no data row is currently showing anything. */ |
| this._isShowingNoDataRow = false; |
| this._multiTemplateDataRows = false; |
| this._fixedLayout = false; |
| // TODO(andrewseguin): Remove max value as the end index |
| // and instead calculate the view on init and scroll. |
| /** |
| * Stream containing the latest information on what rows are being displayed on screen. |
| * Can be used by the data source to as a heuristic of what data should be provided. |
| * |
| * @docs-private |
| */ |
| this.viewChange = new rxjs.BehaviorSubject({ start: 0, end: Number.MAX_VALUE }); |
| if (!role) { |
| this._elementRef.nativeElement.setAttribute('role', 'grid'); |
| } |
| this._document = _document; |
| this._isNativeHtmlTable = this._elementRef.nativeElement.nodeName === 'TABLE'; |
| } |
| Object.defineProperty(CdkTable.prototype, "trackBy", { |
| /** |
| * Tracking function that will be used to check the differences in data changes. Used similarly |
| * to `ngFor` `trackBy` function. Optimize row operations by identifying a row based on its data |
| * relative to the function to know if a row should be added/removed/moved. |
| * Accepts a function that takes two parameters, `index` and `item`. |
| */ |
| get: function () { |
| return this._trackByFn; |
| }, |
| set: function (fn) { |
| if ((typeof ngDevMode === 'undefined' || ngDevMode) && fn != null && typeof fn !== 'function') { |
| console.warn("trackBy must be a function, but received " + JSON.stringify(fn) + "."); |
| } |
| this._trackByFn = fn; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| Object.defineProperty(CdkTable.prototype, "dataSource", { |
| /** |
| * The table's source of data, which can be provided in three ways (in order of complexity): |
| * - Simple data array (each object represents one table row) |
| * - Stream that emits a data array each time the array changes |
| * - `DataSource` object that implements the connect/disconnect interface. |
| * |
| * If a data array is provided, the table must be notified when the array's objects are |
| * added, removed, or moved. This can be done by calling the `renderRows()` function which will |
| * render the diff since the last table render. If the data array reference is changed, the table |
| * will automatically trigger an update to the rows. |
| * |
| * When providing an Observable stream, the table will trigger an update automatically when the |
| * stream emits a new array of data. |
| * |
| * Finally, when providing a `DataSource` object, the table will use the Observable stream |
| * provided by the connect function and trigger updates when that stream emits new data array |
| * values. During the table's ngOnDestroy or when the data source is removed from the table, the |
| * table will call the DataSource's `disconnect` function (may be useful for cleaning up any |
| * subscriptions registered during the connect process). |
| */ |
| get: function () { |
| return this._dataSource; |
| }, |
| set: function (dataSource) { |
| if (this._dataSource !== dataSource) { |
| this._switchDataSource(dataSource); |
| } |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| Object.defineProperty(CdkTable.prototype, "multiTemplateDataRows", { |
| /** |
| * Whether to allow multiple rows per data object by evaluating which rows evaluate their 'when' |
| * predicate to true. If `multiTemplateDataRows` is false, which is the default value, then each |
| * dataobject will render the first row that evaluates its when predicate to true, in the order |
| * defined in the table, or otherwise the default row which does not have a when predicate. |
| */ |
| get: function () { |
| return this._multiTemplateDataRows; |
| }, |
| set: function (v) { |
| this._multiTemplateDataRows = coercion.coerceBooleanProperty(v); |
| // In Ivy if this value is set via a static attribute (e.g. <table multiTemplateDataRows>), |
| // this setter will be invoked before the row outlet has been defined hence the null check. |
| if (this._rowOutlet && this._rowOutlet.viewContainer.length) { |
| this._forceRenderDataRows(); |
| this.updateStickyColumnStyles(); |
| } |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| Object.defineProperty(CdkTable.prototype, "fixedLayout", { |
| /** |
| * Whether to use a fixed table layout. Enabling this option will enforce consistent column widths |
| * and optimize rendering sticky styles for native tables. No-op for flex tables. |
| */ |
| get: function () { |
| return this._fixedLayout; |
| }, |
| set: function (v) { |
| this._fixedLayout = coercion.coerceBooleanProperty(v); |
| // Toggling `fixedLayout` may change column widths. Sticky column styles should be recalculated. |
| this._forceRecalculateCellWidths = true; |
| this._stickyColumnStylesNeedReset = true; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| CdkTable.prototype.ngOnInit = function () { |
| var _this = this; |
| this._setupStickyStyler(); |
| if (this._isNativeHtmlTable) { |
| this._applyNativeTableSections(); |
| } |
| // Set up the trackBy function so that it uses the `RenderRow` as its identity by default. If |
| // the user has provided a custom trackBy, return the result of that function as evaluated |
| // with the values of the `RenderRow`'s data and index. |
| this._dataDiffer = this._differs.find([]).create(function (_i, dataRow) { |
| return _this.trackBy ? _this.trackBy(dataRow.dataIndex, dataRow.data) : dataRow; |
| }); |
| // Table cell dimensions may change after resizing the window. Signal the sticky styler to |
| // refresh its cache of cell widths the next time sticky styles are updated. |
| // @breaking-change 11.0.0 Remove null check for _viewportRuler once it's a required parameter. |
| if (this._viewportRuler) { |
| this._viewportRuler.change().pipe(operators.takeUntil(this._onDestroy)).subscribe(function () { |
| _this._forceRecalculateCellWidths = true; |
| }); |
| } |
| }; |
| CdkTable.prototype.ngAfterContentChecked = function () { |
| // Cache the row and column definitions gathered by ContentChildren and programmatic injection. |
| this._cacheRowDefs(); |
| this._cacheColumnDefs(); |
| // Make sure that the user has at least added header, footer, or data row def. |
| if (!this._headerRowDefs.length && !this._footerRowDefs.length && !this._rowDefs.length && |
| (typeof ngDevMode === 'undefined' || ngDevMode)) { |
| throw getTableMissingRowDefsError(); |
| } |
| // Render updates if the list of columns have been changed for the header, row, or footer defs. |
| var columnsChanged = this._renderUpdatedColumns(); |
| var rowDefsChanged = columnsChanged || this._headerRowDefChanged || this._footerRowDefChanged; |
| // Ensure sticky column styles are reset if set to `true` elsewhere. |
| this._stickyColumnStylesNeedReset = this._stickyColumnStylesNeedReset || rowDefsChanged; |
| this._forceRecalculateCellWidths = rowDefsChanged; |
| // If the header row definition has been changed, trigger a render to the header row. |
| if (this._headerRowDefChanged) { |
| this._forceRenderHeaderRows(); |
| this._headerRowDefChanged = false; |
| } |
| // If the footer row definition has been changed, trigger a render to the footer row. |
| if (this._footerRowDefChanged) { |
| this._forceRenderFooterRows(); |
| this._footerRowDefChanged = false; |
| } |
| // If there is a data source and row definitions, connect to the data source unless a |
| // connection has already been made. |
| if (this.dataSource && this._rowDefs.length > 0 && !this._renderChangeSubscription) { |
| this._observeRenderChanges(); |
| } |
| else if (this._stickyColumnStylesNeedReset) { |
| // In the above case, _observeRenderChanges will result in updateStickyColumnStyles being |
| // called when it row data arrives. Otherwise, we need to call it proactively. |
| this.updateStickyColumnStyles(); |
| } |
| this._checkStickyStates(); |
| }; |
| CdkTable.prototype.ngOnDestroy = function () { |
| this._rowOutlet.viewContainer.clear(); |
| this._noDataRowOutlet.viewContainer.clear(); |
| this._headerRowOutlet.viewContainer.clear(); |
| this._footerRowOutlet.viewContainer.clear(); |
| this._cachedRenderRowsMap.clear(); |
| this._onDestroy.next(); |
| this._onDestroy.complete(); |
| if (collections.isDataSource(this.dataSource)) { |
| this.dataSource.disconnect(this); |
| } |
| }; |
| /** |
| * Renders rows based on the table's latest set of data, which was either provided directly as an |
| * input or retrieved through an Observable stream (directly or from a DataSource). |
| * Checks for differences in the data since the last diff to perform only the necessary |
| * changes (add/remove/move rows). |
| * |
| * If the table's data source is a DataSource or Observable, this will be invoked automatically |
| * each time the provided Observable stream emits a new data array. Otherwise if your data is |
| * an array, this function will need to be called to render any changes. |
| */ |
| CdkTable.prototype.renderRows = function () { |
| var _this = this; |
| this._renderRows = this._getAllRenderRows(); |
| var changes = this._dataDiffer.diff(this._renderRows); |
| if (!changes) { |
| this._updateNoDataRow(); |
| return; |
| } |
| var viewContainer = this._rowOutlet.viewContainer; |
| // @breaking-change 11.0.0 Remove null check for `_viewRepeater` and the |
| // `else` clause once `_viewRepeater` is turned into a required parameter. |
| if (this._viewRepeater) { |
| this._viewRepeater.applyChanges(changes, viewContainer, function (record, _adjustedPreviousIndex, currentIndex) { return _this._getEmbeddedViewArgs(record.item, currentIndex); }, function (record) { return record.item.data; }, function (change) { |
| if (change.operation === 1 /* INSERTED */ && change.context) { |
| _this._renderCellTemplateForItem(change.record.item.rowDef, change.context); |
| } |
| }); |
| } |
| else { |
| changes.forEachOperation(function (record, prevIndex, currentIndex) { |
| if (record.previousIndex == null) { |
| var renderRow = record.item; |
| var rowDef = renderRow.rowDef; |
| var context = { $implicit: renderRow.data }; |
| _this._renderRow(_this._rowOutlet, rowDef, currentIndex, context); |
| } |
| else if (currentIndex == null) { |
| viewContainer.remove(prevIndex); |
| } |
| else { |
| var view = viewContainer.get(prevIndex); |
| viewContainer.move(view, currentIndex); |
| } |
| }); |
| } |
| // Update the meta context of a row's context data (index, count, first, last, ...) |
| this._updateRowIndexContext(); |
| // Update rows that did not get added/removed/moved but may have had their identity changed, |
| // e.g. if trackBy matched data on some property but the actual data reference changed. |
| changes.forEachIdentityChange(function (record) { |
| var rowView = viewContainer.get(record.currentIndex); |
| rowView.context.$implicit = record.item.data; |
| }); |
| this._updateNoDataRow(); |
| this.updateStickyColumnStyles(); |
| }; |
| /** Adds a column definition that was not included as part of the content children. */ |
| CdkTable.prototype.addColumnDef = function (columnDef) { |
| this._customColumnDefs.add(columnDef); |
| }; |
| /** Removes a column definition that was not included as part of the content children. */ |
| CdkTable.prototype.removeColumnDef = function (columnDef) { |
| this._customColumnDefs.delete(columnDef); |
| }; |
| /** Adds a row definition that was not included as part of the content children. */ |
| CdkTable.prototype.addRowDef = function (rowDef) { |
| this._customRowDefs.add(rowDef); |
| }; |
| /** Removes a row definition that was not included as part of the content children. */ |
| CdkTable.prototype.removeRowDef = function (rowDef) { |
| this._customRowDefs.delete(rowDef); |
| }; |
| /** Adds a header row definition that was not included as part of the content children. */ |
| CdkTable.prototype.addHeaderRowDef = function (headerRowDef) { |
| this._customHeaderRowDefs.add(headerRowDef); |
| this._headerRowDefChanged = true; |
| }; |
| /** Removes a header row definition that was not included as part of the content children. */ |
| CdkTable.prototype.removeHeaderRowDef = function (headerRowDef) { |
| this._customHeaderRowDefs.delete(headerRowDef); |
| this._headerRowDefChanged = true; |
| }; |
| /** Adds a footer row definition that was not included as part of the content children. */ |
| CdkTable.prototype.addFooterRowDef = function (footerRowDef) { |
| this._customFooterRowDefs.add(footerRowDef); |
| this._footerRowDefChanged = true; |
| }; |
| /** Removes a footer row definition that was not included as part of the content children. */ |
| CdkTable.prototype.removeFooterRowDef = function (footerRowDef) { |
| this._customFooterRowDefs.delete(footerRowDef); |
| this._footerRowDefChanged = true; |
| }; |
| /** Sets a no data row definition that was not included as a part of the content children. */ |
| CdkTable.prototype.setNoDataRow = function (noDataRow) { |
| this._customNoDataRow = noDataRow; |
| }; |
| /** |
| * Updates the header sticky styles. First resets all applied styles with respect to the cells |
| * sticking to the top. Then, evaluating which cells need to be stuck to the top. This is |
| * automatically called when the header row changes its displayed set of columns, or if its |
| * sticky input changes. May be called manually for cases where the cell content changes outside |
| * of these events. |
| */ |
| CdkTable.prototype.updateStickyHeaderRowStyles = function () { |
| var headerRows = this._getRenderedRows(this._headerRowOutlet); |
| var tableElement = this._elementRef.nativeElement; |
| // Hide the thead element if there are no header rows. This is necessary to satisfy |
| // overzealous a11y checkers that fail because the `rowgroup` element does not contain |
| // required child `row`. |
| var thead = tableElement.querySelector('thead'); |
| if (thead) { |
| thead.style.display = headerRows.length ? '' : 'none'; |
| } |
| var stickyStates = this._headerRowDefs.map(function (def) { return def.sticky; }); |
| this._stickyStyler.clearStickyPositioning(headerRows, ['top']); |
| this._stickyStyler.stickRows(headerRows, stickyStates, 'top'); |
| // Reset the dirty state of the sticky input change since it has been used. |
| this._headerRowDefs.forEach(function (def) { return def.resetStickyChanged(); }); |
| }; |
| /** |
| * Updates the footer sticky styles. First resets all applied styles with respect to the cells |
| * sticking to the bottom. Then, evaluating which cells need to be stuck to the bottom. This is |
| * automatically called when the footer row changes its displayed set of columns, or if its |
| * sticky input changes. May be called manually for cases where the cell content changes outside |
| * of these events. |
| */ |
| CdkTable.prototype.updateStickyFooterRowStyles = function () { |
| var footerRows = this._getRenderedRows(this._footerRowOutlet); |
| var tableElement = this._elementRef.nativeElement; |
| // Hide the tfoot element if there are no footer rows. This is necessary to satisfy |
| // overzealous a11y checkers that fail because the `rowgroup` element does not contain |
| // required child `row`. |
| var tfoot = tableElement.querySelector('tfoot'); |
| if (tfoot) { |
| tfoot.style.display = footerRows.length ? '' : 'none'; |
| } |
| var stickyStates = this._footerRowDefs.map(function (def) { return def.sticky; }); |
| this._stickyStyler.clearStickyPositioning(footerRows, ['bottom']); |
| this._stickyStyler.stickRows(footerRows, stickyStates, 'bottom'); |
| this._stickyStyler.updateStickyFooterContainer(this._elementRef.nativeElement, stickyStates); |
| // Reset the dirty state of the sticky input change since it has been used. |
| this._footerRowDefs.forEach(function (def) { return def.resetStickyChanged(); }); |
| }; |
| /** |
| * Updates the column sticky styles. First resets all applied styles with respect to the cells |
| * sticking to the left and right. Then sticky styles are added for the left and right according |
| * to the column definitions for each cell in each row. This is automatically called when |
| * the data source provides a new set of data or when a column definition changes its sticky |
| * input. May be called manually for cases where the cell content changes outside of these events. |
| */ |
| CdkTable.prototype.updateStickyColumnStyles = function () { |
| var _this = this; |
| var headerRows = this._getRenderedRows(this._headerRowOutlet); |
| var dataRows = this._getRenderedRows(this._rowOutlet); |
| var footerRows = this._getRenderedRows(this._footerRowOutlet); |
| // For tables not using a fixed layout, the column widths may change when new rows are rendered. |
| // In a table using a fixed layout, row content won't affect column width, so sticky styles |
| // don't need to be cleared unless either the sticky column config changes or one of the row |
| // defs change. |
| if ((this._isNativeHtmlTable && !this._fixedLayout) |
| || this._stickyColumnStylesNeedReset) { |
| // Clear the left and right positioning from all columns in the table across all rows since |
| // sticky columns span across all table sections (header, data, footer) |
| this._stickyStyler.clearStickyPositioning(__spread(headerRows, dataRows, footerRows), ['left', 'right']); |
| this._stickyColumnStylesNeedReset = false; |
| } |
| // Update the sticky styles for each header row depending on the def's sticky state |
| headerRows.forEach(function (headerRow, i) { |
| _this._addStickyColumnStyles([headerRow], _this._headerRowDefs[i]); |
| }); |
| // Update the sticky styles for each data row depending on its def's sticky state |
| this._rowDefs.forEach(function (rowDef) { |
| // Collect all the rows rendered with this row definition. |
| var rows = []; |
| for (var i = 0; i < dataRows.length; i++) { |
| if (_this._renderRows[i].rowDef === rowDef) { |
| rows.push(dataRows[i]); |
| } |
| } |
| _this._addStickyColumnStyles(rows, rowDef); |
| }); |
| // Update the sticky styles for each footer row depending on the def's sticky state |
| footerRows.forEach(function (footerRow, i) { |
| _this._addStickyColumnStyles([footerRow], _this._footerRowDefs[i]); |
| }); |
| // Reset the dirty state of the sticky input change since it has been used. |
| Array.from(this._columnDefsByName.values()).forEach(function (def) { return def.resetStickyChanged(); }); |
| }; |
| /** |
| * Get the list of RenderRow objects to render according to the current list of data and defined |
| * row definitions. If the previous list already contained a particular pair, it should be reused |
| * so that the differ equates their references. |
| */ |
| CdkTable.prototype._getAllRenderRows = function () { |
| var renderRows = []; |
| // Store the cache and create a new one. Any re-used RenderRow objects will be moved into the |
| // new cache while unused ones can be picked up by garbage collection. |
| var prevCachedRenderRows = this._cachedRenderRowsMap; |
| this._cachedRenderRowsMap = new Map(); |
| // For each data object, get the list of rows that should be rendered, represented by the |
| // respective `RenderRow` object which is the pair of `data` and `CdkRowDef`. |
| for (var i = 0; i < this._data.length; i++) { |
| var data = this._data[i]; |
| var renderRowsForData = this._getRenderRowsForData(data, i, prevCachedRenderRows.get(data)); |
| if (!this._cachedRenderRowsMap.has(data)) { |
| this._cachedRenderRowsMap.set(data, new WeakMap()); |
| } |
| for (var j = 0; j < renderRowsForData.length; j++) { |
| var renderRow = renderRowsForData[j]; |
| var cache = this._cachedRenderRowsMap.get(renderRow.data); |
| if (cache.has(renderRow.rowDef)) { |
| cache.get(renderRow.rowDef).push(renderRow); |
| } |
| else { |
| cache.set(renderRow.rowDef, [renderRow]); |
| } |
| renderRows.push(renderRow); |
| } |
| } |
| return renderRows; |
| }; |
| /** |
| * Gets a list of `RenderRow<T>` for the provided data object and any `CdkRowDef` objects that |
| * should be rendered for this data. Reuses the cached RenderRow objects if they match the same |
| * `(T, CdkRowDef)` pair. |
| */ |
| CdkTable.prototype._getRenderRowsForData = function (data, dataIndex, cache) { |
| var rowDefs = this._getRowDefs(data, dataIndex); |
| return rowDefs.map(function (rowDef) { |
| var cachedRenderRows = (cache && cache.has(rowDef)) ? cache.get(rowDef) : []; |
| if (cachedRenderRows.length) { |
| var dataRow = cachedRenderRows.shift(); |
| dataRow.dataIndex = dataIndex; |
| return dataRow; |
| } |
| else { |
| return { data: data, rowDef: rowDef, dataIndex: dataIndex }; |
| } |
| }); |
| }; |
| /** Update the map containing the content's column definitions. */ |
| CdkTable.prototype._cacheColumnDefs = function () { |
| var _this = this; |
| this._columnDefsByName.clear(); |
| var columnDefs = mergeArrayAndSet(this._getOwnDefs(this._contentColumnDefs), this._customColumnDefs); |
| columnDefs.forEach(function (columnDef) { |
| if (_this._columnDefsByName.has(columnDef.name) && |
| (typeof ngDevMode === 'undefined' || ngDevMode)) { |
| throw getTableDuplicateColumnNameError(columnDef.name); |
| } |
| _this._columnDefsByName.set(columnDef.name, columnDef); |
| }); |
| }; |
| /** Update the list of all available row definitions that can be used. */ |
| CdkTable.prototype._cacheRowDefs = function () { |
| this._headerRowDefs = mergeArrayAndSet(this._getOwnDefs(this._contentHeaderRowDefs), this._customHeaderRowDefs); |
| this._footerRowDefs = mergeArrayAndSet(this._getOwnDefs(this._contentFooterRowDefs), this._customFooterRowDefs); |
| this._rowDefs = mergeArrayAndSet(this._getOwnDefs(this._contentRowDefs), this._customRowDefs); |
| // After all row definitions are determined, find the row definition to be considered default. |
| var defaultRowDefs = this._rowDefs.filter(function (def) { return !def.when; }); |
| if (!this.multiTemplateDataRows && defaultRowDefs.length > 1 && |
| (typeof ngDevMode === 'undefined' || ngDevMode)) { |
| throw getTableMultipleDefaultRowDefsError(); |
| } |
| this._defaultRowDef = defaultRowDefs[0]; |
| }; |
| /** |
| * Check if the header, data, or footer rows have changed what columns they want to display or |
| * whether the sticky states have changed for the header or footer. If there is a diff, then |
| * re-render that section. |
| */ |
| CdkTable.prototype._renderUpdatedColumns = function () { |
| var columnsDiffReducer = function (acc, def) { return acc || !!def.getColumnsDiff(); }; |
| // Force re-render data rows if the list of column definitions have changed. |
| var dataColumnsChanged = this._rowDefs.reduce(columnsDiffReducer, false); |
| if (dataColumnsChanged) { |
| this._forceRenderDataRows(); |
| } |
| // Force re-render header/footer rows if the list of column definitions have changed. |
| var headerColumnsChanged = this._headerRowDefs.reduce(columnsDiffReducer, false); |
| if (headerColumnsChanged) { |
| this._forceRenderHeaderRows(); |
| } |
| var footerColumnsChanged = this._footerRowDefs.reduce(columnsDiffReducer, false); |
| if (footerColumnsChanged) { |
| this._forceRenderFooterRows(); |
| } |
| return dataColumnsChanged || headerColumnsChanged || footerColumnsChanged; |
| }; |
| /** |
| * Switch to the provided data source by resetting the data and unsubscribing from the current |
| * render change subscription if one exists. If the data source is null, interpret this by |
| * clearing the row outlet. Otherwise start listening for new data. |
| */ |
| CdkTable.prototype._switchDataSource = function (dataSource) { |
| this._data = []; |
| if (collections.isDataSource(this.dataSource)) { |
| this.dataSource.disconnect(this); |
| } |
| // Stop listening for data from the previous data source. |
| if (this._renderChangeSubscription) { |
| this._renderChangeSubscription.unsubscribe(); |
| this._renderChangeSubscription = null; |
| } |
| if (!dataSource) { |
| if (this._dataDiffer) { |
| this._dataDiffer.diff([]); |
| } |
| this._rowOutlet.viewContainer.clear(); |
| } |
| this._dataSource = dataSource; |
| }; |
| /** Set up a subscription for the data provided by the data source. */ |
| CdkTable.prototype._observeRenderChanges = function () { |
| var _this = this; |
| // If no data source has been set, there is nothing to observe for changes. |
| if (!this.dataSource) { |
| return; |
| } |
| var dataStream; |
| if (collections.isDataSource(this.dataSource)) { |
| dataStream = this.dataSource.connect(this); |
| } |
| else if (rxjs.isObservable(this.dataSource)) { |
| dataStream = this.dataSource; |
| } |
| else if (Array.isArray(this.dataSource)) { |
| dataStream = rxjs.of(this.dataSource); |
| } |
| if (dataStream === undefined && (typeof ngDevMode === 'undefined' || ngDevMode)) { |
| throw getTableUnknownDataSourceError(); |
| } |
| this._renderChangeSubscription = dataStream.pipe(operators.takeUntil(this._onDestroy)) |
| .subscribe(function (data) { |
| _this._data = data || []; |
| _this.renderRows(); |
| }); |
| }; |
| /** |
| * Clears any existing content in the header row outlet and creates a new embedded view |
| * in the outlet using the header row definition. |
| */ |
| CdkTable.prototype._forceRenderHeaderRows = function () { |
| var _this = this; |
| // Clear the header row outlet if any content exists. |
| if (this._headerRowOutlet.viewContainer.length > 0) { |
| this._headerRowOutlet.viewContainer.clear(); |
| } |
| this._headerRowDefs.forEach(function (def, i) { return _this._renderRow(_this._headerRowOutlet, def, i); }); |
| this.updateStickyHeaderRowStyles(); |
| }; |
| /** |
| * Clears any existing content in the footer row outlet and creates a new embedded view |
| * in the outlet using the footer row definition. |
| */ |
| CdkTable.prototype._forceRenderFooterRows = function () { |
| var _this = this; |
| // Clear the footer row outlet if any content exists. |
| if (this._footerRowOutlet.viewContainer.length > 0) { |
| this._footerRowOutlet.viewContainer.clear(); |
| } |
| this._footerRowDefs.forEach(function (def, i) { return _this._renderRow(_this._footerRowOutlet, def, i); }); |
| this.updateStickyFooterRowStyles(); |
| }; |
| /** Adds the sticky column styles for the rows according to the columns' stick states. */ |
| CdkTable.prototype._addStickyColumnStyles = function (rows, rowDef) { |
| var _this = this; |
| var columnDefs = Array.from(rowDef.columns || []).map(function (columnName) { |
| var columnDef = _this._columnDefsByName.get(columnName); |
| if (!columnDef && (typeof ngDevMode === 'undefined' || ngDevMode)) { |
| throw getTableUnknownColumnError(columnName); |
| } |
| return columnDef; |
| }); |
| var stickyStartStates = columnDefs.map(function (columnDef) { return columnDef.sticky; }); |
| var stickyEndStates = columnDefs.map(function (columnDef) { return columnDef.stickyEnd; }); |
| this._stickyStyler.updateStickyColumns(rows, stickyStartStates, stickyEndStates, !this._fixedLayout || this._forceRecalculateCellWidths); |
| }; |
| /** Gets the list of rows that have been rendered in the row outlet. */ |
| CdkTable.prototype._getRenderedRows = function (rowOutlet) { |
| var renderedRows = []; |
| for (var i = 0; i < rowOutlet.viewContainer.length; i++) { |
| var viewRef = rowOutlet.viewContainer.get(i); |
| renderedRows.push(viewRef.rootNodes[0]); |
| } |
| return renderedRows; |
| }; |
| /** |
| * Get the matching row definitions that should be used for this row data. If there is only |
| * one row definition, it is returned. Otherwise, find the row definitions that has a when |
| * predicate that returns true with the data. If none return true, return the default row |
| * definition. |
| */ |
| CdkTable.prototype._getRowDefs = function (data, dataIndex) { |
| if (this._rowDefs.length == 1) { |
| return [this._rowDefs[0]]; |
| } |
| var rowDefs = []; |
| if (this.multiTemplateDataRows) { |
| rowDefs = this._rowDefs.filter(function (def) { return !def.when || def.when(dataIndex, data); }); |
| } |
| else { |
| var rowDef = this._rowDefs.find(function (def) { return def.when && def.when(dataIndex, data); }) || this._defaultRowDef; |
| if (rowDef) { |
| rowDefs.push(rowDef); |
| } |
| } |
| if (!rowDefs.length && (typeof ngDevMode === 'undefined' || ngDevMode)) { |
| throw getTableMissingMatchingRowDefError(data); |
| } |
| return rowDefs; |
| }; |
| CdkTable.prototype._getEmbeddedViewArgs = function (renderRow, index) { |
| var rowDef = renderRow.rowDef; |
| var context = { $implicit: renderRow.data }; |
| return { |
| templateRef: rowDef.template, |
| context: context, |
| index: index, |
| }; |
| }; |
| /** |
| * Creates a new row template in the outlet and fills it with the set of cell templates. |
| * Optionally takes a context to provide to the row and cells, as well as an optional index |
| * of where to place the new row template in the outlet. |
| */ |
| CdkTable.prototype._renderRow = function (outlet, rowDef, index, context) { |
| if (context === void 0) { context = {}; } |
| // TODO(andrewseguin): enforce that one outlet was instantiated from createEmbeddedView |
| var view = outlet.viewContainer.createEmbeddedView(rowDef.template, context, index); |
| this._renderCellTemplateForItem(rowDef, context); |
| return view; |
| }; |
| CdkTable.prototype._renderCellTemplateForItem = function (rowDef, context) { |
| var e_1, _a; |
| try { |
| for (var _b = __values(this._getCellTemplates(rowDef)), _c = _b.next(); !_c.done; _c = _b.next()) { |
| var cellTemplate = _c.value; |
| if (CdkCellOutlet.mostRecentCellOutlet) { |
| CdkCellOutlet.mostRecentCellOutlet._viewContainer.createEmbeddedView(cellTemplate, context); |
| } |
| } |
| } |
| catch (e_1_1) { e_1 = { error: e_1_1 }; } |
| finally { |
| try { |
| if (_c && !_c.done && (_a = _b.return)) _a.call(_b); |
| } |
| finally { if (e_1) throw e_1.error; } |
| } |
| this._changeDetectorRef.markForCheck(); |
| }; |
| /** |
| * Updates the index-related context for each row to reflect any changes in the index of the rows, |
| * e.g. first/last/even/odd. |
| */ |
| CdkTable.prototype._updateRowIndexContext = function () { |
| var viewContainer = this._rowOutlet.viewContainer; |
| for (var renderIndex = 0, count = viewContainer.length; renderIndex < count; renderIndex++) { |
| var viewRef = viewContainer.get(renderIndex); |
| var context = viewRef.context; |
| context.count = count; |
| context.first = renderIndex === 0; |
| context.last = renderIndex === count - 1; |
| context.even = renderIndex % 2 === 0; |
| context.odd = !context.even; |
| if (this.multiTemplateDataRows) { |
| context.dataIndex = this._renderRows[renderIndex].dataIndex; |
| context.renderIndex = renderIndex; |
| } |
| else { |
| context.index = this._renderRows[renderIndex].dataIndex; |
| } |
| } |
| }; |
| /** Gets the column definitions for the provided row def. */ |
| CdkTable.prototype._getCellTemplates = function (rowDef) { |
| var _this = this; |
| if (!rowDef || !rowDef.columns) { |
| return []; |
| } |
| return Array.from(rowDef.columns, function (columnId) { |
| var column = _this._columnDefsByName.get(columnId); |
| if (!column && (typeof ngDevMode === 'undefined' || ngDevMode)) { |
| throw getTableUnknownColumnError(columnId); |
| } |
| return rowDef.extractCellTemplate(column); |
| }); |
| }; |
| /** Adds native table sections (e.g. tbody) and moves the row outlets into them. */ |
| CdkTable.prototype._applyNativeTableSections = function () { |
| var e_2, _a, e_3, _b; |
| var documentFragment = this._document.createDocumentFragment(); |
| var sections = [ |
| { tag: 'thead', outlets: [this._headerRowOutlet] }, |
| { tag: 'tbody', outlets: [this._rowOutlet, this._noDataRowOutlet] }, |
| { tag: 'tfoot', outlets: [this._footerRowOutlet] }, |
| ]; |
| try { |
| for (var sections_1 = __values(sections), sections_1_1 = sections_1.next(); !sections_1_1.done; sections_1_1 = sections_1.next()) { |
| var section = sections_1_1.value; |
| var element = this._document.createElement(section.tag); |
| element.setAttribute('role', 'rowgroup'); |
| try { |
| for (var _c = (e_3 = void 0, __values(section.outlets)), _d = _c.next(); !_d.done; _d = _c.next()) { |
| var outlet = _d.value; |
| element.appendChild(outlet.elementRef.nativeElement); |
| } |
| } |
| catch (e_3_1) { e_3 = { error: e_3_1 }; } |
| finally { |
| try { |
| if (_d && !_d.done && (_b = _c.return)) _b.call(_c); |
| } |
| finally { if (e_3) throw e_3.error; } |
| } |
| documentFragment.appendChild(element); |
| } |
| } |
| catch (e_2_1) { e_2 = { error: e_2_1 }; } |
| finally { |
| try { |
| if (sections_1_1 && !sections_1_1.done && (_a = sections_1.return)) _a.call(sections_1); |
| } |
| finally { if (e_2) throw e_2.error; } |
| } |
| // Use a DocumentFragment so we don't hit the DOM on each iteration. |
| this._elementRef.nativeElement.appendChild(documentFragment); |
| }; |
| /** |
| * Forces a re-render of the data rows. Should be called in cases where there has been an input |
| * change that affects the evaluation of which rows should be rendered, e.g. toggling |
| * `multiTemplateDataRows` or adding/removing row definitions. |
| */ |
| CdkTable.prototype._forceRenderDataRows = function () { |
| this._dataDiffer.diff([]); |
| this._rowOutlet.viewContainer.clear(); |
| this.renderRows(); |
| }; |
| /** |
| * Checks if there has been a change in sticky states since last check and applies the correct |
| * sticky styles. Since checking resets the "dirty" state, this should only be performed once |
| * during a change detection and after the inputs are settled (after content check). |
| */ |
| CdkTable.prototype._checkStickyStates = function () { |
| var stickyCheckReducer = function (acc, d) { |
| return acc || d.hasStickyChanged(); |
| }; |
| // Note that the check needs to occur for every definition since it notifies the definition |
| // that it can reset its dirty state. Using another operator like `some` may short-circuit |
| // remaining definitions and leave them in an unchecked state. |
| if (this._headerRowDefs.reduce(stickyCheckReducer, false)) { |
| this.updateStickyHeaderRowStyles(); |
| } |
| if (this._footerRowDefs.reduce(stickyCheckReducer, false)) { |
| this.updateStickyFooterRowStyles(); |
| } |
| if (Array.from(this._columnDefsByName.values()).reduce(stickyCheckReducer, false)) { |
| this._stickyColumnStylesNeedReset = true; |
| this.updateStickyColumnStyles(); |
| } |
| }; |
| /** |
| * Creates the sticky styler that will be used for sticky rows and columns. Listens |
| * for directionality changes and provides the latest direction to the styler. Re-applies column |
| * stickiness when directionality changes. |
| */ |
| CdkTable.prototype._setupStickyStyler = function () { |
| var _this = this; |
| var direction = this._dir ? this._dir.value : 'ltr'; |
| this._stickyStyler = new StickyStyler(this._isNativeHtmlTable, this.stickyCssClass, direction, this._coalescedStyleScheduler, this._platform.isBrowser, this.needsPositionStickyOnElement, this._stickyPositioningListener); |
| (this._dir ? this._dir.change : rxjs.of()) |
| .pipe(operators.takeUntil(this._onDestroy)) |
| .subscribe(function (value) { |
| _this._stickyStyler.direction = value; |
| _this.updateStickyColumnStyles(); |
| }); |
| }; |
| /** Filters definitions that belong to this table from a QueryList. */ |
| CdkTable.prototype._getOwnDefs = function (items) { |
| var _this = this; |
| return items.filter(function (item) { return !item._table || item._table === _this; }); |
| }; |
| /** Creates or removes the no data row, depending on whether any data is being shown. */ |
| CdkTable.prototype._updateNoDataRow = function () { |
| var noDataRow = this._customNoDataRow || this._noDataRow; |
| if (noDataRow) { |
| var shouldShow = this._rowOutlet.viewContainer.length === 0; |
| if (shouldShow !== this._isShowingNoDataRow) { |
| var container = this._noDataRowOutlet.viewContainer; |
| shouldShow ? container.createEmbeddedView(noDataRow.templateRef) : container.clear(); |
| this._isShowingNoDataRow = shouldShow; |
| } |
| } |
| }; |
| return CdkTable; |
| }()); |
| CdkTable.decorators = [ |
| { type: core.Component, args: [{ |
| selector: 'cdk-table, table[cdk-table]', |
| exportAs: 'cdkTable', |
| template: CDK_TABLE_TEMPLATE, |
| host: { |
| 'class': 'cdk-table', |
| '[class.cdk-table-fixed-layout]': 'fixedLayout', |
| }, |
| encapsulation: core.ViewEncapsulation.None, |
| // The "OnPush" status for the `MatTable` component is effectively a noop, so we are removing it. |
| // The view for `MatTable` consists entirely of templates declared in other views. As they are |
| // declared elsewhere, they are checked when their declaration points are checked. |
| // tslint:disable-next-line:validate-decorators |
| changeDetection: core.ChangeDetectionStrategy.Default, |
| providers: [ |
| { provide: CDK_TABLE, useExisting: CdkTable }, |
| { provide: collections._VIEW_REPEATER_STRATEGY, useClass: collections._DisposeViewRepeaterStrategy }, |
| { provide: _COALESCED_STYLE_SCHEDULER, useClass: _CoalescedStyleScheduler }, |
| // Prevent nested tables from seeing this table's StickyPositioningListener. |
| { provide: STICKY_POSITIONING_LISTENER, useValue: null }, |
| ], |
| styles: [".cdk-table-fixed-layout{table-layout:fixed}\n"] |
| },] } |
| ]; |
| CdkTable.ctorParameters = function () { return [ |
| { type: core.IterableDiffers }, |
| { type: core.ChangeDetectorRef }, |
| { type: core.ElementRef }, |
| { type: String, decorators: [{ type: core.Attribute, args: ['role',] }] }, |
| { type: bidi.Directionality, decorators: [{ type: core.Optional }] }, |
| { type: undefined, decorators: [{ type: core.Inject, args: [common.DOCUMENT,] }] }, |
| { type: platform.Platform }, |
| { type: undefined, decorators: [{ type: core.Optional }, { type: core.Inject, args: [collections._VIEW_REPEATER_STRATEGY,] }] }, |
| { type: _CoalescedStyleScheduler, decorators: [{ type: core.Optional }, { type: core.Inject, args: [_COALESCED_STYLE_SCHEDULER,] }] }, |
| { type: undefined, decorators: [{ type: core.Optional }, { type: core.SkipSelf }, { type: core.Inject, args: [STICKY_POSITIONING_LISTENER,] }] }, |
| { type: scrolling.ViewportRuler, decorators: [{ type: core.Optional }] } |
| ]; }; |
| CdkTable.propDecorators = { |
| trackBy: [{ type: core.Input }], |
| dataSource: [{ type: core.Input }], |
| multiTemplateDataRows: [{ type: core.Input }], |
| fixedLayout: [{ type: core.Input }], |
| _rowOutlet: [{ type: core.ViewChild, args: [DataRowOutlet, { static: true },] }], |
| _headerRowOutlet: [{ type: core.ViewChild, args: [HeaderRowOutlet, { static: true },] }], |
| _footerRowOutlet: [{ type: core.ViewChild, args: [FooterRowOutlet, { static: true },] }], |
| _noDataRowOutlet: [{ type: core.ViewChild, args: [NoDataRowOutlet, { static: true },] }], |
| _contentColumnDefs: [{ type: core.ContentChildren, args: [CdkColumnDef, { descendants: true },] }], |
| _contentRowDefs: [{ type: core.ContentChildren, args: [CdkRowDef, { descendants: true },] }], |
| _contentHeaderRowDefs: [{ type: core.ContentChildren, args: [CdkHeaderRowDef, { |
| descendants: true |
| },] }], |
| _contentFooterRowDefs: [{ type: core.ContentChildren, args: [CdkFooterRowDef, { |
| descendants: true |
| },] }], |
| _noDataRow: [{ type: core.ContentChild, args: [CdkNoDataRow,] }] |
| }; |
| /** Utility function that gets a merged list of the entries in an array and values of a Set. */ |
| function mergeArrayAndSet(array, set) { |
| return array.concat(Array.from(set)); |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * Column that simply shows text content for the header and row cells. Assumes that the table |
| * is using the native table implementation (`<table>`). |
| * |
| * By default, the name of this column will be the header text and data property accessor. |
| * The header text can be overridden with the `headerText` input. Cell values can be overridden with |
| * the `dataAccessor` input. Change the text justification to the start or end using the `justify` |
| * input. |
| */ |
| var CdkTextColumn = /** @class */ (function () { |
| function CdkTextColumn( |
| // `CdkTextColumn` is always requiring a table, but we just assert it manually |
| // for better error reporting. |
| // tslint:disable-next-line: lightweight-tokens |
| _table, _options) { |
| this._table = _table; |
| this._options = _options; |
| /** Alignment of the cell values. */ |
| this.justify = 'start'; |
| this._options = _options || {}; |
| } |
| Object.defineProperty(CdkTextColumn.prototype, "name", { |
| /** Column name that should be used to reference this column. */ |
| get: function () { |
| return this._name; |
| }, |
| set: function (name) { |
| this._name = name; |
| // With Ivy, inputs can be initialized before static query results are |
| // available. In that case, we defer the synchronization until "ngOnInit" fires. |
| this._syncColumnDefName(); |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| CdkTextColumn.prototype.ngOnInit = function () { |
| this._syncColumnDefName(); |
| if (this.headerText === undefined) { |
| this.headerText = this._createDefaultHeaderText(); |
| } |
| if (!this.dataAccessor) { |
| this.dataAccessor = |
| this._options.defaultDataAccessor || (function (data, name) { return data[name]; }); |
| } |
| if (this._table) { |
| // Provide the cell and headerCell directly to the table with the static `ViewChild` query, |
| // since the columnDef will not pick up its content by the time the table finishes checking |
| // its content and initializing the rows. |
| this.columnDef.cell = this.cell; |
| this.columnDef.headerCell = this.headerCell; |
| this._table.addColumnDef(this.columnDef); |
| } |
| else if (typeof ngDevMode === 'undefined' || ngDevMode) { |
| throw getTableTextColumnMissingParentTableError(); |
| } |
| }; |
| CdkTextColumn.prototype.ngOnDestroy = function () { |
| if (this._table) { |
| this._table.removeColumnDef(this.columnDef); |
| } |
| }; |
| /** |
| * Creates a default header text. Use the options' header text transformation function if one |
| * has been provided. Otherwise simply capitalize the column name. |
| */ |
| CdkTextColumn.prototype._createDefaultHeaderText = function () { |
| var name = this.name; |
| if (!name && (typeof ngDevMode === 'undefined' || ngDevMode)) { |
| throw getTableTextColumnMissingNameError(); |
| } |
| if (this._options && this._options.defaultHeaderTextTransform) { |
| return this._options.defaultHeaderTextTransform(name); |
| } |
| return name[0].toUpperCase() + name.slice(1); |
| }; |
| /** Synchronizes the column definition name with the text column name. */ |
| CdkTextColumn.prototype._syncColumnDefName = function () { |
| if (this.columnDef) { |
| this.columnDef.name = this.name; |
| } |
| }; |
| return CdkTextColumn; |
| }()); |
| CdkTextColumn.decorators = [ |
| { type: core.Component, args: [{ |
| selector: 'cdk-text-column', |
| 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 ", |
| encapsulation: core.ViewEncapsulation.None, |
| // Change detection is intentionally not set to OnPush. This component's template will be provided |
| // to the table to be inserted into its view. This is problematic when change detection runs since |
| // the bindings in this template will be evaluated _after_ the table's view is evaluated, which |
| // mean's the template in the table's view will not have the updated value (and in fact will cause |
| // an ExpressionChangedAfterItHasBeenCheckedError). |
| // tslint:disable-next-line:validate-decorators |
| changeDetection: core.ChangeDetectionStrategy.Default |
| },] } |
| ]; |
| CdkTextColumn.ctorParameters = function () { return [ |
| { type: CdkTable, decorators: [{ type: core.Optional }] }, |
| { type: undefined, decorators: [{ type: core.Optional }, { type: core.Inject, args: [TEXT_COLUMN_OPTIONS,] }] } |
| ]; }; |
| CdkTextColumn.propDecorators = { |
| name: [{ type: core.Input }], |
| headerText: [{ type: core.Input }], |
| dataAccessor: [{ type: core.Input }], |
| justify: [{ type: core.Input }], |
| columnDef: [{ type: core.ViewChild, args: [CdkColumnDef, { static: true },] }], |
| cell: [{ type: core.ViewChild, args: [CdkCellDef, { static: true },] }], |
| headerCell: [{ type: core.ViewChild, args: [CdkHeaderCellDef, { static: true },] }] |
| }; |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var EXPORTED_DECLARATIONS = [ |
| CdkTable, |
| CdkRowDef, |
| CdkCellDef, |
| CdkCellOutlet, |
| CdkHeaderCellDef, |
| CdkFooterCellDef, |
| CdkColumnDef, |
| CdkCell, |
| CdkRow, |
| CdkHeaderCell, |
| CdkFooterCell, |
| CdkHeaderRow, |
| CdkHeaderRowDef, |
| CdkFooterRow, |
| CdkFooterRowDef, |
| DataRowOutlet, |
| HeaderRowOutlet, |
| FooterRowOutlet, |
| CdkTextColumn, |
| CdkNoDataRow, |
| NoDataRowOutlet, |
| ]; |
| var CdkTableModule = /** @class */ (function () { |
| function CdkTableModule() { |
| } |
| return CdkTableModule; |
| }()); |
| CdkTableModule.decorators = [ |
| { type: core.NgModule, args: [{ |
| exports: EXPORTED_DECLARATIONS, |
| declarations: EXPORTED_DECLARATIONS, |
| imports: [scrolling.ScrollingModule] |
| },] } |
| ]; |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| |
| /** |
| * Generated bundle index. Do not edit. |
| */ |
| |
| Object.defineProperty(exports, 'DataSource', { |
| enumerable: true, |
| get: function () { |
| return collections.DataSource; |
| } |
| }); |
| exports.BaseCdkCell = BaseCdkCell; |
| exports.BaseRowDef = BaseRowDef; |
| exports.CDK_ROW_TEMPLATE = CDK_ROW_TEMPLATE; |
| exports.CDK_TABLE = CDK_TABLE; |
| exports.CDK_TABLE_TEMPLATE = CDK_TABLE_TEMPLATE; |
| exports.CdkCell = CdkCell; |
| exports.CdkCellDef = CdkCellDef; |
| exports.CdkCellOutlet = CdkCellOutlet; |
| exports.CdkColumnDef = CdkColumnDef; |
| exports.CdkFooterCell = CdkFooterCell; |
| exports.CdkFooterCellDef = CdkFooterCellDef; |
| exports.CdkFooterRow = CdkFooterRow; |
| exports.CdkFooterRowDef = CdkFooterRowDef; |
| exports.CdkHeaderCell = CdkHeaderCell; |
| exports.CdkHeaderCellDef = CdkHeaderCellDef; |
| exports.CdkHeaderRow = CdkHeaderRow; |
| exports.CdkHeaderRowDef = CdkHeaderRowDef; |
| exports.CdkNoDataRow = CdkNoDataRow; |
| exports.CdkRow = CdkRow; |
| exports.CdkRowDef = CdkRowDef; |
| exports.CdkTable = CdkTable; |
| exports.CdkTableModule = CdkTableModule; |
| exports.CdkTextColumn = CdkTextColumn; |
| exports.DataRowOutlet = DataRowOutlet; |
| exports.FooterRowOutlet = FooterRowOutlet; |
| exports.HeaderRowOutlet = HeaderRowOutlet; |
| exports.NoDataRowOutlet = NoDataRowOutlet; |
| exports.STICKY_DIRECTIONS = STICKY_DIRECTIONS; |
| exports.STICKY_POSITIONING_LISTENER = STICKY_POSITIONING_LISTENER; |
| exports.StickyStyler = StickyStyler; |
| exports.TEXT_COLUMN_OPTIONS = TEXT_COLUMN_OPTIONS; |
| exports._COALESCED_STYLE_SCHEDULER = _COALESCED_STYLE_SCHEDULER; |
| exports._CoalescedStyleScheduler = _CoalescedStyleScheduler; |
| exports._Schedule = _Schedule; |
| exports.mixinHasStickyInput = mixinHasStickyInput; |
| |
| Object.defineProperty(exports, '__esModule', { value: true }); |
| |
| }))); |
| //# sourceMappingURL=cdk-table.umd.js.map |