@ng-bootstrap/ng-bootstrap
Version:
Angular powered Bootstrap
1,118 lines (1,098 loc) • 467 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common'), require('rxjs'), require('rxjs/operators'), require('@angular/forms')) :
typeof define === 'function' && define.amd ? define('ngb', ['exports', '@angular/core', '@angular/common', 'rxjs', 'rxjs/operators', '@angular/forms'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ngb = {}, global.ng.core, global.ng.common, global.rxjs, global.rxjs.operators, global.ng.forms));
}(this, (function (exports, i0, i1, rxjs, operators, forms) { 'use strict';
function toInteger(value) {
return parseInt("" + value, 10);
}
function toString(value) {
return (value !== undefined && value !== null) ? "" + value : '';
}
function getValueInRange(value, max, min) {
if (min === void 0) { min = 0; }
return Math.max(Math.min(value, max), min);
}
function isString(value) {
return typeof value === 'string';
}
function isNumber(value) {
return !isNaN(toInteger(value));
}
function isInteger(value) {
return typeof value === 'number' && isFinite(value) && Math.floor(value) === value;
}
function isDefined(value) {
return value !== undefined && value !== null;
}
function padNumber(value) {
if (isNumber(value)) {
return ("0" + value).slice(-2);
}
else {
return '';
}
}
function regExpEscape(text) {
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
}
function hasClassName(element, className) {
return element && element.className && element.className.split &&
element.className.split(/\s+/).indexOf(className) >= 0;
}
if (typeof Element !== 'undefined' && !Element.prototype.closest) {
// Polyfill for ie10+
if (!Element.prototype.matches) {
// IE uses the non-standard name: msMatchesSelector
Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
}
Element.prototype.closest = function (s) {
var el = this;
if (!document.documentElement.contains(el)) {
return null;
}
do {
if (el.matches(s)) {
return el;
}
el = el.parentElement || el.parentNode;
} while (el !== null && el.nodeType === 1);
return null;
};
}
function closest(element, selector) {
if (!selector) {
return null;
}
/*
* In certain browsers (e.g. Edge 44.18362.449.0) HTMLDocument does
* not support `Element.prototype.closest`. To emulate the correct behaviour
* we return null when the method is missing.
*
* Note that in evergreen browsers `closest(document.documentElement, 'html')`
* will return the document element whilst in Edge null will be returned. This
* compromise was deemed good enough.
*/
if (typeof element.closest === 'undefined') {
return null;
}
return element.closest(selector);
}
/**
* Force a browser reflow
* @param element element where to apply the reflow
*/
function reflow(element) {
return (element || document.body).getBoundingClientRect();
}
/**
* Creates an observable where all callbacks are executed inside a given zone
*
* @param zone
*/
function runInZone(zone) {
return function (source) {
return new rxjs.Observable(function (observer) {
var onNext = function (value) { return zone.run(function () { return observer.next(value); }); };
var onError = function (e) { return zone.run(function () { return observer.error(e); }); };
var onComplete = function () { return zone.run(function () { return observer.complete(); }); };
return source.subscribe(onNext, onError, onComplete);
});
};
}
function removeAccents(str) {
return str.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
}
var environment = {
animation: true,
transitionTimerDelayMs: 5,
};
/**
* Global ng-bootstrap config
*
* @since 8.0.0
*/
var NgbConfig = /** @class */ (function () {
function NgbConfig() {
this.animation = environment.animation;
}
return NgbConfig;
}());
NgbConfig.ɵprov = i0.ɵɵdefineInjectable({ factory: function NgbConfig_Factory() { return new NgbConfig(); }, token: NgbConfig, providedIn: "root" });
NgbConfig.decorators = [
{ type: i0.Injectable, args: [{ providedIn: 'root' },] }
];
/**
* A configuration service for the [NgbAccordion](#/components/accordion/api#NgbAccordion) component.
*
* You can inject this service, typically in your root component, and customize its properties
* to provide default values for all accordions used in the application.
*/
var NgbAccordionConfig = /** @class */ (function () {
function NgbAccordionConfig(_ngbConfig) {
this._ngbConfig = _ngbConfig;
this.closeOthers = false;
}
Object.defineProperty(NgbAccordionConfig.prototype, "animation", {
get: function () { return (this._animation === undefined) ? this._ngbConfig.animation : this._animation; },
set: function (animation) { this._animation = animation; },
enumerable: false,
configurable: true
});
return NgbAccordionConfig;
}());
NgbAccordionConfig.ɵprov = i0.ɵɵdefineInjectable({ factory: function NgbAccordionConfig_Factory() { return new NgbAccordionConfig(i0.ɵɵinject(NgbConfig)); }, token: NgbAccordionConfig, providedIn: "root" });
NgbAccordionConfig.decorators = [
{ type: i0.Injectable, args: [{ providedIn: 'root' },] }
];
NgbAccordionConfig.ctorParameters = function () { return [
{ type: NgbConfig }
]; };
function getTransitionDurationMs(element) {
var _a = window.getComputedStyle(element), transitionDelay = _a.transitionDelay, transitionDuration = _a.transitionDuration;
var transitionDelaySec = parseFloat(transitionDelay);
var transitionDurationSec = parseFloat(transitionDuration);
return (transitionDelaySec + transitionDurationSec) * 1000;
}
var noopFn = function () { };
var ɵ0 = noopFn;
var transitionTimerDelayMs = environment.transitionTimerDelayMs;
var runningTransitions = new Map();
var ngbRunTransition = function (zone, element, startFn, options) {
// Getting initial context from options
var context = options.context || {};
// Checking if there are already running transitions on the given element.
var running = runningTransitions.get(element);
if (running) {
switch (options.runningTransition) {
// If there is one running and we want for it to 'continue' to run, we have to cancel the new one.
// We're not emitting any values, but simply completing the observable (EMPTY).
case 'continue':
return rxjs.EMPTY;
// If there is one running and we want for it to 'stop', we have to complete the running one.
// We're simply completing the running one and not emitting any values and merging newly provided context
// with the one coming from currently running transition.
case 'stop':
zone.run(function () { return running.transition$.complete(); });
context = Object.assign(running.context, context);
runningTransitions.delete(element);
}
}
// Running the start function
var endFn = startFn(element, options.animation, context) || noopFn;
// If 'prefer-reduced-motion' is enabled, the 'transition' will be set to 'none'.
// If animations are disabled, we have to emit a value and complete the observable
// In this case we have to call the end function, but can finish immediately by emitting a value,
// completing the observable and executing end functions synchronously.
if (!options.animation || window.getComputedStyle(element).transitionProperty === 'none') {
zone.run(function () { return endFn(); });
return rxjs.of(undefined).pipe(runInZone(zone));
}
// Starting a new transition
var transition$ = new rxjs.Subject();
var finishTransition$ = new rxjs.Subject();
var stop$ = transition$.pipe(operators.endWith(true));
runningTransitions.set(element, {
transition$: transition$,
complete: function () {
finishTransition$.next();
finishTransition$.complete();
},
context: context
});
var transitionDurationMs = getTransitionDurationMs(element);
// 1. We have to both listen for the 'transitionend' event and have a 'just-in-case' timer,
// because 'transitionend' event might not be fired in some browsers, if the transitioning
// element becomes invisible (ex. when scrolling, making browser tab inactive, etc.). The timer
// guarantees, that we'll release the DOM element and complete 'ngbRunTransition'.
// 2. We need to filter transition end events, because they might bubble from shorter transitions
// on inner DOM elements. We're only interested in the transition on the 'element' itself.
zone.runOutsideAngular(function () {
var transitionEnd$ = rxjs.fromEvent(element, 'transitionend').pipe(operators.takeUntil(stop$), operators.filter(function (_b) {
var target = _b.target;
return target === element;
}));
var timer$ = rxjs.timer(transitionDurationMs + transitionTimerDelayMs).pipe(operators.takeUntil(stop$));
rxjs.race(timer$, transitionEnd$, finishTransition$).pipe(operators.takeUntil(stop$)).subscribe(function () {
runningTransitions.delete(element);
zone.run(function () {
endFn();
transition$.next();
transition$.complete();
});
});
});
return transition$.asObservable();
};
var ngbCompleteTransition = function (element) {
var _a;
(_a = runningTransitions.get(element)) === null || _a === void 0 ? void 0 : _a.complete();
};
function measureCollapsingElementHeightPx(element) {
// SSR fix for without injecting the PlatformId
if (typeof navigator === 'undefined') {
return '0px';
}
var classList = element.classList;
var hasShownClass = classList.contains('show');
if (!hasShownClass) {
classList.add('show');
}
element.style.height = '';
var height = element.getBoundingClientRect().height + 'px';
if (!hasShownClass) {
classList.remove('show');
}
return height;
}
var ngbCollapsingTransition = function (element, animation, context) {
var direction = context.direction, maxHeight = context.maxHeight;
var classList = element.classList;
function setInitialClasses() {
classList.add('collapse');
if (direction === 'show') {
classList.add('show');
}
else {
classList.remove('show');
}
}
// without animations we just need to set initial classes
if (!animation) {
setInitialClasses();
return;
}
// No maxHeight -> running the transition for the first time
if (!maxHeight) {
maxHeight = measureCollapsingElementHeightPx(element);
context.maxHeight = maxHeight;
// Fix the height before starting the animation
element.style.height = direction !== 'show' ? maxHeight : '0px';
classList.remove('collapse');
classList.remove('collapsing');
classList.remove('show');
reflow(element);
// Start the animation
classList.add('collapsing');
}
// Start or revert the animation
element.style.height = direction === 'show' ? maxHeight : '0px';
return function () {
setInitialClasses();
classList.remove('collapsing');
element.style.height = '';
};
};
var nextId = 0;
/**
* A directive that wraps an accordion panel header with any HTML markup and a toggling button
* marked with [`NgbPanelToggle`](#/components/accordion/api#NgbPanelToggle).
* See the [header customization demo](#/components/accordion/examples#header) for more details.
*
* You can also use [`NgbPanelTitle`](#/components/accordion/api#NgbPanelTitle) to customize only the panel title.
*
* @since 4.1.0
*/
var NgbPanelHeader = /** @class */ (function () {
function NgbPanelHeader(templateRef) {
this.templateRef = templateRef;
}
return NgbPanelHeader;
}());
NgbPanelHeader.decorators = [
{ type: i0.Directive, args: [{ selector: 'ng-template[ngbPanelHeader]' },] }
];
NgbPanelHeader.ctorParameters = function () { return [
{ type: i0.TemplateRef }
]; };
/**
* A directive that wraps only the panel title with HTML markup inside.
*
* You can also use [`NgbPanelHeader`](#/components/accordion/api#NgbPanelHeader) to customize the full panel header.
*/
var NgbPanelTitle = /** @class */ (function () {
function NgbPanelTitle(templateRef) {
this.templateRef = templateRef;
}
return NgbPanelTitle;
}());
NgbPanelTitle.decorators = [
{ type: i0.Directive, args: [{ selector: 'ng-template[ngbPanelTitle]' },] }
];
NgbPanelTitle.ctorParameters = function () { return [
{ type: i0.TemplateRef }
]; };
/**
* A directive that wraps the accordion panel content.
*/
var NgbPanelContent = /** @class */ (function () {
function NgbPanelContent(templateRef) {
this.templateRef = templateRef;
}
return NgbPanelContent;
}());
NgbPanelContent.decorators = [
{ type: i0.Directive, args: [{ selector: 'ng-template[ngbPanelContent]' },] }
];
NgbPanelContent.ctorParameters = function () { return [
{ type: i0.TemplateRef }
]; };
/**
* A directive that wraps an individual accordion panel with title and collapsible content.
*/
var NgbPanel = /** @class */ (function () {
function NgbPanel() {
/**
* If `true`, the panel is disabled an can't be toggled.
*/
this.disabled = false;
/**
* An optional id for the panel that must be unique on the page.
*
* If not provided, it will be auto-generated in the `ngb-panel-xxx` format.
*/
this.id = "ngb-panel-" + nextId++;
this.isOpen = false;
/* A flag to specified that the transition panel classes have been initialized */
this.initClassDone = false;
/* A flag to specified if the panel is currently being animated, to ensure its presence in the dom */
this.transitionRunning = false;
/**
* An event emitted when the panel is shown, after the transition. It has no payload.
*
* @since 8.0.0
*/
this.shown = new i0.EventEmitter();
/**
* An event emitted when the panel is hidden, after the transition. It has no payload.
*
* @since 8.0.0
*/
this.hidden = new i0.EventEmitter();
}
NgbPanel.prototype.ngAfterContentChecked = function () {
// We are using @ContentChildren instead of @ContentChild as in the Angular version being used
// only @ContentChildren allows us to specify the {descendants: false} option.
// Without {descendants: false} we are hitting bugs described in:
// https://github.com/ng-bootstrap/ng-bootstrap/issues/2240
this.titleTpl = this.titleTpls.first;
this.headerTpl = this.headerTpls.first;
this.contentTpl = this.contentTpls.first;
};
return NgbPanel;
}());
NgbPanel.decorators = [
{ type: i0.Directive, args: [{ selector: 'ngb-panel' },] }
];
NgbPanel.propDecorators = {
disabled: [{ type: i0.Input }],
id: [{ type: i0.Input }],
title: [{ type: i0.Input }],
type: [{ type: i0.Input }],
cardClass: [{ type: i0.Input }],
shown: [{ type: i0.Output }],
hidden: [{ type: i0.Output }],
titleTpls: [{ type: i0.ContentChildren, args: [NgbPanelTitle, { descendants: false },] }],
headerTpls: [{ type: i0.ContentChildren, args: [NgbPanelHeader, { descendants: false },] }],
contentTpls: [{ type: i0.ContentChildren, args: [NgbPanelContent, { descendants: false },] }]
};
/**
* Accordion is a collection of collapsible panels (bootstrap cards).
*
* It can ensure only one panel is opened at a time and allows to customize panel
* headers.
*/
var NgbAccordion = /** @class */ (function () {
function NgbAccordion(config, _element, _ngZone, _changeDetector) {
this._element = _element;
this._ngZone = _ngZone;
this._changeDetector = _changeDetector;
/**
* An array or comma separated strings of panel ids that should be opened **initially**.
*
* For subsequent changes use methods like `expand()`, `collapse()`, etc. and
* the `(panelChange)` event.
*/
this.activeIds = [];
/**
* If `true`, panel content will be detached from DOM and not simply hidden when the panel is collapsed.
*/
this.destroyOnHide = true;
/**
* Event emitted right before the panel toggle happens.
*
* See [NgbPanelChangeEvent](#/components/accordion/api#NgbPanelChangeEvent) for payload details.
*/
this.panelChange = new i0.EventEmitter();
/**
* An event emitted when the expanding animation is finished on the panel. The payload is the panel id.
*
* @since 8.0.0
*/
this.shown = new i0.EventEmitter();
/**
* An event emitted when the collapsing animation is finished on the panel, and before the panel element is removed.
* The payload is the panel id.
*
* @since 8.0.0
*/
this.hidden = new i0.EventEmitter();
this.animation = config.animation;
this.type = config.type;
this.closeOtherPanels = config.closeOthers;
}
/**
* Checks if a panel with a given id is expanded.
*/
NgbAccordion.prototype.isExpanded = function (panelId) { return this.activeIds.indexOf(panelId) > -1; };
/**
* Expands a panel with a given id.
*
* Has no effect if the panel is already expanded or disabled.
*/
NgbAccordion.prototype.expand = function (panelId) { this._changeOpenState(this._findPanelById(panelId), true); };
/**
* Expands all panels, if `[closeOthers]` is `false`.
*
* If `[closeOthers]` is `true`, it will expand the first panel, unless there is already a panel opened.
*/
NgbAccordion.prototype.expandAll = function () {
var _this = this;
if (this.closeOtherPanels) {
if (this.activeIds.length === 0 && this.panels.length) {
this._changeOpenState(this.panels.first, true);
}
}
else {
this.panels.forEach(function (panel) { return _this._changeOpenState(panel, true); });
}
};
/**
* Collapses a panel with the given id.
*
* Has no effect if the panel is already collapsed or disabled.
*/
NgbAccordion.prototype.collapse = function (panelId) { this._changeOpenState(this._findPanelById(panelId), false); };
/**
* Collapses all opened panels.
*/
NgbAccordion.prototype.collapseAll = function () {
var _this = this;
this.panels.forEach(function (panel) { _this._changeOpenState(panel, false); });
};
/**
* Toggles a panel with the given id.
*
* Has no effect if the panel is disabled.
*/
NgbAccordion.prototype.toggle = function (panelId) {
var panel = this._findPanelById(panelId);
if (panel) {
this._changeOpenState(panel, !panel.isOpen);
}
};
NgbAccordion.prototype.ngAfterContentChecked = function () {
var _this = this;
// active id updates
if (isString(this.activeIds)) {
this.activeIds = this.activeIds.split(/\s*,\s*/);
}
// update panels open states
this.panels.forEach(function (panel) { panel.isOpen = !panel.disabled && _this.activeIds.indexOf(panel.id) > -1; });
// closeOthers updates
if (this.activeIds.length > 1 && this.closeOtherPanels) {
this._closeOthers(this.activeIds[0], false);
this._updateActiveIds();
}
// Setup the initial classes here
this._ngZone.onStable.pipe(operators.take(1)).subscribe(function () {
_this.panels.forEach(function (panel) {
var panelElement = _this._getPanelElement(panel.id);
if (panelElement) {
if (!panel.initClassDone) {
panel.initClassDone = true;
ngbRunTransition(_this._ngZone, panelElement, ngbCollapsingTransition, {
animation: false,
runningTransition: 'continue',
context: { direction: panel.isOpen ? 'show' : 'hide' }
});
}
}
else {
// Classes must be initialized next time it will be in the dom
panel.initClassDone = false;
}
});
});
};
NgbAccordion.prototype._changeOpenState = function (panel, nextState) {
if (panel != null && !panel.disabled && panel.isOpen !== nextState) {
var defaultPrevented_1 = false;
this.panelChange.emit({ panelId: panel.id, nextState: nextState, preventDefault: function () { defaultPrevented_1 = true; } });
if (!defaultPrevented_1) {
panel.isOpen = nextState;
panel.transitionRunning = true;
if (nextState && this.closeOtherPanels) {
this._closeOthers(panel.id);
}
this._updateActiveIds();
this._runTransitions(this.animation);
}
}
};
NgbAccordion.prototype._closeOthers = function (panelId, enableTransition) {
if (enableTransition === void 0) { enableTransition = true; }
this.panels.forEach(function (panel) {
if (panel.id !== panelId && panel.isOpen) {
panel.isOpen = false;
panel.transitionRunning = enableTransition;
}
});
};
NgbAccordion.prototype._findPanelById = function (panelId) { return this.panels.find(function (p) { return p.id === panelId; }) || null; };
NgbAccordion.prototype._updateActiveIds = function () {
this.activeIds = this.panels.filter(function (panel) { return panel.isOpen && !panel.disabled; }).map(function (panel) { return panel.id; });
};
NgbAccordion.prototype._runTransitions = function (animation) {
var _this = this;
// detectChanges is performed to ensure that all panels are in the dom (via transitionRunning = true)
// before starting the animation
this._changeDetector.detectChanges();
this.panels.forEach(function (panel) {
// When panel.transitionRunning is true, the transition needs to be started OR reversed,
// The direction (show or hide) is choosen by each panel.isOpen state
if (panel.transitionRunning) {
var panelElement = _this._getPanelElement(panel.id);
ngbRunTransition(_this._ngZone, panelElement, ngbCollapsingTransition, {
animation: animation,
runningTransition: 'stop',
context: { direction: panel.isOpen ? 'show' : 'hide' }
}).subscribe(function () {
panel.transitionRunning = false;
var id = panel.id;
if (panel.isOpen) {
panel.shown.emit();
_this.shown.emit(id);
}
else {
panel.hidden.emit();
_this.hidden.emit(id);
}
});
}
});
};
NgbAccordion.prototype._getPanelElement = function (panelId) {
return this._element.nativeElement.querySelector('#' + panelId);
};
return NgbAccordion;
}());
NgbAccordion.decorators = [
{ type: i0.Component, args: [{
selector: 'ngb-accordion',
exportAs: 'ngbAccordion',
encapsulation: i0.ViewEncapsulation.None,
host: { 'class': 'accordion', 'role': 'tablist', '[attr.aria-multiselectable]': '!closeOtherPanels' },
template: "\n <ng-template #t ngbPanelHeader let-panel>\n <button class=\"btn btn-link\" [ngbPanelToggle]=\"panel\">\n {{panel.title}}<ng-template [ngTemplateOutlet]=\"panel.titleTpl?.templateRef\"></ng-template>\n </button>\n </ng-template>\n <ng-template ngFor let-panel [ngForOf]=\"panels\">\n <div [class]=\"'card ' + (panel.cardClass || '')\">\n <div role=\"tab\" id=\"{{panel.id}}-header\" [class]=\"'card-header ' + (panel.type ? 'bg-'+panel.type: type ? 'bg-'+type : '')\">\n <ng-template [ngTemplateOutlet]=\"panel.headerTpl?.templateRef || t\"\n [ngTemplateOutletContext]=\"{$implicit: panel, opened: panel.isOpen}\"></ng-template>\n </div>\n <div id=\"{{panel.id}}\" role=\"tabpanel\" [attr.aria-labelledby]=\"panel.id + '-header'\"\n *ngIf=\"!destroyOnHide || panel.isOpen || panel.transitionRunning\">\n <div class=\"card-body\">\n <ng-template [ngTemplateOutlet]=\"panel.contentTpl?.templateRef || null\"></ng-template>\n </div>\n </div>\n </div>\n </ng-template>\n "
},] }
];
NgbAccordion.ctorParameters = function () { return [
{ type: NgbAccordionConfig },
{ type: i0.ElementRef },
{ type: i0.NgZone },
{ type: i0.ChangeDetectorRef }
]; };
NgbAccordion.propDecorators = {
panels: [{ type: i0.ContentChildren, args: [NgbPanel,] }],
animation: [{ type: i0.Input }],
activeIds: [{ type: i0.Input }],
closeOtherPanels: [{ type: i0.Input, args: ['closeOthers',] }],
destroyOnHide: [{ type: i0.Input }],
type: [{ type: i0.Input }],
panelChange: [{ type: i0.Output }],
shown: [{ type: i0.Output }],
hidden: [{ type: i0.Output }]
};
/**
* A directive to put on a button that toggles panel opening and closing.
*
* To be used inside the [`NgbPanelHeader`](#/components/accordion/api#NgbPanelHeader)
*
* @since 4.1.0
*/
var NgbPanelToggle = /** @class */ (function () {
function NgbPanelToggle(accordion, panel) {
this.accordion = accordion;
this.panel = panel;
}
Object.defineProperty(NgbPanelToggle.prototype, "ngbPanelToggle", {
set: function (panel) {
if (panel) {
this.panel = panel;
}
},
enumerable: false,
configurable: true
});
return NgbPanelToggle;
}());
NgbPanelToggle.decorators = [
{ type: i0.Directive, args: [{
selector: 'button[ngbPanelToggle]',
host: {
'type': 'button',
'[disabled]': 'panel.disabled',
'[class.collapsed]': '!panel.isOpen',
'[attr.aria-expanded]': 'panel.isOpen',
'[attr.aria-controls]': 'panel.id',
'(click)': 'accordion.toggle(panel.id)'
}
},] }
];
NgbPanelToggle.ctorParameters = function () { return [
{ type: NgbAccordion },
{ type: NgbPanel, decorators: [{ type: i0.Optional }, { type: i0.Host }] }
]; };
NgbPanelToggle.propDecorators = {
ngbPanelToggle: [{ type: i0.Input }]
};
var NGB_ACCORDION_DIRECTIVES = [NgbAccordion, NgbPanel, NgbPanelTitle, NgbPanelContent, NgbPanelHeader, NgbPanelToggle];
var NgbAccordionModule = /** @class */ (function () {
function NgbAccordionModule() {
}
return NgbAccordionModule;
}());
NgbAccordionModule.decorators = [
{ type: i0.NgModule, args: [{ declarations: NGB_ACCORDION_DIRECTIVES, exports: NGB_ACCORDION_DIRECTIVES, imports: [i1.CommonModule] },] }
];
/**
* A configuration service for the [NgbAlert](#/components/alert/api#NgbAlert) component.
*
* You can inject this service, typically in your root component, and customize its properties
* to provide default values for all alerts used in the application.
*/
var NgbAlertConfig = /** @class */ (function () {
function NgbAlertConfig(_ngbConfig) {
this._ngbConfig = _ngbConfig;
this.dismissible = true;
this.type = 'warning';
}
Object.defineProperty(NgbAlertConfig.prototype, "animation", {
get: function () { return (this._animation === undefined) ? this._ngbConfig.animation : this._animation; },
set: function (animation) { this._animation = animation; },
enumerable: false,
configurable: true
});
return NgbAlertConfig;
}());
NgbAlertConfig.ɵprov = i0.ɵɵdefineInjectable({ factory: function NgbAlertConfig_Factory() { return new NgbAlertConfig(i0.ɵɵinject(NgbConfig)); }, token: NgbAlertConfig, providedIn: "root" });
NgbAlertConfig.decorators = [
{ type: i0.Injectable, args: [{ providedIn: 'root' },] }
];
NgbAlertConfig.ctorParameters = function () { return [
{ type: NgbConfig }
]; };
var ngbAlertFadingTransition = function (_a) {
var classList = _a.classList;
classList.remove('show');
};
/**
* Alert is a component to provide contextual feedback messages for user.
*
* It supports several alert types and can be dismissed.
*/
var NgbAlert = /** @class */ (function () {
function NgbAlert(config, _renderer, _element, _zone) {
this._renderer = _renderer;
this._element = _element;
this._zone = _zone;
/**
* An event emitted when the close button is clicked. It has no payload and only relevant for dismissible alerts.
*
* @since 8.0.0
*/
this.closed = new i0.EventEmitter();
this.dismissible = config.dismissible;
this.type = config.type;
this.animation = config.animation;
}
/**
* Triggers alert closing programmatically (same as clicking on the close button (×)).
*
* The returned observable will emit and be completed once the closing transition has finished.
* If the animations are turned off this happens synchronously.
*
* Alternatively you could listen or subscribe to the `(closed)` output
*
* @since 8.0.0
*/
NgbAlert.prototype.close = function () {
var _this = this;
var transition = ngbRunTransition(this._zone, this._element.nativeElement, ngbAlertFadingTransition, { animation: this.animation, runningTransition: 'continue' });
transition.subscribe(function () { return _this.closed.emit(); });
return transition;
};
NgbAlert.prototype.ngOnChanges = function (changes) {
var typeChange = changes['type'];
if (typeChange && !typeChange.firstChange) {
this._renderer.removeClass(this._element.nativeElement, "alert-" + typeChange.previousValue);
this._renderer.addClass(this._element.nativeElement, "alert-" + typeChange.currentValue);
}
};
NgbAlert.prototype.ngOnInit = function () { this._renderer.addClass(this._element.nativeElement, "alert-" + this.type); };
return NgbAlert;
}());
NgbAlert.decorators = [
{ type: i0.Component, args: [{
selector: 'ngb-alert',
exportAs: 'ngbAlert',
changeDetection: i0.ChangeDetectionStrategy.OnPush,
encapsulation: i0.ViewEncapsulation.None,
host: { 'role': 'alert', 'class': 'alert show', '[class.fade]': 'animation', '[class.alert-dismissible]': 'dismissible' },
template: "\n <ng-content></ng-content>\n <button *ngIf=\"dismissible\" type=\"button\" class=\"close\" aria-label=\"Close\" i18n-aria-label=\"@@ngb.alert.close\"\n (click)=\"close()\">\n <span aria-hidden=\"true\">×</span>\n </button>\n ",
styles: ["ngb-alert{display:block}"]
},] }
];
NgbAlert.ctorParameters = function () { return [
{ type: NgbAlertConfig },
{ type: i0.Renderer2 },
{ type: i0.ElementRef },
{ type: i0.NgZone }
]; };
NgbAlert.propDecorators = {
animation: [{ type: i0.Input }],
dismissible: [{ type: i0.Input }],
type: [{ type: i0.Input }],
closed: [{ type: i0.Output }]
};
var NgbAlertModule = /** @class */ (function () {
function NgbAlertModule() {
}
return NgbAlertModule;
}());
NgbAlertModule.decorators = [
{ type: i0.NgModule, args: [{ declarations: [NgbAlert], exports: [NgbAlert], imports: [i1.CommonModule], entryComponents: [NgbAlert] },] }
];
var NgbButtonLabel = /** @class */ (function () {
function NgbButtonLabel() {
}
return NgbButtonLabel;
}());
NgbButtonLabel.decorators = [
{ type: i0.Directive, args: [{
selector: '[ngbButtonLabel]',
host: { '[class.btn]': 'true', '[class.active]': 'active', '[class.disabled]': 'disabled', '[class.focus]': 'focused' }
},] }
];
/**
* Allows to easily create Bootstrap-style checkbox buttons.
*
* Integrates with forms, so the value of a checked button is bound to the underlying form control
* either in a reactive or template-driven way.
*/
var NgbCheckBox = /** @class */ (function () {
function NgbCheckBox(_label, _cd) {
this._label = _label;
this._cd = _cd;
/**
* If `true`, the checkbox button will be disabled
*/
this.disabled = false;
/**
* The form control value when the checkbox is checked.
*/
this.valueChecked = true;
/**
* The form control value when the checkbox is unchecked.
*/
this.valueUnChecked = false;
this.onChange = function (_) { };
this.onTouched = function () { };
}
Object.defineProperty(NgbCheckBox.prototype, "focused", {
set: function (isFocused) {
this._label.focused = isFocused;
if (!isFocused) {
this.onTouched();
}
},
enumerable: false,
configurable: true
});
NgbCheckBox.prototype.onInputChange = function ($event) {
var modelToPropagate = $event.target.checked ? this.valueChecked : this.valueUnChecked;
this.onChange(modelToPropagate);
this.onTouched();
this.writeValue(modelToPropagate);
};
NgbCheckBox.prototype.registerOnChange = function (fn) { this.onChange = fn; };
NgbCheckBox.prototype.registerOnTouched = function (fn) { this.onTouched = fn; };
NgbCheckBox.prototype.setDisabledState = function (isDisabled) {
this.disabled = isDisabled;
this._label.disabled = isDisabled;
};
NgbCheckBox.prototype.writeValue = function (value) {
this.checked = value === this.valueChecked;
this._label.active = this.checked;
// label won't be updated, if it is inside the OnPush component when [ngModel] changes
this._cd.markForCheck();
};
return NgbCheckBox;
}());
NgbCheckBox.decorators = [
{ type: i0.Directive, args: [{
selector: '[ngbButton][type=checkbox]',
host: {
'[checked]': 'checked',
'[disabled]': 'disabled',
'(change)': 'onInputChange($event)',
'(focus)': 'focused = true',
'(blur)': 'focused = false'
},
providers: [{ provide: forms.NG_VALUE_ACCESSOR, useExisting: i0.forwardRef(function () { return NgbCheckBox; }), multi: true }]
},] }
];
NgbCheckBox.ctorParameters = function () { return [
{ type: NgbButtonLabel },
{ type: i0.ChangeDetectorRef }
]; };
NgbCheckBox.propDecorators = {
disabled: [{ type: i0.Input }],
valueChecked: [{ type: i0.Input }],
valueUnChecked: [{ type: i0.Input }]
};
var nextId$1 = 0;
/**
* Allows to easily create Bootstrap-style radio buttons.
*
* Integrates with forms, so the value of a checked button is bound to the underlying form control
* either in a reactive or template-driven way.
*/
var NgbRadioGroup = /** @class */ (function () {
function NgbRadioGroup() {
this._radios = new Set();
this._value = null;
/**
* Name of the radio group applied to radio input elements.
*
* Will be applied to all radio input elements inside the group,
* unless [`NgbRadio`](#/components/buttons/api#NgbRadio)'s specify names themselves.
*
* If not provided, will be generated in the `ngb-radio-xx` format.
*/
this.name = "ngb-radio-" + nextId$1++;
this.onChange = function (_) { };
this.onTouched = function () { };
}
Object.defineProperty(NgbRadioGroup.prototype, "disabled", {
get: function () { return this._disabled; },
set: function (isDisabled) { this.setDisabledState(isDisabled); },
enumerable: false,
configurable: true
});
NgbRadioGroup.prototype.onRadioChange = function (radio) {
this.writeValue(radio.value);
this.onChange(radio.value);
};
NgbRadioGroup.prototype.onRadioValueUpdate = function () { this._updateRadiosValue(); };
NgbRadioGroup.prototype.register = function (radio) { this._radios.add(radio); };
NgbRadioGroup.prototype.registerOnChange = function (fn) { this.onChange = fn; };
NgbRadioGroup.prototype.registerOnTouched = function (fn) { this.onTouched = fn; };
NgbRadioGroup.prototype.setDisabledState = function (isDisabled) {
this._disabled = isDisabled;
this._updateRadiosDisabled();
};
NgbRadioGroup.prototype.unregister = function (radio) { this._radios.delete(radio); };
NgbRadioGroup.prototype.writeValue = function (value) {
this._value = value;
this._updateRadiosValue();
};
NgbRadioGroup.prototype._updateRadiosValue = function () {
var _this = this;
this._radios.forEach(function (radio) { return radio.updateValue(_this._value); });
};
NgbRadioGroup.prototype._updateRadiosDisabled = function () { this._radios.forEach(function (radio) { return radio.updateDisabled(); }); };
return NgbRadioGroup;
}());
NgbRadioGroup.decorators = [
{ type: i0.Directive, args: [{
selector: '[ngbRadioGroup]',
host: { 'role': 'radiogroup' },
providers: [{ provide: forms.NG_VALUE_ACCESSOR, useExisting: i0.forwardRef(function () { return NgbRadioGroup; }), multi: true }]
},] }
];
NgbRadioGroup.propDecorators = {
name: [{ type: i0.Input }]
};
/**
* A directive that marks an input of type "radio" as a part of the
* [`NgbRadioGroup`](#/components/buttons/api#NgbRadioGroup).
*/
var NgbRadio = /** @class */ (function () {
function NgbRadio(_group, _label, _renderer, _element, _cd) {
this._group = _group;
this._label = _label;
this._renderer = _renderer;
this._element = _element;
this._cd = _cd;
this._value = null;
this._group.register(this);
this.updateDisabled();
}
Object.defineProperty(NgbRadio.prototype, "value", {
get: function () { return this._value; },
/**
* The form control value when current radio button is checked.
*/
set: function (value) {
this._value = value;
var stringValue = value ? value.toString() : '';
this._renderer.setProperty(this._element.nativeElement, 'value', stringValue);
this._group.onRadioValueUpdate();
},
enumerable: false,
configurable: true
});
Object.defineProperty(NgbRadio.prototype, "disabled", {
get: function () { return this._group.disabled || this._disabled; },
/**
* If `true`, current radio button will be disabled.
*/
set: function (isDisabled) {
this._disabled = isDisabled !== false;
this.updateDisabled();
},
enumerable: false,
configurable: true
});
Object.defineProperty(NgbRadio.prototype, "focused", {
set: function (isFocused) {
if (this._label) {
this._label.focused = isFocused;
}
if (!isFocused) {
this._group.onTouched();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(NgbRadio.prototype, "checked", {
get: function () { return this._checked; },
enumerable: false,
configurable: true
});
Object.defineProperty(NgbRadio.prototype, "nameAttr", {
get: function () { return this.name || this._group.name; },
enumerable: false,
configurable: true
});
NgbRadio.prototype.ngOnDestroy = function () { this._group.unregister(this); };
NgbRadio.prototype.onChange = function () { this._group.onRadioChange(this); };
NgbRadio.prototype.updateValue = function (value) {
// label won't be updated, if it is inside the OnPush component when [ngModel] changes
if (this.value !== value) {
this._cd.markForCheck();
}
this._checked = this.value === value;
this._label.active = this._checked;
};
NgbRadio.prototype.updateDisabled = function () { this._label.disabled = this.disabled; };
return NgbRadio;
}());
NgbRadio.decorators = [
{ type: i0.Directive, args: [{
selector: '[ngbButton][type=radio]',
host: {
'[checked]': 'checked',
'[disabled]': 'disabled',
'[name]': 'nameAttr',
'(change)': 'onChange()',
'(focus)': 'focused = true',
'(blur)': 'focused = false'
}
},] }
];
NgbRadio.ctorParameters = function () { return [
{ type: NgbRadioGroup },
{ type: NgbButtonLabel },
{ type: i0.Renderer2 },
{ type: i0.ElementRef },
{ type: i0.ChangeDetectorRef }
]; };
NgbRadio.propDecorators = {
name: [{ type: i0.Input }],
value: [{ type: i0.Input, args: ['value',] }],
disabled: [{ type: i0.Input, args: ['disabled',] }]
};
var NGB_BUTTON_DIRECTIVES = [NgbButtonLabel, NgbCheckBox, NgbRadioGroup, NgbRadio];
var NgbButtonsModule = /** @class */ (function () {
function NgbButtonsModule() {
}
return NgbButtonsModule;
}());
NgbButtonsModule.decorators = [
{ type: i0.NgModule, args: [{ declarations: NGB_BUTTON_DIRECTIVES, exports: NGB_BUTTON_DIRECTIVES },] }
];
/*! *****************************************************************************
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) {
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 (ta