(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@bravobit/bb-foundation/api'), require('rxjs/operators'), require('rxjs'), require('@angular/forms'), require('@bravobit/bb-foundation'), require('@bravobit/bb-foundation/elements'), require('@bravobit/bb-foundation/localize'), require('@angular/common')) :
    typeof define === 'function' && define.amd ? define('@bravobit/bb-foundation/table', ['exports', '@angular/core', '@bravobit/bb-foundation/api', 'rxjs/operators', 'rxjs', '@angular/forms', '@bravobit/bb-foundation', '@bravobit/bb-foundation/elements', '@bravobit/bb-foundation/localize', '@angular/common'], factory) :
    (global = global || self, factory((global.bravobit = global.bravobit || {}, global.bravobit['bb-foundation'] = global.bravobit['bb-foundation'] || {}, global.bravobit['bb-foundation'].table = {}), global.ng.core, global.bravobit['bb-foundation'].api, global.rxjs.operators, global.rxjs, global.ng.forms, global.bravobit['bb-foundation'], global.bravobit['bb-foundation'].elements, global.bravobit['bb-foundation'].localize, global.ng.common));
}(this, (function (exports, core, api, operators, rxjs, forms, bbFoundation, elements, localize, common) { 'use strict';

    /*! *****************************************************************************
    Copyright (c) Microsoft Corporation. All rights reserved.
    Licensed under the Apache License, Version 2.0 (the "License"); you may not use
    this file except in compliance with the License. You may obtain a copy of the
    License at http://www.apache.org/licenses/LICENSE-2.0

    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
    MERCHANTABLITY OR NON-INFRINGEMENT.

    See the Apache Version 2.0 License for specific language governing permissions
    and limitations under the License.
    ***************************************************************************** */
    /* 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };

    function __extends(d, b) {
        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) {
        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) : new P(function (resolve) { resolve(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 };
        }
    }

    function __exportStar(m, exports) {
        for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
    }

    function __values(o) {
        var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
        if (m) return m.call(o);
        return {
            next: function () {
                if (o && i >= o.length) o = void 0;
                return { value: o && o[i++], done: !o };
            }
        };
    }

    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;
    }

    function __spread() {
        for (var ar = [], i = 0; i < arguments.length; i++)
            ar = ar.concat(__read(arguments[i]));
        return ar;
    }

    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 __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;
    };

    function __importStar(mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
        result.default = mod;
        return result;
    }

    function __importDefault(mod) {
        return (mod && mod.__esModule) ? mod : { default: mod };
    }

    var BbTableColumnDef = /** @class */ (function () {
        function BbTableColumnDef() {
        }
        BbTableColumnDef = __decorate([
            core.Directive({
                selector: '[bbTableColumnDef]'
            })
        ], BbTableColumnDef);
        return BbTableColumnDef;
    }());
    var BbTable = /** @class */ (function () {
        function BbTable() {
            var _this = this;
            // Inputs.
            this.identifier = null;
            this.queryFields = [];
            this.sortingStrategy = 'single';
            this.header = true;
            this.footer = true;
            // Sizes.
            this._sizes = [25, 50, 75, 100];
            // Optimizations.
            this.trackByFn = function (index, item) { return _this.identifier ? item[_this.identifier] : index; };
            this.trackByValue = function (index, item) { return item; };
            this.queryControl = new forms.FormControl('');
        }
        Object.defineProperty(BbTable.prototype, "sizes", {
            get: function () {
                return this._sizes;
            },
            set: function (newValue) {
                this.updateSizes(newValue);
            },
            enumerable: true,
            configurable: true
        });
        BbTable.prototype.ngOnInit = function () {
            this.composeForm();
            this.watchDataChanges();
        };
        BbTable.prototype.ngOnDestroy = function () {
            this._subscription && this._subscription.unsubscribe();
        };
        Object.defineProperty(BbTable.prototype, "sortControl", {
            get: function () {
                return this.form.get('sort');
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(BbTable.prototype, "pageNumberControl", {
            get: function () {
                return this.form.get('pageNumber');
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(BbTable.prototype, "pageSizeControl", {
            get: function () {
                return this.form.get('pageSize');
            },
            enumerable: true,
            configurable: true
        });
        BbTable.prototype.refresh = function () {
            return this.request.update();
        };
        BbTable.prototype.updateSizes = function (newValue) {
            // Validate the sizes has at least one value.
            if (newValue.length <= 0) {
                throw new Error('Cannot set an empty array as the sizes.');
            }
            // Set the new size.
            this._sizes = newValue;
            // Validate that the form exists already.
            if (!this.form) {
                return;
            }
            // Check if the current selected value is
            // in the new sizes array.
            var pageSizeControl = this.form.get('pageSize');
            if (this._sizes.includes(pageSizeControl.value)) {
                return;
            }
            // Set the first value in the array as
            // the new value.
            var firstValue = this._sizes[0];
            pageSizeControl.setValue(firstValue);
        };
        BbTable.prototype.composeForm = function () {
            // Setup the form.
            this.form = new forms.FormGroup({
                pageSize: new forms.FormControl(this._sizes[0]),
                pageNumber: new forms.FormControl(1),
                sort: new forms.FormGroup({})
            });
        };
        BbTable.prototype.watchDataChanges = function () {
            var _this = this;
            // Create a new request.
            this.request = new api.DataSourceRequest();
            this.isLoading$ = this.request.loading;
            if (!this.dataSource) {
                this.data$ = rxjs.of({ state: 'error_datasource' }).pipe(operators.tap(function () { return _this.request.stopLoading(); }));
                return;
            }
            // Pass the request to the data source.
            this.data$ = this.dataSource.handle(this.request).pipe(operators.tap(function () { return _this.request.stopLoading(); }), operators.map(function (result) {
                var count = (result && result.data && result.data.length) || 0;
                if (count <= 0) {
                    return { state: 'empty', result: result };
                }
                return { state: 'success', result: result };
            }), operators.catchError(function (error) {
                _this.request.stopLoading();
                var states = {
                    401: 'error_unauthorized',
                    403: 'error_forbidden',
                    404: 'error_not_found',
                    500: 'error_server'
                };
                return rxjs.of({ state: states[error.status] || 'error_unknown', statusCode: error.status });
            }));
            // Subscribe to the data changes.
            this.subscribeToChanges();
        };
        BbTable.prototype.subscribeToChanges = function () {
            var _this = this;
            var form$ = this.getFormChanges();
            var query$ = this.getQueryChanges();
            this._subscription = rxjs.combineLatest([form$, query$]).subscribe(function (_a) {
                var _b = __read(_a, 2), form = _b[0], query = _b[1];
                var pageNumber = form.pageNumber, pageSize = form.pageSize;
                var sort = Object.keys(form.sort)
                    .map(function (name) { return ({ name: name, direction: form.sort[name] }); })
                    .filter(function (item) { return ['asc', 'desc'].includes(item.direction); });
                _this.request.startLoading();
                return _this.request.update({
                    sort: sort,
                    query: query,
                    pageSize: pageSize,
                    pageNumber: pageNumber,
                    queryFields: _this.queryFields
                });
            });
        };
        BbTable.prototype.getQueryChanges = function () {
            return this.queryControl.valueChanges.pipe(operators.debounceTime(400), operators.distinctUntilChanged(), operators.startWith(this.queryControl.value));
        };
        BbTable.prototype.getFormChanges = function () {
            return this.form.valueChanges.pipe(operators.startWith(this.form.value));
        };
        __decorate([
            core.ContentChildren(BbTableColumnDef, { read: core.TemplateRef })
        ], BbTable.prototype, "tableColumnTemplates", void 0);
        __decorate([
            core.Input()
        ], BbTable.prototype, "identifier", void 0);
        __decorate([
            core.Input()
        ], BbTable.prototype, "dataSource", void 0);
        __decorate([
            core.Input()
        ], BbTable.prototype, "queryFields", void 0);
        __decorate([
            core.Input()
        ], BbTable.prototype, "sortingStrategy", void 0);
        __decorate([
            core.Input()
        ], BbTable.prototype, "header", void 0);
        __decorate([
            core.Input()
        ], BbTable.prototype, "footer", void 0);
        __decorate([
            core.Input()
        ], BbTable.prototype, "sizes", null);
        BbTable = __decorate([
            core.Component({
                selector: 'bb-table',
                template: "<!--\n    This is the header of the table. It can be a user\n    defined custom header or just the default header.\n-->\n\n<header *ngIf=\"(header === true ? headerTemplate : header) as template\"\n        class=\"bb-table-top-actions\">\n    <ng-container *ngTemplateOutlet=\"template\"></ng-container>\n</header>\n\n<!--\n    This is the table that contains the\n    rows and columns.\n-->\n\n<div class=\"bb-table-wrapper\">\n    <div *ngIf=\"isLoading$ | async\"\n         class=\"bb-table-progress\">\n        <div class=\"bb-table-indeterminate\"></div>\n    </div>\n    <table class=\"bb-table-container\">\n        <thead>\n            <tr>\n                <ng-content select=\"bb-table-header-cell\"></ng-content>\n            </tr>\n        </thead>\n        <tbody *ngIf=\"data$ | async as data; else isLoadingTemplate\"\n               [ngSwitch]=\"data?.state\">\n            <ng-container *ngSwitchCase=\"'success'\">\n                <tr *ngFor=\"let item of data?.result?.data; trackBy: trackByFn\">\n                    <ng-container *ngFor=\"let template of tableColumnTemplates\">\n                        <ng-container *ngTemplateOutlet=\"template; context: {item: item}\"></ng-container>\n                    </ng-container>\n                </tr>\n            </ng-container>\n\n            <ng-container *ngSwitchCase=\"'empty'\">\n                <ng-container\n                    *ngTemplateOutlet=\"errorTemplate; context: data\"></ng-container>\n            </ng-container>\n\n            <ng-container *ngSwitchCase=\"'error_datasource'\">\n                <ng-container\n                    *ngTemplateOutlet=\"errorTemplate; context: data\"></ng-container>\n            </ng-container>\n\n            <ng-container *ngSwitchCase=\"'error_not_found'\">\n                <ng-container\n                    *ngTemplateOutlet=\"errorTemplate; context: data\"></ng-container>\n            </ng-container>\n\n            <ng-container *ngSwitchCase=\"'error_server'\">\n                <ng-container\n                    *ngTemplateOutlet=\"errorTemplate; context: data\"></ng-container>\n            </ng-container>\n\n            <ng-container *ngSwitchDefault>\n                <ng-container\n                    *ngTemplateOutlet=\"errorTemplate; context: data\"></ng-container>\n            </ng-container>\n        </tbody>\n    </table>\n</div>\n\n<footer *ngIf=\"(footer === true ? footerTemplate : footer) as template\"\n        class=\"bb-table-bottom-actions\">\n    <ng-container *ngTemplateOutlet=\"template\"></ng-container>\n</footer>\n\n<ng-template #isLoadingTemplate>\n    <tr>\n        <td [attr.colspan]=\"tableColumnTemplates?.length\"\n            class=\"bb-table-template\">\n            <div class=\"bb-table-template-content\">\n                {{ 'tables.loading' | bbLocalize }}\n            </div>\n        </td>\n    </tr>\n</ng-template>\n\n<!--\n    This is the template that will be used when the user has not\n    supplied a custom header template.\n-->\n\n<ng-template #headerTemplate>\n    <ng-content></ng-content>\n    <bb-form-control>\n        <input [formControl]=\"queryControl\"\n               [placeholder]=\"'tables.search' | bbLocalize\"\n               bbInput\n               autocomplete=\"off\">\n        <bb-icon *ngIf=\"queryControl?.value?.length <= 0; else closeButtonTemplate\"\n                 bbSuffix\n                 src=\"material:search\">\n        </bb-icon>\n    </bb-form-control>\n</ng-template>\n\n<!--\n    This is the template that will be used when the user has not\n    supplied a custom footer template.\n-->\n\n<ng-template #footerTemplate>\n    <bb-form-control *ngIf=\"sizes?.length > 1\">\n        <select [formControl]=\"pageSizeControl\"\n                bbInput\n                title=\"Sizes\">\n            <option *ngFor=\"let item of sizes; trackBy: trackByValue\"\n                    [ngValue]=\"item\">\n                {{ item }} / {{ 'tables.page' | bbLocalize }}\n            </option>\n        </select>\n    </bb-form-control>\n\n    <bb-table-pager [totalPages]=\"(data$ | async)?.result?.totalPages\"\n                    [formControl]=\"pageNumberControl\">\n    </bb-table-pager>\n</ng-template>\n\n<!--\n    This the template that will be used when the user\n    has filled in some data in the query control.\n-->\n\n<ng-template #closeButtonTemplate>\n    <button bbSuffix\n            (click)=\"queryControl?.patchValue('')\"\n            type=\"button\"\n            class=\"bb-table-progress-close-query\">\n        <bb-icon src=\"material:close\"></bb-icon>\n    </button>\n</ng-template>\n\n<ng-template #errorTemplate let-state=\"state\" let-status=\"statusCode\">\n    <tr>\n        <td [attr.colspan]=\"tableColumnTemplates?.length\"\n            class=\"bb-table-template\">\n            <div class=\"bb-table-template-content\">\n                <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"64\" height=\"41\">\n                    <g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(0 1)\">\n                        <ellipse cx=\"32\" cy=\"33\" fill=\"#F5F5F5\" rx=\"32\" ry=\"7\"></ellipse>\n                        <g fill-rule=\"nonzero\" stroke=\"#D9D9D9\">\n                            <path\n                                d=\"M55 12.7605604L44.8543047 1.25739633C44.3674414.47382661 43.6558789 0 42.9067617 0H21.0932383c-.7491172 0-1.4606797.47395025-1.947543 1.25739633L9 12.7605604V22h46v-9.2394396z\"></path>\n                            <path fill=\"#FAFAFA\"\n                                  d=\"M41.6132813 15.9315c0-1.6056489.9936718-2.931266 2.2264179-2.9315H55v18.1371277C55 33.2589574 53.6793867 35 52.0504297 35H11.94957031C10.32052344 35 9 33.2588404 9 31.1371277V13h11.1603008c1.2327461 0 2.226418 1.3228085 2.226418 2.9284574v.0211809c0 1.6056489 1.0049921 2.9015426 2.2377382 2.9015426h14.751086c1.2327461 0 2.2377383-1.3078298 2.2377383-2.9134788V15.9315z\"></path>\n                        </g>\n                    </g>\n                </svg>\n                <span *ngIf=\"state as stateLabel\">{{ ('tables.' + stateLabel) | bbLocalize }}</span>\n                <span *ngIf=\"status as statusCode\"\n                      class=\"bb-table-template-content-code\">(HTTP {{ statusCode }})</span>\n            </div>\n        </td>\n    </tr>\n</ng-template>\n",
                host: { 'class': 'bb-table' },
                changeDetection: core.ChangeDetectionStrategy.OnPush,
                encapsulation: core.ViewEncapsulation.None,
                preserveWhitespaces: false,
                styles: [".bb-table{width:100%;display:block;box-shadow:0 6px 6px -6px rgba(0,0,0,.1)}.bb-table.plain{box-shadow:none}.bb-table.plain>.bb-table-wrapper{border-top-left-radius:0;border-top-right-radius:0}.bb-table-wrapper{overflow-x:auto;position:relative;background-color:#fff;border-top-left-radius:4px;border-top-right-radius:4px}.bb-table-container{width:100%}.bb-table-container td{border-bottom:1px solid #d8d8d8}.bb-table-top-actions{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding:20px 20px 10px;background-color:#fff;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom:1px solid #d8d8d8}.bb-table-top-actions>*{margin-left:0;margin-bottom:10px}.bb-table-top-actions+.bb-table-wrapper{border-radius:0}.bb-table-bottom-actions{height:60px;display:-webkit-box;display:-ms-flexbox;display:flex;padding:0 20px;overflow-x:auto;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:#fff;border-bottom-left-radius:4px;border-bottom-right-radius:4px}.bb-table-template{border:none;background-color:#f5f5f5;border-bottom:1px solid #d8d8d8}.bb-table-template-content{padding:20px;display:-webkit-box;display:-ms-flexbox;display:flex;color:#3d464d;font-size:14px;line-height:1.2;font-weight:400;min-height:140px;text-align:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.bb-table-template-content>svg{margin-bottom:12px}.bb-table-template-content-code{opacity:.5;margin-top:5px;display:inline-block}.bb-table-progress{top:0;left:0;right:0;opacity:0;width:100%;height:4px;display:block;overflow:hidden;position:absolute;background-color:rgba(47,64,139,.3);-webkit-animation:250ms cubic-bezier(0,0,.2,1) .1s forwards fadeIn;animation:250ms cubic-bezier(0,0,.2,1) .1s forwards fadeIn}.bb-table-progress .bb-table-indeterminate{background-color:#2f408b}.bb-table-progress .bb-table-indeterminate:before{top:0;left:0;bottom:0;content:\"\";position:absolute;will-change:left,right;background-color:inherit;-webkit-animation:2.1s cubic-bezier(.65,.815,.735,.395) infinite indeterminate;animation:2.1s cubic-bezier(.65,.815,.735,.395) infinite indeterminate}.bb-table-progress .bb-table-indeterminate:after{top:0;left:0;bottom:0;content:\"\";position:absolute;-webkit-animation-delay:1.15s;animation-delay:1.15s;will-change:left,right;background-color:inherit;-webkit-animation:2.1s cubic-bezier(.165,.84,.44,1) infinite indeterminate-short;animation:2.1s cubic-bezier(.165,.84,.44,1) infinite indeterminate-short}.bb-table-progress-close-query{padding:0;border:none;border-radius:4px;background-color:transparent;-webkit-transition:background-color 250ms cubic-bezier(0,0,.2,1);transition:background-color 250ms cubic-bezier(0,0,.2,1)}.bb-table-progress-close-query:hover{background-color:rgba(0,0,0,.08)}.bb-table-progress-close-query:focus{background-color:rgba(0,0,0,.12)}.bb-table-progress-close-query:active{background-color:rgba(0,0,0,.16)}@-webkit-keyframes fadeIn{from{opacity:0}to{opacity:1}}@keyframes fadeIn{from{opacity:0}to{opacity:1}}@-webkit-keyframes indeterminate{0%{left:-35%;right:100%}100%,60%{left:100%;right:-90%}}@keyframes indeterminate{0%{left:-35%;right:100%}100%,60%{left:100%;right:-90%}}@-webkit-keyframes indeterminate-short{0%{left:-200%;right:100%}100%,60%{left:107%;right:-8%}}@keyframes indeterminate-short{0%{left:-200%;right:100%}100%,60%{left:107%;right:-8%}}@media only screen and (min-width:768px){.bb-table-top-actions{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.bb-table-top-actions>:not(:first-child){margin-left:10px;margin-bottom:10px}}"]
            })
        ], BbTable);
        return BbTable;
    }());

    var BbTableCell = /** @class */ (function () {
        function BbTableCell() {
        }
        BbTableCell = __decorate([
            core.Component({
                selector: 'bb-table-cell',
                template: "<div>\n    <ng-content></ng-content>\n</div>",
                changeDetection: core.ChangeDetectionStrategy.OnPush,
                host: { 'class': 'bb-table-cell' },
                encapsulation: core.ViewEncapsulation.None,
                preserveWhitespaces: false,
                styles: [".bb-table-cell{color:#848f99;font-size:14px;text-align:left;line-height:1.2;font-weight:400;padding:12px 20px;display:table-cell;word-wrap:break-word;vertical-align:middle;background-color:#f5f5f5;border-bottom:1px solid #d8d8d8}.bb-table-cell:not(:last-child){border-right:1px solid #d8d8d8}.bb-table-cell.fit{width:1%;white-space:nowrap}.bb-table-cell.left{text-align:left}.bb-table-cell.center{text-align:center}.bb-table-cell.right{text-align:right}"]
            })
        ], BbTableCell);
        return BbTableCell;
    }());

    var BbTableHeaderCellBase = /** @class */ (function () {
        function BbTableHeaderCellBase() {
        }
        return BbTableHeaderCellBase;
    }());
    var BbTableHeaderCellMixinBase = bbFoundation.mixinDisabled(BbTableHeaderCellBase);
    var BbTableHeaderCell = /** @class */ (function (_super) {
        __extends(BbTableHeaderCell, _super);
        function BbTableHeaderCell(_table, _name) {
            var _this = _super.call(this) || this;
            _this._table = _table;
            _this._name = _name;
            // Constants.
            _this._sortDirections = ['none', 'asc', 'desc'];
            _this._control = new forms.FormControl(_this._sortDirections[0]);
            _this.logWarning = function (message) {
                console && console.warn && console.warn(message);
            };
            return _this;
        }
        Object.defineProperty(BbTableHeaderCell.prototype, "sort", {
            get: function () {
                return this._control.value;
            },
            // Sort.
            set: function (value) {
                // Check if the new value is a valid value.
                if (!this._sortDirections.includes(value)) {
                    return;
                }
                // Set the value.
                this._control.setValue(value);
            },
            enumerable: true,
            configurable: true
        });
        BbTableHeaderCell.prototype.ngOnInit = function () {
            // Validate that the name and table are set.
            if (!this._table || !this._name) {
                return;
            }
            // Check if the control already exists in the table.
            if (this._table.sortControl.contains(this._name)) {
                this.disabled = true;
                return this.logWarning("BbTableHeaderCell: The name \"" + this._name + "\" is not unique in the table; Control was not registered.");
            }
            // Register the header cell with the table.
            this._table.sortControl.addControl(this._name, this._control);
            // Get all the value changes.
            this.valueChanges$ = this._control.valueChanges.pipe(operators.startWith(this._control.value));
        };
        BbTableHeaderCell.prototype.ngOnDestroy = function () {
            // Validate that the name and table are set.
            if (!this._table || !this._name) {
                return;
            }
            // Un-register the header cell with the table.
            if (this._table.sortControl.contains(this._name)) {
                this._table.sortControl.removeControl(this._name);
            }
        };
        Object.defineProperty(BbTableHeaderCell.prototype, "isDisabled", {
            get: function () {
                return this.disabled || !this._name;
            },
            enumerable: true,
            configurable: true
        });
        BbTableHeaderCell.prototype.onClick = function () {
            var _this = this;
            // Check if the header cell is disabled.
            if (this.isDisabled) {
                return;
            }
            // Find the index of the current sort and
            // create the new index.
            var index = this._sortDirections.findIndex(function (item) { return item === _this._control.value; });
            var newIndex = (index + 1) % this._sortDirections.length;
            var newSort = this._sortDirections[newIndex];
            // Set the new sort.
            return this.updateTableAndHeaderCell(newSort);
        };
        BbTableHeaderCell.prototype.updateTableAndHeaderCell = function (value) {
            // Check if the new value is a valid value.
            if (!this._sortDirections.includes(value)) {
                return;
            }
            // Validate the table exists.
            if (!this._table) {
                return this._control.setValue(value);
            }
            // Handle the single sorting strategy.
            if (this._table.sortingStrategy === 'single') {
                return this.handleSingleSortingStrategy(value);
            }
            // Default case when no other strategy
            // is used.
            return this._control.setValue(value);
        };
        BbTableHeaderCell.prototype.handleSingleSortingStrategy = function (value) {
            var _this = this;
            // Get the sort control.
            var control = this._table.sortControl;
            // Set each value to false since we only want to
            // sort on one property at a time with this strategy.
            var newValue = Object.keys(control.controls).reduce(function (previous, current) {
                previous[current] = current === _this._name ? value : 'none';
                return previous;
            }, {});
            // Patch the entire sort value.
            this._table.sortControl.patchValue(newValue);
        };
        BbTableHeaderCell.ctorParameters = function () { return [
            { type: BbTable, decorators: [{ type: core.Optional }, { type: core.Host }] },
            { type: String, decorators: [{ type: core.Optional }, { type: core.Attribute, args: ['name',] }] }
        ]; };
        __decorate([
            core.Input()
        ], BbTableHeaderCell.prototype, "sort", null);
        __decorate([
            core.HostListener('click')
        ], BbTableHeaderCell.prototype, "onClick", null);
        BbTableHeaderCell = __decorate([
            core.Component({
                selector: 'bb-table-header-cell',
                template: "<!-- The content. -->\n<ng-content></ng-content>\n\n<!-- The indicator for the sort direction. -->\n<ng-container *ngIf=\"valueChanges$ | async as value\">\n    <button *ngIf=\"!isDisabled\"\n            [class.asc]=\"value === 'asc'\"\n            [class.desc]=\"value === 'desc'\"\n            class=\"bb-table-header-cell-toggle\"\n            type=\"button\"></button>\n</ng-container>\n",
                changeDetection: core.ChangeDetectionStrategy.OnPush,
                host: {
                    'class': 'bb-table-header-cell',
                    '[class.disabled]': 'isDisabled'
                },
                inputs: ['disabled'],
                encapsulation: core.ViewEncapsulation.None,
                preserveWhitespaces: false,
                styles: [".bb-table-header-cell{height:50px;color:#212529;cursor:pointer;font-size:16px;font-weight:500;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;padding:10px 20px;position:relative;display:table-cell;vertical-align:middle;border-bottom:1px solid #d8d8d8}.bb-table-header-cell:active>.bb-table-header-cell-toggle{background-color:rgba(0,0,0,.08)}.bb-table-header-cell:not(.disabled){padding-right:52px}.bb-table-header-cell.fit{width:1%;white-space:nowrap}.bb-table-header-cell.left{text-align:left}.bb-table-header-cell.center{text-align:center}.bb-table-header-cell.right{text-align:right}.bb-table-header-cell.disabled{cursor:default;pointer-events:none}.bb-table-header-cell-toggle{top:50%;right:14px;width:22px;border:none;height:22px;margin-left:auto;position:absolute;border-radius:4px;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);background-position:center;background-repeat:no-repeat;background-color:transparent;-webkit-transition:background-color .2s cubic-bezier(0,0,.2,1);transition:background-color .2s cubic-bezier(0,0,.2,1);background-image:url('data:image/svg+xml,%3Csvg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 9 15\" width=\"9\" height=\"15\"%3E%3Cpath fill=\"%23dcdcdc\" d=\"M4.5 0L0 7h9z\"%3E%3C/path%3E%3Cpath fill=\"%23dcdcdc\" d=\"M4.5 15L9 8H0z\"%3E%3C/path%3E%3C/svg%3E')}.bb-table-header-cell-toggle.desc{background-image:url('data:image/svg+xml,%3Csvg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 9 15\" width=\"9\" height=\"15\"%3E%3Cpath fill=\"%23dcdcdc\" d=\"M4.5 0L0 7h9z\"%3E%3C/path%3E%3Cpath fill=\"black\" d=\"M4.5 15L9 8H0z\"%3E%3C/path%3E%3C/svg%3E')}.bb-table-header-cell-toggle.asc{background-image:url('data:image/svg+xml,%3Csvg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 9 15\" width=\"9\" height=\"15\"%3E%3Cpath fill=\"black\" d=\"M4.5 0L0 7h9z\"%3E%3C/path%3E%3Cpath fill=\"%23dcdcdc\" d=\"M4.5 15L9 8H0z\"%3E%3C/path%3E%3C/svg%3E')}"]
            }),
            __param(0, core.Optional()), __param(0, core.Host()),
            __param(1, core.Optional()), __param(1, core.Attribute('name'))
        ], BbTableHeaderCell);
        return BbTableHeaderCell;
    }(BbTableHeaderCellMixinBase));

    var BbTablePagerBase = /** @class */ (function () {
        function BbTablePagerBase() {
        }
        return BbTablePagerBase;
    }());
    var BbTablePagerMixinBase = bbFoundation.mixinDisabled(BbTablePagerBase);
    var BbTablePager = /** @class */ (function (_super) {
        __extends(BbTablePager, _super);
        function BbTablePager() {
            var _this = _super !== null && _super.apply(this, arguments) || this;
            // Inputs.
            _this.amountOfButtons = 5;
            _this.showArrowButtons = true;
            // Methods.
            _this.onChange = function () { return ({}); };
            _this.onTouched = function () { return ({}); };
            _this.trackByIndex = function (index, item) { return item.page; };
            // Data.
            _this._totalPages$ = new rxjs.BehaviorSubject(1);
            _this._pageNumber$ = new rxjs.BehaviorSubject(1);
            return _this;
        }
        BbTablePager_1 = BbTablePager;
        BbTablePager.prototype.ngOnInit = function () {
            var _this = this;
            // Validate the previous button is disabled.
            this.isPreviousDisabled$ = this._pageNumber$.pipe(operators.map(function (pageNumber) { return pageNumber === 1; }));
            // Validate the next button is disabled.
            this.isNextDisabled$ = rxjs.combineLatest([this._pageNumber$, this._totalPages$]).pipe(operators.map(function (_a) {
                var _b = __read(_a, 2), pageNumber = _b[0], totalPages = _b[1];
                return pageNumber === totalPages;
            }));
            // Create the list with page numbers.
            this.list$ = rxjs.combineLatest([this._pageNumber$, this._totalPages$]).pipe(operators.map(function (_a) {
                var _b = __read(_a, 2), pageNumber = _b[0], totalPages = _b[1];
                return _this.filterActivePages(pageNumber, totalPages);
            }), operators.share());
        };
        Object.defineProperty(BbTablePager.prototype, "pageNumber", {
            get: function () {
                return this._pageNumber$.getValue();
            },
            set: function (newValue) {
                this.update(newValue);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(BbTablePager.prototype, "totalPages", {
            get: function () {
                return this._totalPages$.getValue();
            },
            set: function (newValue) {
                var newTotalPages = Math.max(1, newValue);
                this._totalPages$.next(newTotalPages);
            },
            enumerable: true,
            configurable: true
        });
        BbTablePager.prototype.registerOnChange = function (fn) {
            this.onChange = fn;
        };
        BbTablePager.prototype.registerOnTouched = function (fn) {
            this.onTouched = fn;
        };
        BbTablePager.prototype.setDisabledState = function (isDisabled) {
            this.disabled = isDisabled;
        };
        BbTablePager.prototype.writeValue = function (newValue) {
            this.update(newValue, false);
        };
        BbTablePager.prototype.goToPrevious = function () {
            var newValue = this._pageNumber$.getValue() - 1;
            return this.update(newValue);
        };
        BbTablePager.prototype.goToNext = function () {
            var newValue = this._pageNumber$.getValue() + 1;
            return this.update(newValue);
        };
        BbTablePager.prototype.goToIndex = function (index) {
            return this.update(index);
        };
        BbTablePager.prototype.update = function (pageNumber, notify) {
            if (notify === void 0) { notify = true; }
            // You can only update when not disabled.
            if (this.disabled) {
                return;
            }
            // Calculate the new value.
            var newValue = Math.min(this.totalPages, Math.max(1, pageNumber));
            // Don't do anything if the page number is the same.
            if (this._pageNumber$.getValue() === newValue) {
                return;
            }
            // Push the new value.
            this._pageNumber$.next(newValue);
            if (notify) {
                return this.onChange(pageNumber);
            }
        };
        BbTablePager.prototype.calculatePages = function (pageNumber) {
            var min = 1;
            var max = this.totalPages;
            var amount = Math.max(1, this.amountOfButtons);
            var data = Array(amount)
                .fill(0)
                .map(function (_, index) { return pageNumber + (index - 1); });
            // Validate if the minimum value less than
            // the first value.
            if (data[0] < min) {
                return data.map(function (item) { return item + 1; });
            }
            // Calculate the difference with the max
            // if this value is higher than 0 we should minus it.
            var lastValueInArray = data[data.length - 1];
            var differenceWithMax = lastValueInArray - max;
            if (differenceWithMax > 0) {
                return data.map(function (item) { return item - differenceWithMax; });
            }
            // Just return the default data.
            return data;
        };
        BbTablePager.prototype.filterActivePages = function (pageNumber, totalPages) {
            return this.calculatePages(pageNumber)
                .filter(function (page) { return page > 0 && page <= totalPages; })
                .map(function (page) { return ({ page: page, active: pageNumber === page }); });
        };
        var BbTablePager_1;
        __decorate([
            core.Input()
        ], BbTablePager.prototype, "amountOfButtons", void 0);
        __decorate([
            core.Input()
        ], BbTablePager.prototype, "showArrowButtons", void 0);
        __decorate([
            core.Input()
        ], BbTablePager.prototype, "pageNumber", null);
        __decorate([
            core.Input()
        ], BbTablePager.prototype, "totalPages", null);
        BbTablePager = BbTablePager_1 = __decorate([
            core.Component({
                selector: 'bb-table-pager',
                template: "<ul class=\"bb-pager-list\">\n    <!-- The previous page arrow button. -->\n    <li *ngIf=\"showArrowButtons\"\n        class=\"bb-pager-list-item\"\n        title=\"Previous page\">\n        <button [disabled]=\"isPreviousDisabled$ | async\"\n                (click)=\"goToPrevious()\"\n                class=\"bb-pager-list-button\"\n                type=\"button\">\n            <bb-icon src=\"material:keyboard_arrow_left\"></bb-icon>\n        </button>\n    </li>\n\n    <!-- The list of number buttons to navigate through the list. -->\n    <ng-container *ngIf=\"list$ | async as list\">\n        <li *ngFor=\"let item of list; trackBy: trackByIndex\"\n            [title]=\"'Page ' + item?.page\"\n            class=\"bb-pager-list-item\">\n            <button (click)=\"goToIndex(item?.page)\"\n                    [class.active]=\"item?.active\"\n                    class=\"bb-pager-list-button\"\n                    type=\"button\">\n                {{ item?.page }}\n            </button>\n        </li>\n    </ng-container>\n\n    <!-- The next page arrow button. -->\n    <li *ngIf=\"showArrowButtons\"\n        class=\"bb-pager-list-item\"\n        title=\"Next page\">\n        <button [disabled]=\"isNextDisabled$ | async\"\n                (click)=\"goToNext()\"\n                class=\"bb-pager-list-button\"\n                type=\"button\">\n            <bb-icon src=\"material:keyboard_arrow_right\"></bb-icon>\n        </button>\n    </li>\n</ul>\n",
                changeDetection: core.ChangeDetectionStrategy.OnPush,
                host: {
                    'class': 'bb-table-pager',
                    '[class.disabled]': 'disabled'
                },
                inputs: ['disabled'],
                encapsulation: core.ViewEncapsulation.None,
                preserveWhitespaces: false,
                providers: [
                    { provide: forms.NG_VALUE_ACCESSOR, useExisting: core.forwardRef(function () { return BbTablePager_1; }), multi: true }
                ],
                styles: [".bb-table-pager{-webkit-box-flex:1;-ms-flex:1;flex:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.bb-table-pager.disabled{opacity:.5;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;pointer-events:none}.bb-pager-list{display:-webkit-box;display:-ms-flexbox;display:flex}.bb-pager-list-item{margin-left:8px}.bb-pager-list-button{padding:0;color:#3d464d;line-height:1;min-width:32px;font-size:16px;-webkit-appearance:none;-moz-appearance:none;appearance:none;font-weight:500;min-height:32px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border-radius:4px;-webkit-box-align:center;-ms-flex-align:center;align-items:center;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;border:1px solid #b6bbc1;-webkit-transition-duration:.2s;transition-duration:.2s;background-color:transparent;-webkit-transition-timing-function:cubic-bezier(0,0,.2,1);transition-timing-function:cubic-bezier(0,0,.2,1);-webkit-transition-property:color,border-color,opacity,background-color;transition-property:color,border-color,opacity,background-color;box-shadow:inset 0 3px 0 0 rgba(183,188,194,.2),0 6px 6px -6px rgba(0,0,0,.1)}.bb-pager-list-button:focus,.bb-pager-list-button:hover{background-color:rgba(0,0,0,.04)}.bb-pager-list-button.active,.bb-pager-list-button.active:hover{color:#2196f3;cursor:default;border-color:#2196f3;background-color:transparent}.bb-pager-list-button:disabled{opacity:.35;cursor:default;pointer-events:none}"]
            })
        ], BbTablePager);
        return BbTablePager;
    }(BbTablePagerMixinBase));

    var DECLARATIONS_EXPORTS = [
        BbTable,
        BbTableColumnDef,
        BbTableHeaderCell,
        BbTableCell
    ];
    var TableModule = /** @class */ (function () {
        function TableModule() {
        }
        TableModule = __decorate([
            core.NgModule({
                imports: [common.CommonModule, forms.FormsModule, forms.ReactiveFormsModule, elements.ElementsModule, localize.LocalizeModule],
                declarations: __spread([BbTablePager], DECLARATIONS_EXPORTS),
                exports: __spread(DECLARATIONS_EXPORTS)
            })
        ], TableModule);
        return TableModule;
    }());

    exports.BbTable = BbTable;
    exports.BbTableCell = BbTableCell;
    exports.BbTableColumnDef = BbTableColumnDef;
    exports.BbTableHeaderCell = BbTableHeaderCell;
    exports.TableModule = TableModule;
    exports.ɵa = BbTablePager;

    Object.defineProperty(exports, '__esModule', { value: true });

})));
//# sourceMappingURL=bravobit-bb-foundation-table.umd.js.map
