@clr/angular
Version:
Angular components for Clarity
1,085 lines (1,042 loc) • 94.5 kB
JavaScript
import { FormControl, FormGroup } from '@angular/forms';
import * as i0 from '@angular/core';
import { Injectable, EventEmitter, Output, Input, Directive, NgModule, TemplateRef, ViewChild, Component, ElementRef, HostListener, HostBinding, InjectionToken, PLATFORM_ID, DOCUMENT, Inject, Optional, ContentChildren, SkipSelf, Renderer2 } from '@angular/core';
import { CommonModule, isPlatformBrowser } from '@angular/common';
import * as i2 from '@angular/animations';
import { animation, style, animate, state, transition, trigger, useAnimation } from '@angular/animations';
export * from '@clr/angular/utils/loading';
export * from '@clr/angular/utils/conditional';
import { Subject, fromEvent, Observable, isObservable, of } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import * as i1 from '@angular/cdk/a11y';
import { CdkTrapFocus } from '@angular/cdk/a11y';
import * as i2$1 from '@angular/cdk/drag-drop';
import { CdkDrag, CDK_DROP_LIST, CDK_DRAG_CONFIG } from '@angular/cdk/drag-drop';
import * as i1$1 from '@angular/cdk/bidi';
/*
* 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.
*/
function triggerAllFormControlValidation(formGroup) {
Object.keys(formGroup.controls).forEach(field => {
const control = formGroup.get(field);
if (control instanceof FormControl) {
control.markAsTouched();
control.markAsDirty();
control.updateValueAndValidity();
}
else if (control instanceof FormGroup) {
triggerAllFormControlValidation(control);
}
});
}
/*
* 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.
*/
/*
* If we someday want to be able to render the datagrid in a webworker,
* this is where we would test if we're in headless mode. Right now it's not testing anything, but any access
* to native DOM elements' methods and properties in the Datagrid happens here.
*/
class DomAdapter {
/*
We clone the element and take its measurements from outside the grid
so we don't trigger reflow for the whole datagrid.
*/
userDefinedWidth(element) {
const clonedElement = element.cloneNode(true);
if (clonedElement.id) {
clonedElement.id = clonedElement.id + '-clone';
}
clonedElement.classList.add('datagrid-cell-width-zero');
document.body.appendChild(clonedElement);
const userDefinedWidth = this.clientRect(clonedElement).width;
clonedElement.remove();
return userDefinedWidth;
}
scrollBarWidth(element) {
return element.offsetWidth - element.clientWidth;
}
scrollWidth(element) {
return element.scrollWidth || 0;
}
computedHeight(element) {
return parseInt(getComputedStyle(element).getPropertyValue('height'), 10);
}
clientRect(element) {
const elementClientRect = element.getBoundingClientRect();
return {
top: parseInt(elementClientRect.top, 10),
bottom: parseInt(elementClientRect.bottom, 10),
left: parseInt(elementClientRect.left, 10),
right: parseInt(elementClientRect.right, 10),
width: parseInt(elementClientRect.width, 10),
height: parseInt(elementClientRect.height, 10),
};
}
minWidth(element) {
return parseInt(getComputedStyle(element).getPropertyValue('min-width'), 10);
}
focus(element) {
element.focus();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DomAdapter, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DomAdapter }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DomAdapter, 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 MockDomAdapter extends DomAdapter {
constructor() {
super(...arguments);
this._userDefinedWidth = 0;
this._scrollBarWidth = 0;
this._scrollWidth = 0;
this._computedHeight = 0;
}
userDefinedWidth(_element) {
return this._userDefinedWidth;
}
scrollBarWidth(_element) {
return this._scrollBarWidth;
}
scrollWidth(_element) {
return this._scrollWidth;
}
computedHeight(_element) {
return this._computedHeight;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: MockDomAdapter, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: MockDomAdapter }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: MockDomAdapter, decorators: [{
type: Injectable
}] });
const MOCK_DOM_ADAPTER_PROVIDER = {
provide: DomAdapter,
useClass: MockDomAdapter,
};
/*
* 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 OutsideClick {
constructor(host, renderer, ngZone) {
this.strict = false;
this.outsideClick = new EventEmitter(false);
ngZone.runOutsideAngular(() => {
this.documentClickListener = renderer.listen('document', 'click', (event) => {
// Compare the element in the DOM on which the mouse was clicked
// with the current actionMenu native HTML element.
if (host.nativeElement === event.target) {
return;
}
if (!this.strict && host.nativeElement.contains(event.target)) {
return;
}
// We'll run change detection only if the click event actually happened outside of
// the host element.
ngZone.run(() => {
this.outsideClick.emit(event);
});
});
});
}
ngOnDestroy() {
this.documentClickListener();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: OutsideClick, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.3", type: OutsideClick, isStandalone: false, selector: "[clrOutsideClick]", inputs: { strict: ["clrStrict", "strict"] }, outputs: { outsideClick: "clrOutsideClick" }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: OutsideClick, decorators: [{
type: Directive,
args: [{
selector: '[clrOutsideClick]',
standalone: false,
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }], propDecorators: { strict: [{
type: Input,
args: ['clrStrict']
}], outsideClick: [{
type: Output,
args: ['clrOutsideClick']
}] } });
/*
* 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 OUSTIDE_CLICK_DIRECTIVES = [OutsideClick];
class ClrOutsideClickModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrOutsideClickModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: ClrOutsideClickModule, declarations: [OutsideClick], imports: [CommonModule], exports: [OutsideClick] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrOutsideClickModule, imports: [CommonModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrOutsideClickModule, decorators: [{
type: NgModule,
args: [{
imports: [CommonModule],
declarations: [OUSTIDE_CLICK_DIRECTIVES],
exports: [OUSTIDE_CLICK_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.
*/
/*
* 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 TemplateRefContainer {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: TemplateRefContainer, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.3", type: TemplateRefContainer, isStandalone: false, selector: "ng-component", viewQueries: [{ propertyName: "template", first: true, predicate: TemplateRef, descendants: true }], ngImport: i0, template: `
<ng-template>
<ng-content></ng-content>
</ng-template>
`, isInline: true }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: TemplateRefContainer, decorators: [{
type: Component,
args: [{
template: `
<ng-template>
<ng-content></ng-content>
</ng-template>
`,
standalone: false,
}]
}], propDecorators: { template: [{
type: ViewChild,
args: [TemplateRef]
}] } });
/*
* 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 ClrTemplateRefModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrTemplateRefModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: ClrTemplateRefModule, declarations: [TemplateRefContainer], imports: [CommonModule], exports: [TemplateRefContainer] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrTemplateRefModule, imports: [CommonModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrTemplateRefModule, decorators: [{
type: NgModule,
args: [{
imports: [CommonModule],
declarations: [TemplateRefContainer],
exports: [TemplateRefContainer],
}]
}] });
/*
* 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.
*/
/*
* 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.
*/
/**
* TODO:
* Using core functions like:
* - pluckPixelValue
* - getCssPropertyValue
*
* to get the value of the design token.
*
* Note: Memoization/Cache usage possible.
*/
// iPad mini screen width
// http://stephen.io/mediaqueries/#iPadMini
const DATEPICKER_ENABLE_BREAKPOINT = 768;
const SMALL_BREAKPOINT = 576;
const MEDIUM_BREAKPOINT = 768;
const LARGE_BREAKPOINT = 992;
const EXTRA_LARGE_BREAKPOINT = 1200;
/*
* 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 EmptyAnchor {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: EmptyAnchor, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.3", type: EmptyAnchor, isStandalone: false, selector: "ng-component", ngImport: i0, template: '', isInline: true }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: EmptyAnchor, decorators: [{
type: Component,
args: [{
template: '',
standalone: false,
}]
}] });
/*
* 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.
*/
/**
* HostWrapper must be called in OnInit to ensure that the Views are ready. If its called in a constructor the view is
* still undefined.
*/
class HostWrapper {
constructor(containerType, vcr, index = 0) {
this.injector = vcr.injector;
// If the host is already wrapped, we don't do anything
if (!this.injector.get(containerType, null)) {
const el = this.injector.get(ElementRef);
// We need a new anchor, since we're projecting the current one.
vcr.createComponent(EmptyAnchor);
// Craft the element array based on what slot to use. Angular only uses the index to determine
// which ng-content to project into, so if you have more than one ng-content you'll need to set
// the index in the constructor appropriately
const element = [];
element[index] = [el.nativeElement];
// We're assuming only one projection slot, but in more complex cases we might want to provide
// a different array of projected elements.
const containerRef = vcr.createComponent(containerType, {
projectableNodes: element,
});
// We can now remove the useless anchor
vcr.remove(0);
// We keep the wrapper's injector to access the dependencies that weren't available before.
this.injector = containerRef.injector;
}
}
get(token, notFoundValue) {
return this.injector.get(token, notFoundValue);
}
}
/*
* 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.
*/
/**
* Internal module, please do not export!
*/
class ClrHostWrappingModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrHostWrappingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: ClrHostWrappingModule, declarations: [EmptyAnchor], exports: [EmptyAnchor] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrHostWrappingModule }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrHostWrappingModule, decorators: [{
type: NgModule,
args: [{
declarations: [EmptyAnchor],
exports: [EmptyAnchor],
}]
}] });
/*
* 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.
*/
/*
* 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.
*/
function assertNever(value) {
throw new Error(`Unhandled value: ${value}`);
}
/*
* 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.
*/
function isBooleanAttributeSet(value) {
// for null just return false no need to check anything
if (value === null) {
return false;
}
if (typeof value === 'string') {
// Empty string is valid, 'true' as string is also valid
return value.length >= 0;
}
// Boolean value will be read as it is, everything else is false
return typeof value === 'boolean' ? value : false;
}
/*
* 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 defaultAnimationTiming = '0.2s ease-in-out';
const defaultExpandAnimation = animation([style({ height: '{{ startHeight }}px' }), animate(defaultAnimationTiming, style({ height: '*' }))], {
params: {
startHeight: 0, // default
},
});
/*
* 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.
*/
function collapse() {
'use strict';
return [
state('true', style({ height: 0, 'overflow-y': 'hidden' })),
transition('true => false', [animate(defaultAnimationTiming, style({ height: '*', 'overflow-y': 'hidden' }))]),
transition('false => true', [style({ height: '*', 'overflow-y': 'hidden' }), animate(defaultAnimationTiming)]),
];
}
/*
* 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.
*/
/*
* 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 BaseExpandableAnimation {
constructor(element, domAdapter, renderer) {
this.element = element;
this.domAdapter = domAdapter;
this.renderer = renderer;
this.startHeight = 0;
}
updateStartHeight() {
this.startHeight = this.domAdapter.computedHeight(this.element.nativeElement) || 0;
}
initAnimationEffects() {
this.renderer.setStyle(this.element.nativeElement, 'overflow', 'hidden');
}
cleanupAnimationEffects(cancelAnimations = false) {
this.renderer.removeStyle(this.element.nativeElement, 'overflow');
// A "safe" auto-update of the height ensuring basic OOTB user experience .
// Prone to small jumps in initial animation height if data was changed in the meantime, the window was resized, etc.
// For optimal behavior call manually updateStartHeight() from the parent component before initiating the update.
this.updateStartHeight();
if (cancelAnimations) {
this.cancelElementAnimations();
}
}
cancelElementAnimations() {
this.element.nativeElement.getAnimations().forEach(animation => {
if (animation.playState === 'finished') {
animation.cancel(); // clears animation-style set on the element
}
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: BaseExpandableAnimation, deps: [{ token: i0.ElementRef }, { token: DomAdapter }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.3", type: BaseExpandableAnimation, isStandalone: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: BaseExpandableAnimation, decorators: [{
type: Directive
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: DomAdapter }, { type: i0.Renderer2 }] });
/*
* 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 ClrExpandableAnimation extends BaseExpandableAnimation {
constructor() {
super(...arguments);
this.clrExpandTrigger = false;
}
get expandAnimation() {
return { value: this.clrExpandTrigger, params: { startHeight: this.startHeight } };
}
animationStart(event) {
if (event.fromState !== 'void') {
this.initAnimationEffects();
}
}
animationDone(event) {
if (event.fromState !== 'void') {
this.cleanupAnimationEffects();
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrExpandableAnimation, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.3", type: ClrExpandableAnimation, isStandalone: false, selector: "clr-expandable-animation", inputs: { clrExpandTrigger: "clrExpandTrigger" }, host: { listeners: { "@expandAnimation.start": "animationStart($event)", "@expandAnimation.done": "animationDone($event)" }, properties: { "@expandAnimation": "this.expandAnimation" } }, providers: [DomAdapter], usesInheritance: true, ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, styles: [":host{display:block}\n"], animations: [trigger('expandAnimation', [transition('true <=> false', [useAnimation(defaultExpandAnimation)])])] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrExpandableAnimation, decorators: [{
type: Component,
args: [{ selector: 'clr-expandable-animation', template: `<ng-content></ng-content>`, animations: [trigger('expandAnimation', [transition('true <=> false', [useAnimation(defaultExpandAnimation)])])], providers: [DomAdapter], standalone: false, styles: [":host{display:block}\n"] }]
}], propDecorators: { clrExpandTrigger: [{
type: Input
}], expandAnimation: [{
type: HostBinding,
args: ['@expandAnimation']
}], animationStart: [{
type: HostListener,
args: ['@expandAnimation.start', ['$event']]
}], animationDone: [{
type: HostListener,
args: ['@expandAnimation.done', ['$event']]
}] } });
/*
* 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 ClrExpandableAnimationDirective extends BaseExpandableAnimation {
constructor(element, domAdapter, renderer, builder) {
super(element, domAdapter, renderer);
this.builder = builder;
this.expanded = false;
}
ngOnChanges(changes) {
if (changes['expanded'] && !changes['expanded'].firstChange) {
Promise.resolve().then(() => this.playAnimation());
}
}
ngOnDestroy() {
this.player?.destroy();
}
playAnimation() {
if (this.player) {
this.player.destroy();
}
this.player = this.builder
.build([useAnimation(defaultExpandAnimation, { params: { startHeight: this.startHeight } })])
.create(this.element.nativeElement);
this.player.onStart(() => this.initAnimationEffects());
this.player.onDone(() => this.cleanupAnimationEffects(true));
this.player.play();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrExpandableAnimationDirective, deps: [{ token: i0.ElementRef }, { token: DomAdapter }, { token: i0.Renderer2 }, { token: i2.AnimationBuilder }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.3", type: ClrExpandableAnimationDirective, isStandalone: false, selector: "[clrExpandableAnimation]", inputs: { expanded: ["clrExpandableAnimation", "expanded"] }, host: { properties: { "class.clr-expandable-animation": "true" } }, providers: [DomAdapter], usesInheritance: true, usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrExpandableAnimationDirective, decorators: [{
type: Directive,
args: [{
selector: '[clrExpandableAnimation]',
providers: [DomAdapter],
host: {
'[class.clr-expandable-animation]': 'true',
},
standalone: false,
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: DomAdapter }, { type: i0.Renderer2 }, { type: i2.AnimationBuilder }], propDecorators: { expanded: [{
type: Input,
args: ['clrExpandableAnimation']
}] } });
/*
* 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 EXPANDABLE_ANIMATION_DIRECTIVES = [ClrExpandableAnimation, ClrExpandableAnimationDirective];
class ClrExpandableAnimationModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrExpandableAnimationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: ClrExpandableAnimationModule, declarations: [ClrExpandableAnimation, ClrExpandableAnimationDirective], imports: [CommonModule], exports: [ClrExpandableAnimation, ClrExpandableAnimationDirective] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrExpandableAnimationModule, imports: [CommonModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrExpandableAnimationModule, decorators: [{
type: NgModule,
args: [{
imports: [CommonModule],
declarations: [EXPANDABLE_ANIMATION_DIRECTIVES],
exports: [EXPANDABLE_ANIMATION_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.
*/
/*
* 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.
*/
function fade(opacity = 1) {
return [
transition('void => *', [style({ opacity: 0 }), animate(defaultAnimationTiming, style({ opacity: opacity }))]),
transition('* => void', [animate(defaultAnimationTiming, style({ opacity: 0 }))]),
];
}
/*
* 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.
*/
/*
* 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.
*/
function fadeSlide(direction) {
let transform = null;
if (direction === 'up') {
transform = 'translate(0, 25%)';
}
else if (direction === 'down') {
transform = 'translate(0, -25%)';
}
else if (direction === 'left') {
transform = 'translate(25%, 0)';
}
else if (direction === 'right') {
transform = 'translate(-25%, 0)';
}
else {
throw new Error('Unknown direction ' + direction + ' for slide animation.');
}
return [
transition('void => *', [style({ opacity: 0, transform: transform }), animate(defaultAnimationTiming)]),
transition('* => void', [animate(defaultAnimationTiming, style({ opacity: 0, transform: transform }))]),
];
}
/*
* 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.
*/
/*
* 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.
*/
function slide(direction) {
let transform = null;
if (direction === 'up') {
transform = 'translate(0, 25%)';
}
else if (direction === 'down') {
transform = 'translate(0, -25%)';
}
else if (direction === 'left') {
transform = 'translate(25%, 0)';
}
else if (direction === 'right') {
transform = 'translate(-25%, 0)';
}
else {
throw new Error('Unknown direction ' + direction + ' for slide animation.');
}
return [
transition('void => *', [style({ transform: transform }), animate(defaultAnimationTiming)]),
transition('* => void', [animate(defaultAnimationTiming, style({ transform: transform }))]),
];
}
/*
* 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.
*/
/*
* 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.
*/
/*
* 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 commonStringsDefault = {
open: 'Open',
close: 'Close',
show: 'Show',
hide: 'Hide',
apply: 'Apply',
cancel: 'Cancel',
expand: 'Expand',
collapse: 'Collapse',
more: 'More',
select: 'Select',
selectAll: 'Select All',
previous: 'Previous',
next: 'Next',
current: 'Jump to current',
info: 'Info',
success: 'Success',
warning: 'Warning',
danger: 'Error',
neutral: 'Neutral',
unknown: 'Unknown',
rowActions: 'Available actions',
pickColumns: 'Manage Columns',
showColumns: 'Show Columns',
sortColumn: 'Sort Column',
firstPage: 'First Page',
lastPage: 'Last Page',
nextPage: 'Next Page',
previousPage: 'Previous Page',
currentPage: 'Current Page',
totalPages: 'Total Pages',
filterItems: 'Filter items',
minValue: 'Min value',
maxValue: 'Max value',
modalContentStart: 'Beginning of Modal Content',
modalContentEnd: 'End of Modal Content',
sidePanelPin: 'Pin Side Panel',
showColumnsMenuDescription: 'Show or hide columns menu',
allColumnsSelected: 'All columns selected',
signpostToggle: 'Signpost Toggle',
signpostClose: 'Close',
loading: 'Loading',
// Datagrid
detailPaneStart: 'Start of row details',
detailPaneEnd: 'End of row details',
singleSelectionAriaLabel: 'Single selection header',
singleActionableAriaLabel: 'Single actionable header',
detailExpandableAriaLabel: 'Toggle more row content',
datagridFilterAriaLabel: '{COLUMN} filter',
datagridFilterLabel: '{COLUMN} filter',
datagridFilterDialogAriaLabel: 'Filter dialog',
columnSeparatorAriaLabel: 'Column resize handle',
columnSeparatorDescription: 'Use left or right key to resize the column',
fromLabel: 'From',
toLabel: 'To',
// Alert
alertCloseButtonAriaLabel: 'Close alert',
alertNextAlertAriaLabel: 'Next alert message, {CURRENT} of {COUNT}',
alertPreviousAlertAriaLabel: 'Previous alert message, {CURRENT} of {COUNT}',
// Date Picker
datepickerDialogLabel: 'Choose date',
datepickerToggleChooseDateLabel: 'Choose date',
datepickerToggleChangeDateLabel: 'Change date, {SELECTED_DATE}',
datepickerPreviousMonth: 'Previous month',
datepickerCurrentMonth: 'Current month',
datepickerNextMonth: 'Next month',
datepickerPreviousDecade: 'Previous decade',
datepickerNextDecade: 'Next decade',
datepickerCurrentDecade: 'Current decade',
datepickerSelectMonthText: 'Select month, the current month is {CALENDAR_MONTH}',
datepickerSelectYearText: 'Select year, the current year is {CALENDAR_YEAR}',
datepickerSelectedLabel: '{FULL_DATE} - Selected',
// Stack View
stackViewChanged: 'Value changed.',
// Responsive Nav
responsiveNavToggleOpen: 'Open navigation menu',
responsiveNavToggleClose: 'Close navigation menu',
responsiveNavOverflowOpen: 'Open navigation overflow menu',
responsiveNavOverflowClose: 'Close navigation overflow menu',
//Vertical Nav
verticalNavToggle: 'Toggle vertical navigation',
// Timeline steps
timelineStepNotStarted: 'Not started',
timelineStepCurrent: 'Current',
timelineStepSuccess: 'Completed',
timelineStepError: 'Error',
timelineStepProcessing: 'In progress',
// Combobox
comboboxDelete: 'Delete selected option',
comboboxSearching: 'Searching for matches for "{INPUT}"',
comboboxSelection: 'Selection',
comboboxSelected: 'Selected',
comboboxNoResults: 'No results',
comboboxOpen: 'Show options',
comboboxSelectAll: 'Select All',
comboboxUnselectAll: 'Unselect All',
comboboxShowAll: 'Show all {ITEMS} selected',
comboboxAllSelected: 'All {ITEMS} selected',
comboboxShowLess: 'Show less',
// Datagrid expandable rows
datagridExpandableBeginningOf: 'Beginning of',
datagridExpandableEndOf: 'End of',
datagridExpandableRowContent: 'Expandable row content',
datagridExpandableRowsHelperText: `Screen reader table commands may not work for viewing expanded content, please use your screen reader's browse mode to read the content exposed by this button`,
// Wizard
wizardStep: 'Step',
wizardStepCurrent: 'Current',
wizardStepSuccess: 'Completed',
wizardStepError: 'Error',
wizardStepnavAriaLabel: 'Wizard steps',
/**
* Password Input
* Screen-reader text for the hide/show password field button
*/
passwordHide: 'Hide password for {LABEL}',
passwordShow: 'Show password for {LABEL}',
/**
* Datagrid footer; sr-only text after the number of selected rows.
*/
selectedRows: 'Selected rows',
// Accordion/Stepper
stepComplete: 'Step {STEP} complete',
stepError: 'Error in step {STEP}',
// File input
browse: 'Browse',
fileCount: '{COUNT} files',
clearFile: 'Clear {FILE}',
clearFiles: 'Clear {COUNT} files',
// Tree
selectedTreeNode: 'selected',
unselectedTreeNode: 'unselected',
// Breadcrumbs
breadcrumbsLabel: 'breadcrumbs',
expandBreadcrumbsLabel: 'Expand breadcrumbs',
};
/*
* 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 ClrCommonStringsService {
constructor() {
this._strings = commonStringsDefault;
}
/**
* Access to all of the keys as strings
*/
get keys() {
return this._strings;
}
/**
* Allows you to pass in new overrides for localization
*/
localize(overrides) {
this._strings = { ...this._strings, ...overrides };
}
/**
* Parse a string with a set of tokens to replace
*/
parse(source, tokens = {}) {
const names = Object.keys(tokens);
let output = source;
if (names.length) {
names.forEach(name => {
output = output.replace(`{${name}}`, tokens[name]);
});
}
return output;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrCommonStringsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrCommonStringsService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrCommonStringsService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}] });
/*
* 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.
*/
/*
* 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.
*/
/*
* 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 FOCUS_ON_VIEW_INIT = new InjectionToken('FOCUS_ON_VIEW_INIT');
// This provider holds the default value for clrFocusOnViewInit directive's isEnabled property.
// So users can interject this provider and set their own value for this provider.
const FOCUS_ON_VIEW_INIT_PROVIDER = {
provide: FOCUS_ON_VIEW_INIT,
useValue: true,
};
/*
* 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.
*/
/* This directive is for guiding the document focus to the newly added content when its view is initialized
so that assistive technologies can read its content. */
class ClrFocusOnViewInit {
constructor(el, platformId, focusOnViewInit, document, renderer, ngZone) {
this.el = el;
this.platformId = platformId;
this.focusOnViewInit = focusOnViewInit;
this.renderer = renderer;
this.directFocus = true; // true if the element gets focused without need to set tabindex;
this.destroy$ = new Subject();
this._isEnabled = focusOnViewInit;
// Angular compiler doesn't understand the type Document
// when working out the metadata for injectable parameters,
// even though it understands the injection token DOCUMENT
// https://github.com/angular/angular/issues/20351
this.document = document;
ngZone.runOutsideAngular(() => fromEvent(el.nativeElement, 'focusout')
.pipe(takeUntil(this.destroy$))
.subscribe(() => {
if (!this.directFocus) {
// manually set attributes and styles should be removed
renderer.removeAttribute(el.nativeElement, 'tabindex');
renderer.setStyle(el.nativeElement, 'outline', null);
}
}));
}
set isEnabled(value) {
if (this.focusOnViewInit && typeof value === 'boolean') {
this._isEnabled = value;
}
}
ngAfterViewInit() {
this.focus();
}
ngOnDestroy() {
this.destroy$.next();
}
focus() {
if (!isPlatformBrowser(this.platformId)) {
return;
}
if (!this._isEnabled) {
return;
}
if (this.document && this.document.activeElement !== this.el.nativeElement) {
this.el.nativeElement.focus();
if (this.document.activeElement !== this.el.nativeElement) {
// if it's not directly focused now, it means it was a non-interactive element
// so we need to give it a tabindex.
this.directFocus = false;
this.renderer.setAttribute(this.el.nativeElement, 'tabindex', '-1');
this.renderer.setStyle(this.el.nativeElement, 'outline', 'none');
this.el.nativeElement.focus();
}
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrFocusOnViewInit, deps: [{ token: i0.ElementRef }, { token: PLATFORM_ID }, { token: FOCUS_ON_VIEW_INIT }, { token: DOCUMENT }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.3", type: ClrFocusOnViewInit, isStandalone: false, selector: "[clrFocusOnViewInit]", inputs: { isEnabled: ["clrFocusOnViewInit", "isEnabled"] }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrFocusOnViewInit, decorators: [{
type: Directive,
args: [{
selector: '[clrFocusOnViewInit]',
standalone: false,
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: undefined, decorators: [{
type: Inject,
args: [PLATFORM_ID]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [FOCUS_ON_VIEW_INIT]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }, { type: i0.Renderer2 }, { type: i0.NgZone }], propDecorators: { isEnabled: [{
type: Input,
args: ['clrFocusOnViewInit']
}] } });
/*
* 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 FOCUS_ON_VIEW_INIT_DIRECTIVES = [ClrFocusOnViewInit];
class ClrFocusOnViewInitModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrFocusOnViewInitModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: ClrFocusOnViewInitModule, declarations: [ClrFocusOnViewInit], imports: [CommonModule], exports: [ClrFocusOnViewInit] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrFocusOnViewInitModule, providers: [FOCUS_ON_VIEW_INIT_PROVIDER], imports: [CommonModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrFocusOnViewInitModule, decorators: [{
type: NgModule,
args: [{
imports: [CommonModule],
declarations: [FOCUS_ON_VIEW_INIT_DIRECTIVES],
providers: [FOCUS_ON_VIEW_INIT_PROVIDER],
exports: [FOCUS_ON_VIEW_INIT_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.
*/
/*
* 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 ClrStandaloneCdkTrapFocus extends CdkTrapFocus {
/**
* Include the constructor to forward all the dependencies to the base class
* as a workaround to fix Angular "ɵɵinvalidFactoryDep" error after upgrading storybook
* https://github.com/storybookjs/storybook/issues/23534
*/
constructor(elementRef, focusTrapFactory, document) {
super(elementRef, focusTrapFactory, document);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrStandaloneCdkTrapFocus, deps: [{ token: i0.ElementRef }, { token: i1.FocusTrapFactory }, { token: DOCUMENT, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.3", type: ClrStandaloneCdkTrapFocus, isStandalone: true, usesInheritance: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrStandaloneCdkTrapFocus, decorators: [{
type: Directive,
args: [{
standalone: true,
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.FocusTrapFactory }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [DOCUMENT]
}] }] });
/*
* 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.
*/
/*
* 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.
*/
var ClrFocusDirection;
(function (ClrFocusDirection) {
ClrFocusDirection["VERTICAL"] = "vertical";
ClrFocusDirection["HORIZONTAL"] = "horizontal";
ClrFocusDirection["BOTH"] = "both";
})(ClrFocusDirection || (ClrFocusDirection = {}));
/*
* 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 t