@clr/angular
Version:
Angular components for Clarity
991 lines (965 loc) • 1.54 MB
JavaScript
import * as i0 from '@angular/core';
import { Directive, NgModule, Optional, Input, Injectable, Component, ChangeDetectionStrategy, EventEmitter, SkipSelf, HostBinding, Output, ContentChildren, PLATFORM_ID, Inject, ViewChild, HostListener, Renderer2, InjectionToken, ElementRef, NgZone, ChangeDetectorRef, ContentChild, ComponentFactoryResolver, KeyValueDiffers, Self, forwardRef, Attribute, TemplateRef, ViewContainerRef, LOCALE_ID, inject, Injector, VERSION, EnvironmentInjector, IterableDiffers, ViewChildren } from '@angular/core';
import * as i5 from '@angular/common';
import { CommonModule, isPlatformBrowser, DOCUMENT, NgForOf, getLocaleDayNames, FormStyle, TranslationWidth, getLocaleMonthNames, getLocaleFirstDayOfWeek, getLocaleDateFormat, FormatWidth } from '@angular/common';
import { ClarityIcons, angleIcon, exclamationCircleIcon, checkCircleIcon, ellipsisHorizontalIcon, windowCloseIcon, infoCircleIcon, timesIcon, angleDoubleIcon, eventIcon, calendarIcon, folderOpenIcon, minusIcon, plusIcon, eyeHideIcon, eyeIcon, ellipsisVerticalIcon, viewColumnsIcon, arrowIcon, stepForward2Icon, filterGridCircleIcon, filterGridIcon, errorStandardIcon, helpIcon, infoStandardIcon, noteIcon, successStandardIcon, warningStandardIcon, circleIcon, dotCircleIcon } from '@cds/core/icon';
import { map, tap, startWith, distinctUntilChanged, filter, skipUntil, debounceTime, takeUntil, take, first, switchMap as switchMap$1 } from 'rxjs/operators';
import * as i3 from 'rxjs';
import { Subject, BehaviorSubject, Observable, fromEvent, isObservable, of, shareReplay, combineLatest, startWith as startWith$1, switchMap, merge, map as map$1, EMPTY, ReplaySubject, tap as tap$1 } from 'rxjs';
import * as i2 from '@angular/animations';
import { animation, style, animate, trigger, transition, state, useAnimation, keyframes } from '@angular/animations';
import * as i1 from '@angular/forms';
import { FormControl, FormGroup, FormsModule, NG_VALIDATORS, NG_VALUE_ACCESSOR, SelectMultipleControlValueAccessor } from '@angular/forms';
import * as i1$1 from '@angular/router';
import { RouterModule } from '@angular/router';
import * as i1$2 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$3 from '@angular/cdk/bidi';
import { Directionality } from '@angular/cdk/bidi';
import { coerceNumberProperty } from '@angular/cdk/coercion';
import { _RecycleViewRepeaterStrategy, _VIEW_REPEATER_STRATEGY } from '@angular/cdk/collections';
import * as i3$1 from '@angular/cdk/scrolling';
import { FixedSizeVirtualScrollStrategy, CdkVirtualScrollViewport, VIRTUAL_SCROLL_STRATEGY, ScrollDispatcher, ViewportRuler, CdkVirtualScrollable, CdkVirtualForOf } from '@angular/cdk/scrolling';
import '@cds/core/icon/register';
/*
* Copyright (c) 2016-2025 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 ClrIconCustomTag {
}
ClrIconCustomTag.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrIconCustomTag, deps: [], target: i0.ɵɵFactoryTarget.Directive });
ClrIconCustomTag.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: ClrIconCustomTag, selector: "clr-icon", ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrIconCustomTag, decorators: [{
type: Directive,
args: [{
selector: 'clr-icon',
}]
}] });
class CdsIconCustomTag {
}
CdsIconCustomTag.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: CdsIconCustomTag, deps: [], target: i0.ɵɵFactoryTarget.Directive });
CdsIconCustomTag.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: CdsIconCustomTag, selector: "cds-icon", ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: CdsIconCustomTag, decorators: [{
type: Directive,
args: [{
selector: 'cds-icon',
}]
}] });
/*
* Copyright (c) 2016-2025 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 CLR_ICON_DIRECTIVES = [ClrIconCustomTag, CdsIconCustomTag];
class ClrIconModule {
}
ClrIconModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrIconModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
ClrIconModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.2", ngImport: i0, type: ClrIconModule, declarations: [ClrIconCustomTag, CdsIconCustomTag], imports: [CommonModule], exports: [ClrIconCustomTag, CdsIconCustomTag] });
ClrIconModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrIconModule, imports: [CommonModule] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrIconModule, decorators: [{
type: NgModule,
args: [{
imports: [CommonModule],
declarations: [CLR_ICON_DIRECTIVES],
exports: [CLR_ICON_DIRECTIVES],
}]
}] });
/*
* Copyright (c) 2016-2025 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 is an abstract class because we need it to still be a valid token for dependency injection after transpiling.
* This does not mean you should extend it, simply implementing it is fine.
*/
class LoadingListener {
}
/*
* Copyright (c) 2016-2025 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 ClrLoadingState;
(function (ClrLoadingState) {
ClrLoadingState[ClrLoadingState["DEFAULT"] = 0] = "DEFAULT";
ClrLoadingState[ClrLoadingState["LOADING"] = 1] = "LOADING";
ClrLoadingState[ClrLoadingState["SUCCESS"] = 2] = "SUCCESS";
ClrLoadingState[ClrLoadingState["ERROR"] = 3] = "ERROR";
})(ClrLoadingState || (ClrLoadingState = {}));
class ClrLoading {
// We find the first parent that handles something loading
constructor(listener) {
this.listener = listener;
this._loadingState = ClrLoadingState.DEFAULT;
}
get loadingState() {
return this._loadingState;
}
set loadingState(value) {
if (value === true) {
value = ClrLoadingState.LOADING;
}
else if (!value) {
value = ClrLoadingState.DEFAULT;
}
if (value === this._loadingState) {
return;
}
this._loadingState = value;
if (this.listener) {
this.listener.loadingStateChange(value);
}
}
ngOnDestroy() {
this.loadingState = ClrLoadingState.DEFAULT;
}
}
ClrLoading.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrLoading, deps: [{ token: LoadingListener, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
ClrLoading.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: ClrLoading, selector: "[clrLoading]", inputs: { loadingState: ["clrLoading", "loadingState"] }, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrLoading, decorators: [{
type: Directive,
args: [{
selector: '[clrLoading]',
}]
}], ctorParameters: function () {
return [{ type: LoadingListener, decorators: [{
type: Optional
}] }];
}, propDecorators: { loadingState: [{
type: Input,
args: ['clrLoading']
}] } });
/*
* Copyright (c) 2016-2025 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;
}
}
}
IfExpandService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: IfExpandService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
IfExpandService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: IfExpandService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: IfExpandService, decorators: [{
type: Injectable
}] });
/*
* Copyright (c) 2016-2025 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 NB_INSTANCES = 0;
function uniqueIdFactory() {
return 'clr-id-' + NB_INSTANCES++;
}
/*
* Copyright (c) 2016-2025 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 ClrAccordionDescription {
}
ClrAccordionDescription.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrAccordionDescription, deps: [], target: i0.ɵɵFactoryTarget.Component });
ClrAccordionDescription.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrAccordionDescription, selector: "clr-accordion-description, clr-step-description", host: { properties: { "class.clr-accordion-description": "true" } }, ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrAccordionDescription, decorators: [{
type: Component,
args: [{
selector: 'clr-accordion-description, clr-step-description',
template: `<ng-content></ng-content>`,
host: { '[class.clr-accordion-description]': 'true' },
changeDetection: ChangeDetectionStrategy.OnPush,
}]
}] });
/*
* Copyright (c) 2016-2025 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-2025 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 panelAnimation = [
trigger('skipInitialRender', [transition(':enter', [])]),
trigger('toggle', [
transition('void => *', [
style({ display: 'block', height: 0 }),
animate(defaultAnimationTiming, style({ height: '*' })),
]),
]),
];
const stepAnimation = [
trigger('skipInitialRender', [transition(':enter', [])]),
trigger('toggle', [
transition('void => *', [
style({ display: 'block', height: 0 }),
animate(defaultAnimationTiming, style({ height: '*' })),
]),
transition('* => void', [
style({ display: 'block' }),
animate(defaultAnimationTiming, style({ height: 0, display: 'none' })),
]),
]),
];
/*
* Copyright (c) 2016-2025 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',
// 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-2025 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 = Object.assign(Object.assign({}, 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;
}
}
ClrCommonStringsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrCommonStringsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
ClrCommonStringsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrCommonStringsService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrCommonStringsService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}] });
/*
* Copyright (c) 2016-2025 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 AccordionStatus;
(function (AccordionStatus) {
AccordionStatus["Inactive"] = "inactive";
AccordionStatus["Error"] = "error";
AccordionStatus["Complete"] = "complete";
})(AccordionStatus || (AccordionStatus = {}));
/*
* Copyright (c) 2016-2025 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 AccordionStrategy;
(function (AccordionStrategy) {
AccordionStrategy["Default"] = "default";
AccordionStrategy["Multi"] = "multi";
})(AccordionStrategy || (AccordionStrategy = {}));
/*
* Copyright (c) 2016-2025 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 accordionCount = 0;
class AccordionPanelModel {
constructor(id, accordionId) {
this.id = id;
this.accordionId = accordionId;
this.status = AccordionStatus.Inactive;
this.index = null;
this.disabled = false;
this.open = false;
this.templateId = `${this.id}-${this.accordionId}`;
}
}
class AccordionModel {
constructor() {
this.strategy = AccordionStrategy.Default;
this.accordionCount = accordionCount++;
this._panels = {};
}
get panels() {
return Object.keys(this._panels).map(id => this._panels[id]);
}
setStrategy(strategy) {
this.strategy = strategy;
}
updatePanelOrder(ids) {
ids.forEach((id, index) => (this._panels[id].index = index));
this.removeOldPanels(ids);
}
addPanel(id, open = false) {
this._panels[id] = new AccordionPanelModel(id, this.accordionCount);
this._panels[id].open = open;
}
togglePanel(panelId, open) {
const panelIsOpen = this._panels[panelId].open;
const newOpenState = open !== undefined ? open : !panelIsOpen;
if (newOpenState && this.strategy === AccordionStrategy.Default) {
this.closeAllPanels();
}
this._panels[panelId].open = newOpenState;
}
disablePanel(panelId, disabled) {
this._panels[panelId].disabled = disabled;
}
closeAllPanels() {
this.panels.forEach(panel => (this._panels[panel.id].open = false));
}
removeOldPanels(ids) {
this.panels
.filter(panel => ids.find(id => id === panel.id) === undefined)
.forEach(panel => delete this._panels[panel.id]);
}
}
/*
* Copyright (c) 2016-2025 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 AccordionService {
constructor() {
this.accordion = new AccordionModel();
this._panelsChanges = new BehaviorSubject(this.accordion.panels);
}
getPanelChanges(panelId) {
return this._panelsChanges.pipe(map(panels => panels.find(s => s.id === panelId)));
}
setStrategy(strategy) {
this.accordion.setStrategy(strategy);
}
addPanel(panelId, open = false) {
this.accordion.addPanel(panelId, open);
this.emitUpdatedPanels();
}
togglePanel(panelId, open) {
this.accordion.togglePanel(panelId, open);
this.emitUpdatedPanels();
}
disablePanel(panelId, disabled) {
this.accordion.disablePanel(panelId, disabled);
this.emitUpdatedPanels();
}
updatePanelOrder(ids) {
this.accordion.updatePanelOrder(ids);
this.emitUpdatedPanels();
}
emitUpdatedPanels() {
this._panelsChanges.next(this.accordion.panels);
}
}
AccordionService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: AccordionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
AccordionService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: AccordionService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: AccordionService, decorators: [{
type: Injectable
}] });
/*
* Copyright (c) 2016-2025 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 ClrAccordionPanel {
constructor(parent, commonStrings, accordionService, ifExpandService, cdr) {
this.parent = parent;
this.commonStrings = commonStrings;
this.accordionService = accordionService;
this.ifExpandService = ifExpandService;
this.cdr = cdr;
this.disabled = false;
this.panelOpen = false;
this.headingEnabled = false;
this.panelOpenChange = new EventEmitter();
this._id = uniqueIdFactory();
}
get id() {
return this._id;
}
set id(value) {
this._id = value;
}
get panelNumber() {
return this._panelIndex + 1;
}
get headingLevel() {
if (this.explicitHeadingLevel) {
return this.explicitHeadingLevel;
}
return this.parent ? 4 : 3;
}
ngOnInit() {
this.panel = this.accordionService.getPanelChanges(this.id).pipe(tap(panel => this.emitPanelChange(panel)));
this.accordionService.addPanel(this.id, this.panelOpen);
this.accordionService.togglePanel(this.id, this.panelOpen);
this.accordionService.disablePanel(this.id, this.disabled);
}
ngOnChanges(changes) {
if (this.panel && changes.panelOpen && changes.panelOpen.currentValue !== changes.panelOpen.previousValue) {
this.accordionService.togglePanel(this.id, changes.panelOpen.currentValue);
}
if (this.panel && changes.disabled && changes.disabled.currentValue !== changes.disabled.previousValue) {
this.accordionService.disablePanel(this.id, changes.disabled.currentValue);
}
}
togglePanel() {
this.accordionService.togglePanel(this.id);
}
collapsePanelOnAnimationDone(panel) {
if (!panel.open) {
this.ifExpandService.expanded = false;
}
}
getPanelStateClasses(panel) {
return `clr-accordion-panel-${panel.status} ${panel.open ? 'clr-accordion-panel-open' : ''}`;
}
getAccordionContentId(id) {
return `clr-accordion-content-${id}'`;
}
getAccordionHeaderId(id) {
return `clr-accordion-header-${id}`;
}
stepCompleteText(panelNumber) {
return this.commonStrings.parse(this.commonStrings.keys.stepComplete, { STEP: panelNumber.toString() });
}
stepErrorText(panelNumber) {
return this.commonStrings.parse(this.commonStrings.keys.stepError, { STEP: panelNumber.toString() });
}
emitPanelChange(panel) {
if (panel.index !== this._panelIndex) {
this._panelIndex = panel.index;
// The whole chain of updates leading to this line starts in a ngAfterViewInit subscription in accordion.ts,
// listening for DOM changes. It seems to only fails in tests, but as this is not a frequently called code,
// I prefer to stay on the safe side and initiate a detection cycle here.
this.cdr.detectChanges();
}
if (panel.open !== this.panelOpen) {
this.panelOpenChange.emit(panel.open);
/**
* @Note: this line below is needed because we don't want to use another value to track
* for changes of the panel. Because we use BehaviorSubject this emit event is trigger on
* init (that is not needed - there is no change of the original value) - in some cases this
* lead to duplicate events.
*
* To prevent this we try to emit only when the value is changed and keep the value in sync
* even that is used only into the Initial Lifecycle (ngOnInit).
*/
this.panelOpen = panel.open;
}
if (panel.open) {
this.ifExpandService.expanded = true;
}
}
}
ClrAccordionPanel.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrAccordionPanel, deps: [{ token: ClrAccordionPanel, optional: true, skipSelf: true }, { token: ClrCommonStringsService }, { token: AccordionService }, { token: IfExpandService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
ClrAccordionPanel.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrAccordionPanel, selector: "clr-accordion-panel", inputs: { disabled: ["clrAccordionPanelDisabled", "disabled"], panelOpen: ["clrAccordionPanelOpen", "panelOpen"], headingEnabled: ["clrAccordionPanelHeadingEnabled", "headingEnabled"], explicitHeadingLevel: ["clrAccordionPanelHeadingLevel", "explicitHeadingLevel"] }, outputs: { panelOpenChange: "clrAccordionPanelOpenChange" }, host: { properties: { "class.clr-accordion-panel": "true", "class.clr-accordion-panel-disabled": "this.disabled" } }, providers: [IfExpandService], queries: [{ propertyName: "accordionDescription", predicate: ClrAccordionDescription }], usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"panel | async; let panel\">\n <div [ngClass]=\"getPanelStateClasses(panel)\">\n <div\n class=\"clr-accordion-header\"\n [attr.role]=\"headingEnabled || explicitHeadingLevel ? 'heading' : null\"\n [attr.aria-level]=\"headingEnabled || explicitHeadingLevel ? headingLevel : null\"\n >\n <button\n type=\"button\"\n class=\"clr-accordion-header-button\"\n (click)=\"togglePanel()\"\n [id]=\"getAccordionHeaderId(panel.templateId)\"\n [disabled]=\"panel.disabled\"\n [attr.aria-controls]=\"!panel.disabled && panel.open ? getAccordionContentId(panel.templateId) : null\"\n [attr.aria-expanded]=\"panel.open\"\n [class.clr-accordion-header-has-description]=\"(accordionDescription.changes | async)?.length || accordionDescription.length\"\n #headerButton\n >\n <span class=\"clr-accordion-status\">\n <cds-icon shape=\"angle\" direction=\"right\" class=\"clr-accordion-angle\"></cds-icon>\n </span>\n <ng-content select=\"clr-accordion-title, clr-step-title\"></ng-content>\n <ng-content select=\"clr-accordion-description, clr-step-description\"></ng-content>\n </button>\n </div>\n <div\n @skipInitialRender\n role=\"region\"\n class=\"clr-accordion-content-region\"\n [id]=\"getAccordionContentId(panel.templateId)\"\n [attr.aria-hidden]=\"!panel.open\"\n [attr.aria-labelledby]=\"getAccordionHeaderId(panel.templateId)\"\n >\n <div\n *ngIf=\"panel.open\"\n @toggle\n (@toggle.done)=\"collapsePanelOnAnimationDone(panel)\"\n class=\"clr-accordion-content\"\n >\n <div class=\"clr-accordion-inner-content\">\n <ng-content></ng-content>\n </div>\n </div>\n </div>\n </div>\n</ng-container>\n", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }], animations: panelAnimation, changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrAccordionPanel, decorators: [{
type: Component,
args: [{ selector: 'clr-accordion-panel', host: { '[class.clr-accordion-panel]': 'true' }, changeDetection: ChangeDetectionStrategy.OnPush, animations: panelAnimation, providers: [IfExpandService], template: "<ng-container *ngIf=\"panel | async; let panel\">\n <div [ngClass]=\"getPanelStateClasses(panel)\">\n <div\n class=\"clr-accordion-header\"\n [attr.role]=\"headingEnabled || explicitHeadingLevel ? 'heading' : null\"\n [attr.aria-level]=\"headingEnabled || explicitHeadingLevel ? headingLevel : null\"\n >\n <button\n type=\"button\"\n class=\"clr-accordion-header-button\"\n (click)=\"togglePanel()\"\n [id]=\"getAccordionHeaderId(panel.templateId)\"\n [disabled]=\"panel.disabled\"\n [attr.aria-controls]=\"!panel.disabled && panel.open ? getAccordionContentId(panel.templateId) : null\"\n [attr.aria-expanded]=\"panel.open\"\n [class.clr-accordion-header-has-description]=\"(accordionDescription.changes | async)?.length || accordionDescription.length\"\n #headerButton\n >\n <span class=\"clr-accordion-status\">\n <cds-icon shape=\"angle\" direction=\"right\" class=\"clr-accordion-angle\"></cds-icon>\n </span>\n <ng-content select=\"clr-accordion-title, clr-step-title\"></ng-content>\n <ng-content select=\"clr-accordion-description, clr-step-description\"></ng-content>\n </button>\n </div>\n <div\n @skipInitialRender\n role=\"region\"\n class=\"clr-accordion-content-region\"\n [id]=\"getAccordionContentId(panel.templateId)\"\n [attr.aria-hidden]=\"!panel.open\"\n [attr.aria-labelledby]=\"getAccordionHeaderId(panel.templateId)\"\n >\n <div\n *ngIf=\"panel.open\"\n @toggle\n (@toggle.done)=\"collapsePanelOnAnimationDone(panel)\"\n class=\"clr-accordion-content\"\n >\n <div class=\"clr-accordion-inner-content\">\n <ng-content></ng-content>\n </div>\n </div>\n </div>\n </div>\n</ng-container>\n" }]
}], ctorParameters: function () {
return [{ type: ClrAccordionPanel, decorators: [{
type: Optional
}, {
type: SkipSelf
}] }, { type: ClrCommonStringsService }, { type: AccordionService }, { type: IfExpandService }, { type: i0.ChangeDetectorRef }];
}, propDecorators: { disabled: [{
type: Input,
args: ['clrAccordionPanelDisabled']
}, {
type: HostBinding,
args: ['class.clr-accordion-panel-disabled']
}], panelOpen: [{
type: Input,
args: ['clrAccordionPanelOpen']
}], headingEnabled: [{
type: Input,
args: ['clrAccordionPanelHeadingEnabled']
}], explicitHeadingLevel: [{
type: Input,
args: ['clrAccordionPanelHeadingLevel']
}], panelOpenChange: [{
type: Output,
args: ['clrAccordionPanelOpenChange']
}], accordionDescription: [{
type: ContentChildren,
args: [ClrAccordionDescription]
}] } });
/*
* Copyright (c) 2016-2025 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 ClrAccordion {
constructor(accordionService) {
this.accordionService = accordionService;
this.multiPanel = false;
this.subscriptions = [];
}
ngOnInit() {
this.setAccordionStrategy();
}
ngOnChanges(changes) {
if (changes.multiPanel.currentValue !== changes.multiPanel.previousValue) {
this.setAccordionStrategy();
}
}
ngAfterViewInit() {
this.subscriptions.push(this.listenForDOMChanges());
}
ngOnDestroy() {
this.subscriptions.forEach(s => s.unsubscribe());
}
setAccordionStrategy() {
const strategy = this.multiPanel ? AccordionStrategy.Multi : AccordionStrategy.Default;
this.accordionService.setStrategy(strategy);
}
listenForDOMChanges() {
return this.panels.changes
.pipe(startWith(this.panels))
.subscribe((panels) => this.accordionService.updatePanelOrder(panels.toArray().map(p => p.id)));
}
}
ClrAccordion.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrAccordion, deps: [{ token: AccordionService }], target: i0.ɵɵFactoryTarget.Component });
ClrAccordion.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrAccordion, selector: "clr-accordion", inputs: { multiPanel: ["clrAccordionMultiPanel", "multiPanel"] }, host: { properties: { "class.clr-accordion": "true" } }, providers: [AccordionService], queries: [{ propertyName: "panels", predicate: ClrAccordionPanel }], usesOnChanges: true, ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrAccordion, decorators: [{
type: Component,
args: [{
selector: 'clr-accordion',
template: `<ng-content></ng-content>`,
host: { '[class.clr-accordion]': 'true' },
providers: [AccordionService],
changeDetection: ChangeDetectionStrategy.OnPush,
}]
}], ctorParameters: function () { return [{ type: AccordionService }]; }, propDecorators: { multiPanel: [{
type: Input,
args: ['clrAccordionMultiPanel']
}], panels: [{
type: ContentChildren,
args: [ClrAccordionPanel]
}] } });
/*
* Copyright (c) 2016-2025 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 ClrAccordionContent {
}
ClrAccordionContent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrAccordionContent, deps: [], target: i0.ɵɵFactoryTarget.Component });
ClrAccordionContent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrAccordionContent, selector: "clr-accordion-content, clr-step-content", ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrAccordionContent, decorators: [{
type: Component,
args: [{
selector: 'clr-accordion-content, clr-step-content',
template: `<ng-content></ng-content>`,
changeDetection: ChangeDetectionStrategy.OnPush,
}]
}] });
/*
* Copyright (c) 2016-2025 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 ClrAccordionTitle {
}
ClrAccordionTitle.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrAccordionTitle, deps: [], target: i0.ɵɵFactoryTarget.Component });
ClrAccordionTitle.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrAccordionTitle, selector: "clr-accordion-title, clr-step-title", host: { properties: { "class.clr-accordion-title": "true" } }, ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrAccordionTitle, decorators: [{
type: Component,
args: [{
selector: 'clr-accordion-title, clr-step-title',
template: `<ng-content></ng-content>`,
host: { '[class.clr-accordion-title]': 'true' },
changeDetection: ChangeDetectionStrategy.OnPush,
}]
}] });
/*
* Copyright (c) 2016-2025 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.
*/
/*
* After a conversation with the Angular core team, it turns out we don't have much of a choice for our
* declarative API, we need to fight against change detection and its one-way flow. This is
* currently the least dirty solution to do what we want.
*
* Do not modify or even use this class unless you know exactly what you're doing.
* It has the potential to trigger change detection loops or kill app performances.
*/
class WillyWonka {
constructor() {
this.disableChocolateCheck = false;
this._chocolate = new Subject();
}
get chocolate() {
return this._chocolate.asObservable();
}
ngAfterViewChecked() {
if (!this.disableChocolateCheck) {
this._chocolate.next();
}
}
}
WillyWonka.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: WillyWonka, deps: [], target: i0.ɵɵFactoryTarget.Directive });
WillyWonka.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: WillyWonka, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: WillyWonka, decorators: [{
type: Directive
}] });
/*
* Copyright (c) 2016-2025 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 OompaLoompa {
// FIXME: Request Injector once we move to Angular 4.2+, it'll allow easier refactors
constructor(cdr, willyWonka) {
this.subscription = willyWonka.chocolate.subscribe(() => {
if (this.latestFlavor !== this.flavor) {
willyWonka.disableChocolateCheck = true;
cdr.detectChanges();
willyWonka.disableChocolateCheck = false;
}
});
}
ngAfterContentChecked() {
this.latestFlavor = this.flavor;
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
OompaLoompa.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: OompaLoompa, deps: [{ token: i0.ChangeDetectorRef }, { token: WillyWonka }], target: i0.ɵɵFactoryTarget.Directive });
OompaLoompa.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: OompaLoompa, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: OompaLoompa, decorators: [{
type: Directive
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: WillyWonka }]; } });
/*
* Copyright (c) 2016-2025 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 AccordionWillyWonka extends WillyWonka {
}
AccordionWillyWonka.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: AccordionWillyWonka, deps: null, target: i0.ɵɵFactoryTarget.Directive });
AccordionWillyWonka.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: AccordionWillyWonka, selector: "clr-accordion", usesInheritance: true, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: AccordionWillyWonka, decorators: [{
type: Directive,
args: [{
selector: 'clr-accordion',
}]
}] });
/*
* Copyright (c) 2016-2025 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 AccordionOompaLoompa extends OompaLoompa {
constructor(cdr, willyWonka, ifExpandService) {
if (!willyWonka) {
throw new Error('clr-accordion-panel should only be used inside of clr-accordion');
}
super(cdr, willyWonka);
this.expand = ifExpandService;
}
get flavor() {
return this.expand.expanded;
}
}
AccordionOompaLoompa.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: AccordionOompaLoompa, deps: [{ token: i0.ChangeDetectorRef }, { token: AccordionWillyWonka, optional: true }, { token: IfExpandService }], target: i0.ɵɵFactoryTarget.Directive });
AccordionOompaLoompa.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: AccordionOompaLoompa, selector: "clr-accordion-panel", usesInheritance: true, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: AccordionOompaLoompa, decorators: [{
type: Directive,
args: [{
selector: 'clr-accordion-panel',
}]
}], ctorParameters: function () {
return [{ type: i0.ChangeDetectorRef }, { type: AccordionWillyWonka, decorators: [{
type: Optional
}] }, { type: IfExpandService }];
} });
/*
* Copyright (c) 2016-2025 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 declarations$1 = [
ClrAccordion,
ClrAccordionPanel,
ClrAccordionTitle,
ClrAccordionDescription,
ClrAccordionContent,
AccordionOompaLoompa,
AccordionWillyWonka,
];
class ClrAccordionModule {
constructor() {
ClarityIcons.addIcons(angleIcon, exclamationCircleIcon, checkCircleIcon);
}
}
ClrAccordionModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrAccordionModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
ClrAccordionModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.2", ngImport: i0, type: ClrAccordionModule, declarations: [ClrAccordion,
ClrAccordionPanel,
ClrAccordionTitle,
ClrAccordionDescription,
ClrAccordionContent,
AccordionOompaLoompa,
AccordionWillyWonka], imports: [CommonModule, ClrIconModule], exports: [ClrAccordion,
ClrAccordionPanel,
ClrAccordionTitle,
ClrAccordionDescription,
ClrAccordionContent,
AccordionOompaLoompa,
AccordionWillyWonka] });
ClrAccordionModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrAccordionModule, imports: [CommonModule, ClrIconModule] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrAccordionModule, decorators: [{
type: NgModule,
args: [{
imports: [CommonModule, ClrIconModule],
declarations: [...declarations$1],
exports: [...declarations$1],
}]
}], ctorParameters: function () { return []; } });
/*
* Copyright (c) 2016-2025 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-2025 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 StepperModel extends AccordionModel {
constructor()