UNPKG

@clr/angular

Version:

Angular components for Clarity

352 lines (343 loc) 14.5 kB
import * as i0 from '@angular/core'; import { InjectionToken, Injectable, EventEmitter, Input, Output, Inject, Directive, Optional, NgModule } from '@angular/core'; import { Subject } from 'rxjs'; import { ClrLoadingState } from '@clr/angular/utils/loading'; import { CommonModule } from '@angular/common'; /* * Copyright (c) 2016-2026 Broadcom. All Rights Reserved. * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. * This software is released under MIT license. * The full license information can be found in LICENSE in the root directory of this project. */ let activeCounter = 0; const IF_ACTIVE_ID = new InjectionToken('IF_ACTIVE_ID'); function tokenFactory() { return ++activeCounter; } const IF_ACTIVE_ID_PROVIDER = { provide: IF_ACTIVE_ID, useFactory: tokenFactory, }; /********* * @class IfActiveService * * @description * An injectable service used by IfActive structural directives and the components that implement IfActive in their * templates. It holds the value of the current state and provides an Observable that both the directive and the * implementing component can subscribe to in order to take action on current value changes. * */ class IfActiveService { constructor() { /******** * @property _currentChange * * @description * A RXJS Subject that updates and provides subscriptions to for the current current state of a component template * implemting the IfActive structural directive. * */ this._currentChange = new Subject(); } /********* * * @description * A getter function that provides an observable for the _current Subject. * */ get currentChange() { return this._currentChange.asObservable(); } /********* * * @description * A property that gets/sets the current state of _current for this instance of IfActive structural directive. * And, broadcasts the new value to all subscribers. * */ get current() { return this._current; } set current(value) { if (this._current !== value) { this._current = value; this._currentChange.next(value); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: IfActiveService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: IfActiveService }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: IfActiveService, decorators: [{ type: Injectable }] }); /* * Copyright (c) 2016-2026 Broadcom. All Rights Reserved. * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. * This software is released under MIT license. * The full license information can be found in LICENSE in the root directory of this project. */ /********** * * @class ClrIfActive * * @description * A structural directive that controls whether or not the associated TemplateRef is instantiated or not. * It makes use of a Component instance level service: IfActiveService to maintain state between itself and * the component using it in the component template. * */ class ClrIfActive { constructor(ifActiveService, id, template, container) { this.ifActiveService = ifActiveService; this.id = id; this.template = template; this.container = container; /********** * @property activeChange * * @description * An event emitter that emits when the active property is set to allow for 2way binding when the directive is * used with de-structured / de-sugared syntax. * */ this.activeChange = new EventEmitter(false); this.wasActive = false; this.checkAndUpdateView(ifActiveService.current); this.subscription = ifActiveService.currentChange.subscribe(newCurrentId => { this.checkAndUpdateView(newCurrentId); }); } /** * @description * A property that gets/sets IfActiveService.active with value. * */ get active() { return this.ifActiveService.current === this.id; } set active(value) { if (value) { this.ifActiveService.current = this.id; } } ngOnDestroy() { this.subscription.unsubscribe(); } /** * @description * Function that takes a any value and either created an embedded view for the associated ViewContainerRef or, * Clears all views from the ViewContainerRef */ updateView(value) { if (value) { this.container.createEmbeddedView(this.template); } else { this.container.clear(); } } checkAndUpdateView(currentId) { const isNowActive = currentId === this.id; // only emit if the new active state is changed since last time. if (isNowActive !== this.wasActive) { this.updateView(isNowActive); this.activeChange.emit(isNowActive); this.wasActive = isNowActive; } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrIfActive, deps: [{ token: IfActiveService }, { token: IF_ACTIVE_ID }, { token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.3", type: ClrIfActive, isStandalone: true, selector: "[clrIfActive]", inputs: { active: ["clrIfActive", "active"] }, outputs: { activeChange: "clrIfActiveChange" }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrIfActive, decorators: [{ type: Directive, args: [{ selector: '[clrIfActive]', }] }], ctorParameters: () => [{ type: IfActiveService }, { type: undefined, decorators: [{ type: Inject, args: [IF_ACTIVE_ID] }] }, { type: i0.TemplateRef }, { type: i0.ViewContainerRef }], propDecorators: { activeChange: [{ type: Output, args: ['clrIfActiveChange'] }], active: [{ type: Input, args: ['clrIfActive'] }] } }); /* * Copyright (c) 2016-2026 Broadcom. All Rights Reserved. * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. * This software is released under MIT license. * The full license information can be found in LICENSE in the root directory of this project. */ class IfExpandService { constructor() { this.expandable = 0; this.hasExpandTemplate = false; this._loading = false; this._expanded = false; this._expandChange = new Subject(); } get loading() { return this._loading; } set loading(value) { value = !!value; if (value !== this._loading) { this._loading = value; } } get expanded() { return this._expanded; } set expanded(value) { value = !!value; if (value !== this._expanded) { this._expanded = value; this._expandChange.next(value); } } get expandChange() { return this._expandChange.asObservable(); } toggle() { this.expanded = !this._expanded; } loadingStateChange(state) { switch (state) { case ClrLoadingState.LOADING: this.loading = true; break; default: this.loading = false; break; } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: IfExpandService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: IfExpandService }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: IfExpandService, decorators: [{ type: Injectable }] }); /* * Copyright (c) 2016-2026 Broadcom. All Rights Reserved. * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. * This software is released under MIT license. * The full license information can be found in LICENSE in the root directory of this project. */ class ClrIfExpanded { constructor(template, container, el, renderer, expand) { this.template = template; this.container = container; this.el = el; this.renderer = renderer; this.expand = expand; this.expandedChange = new EventEmitter(true); this._expanded = false; /** * Subscriptions to all the services and queries changes */ this._subscriptions = []; this._subscriptions.push(expand.expandChange.subscribe(() => { this.updateView(); this.expandedChange.emit(expand.expanded); })); expand.hasExpandTemplate = !!template; } get expanded() { return this._expanded; } set expanded(value) { if (typeof value === 'boolean') { this.expand.expanded = value; this._expanded = value; } } ngOnInit() { this.expand.expandable++; this.updateView(); } ngOnDestroy() { this.expand.expandable--; this._subscriptions.forEach((sub) => sub.unsubscribe()); } updateView() { if (this.expand.expanded && this.container.length !== 0) { return; } if (this.template) { if (this.expand.expanded) { // Should we pass a context? I don't see anything useful to pass right now, // but we can come back to it in the future as a solution for additional features. this.container.createEmbeddedView(this.template); } else { // TODO: Move when we move the animation logic to Datagrid Row Expand // We clear before the animation is over. Not ideal, but doing better would involve a much heavier // process for very little gain. Once Angular animations are dynamic enough, we should be able to // get the optimal behavior. this.container.clear(); } } else { try { // If we don't have a template ref, we fallback to a crude display: none for now. if (this.expand.expanded) { this.renderer.setStyle(this.el.nativeElement, 'display', null); } else { this.renderer.setStyle(this.el.nativeElement, 'display', 'none'); } // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (e) { // We catch the case where clrIfExpanded was put on a non-DOM element, and we just do nothing } } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrIfExpanded, deps: [{ token: i0.TemplateRef, optional: true }, { token: i0.ViewContainerRef }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: IfExpandService }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.3", type: ClrIfExpanded, isStandalone: true, selector: "[clrIfExpanded]", inputs: { expanded: ["clrIfExpanded", "expanded"] }, outputs: { expandedChange: "clrIfExpandedChange" }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrIfExpanded, decorators: [{ type: Directive, args: [{ selector: '[clrIfExpanded]', }] }], ctorParameters: () => [{ type: i0.TemplateRef, decorators: [{ type: Optional }] }, { type: i0.ViewContainerRef }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: IfExpandService }], propDecorators: { expandedChange: [{ type: Output, args: ['clrIfExpandedChange'] }], expanded: [{ type: Input, args: ['clrIfExpanded'] }] } }); /* * Copyright (c) 2016-2026 Broadcom. All Rights Reserved. * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. * This software is released under MIT license. * The full license information can be found in LICENSE in the root directory of this project. */ const CONDITIONAL_DIRECTIVES = [ClrIfActive, ClrIfExpanded]; class ClrConditionalModule { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrConditionalModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: ClrConditionalModule, imports: [CommonModule, ClrIfActive, ClrIfExpanded], exports: [ClrIfActive, ClrIfExpanded] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrConditionalModule, imports: [CommonModule] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrConditionalModule, decorators: [{ type: NgModule, args: [{ imports: [CommonModule, CONDITIONAL_DIRECTIVES], exports: [CONDITIONAL_DIRECTIVES], }] }] }); /* * Copyright (c) 2016-2026 Broadcom. All Rights Reserved. * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. * This software is released under MIT license. * The full license information can be found in LICENSE in the root directory of this project. */ /** * Generated bundle index. Do not edit. */ export { CONDITIONAL_DIRECTIVES, ClrConditionalModule, ClrIfActive, ClrIfExpanded, IF_ACTIVE_ID, IF_ACTIVE_ID_PROVIDER, IfActiveService, IfExpandService, tokenFactory }; //# sourceMappingURL=clr-angular-utils-conditional.mjs.map