@clr/angular 17.7.1 → 17.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/clarity.api.md +49 -8
  2. package/data/datagrid/datagrid-virtual-scroll.directive.d.ts +4 -0
  3. package/data/datagrid/datagrid.d.ts +6 -2
  4. package/data/datagrid/utils/key-navigation-grid.controller.d.ts +19 -2
  5. package/esm2020/data/datagrid/datagrid-column.mjs +9 -9
  6. package/esm2020/data/datagrid/datagrid-row-detail.mjs +29 -7
  7. package/esm2020/data/datagrid/datagrid-row.mjs +3 -3
  8. package/esm2020/data/datagrid/datagrid-virtual-scroll.directive.mjs +14 -3
  9. package/esm2020/data/datagrid/datagrid.mjs +10 -6
  10. package/esm2020/data/datagrid/utils/key-navigation-grid.controller.mjs +238 -56
  11. package/esm2020/data/tree-view/tree-node.mjs +3 -3
  12. package/esm2020/emphasis/alert/alerts-pager.mjs +3 -3
  13. package/esm2020/forms/checkbox/checkbox-container.mjs +7 -3
  14. package/esm2020/forms/checkbox/checkbox-wrapper.mjs +8 -3
  15. package/esm2020/forms/checkbox/checkbox.mjs +5 -1
  16. package/esm2020/forms/datepicker/day.mjs +2 -2
  17. package/esm2020/forms/datepicker/yearpicker.mjs +6 -1
  18. package/esm2020/layout/breadcrumbs/index.mjs +2 -1
  19. package/esm2020/modal/modal.mjs +4 -3
  20. package/esm2020/modal/side-panel.mjs +5 -1
  21. package/esm2020/popover/signpost/signpost.mjs +9 -6
  22. package/esm2020/utils/conditional/if-expanded.directive.mjs +2 -1
  23. package/esm2020/utils/conditional/if-expanded.service.mjs +2 -1
  24. package/esm2020/utils/i18n/common-strings.default.mjs +2 -2
  25. package/esm2020/wizard/wizard-stepnav-item.mjs +34 -7
  26. package/esm2020/wizard/wizard-stepnav.mjs +30 -24
  27. package/esm2020/wizard/wizard.mjs +3 -3
  28. package/fesm2015/clr-angular.mjs +828 -550
  29. package/fesm2015/clr-angular.mjs.map +1 -1
  30. package/fesm2020/clr-angular.mjs +831 -549
  31. package/fesm2020/clr-angular.mjs.map +1 -1
  32. package/forms/checkbox/checkbox-container.d.ts +1 -0
  33. package/forms/checkbox/checkbox-wrapper.d.ts +3 -1
  34. package/forms/checkbox/checkbox.d.ts +2 -0
  35. package/forms/datepicker/yearpicker.d.ts +1 -0
  36. package/layout/breadcrumbs/index.d.ts +1 -0
  37. package/package.json +2 -2
  38. package/popover/signpost/signpost.d.ts +2 -1
  39. package/utils/conditional/if-expanded.service.d.ts +1 -0
  40. package/wizard/wizard-stepnav-item.d.ts +5 -0
  41. package/wizard/wizard-stepnav.d.ts +2 -1
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- 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, Attribute, TemplateRef, ViewContainerRef, LOCALE_ID, forwardRef, inject, Injector, VERSION, EnvironmentInjector, IterableDiffers } from '@angular/core';
2
+ 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 } from '@angular/core';
3
3
  import * as i5 from '@angular/common';
4
4
  import { CommonModule, isPlatformBrowser, DOCUMENT, NgForOf, getLocaleDayNames, FormStyle, TranslationWidth, getLocaleMonthNames, getLocaleFirstDayOfWeek, getLocaleDateFormat, FormatWidth } from '@angular/common';
5
5
  import { ClarityIcons, angleIcon, exclamationCircleIcon, checkCircleIcon, ellipsisHorizontalIcon, windowCloseIcon, infoCircleIcon, timesIcon, angleDoubleIcon, eventIcon, calendarIcon, folderOpenIcon, eyeHideIcon, eyeIcon, ellipsisVerticalIcon, viewColumnsIcon, arrowIcon, stepForward2Icon, filterGridCircleIcon, filterGridIcon, errorStandardIcon, helpIcon, infoStandardIcon, noteIcon, successStandardIcon, warningStandardIcon, circleIcon, dotCircleIcon } from '@cds/core/icon';
@@ -148,6 +148,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
148
148
  class IfExpandService {
149
149
  constructor() {
150
150
  this.expandable = 0;
151
+ this.hasExpandTemplate = false;
151
152
  this._loading = false;
152
153
  this._expanded = false;
153
154
  this._expandChange = new Subject();
@@ -371,7 +372,7 @@ const commonStringsDefault = {
371
372
  wizardStep: 'Step',
372
373
  wizardStepSuccess: 'Completed',
373
374
  wizardStepError: 'Error',
374
- wizardStepnavAriaLabel: 'Step navigation',
375
+ wizardStepnavAriaLabel: 'Wizard steps',
375
376
  /**
376
377
  * Password Input
377
378
  * Screen-reader text for the hide/show password field button
@@ -3562,6 +3563,7 @@ class ClrIfExpanded {
3562
3563
  this.updateView();
3563
3564
  this.expandedChange.emit(expand.expanded);
3564
3565
  }));
3566
+ expand.hasExpandTemplate = !!template;
3565
3567
  }
3566
3568
  get expanded() {
3567
3569
  return this._expanded;
@@ -5832,13 +5834,13 @@ class ClrSignpost {
5832
5834
  }
5833
5835
  }
5834
5836
  ClrSignpost.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrSignpost, deps: [{ token: ClrCommonStringsService }], target: i0.ɵɵFactoryTarget.Component });
5835
- ClrSignpost.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrSignpost, selector: "clr-signpost", host: { properties: { "class.signpost": "true" } }, providers: [SignpostFocusManager, SignpostIdService], queries: [{ propertyName: "customTrigger", first: true, predicate: ClrSignpostTrigger, descendants: true }], hostDirectives: [{ directive: ClrPopoverHostDirective }], ngImport: i0, template: `
5837
+ ClrSignpost.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrSignpost, selector: "clr-signpost", inputs: { signpostTriggerAriaLabel: ["clrSignpostTriggerAriaLabel", "signpostTriggerAriaLabel"] }, host: { properties: { "class.signpost": "true" } }, providers: [SignpostFocusManager, SignpostIdService], queries: [{ propertyName: "customTrigger", first: true, predicate: ClrSignpostTrigger, descendants: true }], hostDirectives: [{ directive: ClrPopoverHostDirective }], ngImport: i0, template: `
5836
5838
  <ng-container *ngIf="!useCustomTrigger">
5837
5839
  <button
5838
5840
  type="button"
5839
5841
  class="signpost-action btn btn-sm btn-icon btn-link"
5840
5842
  clrSignpostTrigger
5841
- [attr.aria-label]="commonStrings.keys.signpostToggle"
5843
+ [attr.aria-label]="signpostTriggerAriaLabel || commonStrings.keys.signpostToggle"
5842
5844
  >
5843
5845
  <cds-icon shape="info-circle" [attr.title]="commonStrings.keys.info"></cds-icon>
5844
5846
  </button>
@@ -5856,7 +5858,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
5856
5858
  type="button"
5857
5859
  class="signpost-action btn btn-sm btn-icon btn-link"
5858
5860
  clrSignpostTrigger
5859
- [attr.aria-label]="commonStrings.keys.signpostToggle"
5861
+ [attr.aria-label]="signpostTriggerAriaLabel || commonStrings.keys.signpostToggle"
5860
5862
  >
5861
5863
  <cds-icon shape="info-circle" [attr.title]="commonStrings.keys.info"></cds-icon>
5862
5864
  </button>
@@ -5868,7 +5870,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
5868
5870
  providers: [SignpostFocusManager, SignpostIdService],
5869
5871
  hostDirectives: [ClrPopoverHostDirective],
5870
5872
  }]
5871
- }], ctorParameters: function () { return [{ type: ClrCommonStringsService }]; }, propDecorators: { customTrigger: [{
5873
+ }], ctorParameters: function () { return [{ type: ClrCommonStringsService }]; }, propDecorators: { signpostTriggerAriaLabel: [{
5874
+ type: Input,
5875
+ args: ['clrSignpostTriggerAriaLabel']
5876
+ }], customTrigger: [{
5872
5877
  type: ContentChild,
5873
5878
  args: [ClrSignpostTrigger]
5874
5879
  }] } });
@@ -7479,7 +7484,7 @@ class ClrCheckboxWrapper {
7479
7484
  }
7480
7485
  }
7481
7486
  ClrCheckboxWrapper.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrCheckboxWrapper, deps: [{ token: IS_TOGGLE }], target: i0.ɵɵFactoryTarget.Component });
7482
- ClrCheckboxWrapper.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrCheckboxWrapper, selector: "clr-checkbox-wrapper,clr-toggle-wrapper", host: { properties: { "class.clr-checkbox-wrapper": "!toggle", "class.clr-toggle-wrapper": "toggle" } }, providers: [ControlIdService, IS_TOGGLE_PROVIDER], queries: [{ propertyName: "label", first: true, predicate: ClrLabel, descendants: true, static: true }], ngImport: i0, template: `
7487
+ ClrCheckboxWrapper.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrCheckboxWrapper, selector: "clr-checkbox-wrapper,clr-toggle-wrapper", host: { properties: { "class.clr-checkbox-wrapper": "!toggle", "class.clr-checkbox-wrapper-disabled": "checkbox?.controlDisabled", "class.clr-toggle-wrapper": "toggle" } }, providers: [ControlIdService, IS_TOGGLE_PROVIDER], queries: [{ propertyName: "label", first: true, predicate: ClrLabel, descendants: true, static: true }, { propertyName: "checkbox", first: true, predicate: i0.forwardRef(function () { return ClrCheckbox; }), descendants: true, static: true }], ngImport: i0, template: `
7483
7488
  <ng-content select="[clrCheckbox],[clrToggle]"></ng-content>
7484
7489
  <ng-content select="label"></ng-content>
7485
7490
  <label *ngIf="!label"></label>
@@ -7495,6 +7500,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
7495
7500
  `,
7496
7501
  host: {
7497
7502
  '[class.clr-checkbox-wrapper]': '!toggle',
7503
+ '[class.clr-checkbox-wrapper-disabled]': 'checkbox?.controlDisabled',
7498
7504
  '[class.clr-toggle-wrapper]': 'toggle',
7499
7505
  },
7500
7506
  providers: [ControlIdService, IS_TOGGLE_PROVIDER],
@@ -7505,6 +7511,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
7505
7511
  }] }]; }, propDecorators: { label: [{
7506
7512
  type: ContentChild,
7507
7513
  args: [ClrLabel, { static: true }]
7514
+ }], checkbox: [{
7515
+ type: ContentChild,
7516
+ args: [forwardRef(() => ClrCheckbox), { static: true }]
7508
7517
  }] } });
7509
7518
 
7510
7519
  /*
@@ -7522,8 +7531,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
7522
7531
  class ClrCheckbox extends WrappedFormControl {
7523
7532
  constructor(vcr, injector, control, renderer, el, toggle) {
7524
7533
  super(vcr, ClrCheckboxWrapper, injector, control, renderer, el);
7534
+ this.control = control;
7525
7535
  this.toggle = toggle;
7526
7536
  }
7537
+ get controlDisabled() {
7538
+ return this.control?.disabled;
7539
+ }
7527
7540
  ngOnInit() {
7528
7541
  super.ngOnInit();
7529
7542
  const toggleService = this.getProviderFromContainer(IS_TOGGLE, null);
@@ -7580,6 +7593,10 @@ class ClrCheckboxContainer extends ClrAbstractContainer {
7580
7593
  this.inline = !!value;
7581
7594
  }
7582
7595
  }
7596
+ get allCheckboxesDisabled() {
7597
+ return (this.control?.disabled &&
7598
+ (!this.additionalControls?.length || this.additionalControls.every(control => control.disabled)));
7599
+ }
7583
7600
  ngAfterContentInit() {
7584
7601
  this.setAriaRoles();
7585
7602
  }
@@ -7588,7 +7605,7 @@ class ClrCheckboxContainer extends ClrAbstractContainer {
7588
7605
  }
7589
7606
  }
7590
7607
  ClrCheckboxContainer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrCheckboxContainer, deps: [{ token: LayoutService, optional: true }, { token: ControlClassService }, { token: NgControlService }, { token: IfControlStateService }], target: i0.ɵɵFactoryTarget.Component });
7591
- ClrCheckboxContainer.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrCheckboxContainer, selector: "clr-checkbox-container,clr-toggle-container", inputs: { clrInline: "clrInline" }, host: { properties: { "class.clr-form-control": "true", "class.clr-form-control-disabled": "control?.disabled", "class.clr-row": "addGrid()", "attr.role": "role" } }, providers: [IfControlStateService, NgControlService, ControlClassService, ContainerIdService], queries: [{ propertyName: "checkboxes", predicate: ClrCheckbox, descendants: true }], usesInheritance: true, ngImport: i0, template: `
7608
+ ClrCheckboxContainer.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrCheckboxContainer, selector: "clr-checkbox-container,clr-toggle-container", inputs: { clrInline: "clrInline" }, host: { properties: { "class.clr-form-control": "true", "class.clr-form-control-disabled": "allCheckboxesDisabled", "class.clr-row": "addGrid()", "attr.role": "role" } }, providers: [IfControlStateService, NgControlService, ControlClassService, ContainerIdService], queries: [{ propertyName: "checkboxes", predicate: ClrCheckbox, descendants: true }], usesInheritance: true, ngImport: i0, template: `
7592
7609
  <ng-content select="label"></ng-content>
7593
7610
  <label *ngIf="!label && addGrid()"></label>
7594
7611
  <div class="clr-control-container" [class.clr-control-inline]="clrInline" [ngClass]="controlClass()">
@@ -7650,7 +7667,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
7650
7667
  `,
7651
7668
  host: {
7652
7669
  '[class.clr-form-control]': 'true',
7653
- '[class.clr-form-control-disabled]': 'control?.disabled',
7670
+ '[class.clr-form-control-disabled]': 'allCheckboxesDisabled',
7654
7671
  '[class.clr-row]': 'addGrid()',
7655
7672
  '[attr.role]': 'role',
7656
7673
  },
@@ -9986,6 +10003,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
9986
10003
  * The full license information can be found in LICENSE in the root directory of this project.
9987
10004
  */
9988
10005
 
10006
+ /*
10007
+ * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
10008
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
10009
+ * This software is released under MIT license.
10010
+ * The full license information can be found in LICENSE in the root directory of this project.
10011
+ */
10012
+
9989
10013
  /*
9990
10014
  * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
9991
10015
  * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
@@ -13116,7 +13140,7 @@ class ClrDay {
13116
13140
  }
13117
13141
  else if (this._dateNavigationService.selectedDay && !this._dateNavigationService.selectedEndDay) {
13118
13142
  return (this._dayView.dayModel?.isAfter(this._dateNavigationService.selectedDay) &&
13119
- this._dayView.dayModel?.isBefore(this._dateNavigationService.hoveredDay));
13143
+ this._dayView.dayModel?.isBefore(this._dateNavigationService.hoveredDay, true));
13120
13144
  }
13121
13145
  else {
13122
13146
  return false;
@@ -14273,6 +14297,9 @@ class ClrYearpicker {
14273
14297
  get calendarYear() {
14274
14298
  return this._dateNavigationService.displayedCalendar.year;
14275
14299
  }
14300
+ isCurrentCalendarYear(year) {
14301
+ return year === new Date().getFullYear();
14302
+ }
14276
14303
  getIsRangeStartYear(year) {
14277
14304
  return this._dateNavigationService.isRangePicker && year === this._dateNavigationService.selectedDay?.year;
14278
14305
  }
@@ -14456,6 +14483,7 @@ ClrYearpicker.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version:
14456
14483
  [class.is-start-range]="getIsRangeStartYear(year)"
14457
14484
  [class.is-end-range]="getIsRangeEndYear(year)"
14458
14485
  [class.in-range]="isInRange(year)"
14486
+ [class.is-today]="isCurrentCalendarYear(year)"
14459
14487
  (click)="changeYear(year)"
14460
14488
  (mouseenter)="onHover(year)"
14461
14489
  >
@@ -14516,6 +14544,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
14516
14544
  [class.is-start-range]="getIsRangeStartYear(year)"
14517
14545
  [class.is-end-range]="getIsRangeEndYear(year)"
14518
14546
  [class.in-range]="isInRange(year)"
14547
+ [class.is-today]="isCurrentCalendarYear(year)"
14519
14548
  (click)="changeYear(year)"
14520
14549
  (mouseenter)="onHover(year)"
14521
14550
  >
@@ -17639,22 +17668,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
17639
17668
  * This software is released under MIT license.
17640
17669
  * The full license information can be found in LICENSE in the root directory of this project.
17641
17670
  */
17642
- function getTabableItems(el) {
17643
- const tabableSelector = [
17644
- 'a[href]',
17645
- 'area[href]',
17646
- 'input:not([disabled])',
17647
- 'button:not([disabled])',
17648
- 'select:not([disabled])',
17649
- 'textarea:not([disabled])',
17650
- 'iframe',
17651
- 'object',
17652
- 'embed',
17653
- '*[tabindex]:not([disabled])',
17654
- '*[contenteditable=true]',
17655
- '[role=button]:not([disabled])',
17656
- ].join(',');
17657
- return Array.from(el.querySelectorAll(tabableSelector));
17671
+ const actionableItemSelectors = [
17672
+ 'a[href]',
17673
+ 'area[href]',
17674
+ 'input:not([disabled])',
17675
+ 'button:not([disabled])',
17676
+ 'select:not([disabled])',
17677
+ 'textarea:not([disabled])',
17678
+ 'iframe',
17679
+ 'object',
17680
+ 'embed',
17681
+ '[contenteditable=true]',
17682
+ '[role=button]:not([disabled])',
17683
+ ];
17684
+ function getTabbableItems(el) {
17685
+ const tabbableItemSelectors = [...actionableItemSelectors, '[tabindex="0"]:not([disabled])'];
17686
+ const tabbableSelector = tabbableItemSelectors.join(',');
17687
+ return Array.from(el.querySelectorAll(tabbableSelector));
17688
+ }
17689
+ function isActionableItem(el) {
17690
+ const actionableSelector = actionableItemSelectors.join(',');
17691
+ return el.matches(actionableSelector);
17658
17692
  }
17659
17693
  class KeyNavigationGridController {
17660
17694
  constructor(zone) {
@@ -17664,7 +17698,7 @@ class KeyNavigationGridController {
17664
17698
  this.destroy$ = new Subject();
17665
17699
  this._activeCell = null;
17666
17700
  this.config = {
17667
- keyGridRows: '[role=row]:not(.datagrid-placeholder)',
17701
+ keyGridRows: '[role=row]:not(.datagrid-placeholder):not([style*="display: none"])',
17668
17702
  keyGridCells: '[role=gridcell]:not(.datagrid-hidden-column):not(.datagrid-placeholder-content), [role=columnheader]:not(.datagrid-hidden-column):not(.datagrid-placeholder-content), .datagrid-detail-caret',
17669
17703
  keyGrid: '[role=grid]',
17670
17704
  };
@@ -17696,7 +17730,7 @@ class KeyNavigationGridController {
17696
17730
  ? Array.from(this.cells).find(c => c === e.target || c === e.target.closest(this.config.keyGridCells))
17697
17731
  : null;
17698
17732
  if (activeCell) {
17699
- this.setActiveCell(activeCell);
17733
+ this.setActiveCell(activeCell, { keepFocus: isActionableItem(e.target) });
17700
17734
  }
17701
17735
  }
17702
17736
  });
@@ -17729,9 +17763,12 @@ class KeyNavigationGridController {
17729
17763
  e.key === Keys.Home ||
17730
17764
  e.key === Keys.PageUp ||
17731
17765
  e.key === Keys.PageDown) {
17732
- const { x, y } = this.getNextItemCoordinate(e);
17766
+ const currentCellCoords = this.getCurrentCellCoordinates();
17767
+ const nextCellCoords = this.isExpandedRow(currentCellCoords.y) || this.isDetailsRow(currentCellCoords.y)
17768
+ ? this.getNextForExpandedRowCoordinate(e, currentCellCoords)
17769
+ : this.getNextItemCoordinate(e, currentCellCoords);
17733
17770
  const activeItem = this.rows
17734
- ? Array.from(this.rows[y].querySelectorAll(this.config.keyGridCells))[x]
17771
+ ? Array.from(this.getCellsForRow(nextCellCoords.y))[nextCellCoords.x]
17735
17772
  : null;
17736
17773
  if (activeItem) {
17737
17774
  this.setActiveCell(activeItem);
@@ -17758,66 +17795,240 @@ class KeyNavigationGridController {
17758
17795
  getActiveCell() {
17759
17796
  return this._activeCell;
17760
17797
  }
17761
- setActiveCell(activeCell) {
17798
+ setActiveCell(activeCell, { keepFocus } = { keepFocus: false }) {
17762
17799
  const prior = this.cells ? Array.from(this.cells).find(c => c.getAttribute('tabindex') === '0') : null;
17763
17800
  if (prior) {
17764
17801
  prior.setAttribute('tabindex', '-1');
17765
17802
  }
17766
17803
  activeCell.setAttribute('tabindex', '0');
17767
17804
  this._activeCell = activeCell;
17768
- const items = getTabableItems(activeCell);
17769
- const item = activeCell.getAttribute('role') !== 'columnheader' && items[0] ? items[0] : activeCell;
17770
- if (!this.skipItemFocus) {
17771
- item.focus();
17805
+ if (!this.skipItemFocus && !keepFocus) {
17806
+ let elementToFocus;
17807
+ if (activeCell.getAttribute('role') === 'columnheader') {
17808
+ elementToFocus = activeCell;
17809
+ }
17810
+ else {
17811
+ const tabbableElements = getTabbableItems(activeCell);
17812
+ elementToFocus = tabbableElements.length ? tabbableElements[0] : activeCell;
17813
+ }
17814
+ elementToFocus.focus();
17772
17815
  }
17773
17816
  }
17774
- getNextItemCoordinate(e) {
17775
- let currentCell = this.cells ? Array.from(this.cells).find(i => i.getAttribute('tabindex') === '0') : null;
17776
- if (e.key === Keys.Tab) {
17777
- currentCell = document.activeElement;
17817
+ getNextForExpandedRowCoordinate(e, currentCellCoords) {
17818
+ if (e.key === Keys.PageUp || e.key === Keys.PageDown) {
17819
+ return this.getNextItemCoordinate(e, currentCellCoords);
17778
17820
  }
17779
- const currentRow = this.rows && currentCell ? Array.from(this.rows).find(r => r.contains(currentCell)) : null;
17780
- const numOfRows = this.rows ? this.rows.length - 1 : 0;
17781
- const numOfColumns = this.cells ? Math.floor(this.cells.length / this.rows.length - 1) : 0;
17782
- let x = currentRow && currentCell
17783
- ? Array.from(currentRow.querySelectorAll(this.config.keyGridCells)).indexOf(currentCell)
17784
- : 0;
17785
- let y = currentRow && currentCell && this.rows ? Array.from(this.rows).indexOf(currentRow) : 0;
17786
- const dir = this.host.dir;
17787
- const inlineStart = dir === 'rtl' ? Keys.ArrowRight : Keys.ArrowLeft;
17788
- const inlineEnd = dir === 'rtl' ? Keys.ArrowLeft : Keys.ArrowRight;
17789
- const itemsPerPage = Math.floor(this.host?.querySelector('.datagrid').clientHeight / this.rows[0].clientHeight) - 1 || 0;
17790
- if (e.key === Keys.ArrowUp && y !== 0) {
17791
- y = y - 1;
17821
+ if (!this.isDetailsRow(currentCellCoords.y) &&
17822
+ !this.isRowReplaced(currentCellCoords.y) &&
17823
+ (e.key === Keys.Home || e.key === Keys.End || e.key === Keys.ArrowRight || e.key === Keys.ArrowLeft)) {
17824
+ return this.getNextItemCoordinate(e, currentCellCoords);
17825
+ }
17826
+ const { numOfRows, numOfColumns, inlineStart, inlineEnd, isActionCell, nextCellCoords } = this.getCalcVariables(currentCellCoords);
17827
+ const isSingleCellExpandedRow = this.isSingleCellExpandedRow(currentCellCoords.y);
17828
+ if (e.key === Keys.ArrowUp && currentCellCoords.y !== 0) {
17829
+ nextCellCoords.y = currentCellCoords.y - 1;
17830
+ if (isSingleCellExpandedRow && !isActionCell) {
17831
+ if (this.isRowReplaced(currentCellCoords.y)) {
17832
+ nextCellCoords.y = nextCellCoords.y - 1;
17833
+ }
17834
+ if (this.isDetailsRow(nextCellCoords.y)) {
17835
+ nextCellCoords.x = 0;
17836
+ }
17837
+ else if (this.isDetailsRow(currentCellCoords.y) === false) {
17838
+ // false check is intentional, the ! operator may be missed easily in this case
17839
+ nextCellCoords.x = currentCellCoords.x;
17840
+ }
17841
+ else {
17842
+ nextCellCoords.x = this.actionCellCount(nextCellCoords.y);
17843
+ }
17844
+ return nextCellCoords;
17845
+ }
17846
+ if (isActionCell && this.isDetailsRow(nextCellCoords.y)) {
17847
+ nextCellCoords.y = nextCellCoords.y - 1;
17848
+ }
17849
+ else if (this.isRowReplaced(nextCellCoords.y)) {
17850
+ nextCellCoords.y = nextCellCoords.y - 1;
17851
+ if (!this.isDetailsRow(nextCellCoords.y)) {
17852
+ nextCellCoords.x = currentCellCoords.x + this.actionCellCount(nextCellCoords.y);
17853
+ }
17854
+ }
17855
+ else if (this.isDetailsRow(currentCellCoords.y) && !this.isDetailsRow(nextCellCoords.y)) {
17856
+ nextCellCoords.x = currentCellCoords.x + this.actionCellCount(nextCellCoords.y);
17857
+ }
17858
+ else if (!isActionCell && this.isDetailsRow(nextCellCoords.y)) {
17859
+ nextCellCoords.x = currentCellCoords.x - this.actionCellCount(currentCellCoords.y);
17860
+ }
17861
+ }
17862
+ else if (e.key === Keys.ArrowDown && currentCellCoords.y < numOfRows) {
17863
+ nextCellCoords.y = currentCellCoords.y + 1;
17864
+ if (isSingleCellExpandedRow && !isActionCell) {
17865
+ if (this.isRowReplaced(nextCellCoords.y)) {
17866
+ nextCellCoords.y = nextCellCoords.y + 1;
17867
+ }
17868
+ if (this.isDetailsRow(nextCellCoords.y)) {
17869
+ nextCellCoords.x = 0;
17870
+ }
17871
+ else {
17872
+ nextCellCoords.x = this.actionCellCount(nextCellCoords.y);
17873
+ }
17874
+ return nextCellCoords;
17875
+ }
17876
+ if (isActionCell || this.isRowReplaced(nextCellCoords.y)) {
17877
+ nextCellCoords.y = nextCellCoords.y + 1;
17878
+ }
17879
+ else if (this.getCellsForRow(currentCellCoords.y).length > numOfColumns) {
17880
+ nextCellCoords.x = currentCellCoords.x - this.actionCellCount(currentCellCoords.y);
17881
+ }
17882
+ else {
17883
+ nextCellCoords.x = currentCellCoords.x + this.actionCellCount(nextCellCoords.y);
17884
+ }
17885
+ }
17886
+ else if (e.key === inlineStart) {
17887
+ if (currentCellCoords.x !== 0) {
17888
+ nextCellCoords.x = currentCellCoords.x - 1;
17889
+ }
17890
+ else if (!isActionCell) {
17891
+ nextCellCoords.y = currentCellCoords.y - 1;
17892
+ nextCellCoords.x = this.actionCellCount(nextCellCoords.y) - 1;
17893
+ }
17894
+ }
17895
+ else if (e.key === inlineEnd && currentCellCoords.x < numOfColumns) {
17896
+ if (isActionCell &&
17897
+ currentCellCoords.x === this.actionCellCount(currentCellCoords.x) - 1 &&
17898
+ this.isRowReplaced(currentCellCoords.y) &&
17899
+ !this.isDetailsRow(currentCellCoords.y)) {
17900
+ nextCellCoords.y = currentCellCoords.y + 1;
17901
+ nextCellCoords.x = 0;
17902
+ }
17903
+ else {
17904
+ nextCellCoords.x = currentCellCoords.x + 1;
17905
+ }
17906
+ }
17907
+ else if (e.key === Keys.End) {
17908
+ nextCellCoords.x = this.getCellsForRow(currentCellCoords.y).length - 1;
17909
+ if (e.ctrlKey) {
17910
+ nextCellCoords.x = numOfColumns;
17911
+ nextCellCoords.y = numOfRows;
17912
+ }
17913
+ }
17914
+ else if (e.key === Keys.Home) {
17915
+ nextCellCoords.x = 0;
17916
+ nextCellCoords.y = currentCellCoords.y - 1;
17917
+ if (e.ctrlKey) {
17918
+ nextCellCoords.y = 0;
17919
+ }
17920
+ }
17921
+ return nextCellCoords;
17922
+ }
17923
+ getNextItemCoordinate(e, currentCellCoords) {
17924
+ const { numOfRows, numOfColumns, inlineStart, inlineEnd, itemsPerPage, isActionCell, nextCellCoords } = this.getCalcVariables(currentCellCoords);
17925
+ if (e.key === Keys.ArrowUp && currentCellCoords.y !== 0) {
17926
+ nextCellCoords.y = currentCellCoords.y - 1;
17927
+ if (this.isSingleCellExpandedRow(nextCellCoords.y) && !isActionCell && this.isDetailsRow(nextCellCoords.y)) {
17928
+ nextCellCoords.x = 0;
17929
+ return nextCellCoords;
17930
+ }
17931
+ if (this.isDetailsRow(nextCellCoords.y)) {
17932
+ if (isActionCell) {
17933
+ nextCellCoords.y = nextCellCoords.y - 1;
17934
+ }
17935
+ else {
17936
+ nextCellCoords.x = nextCellCoords.x - this.actionCellCount(currentCellCoords.y);
17937
+ }
17938
+ }
17792
17939
  }
17793
- else if (e.key === Keys.ArrowDown && y < numOfRows) {
17794
- y = y + 1;
17940
+ else if (e.key === Keys.ArrowDown && currentCellCoords.y < numOfRows) {
17941
+ nextCellCoords.y = currentCellCoords.y + 1;
17942
+ if (this.isSingleCellExpandedRow(nextCellCoords.y) && !isActionCell && this.isRowReplaced(nextCellCoords.y)) {
17943
+ nextCellCoords.x = 0;
17944
+ nextCellCoords.y = nextCellCoords.y + 1;
17945
+ return nextCellCoords;
17946
+ }
17947
+ if (!isActionCell && this.isRowReplaced(nextCellCoords.y)) {
17948
+ nextCellCoords.y = nextCellCoords.y + 1;
17949
+ nextCellCoords.x = nextCellCoords.x - this.actionCellCount(currentCellCoords.y);
17950
+ }
17795
17951
  }
17796
- else if (e.key === inlineStart && x !== 0) {
17797
- x = x - 1;
17952
+ else if (e.key === inlineStart && currentCellCoords.x !== 0) {
17953
+ nextCellCoords.x = currentCellCoords.x - 1;
17798
17954
  }
17799
- else if (e.key === inlineEnd && x < numOfColumns) {
17800
- x = x + 1;
17955
+ else if (e.key === inlineEnd && currentCellCoords.x < numOfColumns) {
17956
+ nextCellCoords.x = currentCellCoords.x + 1;
17801
17957
  }
17802
17958
  else if (e.key === Keys.End) {
17803
- x = numOfColumns;
17959
+ nextCellCoords.x = numOfColumns;
17804
17960
  if (e.ctrlKey) {
17805
- y = numOfRows;
17961
+ nextCellCoords.y = numOfRows;
17806
17962
  }
17807
17963
  }
17808
17964
  else if (e.key === Keys.Home) {
17809
- x = 0;
17965
+ nextCellCoords.x = 0;
17810
17966
  if (e.ctrlKey) {
17811
- y = 0;
17967
+ nextCellCoords.y = 0;
17812
17968
  }
17813
17969
  }
17814
17970
  else if (e.key === Keys.PageUp) {
17815
- y = y - itemsPerPage > 0 ? y - itemsPerPage + 1 : 1;
17971
+ nextCellCoords.y = currentCellCoords.y - itemsPerPage > 0 ? currentCellCoords.y - itemsPerPage + 1 : 1;
17816
17972
  }
17817
17973
  else if (e.key === Keys.PageDown) {
17818
- y = y + itemsPerPage < numOfRows ? y + itemsPerPage : numOfRows;
17974
+ nextCellCoords.y =
17975
+ currentCellCoords.y + itemsPerPage < numOfRows ? currentCellCoords.y + itemsPerPage : numOfRows;
17819
17976
  }
17820
- return { x, y };
17977
+ return nextCellCoords;
17978
+ }
17979
+ getCalcVariables(currentCellCoords) {
17980
+ const numOfRows = this.rows ? this.rows.length - 1 : 0;
17981
+ // calculate numOfColumns based on header cells.
17982
+ const numOfColumns = numOfRows ? this.getCellsForRow(0).length - 1 : 0;
17983
+ const dir = this.host.dir;
17984
+ const inlineStart = dir === 'rtl' ? Keys.ArrowRight : Keys.ArrowLeft;
17985
+ const inlineEnd = dir === 'rtl' ? Keys.ArrowLeft : Keys.ArrowRight;
17986
+ const itemsPerPage = Math.floor(this.host?.querySelector('.datagrid').clientHeight / this.rows[0].clientHeight) - 1 || 0;
17987
+ const isActionCell = this.isActionCell(currentCellCoords);
17988
+ const nextCellCoords = {
17989
+ x: currentCellCoords.x,
17990
+ y: currentCellCoords.y,
17991
+ };
17992
+ return { numOfRows, numOfColumns, inlineStart, inlineEnd, itemsPerPage, isActionCell, nextCellCoords };
17993
+ }
17994
+ getCurrentCellCoordinates() {
17995
+ const currentCell = this.cells ? Array.from(this.cells).find(i => i.getAttribute('tabindex') === '0') : null;
17996
+ const currentRow = currentCell ? currentCell.closest(this.config.keyGridRows) : null;
17997
+ const coordinates = {
17998
+ x: currentRow && currentCell
17999
+ ? Array.from(currentRow.querySelectorAll(this.config.keyGridCells)).indexOf(currentCell)
18000
+ : 0,
18001
+ y: currentRow && currentCell && this.rows ? Array.from(this.rows).indexOf(currentRow) : 0,
18002
+ };
18003
+ return coordinates;
18004
+ }
18005
+ getCellsForRow(index) {
18006
+ return this.rows[index].querySelectorAll(this.config.keyGridCells);
18007
+ }
18008
+ isExpandedRow(index) {
18009
+ const selectedElement = this.rows[index].querySelector('.datagrid-row-detail');
18010
+ return selectedElement ? selectedElement.style.display !== 'none' : false;
18011
+ }
18012
+ isDetailsRow(index) {
18013
+ return this.rows[index].classList.contains('datagrid-row-detail');
18014
+ }
18015
+ isRowReplaced(index) {
18016
+ return !!this.rows[index].closest('clr-dg-row.datagrid-row-replaced');
18017
+ }
18018
+ isSingleCellExpandedRow(index) {
18019
+ const row = this.rows[index].classList.contains('datagrid-row-detail')
18020
+ ? this.rows[index]
18021
+ : this.rows[index].querySelector('.datagrid-row-detail');
18022
+ return row?.querySelectorAll(this.config.keyGridCells).length === 1;
18023
+ }
18024
+ actionCellCount(index) {
18025
+ return this.actionCellsAsArray(index).length;
18026
+ }
18027
+ actionCellsAsArray(index) {
18028
+ return Array.from(this.rows[index].querySelectorAll('.datagrid-row-sticky .datagrid-cell, .datagrid-row-sticky .datagrid-column'));
18029
+ }
18030
+ isActionCell(cellCoords) {
18031
+ return !!this.actionCellsAsArray(cellCoords.y)[cellCoords.x];
17821
18032
  }
17822
18033
  }
17823
18034
  KeyNavigationGridController.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: KeyNavigationGridController, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
@@ -19542,17 +19753,17 @@ class ClrDatagridColumn extends DatagridFilterRegistrar {
19542
19753
  return;
19543
19754
  }
19544
19755
  switch (value) {
19545
- // the Unsorted case happens when the current state is either Asc or Desc
19546
- default:
19547
- case ClrDatagridSortOrder.UNSORTED:
19548
- this._sort.clear();
19549
- break;
19550
19756
  case ClrDatagridSortOrder.ASC:
19551
19757
  this.sort(false);
19552
19758
  break;
19553
19759
  case ClrDatagridSortOrder.DESC:
19554
19760
  this.sort(true);
19555
19761
  break;
19762
+ // the Unsorted case happens when the current state is neither Asc or Desc
19763
+ case ClrDatagridSortOrder.UNSORTED:
19764
+ default:
19765
+ this._sort.clear();
19766
+ break;
19556
19767
  }
19557
19768
  }
19558
19769
  set updateFilterValue(newValue) {
@@ -19592,13 +19803,13 @@ class ClrDatagridColumn extends DatagridFilterRegistrar {
19592
19803
  }
19593
19804
  get ariaSort() {
19594
19805
  switch (this._sortOrder) {
19595
- default:
19596
- case ClrDatagridSortOrder.UNSORTED:
19597
- return 'none';
19598
19806
  case ClrDatagridSortOrder.ASC:
19599
19807
  return 'ascending';
19600
19808
  case ClrDatagridSortOrder.DESC:
19601
19809
  return 'descending';
19810
+ case ClrDatagridSortOrder.UNSORTED:
19811
+ default:
19812
+ return 'none';
19602
19813
  }
19603
19814
  }
19604
19815
  get sortDirection() {
@@ -20953,7 +21164,7 @@ ClrDatagridRow.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version
20953
21164
  DatagridIfExpandService,
20954
21165
  { provide: IfExpandService, useExisting: DatagridIfExpandService },
20955
21166
  { provide: LoadingListener, useExisting: DatagridIfExpandService },
20956
- ], queries: [{ propertyName: "dgCells", predicate: ClrDatagridCell }], viewQueries: [{ propertyName: "expandAnimation", first: true, predicate: ClrExpandableAnimation, descendants: true }, { propertyName: "detailButton", first: true, predicate: ["detailButton"], descendants: true }, { propertyName: "_stickyCells", first: true, predicate: ["stickyCells"], descendants: true, read: ViewContainerRef }, { propertyName: "_scrollableCells", first: true, predicate: ["scrollableCells"], descendants: true, read: ViewContainerRef }, { propertyName: "_calculatedCells", first: true, predicate: ["calculatedCells"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<!--\n We need to wrap the #rowContent in label element if we are in rowSelectionMode.\n Clicking of that wrapper label will equate to clicking on the whole row, which triggers the checkbox to toggle.\n-->\n<div\n class=\"datagrid-row-clickable\"\n *ngIf=\"selection.rowSelectionMode\"\n (mousedown)=\"clearRanges($event)\"\n (click)=\"selectRow(!selected, $event)\"\n>\n <clr-expandable-animation [clrExpandTrigger]=\"expandAnimationTrigger\" *ngIf=\"expand.expandable\">\n <ng-template [ngTemplateOutlet]=\"rowContent\"></ng-template>\n </clr-expandable-animation>\n <ng-template [ngTemplateOutlet]=\"rowContent\" *ngIf=\"!expand.expandable\"></ng-template>\n</div>\n\n<clr-expandable-animation\n *ngIf=\"!selection.rowSelectionMode && expand.expandable\"\n [clrExpandTrigger]=\"expandAnimationTrigger\"\n>\n <ng-template [ngTemplateOutlet]=\"rowContent\"></ng-template>\n</clr-expandable-animation>\n\n<ng-template *ngIf=\"!selection.rowSelectionMode && !expand.expandable\" [ngTemplateOutlet]=\"rowContent\"></ng-template>\n\n<!--\n We need the \"project into template\" hacks because we need this in 2 different places\n depending on whether the details replace the row or not.\n-->\n<ng-template #detail>\n <ng-content select=\"clr-dg-row-detail\"></ng-content>\n</ng-template>\n\n<ng-template #rowContent>\n <div\n role=\"row\"\n [id]=\"id\"\n class=\"datagrid-row-master datagrid-row-flex\"\n [class.datagrid-row-detail-open]=\"detailService.isRowOpen(item)\"\n >\n <div class=\"datagrid-row-sticky\">\n <!-- Sticky elements here -->\n <ng-container #stickyCells>\n <div\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Multi\"\n class=\"datagrid-select datagrid-fixed-column datagrid-cell\"\n [ngClass]=\"{ 'clr-form-control-disabled': !clrDgSelectable }\"\n role=\"gridcell\"\n >\n <div class=\"clr-checkbox-wrapper\">\n <input\n tabindex=\"-1\"\n type=\"checkbox\"\n [ngModel]=\"selected\"\n (ngModelChange)=\"toggle($event)\"\n [id]=\"checkboxId\"\n [disabled]=\"clrDgSelectable ? null : true\"\n [attr.aria-disabled]=\"clrDgSelectable ? null : true\"\n />\n <!-- Usage of class clr-col-null here prevents clr-col-* classes from being added when a datagrid is wrapped inside clrForm -->\n <label [for]=\"checkboxId\" class=\"clr-control-label clr-col-null\" (click)=\"clearRanges($event)\">\n <span class=\"clr-sr-only\">{{clrDgRowSelectionLabel || commonStrings.keys.select}}</span>\n </label>\n </div>\n </div>\n <div\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Single\"\n class=\"datagrid-select datagrid-fixed-column datagrid-cell\"\n [ngClass]=\"{ 'clr-form-control-disabled': !clrDgSelectable }\"\n role=\"gridcell\"\n >\n <clr-radio-wrapper>\n <input\n tabindex=\"-1\"\n type=\"radio\"\n clrRadio\n [id]=\"radioId\"\n [name]=\"selection.id + '-radio'\"\n [value]=\"item\"\n [(ngModel)]=\"selection.currentSingle\"\n [checked]=\"selection.currentSingle === item\"\n [disabled]=\"clrDgSelectable ? null : true\"\n [attr.aria-disabled]=\"clrDgSelectable ? null : true\"\n />\n <label class=\"clr-control-label clr-col-null\" [for]=\"radioId\">\n <span class=\"clr-sr-only\">{{ clrDgRowSelectionLabel || commonStrings.keys.select }}</span>\n </label>\n </clr-radio-wrapper>\n </div>\n <div\n *ngIf=\"rowActionService.hasActionableRow\"\n class=\"datagrid-row-actions datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <ng-content select=\"clr-dg-action-overflow\"></ng-content>\n </div>\n <div\n *ngIf=\"globalExpandable.hasExpandableRow\"\n class=\"datagrid-expandable-caret datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <ng-container *ngIf=\"expand.expandable\">\n <button\n tabindex=\"-1\"\n *ngIf=\"!expand.loading\"\n (click)=\"toggleExpand()\"\n type=\"button\"\n class=\"datagrid-expandable-caret-button\"\n [attr.aria-expanded]=\"expand.expanded\"\n [attr.aria-label]=\"expand.expanded ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-controls]=\"expandableId\"\n >\n <cds-icon\n shape=\"angle\"\n class=\"datagrid-expandable-caret-icon\"\n [attr.direction]=\"expand.expanded ? 'down' : 'right'\"\n [attr.title]=\"expand.expanded ? commonStrings.keys.collapse : commonStrings.keys.expand\"\n ></cds-icon>\n </button>\n <clr-spinner *ngIf=\"expand.loading\" clrSmall>{{ commonStrings.keys.loading }}</clr-spinner>\n </ng-container>\n </div>\n <div\n *ngIf=\"detailService.enabled\"\n class=\"datagrid-detail-caret datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <button\n tabindex=\"-1\"\n (click)=\"detailService.toggle(item, detailButton)\"\n type=\"button\"\n #detailButton\n class=\"datagrid-detail-caret-button\"\n [disabled]=\"detailDisabled\"\n *ngIf=\"!detailHidden\"\n [class.is-open]=\"detailService.isRowOpen(item)\"\n [attr.aria-label]=\"detailService.isRowOpen(item) ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-expanded]=\"detailService.isRowOpen(item)\"\n [attr.aria-controls]=\"detailService.id\"\n aria-haspopup=\"dialog\"\n >\n <cds-icon\n shape=\"angle-double\"\n [attr.direction]=\"detailService.isRowOpen(item) ? 'left' : 'right'\"\n class=\"datagrid-detail-caret-icon\"\n [attr.title]=\"detailService.isRowOpen(item) ? commonStrings.keys.close: commonStrings.keys.open\"\n ></cds-icon>\n </button>\n </div>\n </ng-container>\n <!-- placeholder for projecting other sticky cells as pinned-->\n </div>\n <div class=\"datagrid-row-scrollable\" [ngClass]=\"{'is-replaced': replaced && expanded}\">\n <div class=\"datagrid-scrolling-cells\">\n <ng-content select=\"clr-dg-cell\"></ng-content>\n <ng-container #scrollableCells></ng-container>\n </div>\n <!-- details here when replace, re-visit when sticky container is used for pinned cells -->\n <ng-template *ngIf=\"replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n <ng-template *ngIf=\"!replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n </div>\n </div>\n</ng-template>\n\n<ng-container #calculatedCells></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: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }, { kind: "directive", type: ClrLabel, selector: "label", inputs: ["id", "for"] }, { kind: "directive", type: ClrRadio, selector: "[clrRadio]" }, { kind: "component", type: ClrRadioWrapper, selector: "clr-radio-wrapper" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ClrExpandableAnimation, selector: "clr-expandable-animation", inputs: ["clrExpandTrigger"] }, { kind: "component", type: ClrSpinner, selector: "clr-spinner", inputs: ["clrInline", "clrInverse", "clrSmall", "clrMedium"] }, { kind: "directive", type: ClrDatagridSelectionCellDirective, selector: ".datagrid-select" }] });
21167
+ ], queries: [{ propertyName: "dgCells", predicate: ClrDatagridCell }], viewQueries: [{ propertyName: "expandAnimation", first: true, predicate: ClrExpandableAnimation, descendants: true }, { propertyName: "detailButton", first: true, predicate: ["detailButton"], descendants: true }, { propertyName: "_stickyCells", first: true, predicate: ["stickyCells"], descendants: true, read: ViewContainerRef }, { propertyName: "_scrollableCells", first: true, predicate: ["scrollableCells"], descendants: true, read: ViewContainerRef }, { propertyName: "_calculatedCells", first: true, predicate: ["calculatedCells"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<!--\n We need to wrap the #rowContent in label element if we are in rowSelectionMode.\n Clicking of that wrapper label will equate to clicking on the whole row, which triggers the checkbox to toggle.\n-->\n<div\n class=\"datagrid-row-clickable\"\n *ngIf=\"selection.rowSelectionMode\"\n (mousedown)=\"clearRanges($event)\"\n (click)=\"selectRow(!selected, $event)\"\n>\n <clr-expandable-animation [clrExpandTrigger]=\"expandAnimationTrigger\" *ngIf=\"expand.expandable\">\n <ng-template [ngTemplateOutlet]=\"rowContent\"></ng-template>\n </clr-expandable-animation>\n <ng-template [ngTemplateOutlet]=\"rowContent\" *ngIf=\"!expand.expandable\"></ng-template>\n</div>\n\n<clr-expandable-animation\n *ngIf=\"!selection.rowSelectionMode && expand.expandable\"\n [clrExpandTrigger]=\"expandAnimationTrigger\"\n>\n <ng-template [ngTemplateOutlet]=\"rowContent\"></ng-template>\n</clr-expandable-animation>\n\n<ng-template *ngIf=\"!selection.rowSelectionMode && !expand.expandable\" [ngTemplateOutlet]=\"rowContent\"></ng-template>\n\n<!--\n We need the \"project into template\" hacks because we need this in 2 different places\n depending on whether the details replace the row or not.\n-->\n<ng-template #detail>\n <ng-content select=\"clr-dg-row-detail\"></ng-content>\n</ng-template>\n\n<ng-template #rowContent>\n <div\n role=\"row\"\n [id]=\"id\"\n class=\"datagrid-row-master datagrid-row-flex\"\n [class.datagrid-row-detail-open]=\"detailService.isRowOpen(item)\"\n >\n <div class=\"datagrid-row-sticky\">\n <!-- Sticky elements here -->\n <ng-container #stickyCells>\n <div\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Multi\"\n class=\"datagrid-select datagrid-fixed-column datagrid-cell\"\n [ngClass]=\"{ 'clr-form-control-disabled': !clrDgSelectable }\"\n role=\"gridcell\"\n >\n <div class=\"clr-checkbox-wrapper\">\n <input\n tabindex=\"-1\"\n type=\"checkbox\"\n [ngModel]=\"selected\"\n (ngModelChange)=\"toggle($event)\"\n [id]=\"checkboxId\"\n [disabled]=\"clrDgSelectable ? null : true\"\n [attr.aria-disabled]=\"clrDgSelectable ? null : true\"\n />\n <!-- Usage of class clr-col-null here prevents clr-col-* classes from being added when a datagrid is wrapped inside clrForm -->\n <label [for]=\"checkboxId\" class=\"clr-control-label clr-col-null\" (click)=\"clearRanges($event)\">\n <span class=\"clr-sr-only\">{{clrDgRowSelectionLabel || commonStrings.keys.select}}</span>\n </label>\n </div>\n </div>\n <div\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Single\"\n class=\"datagrid-select datagrid-fixed-column datagrid-cell\"\n [ngClass]=\"{ 'clr-form-control-disabled': !clrDgSelectable }\"\n role=\"gridcell\"\n >\n <clr-radio-wrapper>\n <input\n tabindex=\"-1\"\n type=\"radio\"\n clrRadio\n [id]=\"radioId\"\n [name]=\"selection.id + '-radio'\"\n [value]=\"item\"\n [(ngModel)]=\"selection.currentSingle\"\n [checked]=\"selection.currentSingle === item\"\n [disabled]=\"clrDgSelectable ? null : true\"\n [attr.aria-disabled]=\"clrDgSelectable ? null : true\"\n />\n <label class=\"clr-control-label clr-col-null\" [for]=\"radioId\">\n <span class=\"clr-sr-only\">{{ clrDgRowSelectionLabel || commonStrings.keys.select }}</span>\n </label>\n </clr-radio-wrapper>\n </div>\n <div\n *ngIf=\"rowActionService.hasActionableRow\"\n class=\"datagrid-row-actions datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <ng-content select=\"clr-dg-action-overflow\"></ng-content>\n </div>\n <div\n *ngIf=\"globalExpandable.hasExpandableRow\"\n class=\"datagrid-expandable-caret datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <ng-container *ngIf=\"expand.expandable\">\n <button\n tabindex=\"-1\"\n *ngIf=\"!expand.loading\"\n (click)=\"toggleExpand()\"\n type=\"button\"\n class=\"datagrid-expandable-caret-button\"\n [attr.aria-expanded]=\"expand.expanded\"\n [attr.aria-label]=\"expand.expanded ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-controls]=\"expand.hasExpandTemplate && !expand.expanded ? null : expandableId\"\n >\n <cds-icon\n shape=\"angle\"\n class=\"datagrid-expandable-caret-icon\"\n [attr.direction]=\"expand.expanded ? 'down' : 'right'\"\n [attr.title]=\"expand.expanded ? commonStrings.keys.collapse : commonStrings.keys.expand\"\n ></cds-icon>\n </button>\n <clr-spinner *ngIf=\"expand.loading\" clrSmall>{{ commonStrings.keys.loading }}</clr-spinner>\n </ng-container>\n </div>\n <div\n *ngIf=\"detailService.enabled\"\n class=\"datagrid-detail-caret datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <button\n tabindex=\"-1\"\n (click)=\"detailService.toggle(item, detailButton)\"\n type=\"button\"\n #detailButton\n class=\"datagrid-detail-caret-button\"\n [disabled]=\"detailDisabled\"\n *ngIf=\"!detailHidden\"\n [class.is-open]=\"detailService.isRowOpen(item)\"\n [attr.aria-label]=\"detailService.isRowOpen(item) ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-expanded]=\"detailService.isRowOpen(item)\"\n [attr.aria-controls]=\"detailService.id\"\n aria-haspopup=\"dialog\"\n >\n <cds-icon\n shape=\"angle-double\"\n [attr.direction]=\"detailService.isRowOpen(item) ? 'left' : 'right'\"\n class=\"datagrid-detail-caret-icon\"\n [attr.title]=\"detailService.isRowOpen(item) ? commonStrings.keys.close: commonStrings.keys.open\"\n ></cds-icon>\n </button>\n </div>\n </ng-container>\n <!-- placeholder for projecting other sticky cells as pinned-->\n </div>\n <div class=\"datagrid-row-scrollable\" [ngClass]=\"{'is-replaced': replaced && expanded}\">\n <div class=\"datagrid-scrolling-cells\">\n <ng-content select=\"clr-dg-cell\"></ng-content>\n <ng-container #scrollableCells></ng-container>\n </div>\n <!-- details here when replace, re-visit when sticky container is used for pinned cells -->\n <ng-template *ngIf=\"replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n <ng-template *ngIf=\"!replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n </div>\n </div>\n</ng-template>\n\n<ng-container #calculatedCells></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: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }, { kind: "directive", type: ClrLabel, selector: "label", inputs: ["id", "for"] }, { kind: "directive", type: ClrRadio, selector: "[clrRadio]" }, { kind: "component", type: ClrRadioWrapper, selector: "clr-radio-wrapper" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ClrExpandableAnimation, selector: "clr-expandable-animation", inputs: ["clrExpandTrigger"] }, { kind: "component", type: ClrSpinner, selector: "clr-spinner", inputs: ["clrInline", "clrInverse", "clrSmall", "clrMedium"] }, { kind: "directive", type: ClrDatagridSelectionCellDirective, selector: ".datagrid-select" }] });
20957
21168
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridRow, decorators: [{
20958
21169
  type: Component,
20959
21170
  args: [{ selector: 'clr-dg-row', host: {
@@ -20965,7 +21176,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
20965
21176
  DatagridIfExpandService,
20966
21177
  { provide: IfExpandService, useExisting: DatagridIfExpandService },
20967
21178
  { provide: LoadingListener, useExisting: DatagridIfExpandService },
20968
- ], template: "<!--\n We need to wrap the #rowContent in label element if we are in rowSelectionMode.\n Clicking of that wrapper label will equate to clicking on the whole row, which triggers the checkbox to toggle.\n-->\n<div\n class=\"datagrid-row-clickable\"\n *ngIf=\"selection.rowSelectionMode\"\n (mousedown)=\"clearRanges($event)\"\n (click)=\"selectRow(!selected, $event)\"\n>\n <clr-expandable-animation [clrExpandTrigger]=\"expandAnimationTrigger\" *ngIf=\"expand.expandable\">\n <ng-template [ngTemplateOutlet]=\"rowContent\"></ng-template>\n </clr-expandable-animation>\n <ng-template [ngTemplateOutlet]=\"rowContent\" *ngIf=\"!expand.expandable\"></ng-template>\n</div>\n\n<clr-expandable-animation\n *ngIf=\"!selection.rowSelectionMode && expand.expandable\"\n [clrExpandTrigger]=\"expandAnimationTrigger\"\n>\n <ng-template [ngTemplateOutlet]=\"rowContent\"></ng-template>\n</clr-expandable-animation>\n\n<ng-template *ngIf=\"!selection.rowSelectionMode && !expand.expandable\" [ngTemplateOutlet]=\"rowContent\"></ng-template>\n\n<!--\n We need the \"project into template\" hacks because we need this in 2 different places\n depending on whether the details replace the row or not.\n-->\n<ng-template #detail>\n <ng-content select=\"clr-dg-row-detail\"></ng-content>\n</ng-template>\n\n<ng-template #rowContent>\n <div\n role=\"row\"\n [id]=\"id\"\n class=\"datagrid-row-master datagrid-row-flex\"\n [class.datagrid-row-detail-open]=\"detailService.isRowOpen(item)\"\n >\n <div class=\"datagrid-row-sticky\">\n <!-- Sticky elements here -->\n <ng-container #stickyCells>\n <div\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Multi\"\n class=\"datagrid-select datagrid-fixed-column datagrid-cell\"\n [ngClass]=\"{ 'clr-form-control-disabled': !clrDgSelectable }\"\n role=\"gridcell\"\n >\n <div class=\"clr-checkbox-wrapper\">\n <input\n tabindex=\"-1\"\n type=\"checkbox\"\n [ngModel]=\"selected\"\n (ngModelChange)=\"toggle($event)\"\n [id]=\"checkboxId\"\n [disabled]=\"clrDgSelectable ? null : true\"\n [attr.aria-disabled]=\"clrDgSelectable ? null : true\"\n />\n <!-- Usage of class clr-col-null here prevents clr-col-* classes from being added when a datagrid is wrapped inside clrForm -->\n <label [for]=\"checkboxId\" class=\"clr-control-label clr-col-null\" (click)=\"clearRanges($event)\">\n <span class=\"clr-sr-only\">{{clrDgRowSelectionLabel || commonStrings.keys.select}}</span>\n </label>\n </div>\n </div>\n <div\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Single\"\n class=\"datagrid-select datagrid-fixed-column datagrid-cell\"\n [ngClass]=\"{ 'clr-form-control-disabled': !clrDgSelectable }\"\n role=\"gridcell\"\n >\n <clr-radio-wrapper>\n <input\n tabindex=\"-1\"\n type=\"radio\"\n clrRadio\n [id]=\"radioId\"\n [name]=\"selection.id + '-radio'\"\n [value]=\"item\"\n [(ngModel)]=\"selection.currentSingle\"\n [checked]=\"selection.currentSingle === item\"\n [disabled]=\"clrDgSelectable ? null : true\"\n [attr.aria-disabled]=\"clrDgSelectable ? null : true\"\n />\n <label class=\"clr-control-label clr-col-null\" [for]=\"radioId\">\n <span class=\"clr-sr-only\">{{ clrDgRowSelectionLabel || commonStrings.keys.select }}</span>\n </label>\n </clr-radio-wrapper>\n </div>\n <div\n *ngIf=\"rowActionService.hasActionableRow\"\n class=\"datagrid-row-actions datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <ng-content select=\"clr-dg-action-overflow\"></ng-content>\n </div>\n <div\n *ngIf=\"globalExpandable.hasExpandableRow\"\n class=\"datagrid-expandable-caret datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <ng-container *ngIf=\"expand.expandable\">\n <button\n tabindex=\"-1\"\n *ngIf=\"!expand.loading\"\n (click)=\"toggleExpand()\"\n type=\"button\"\n class=\"datagrid-expandable-caret-button\"\n [attr.aria-expanded]=\"expand.expanded\"\n [attr.aria-label]=\"expand.expanded ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-controls]=\"expandableId\"\n >\n <cds-icon\n shape=\"angle\"\n class=\"datagrid-expandable-caret-icon\"\n [attr.direction]=\"expand.expanded ? 'down' : 'right'\"\n [attr.title]=\"expand.expanded ? commonStrings.keys.collapse : commonStrings.keys.expand\"\n ></cds-icon>\n </button>\n <clr-spinner *ngIf=\"expand.loading\" clrSmall>{{ commonStrings.keys.loading }}</clr-spinner>\n </ng-container>\n </div>\n <div\n *ngIf=\"detailService.enabled\"\n class=\"datagrid-detail-caret datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <button\n tabindex=\"-1\"\n (click)=\"detailService.toggle(item, detailButton)\"\n type=\"button\"\n #detailButton\n class=\"datagrid-detail-caret-button\"\n [disabled]=\"detailDisabled\"\n *ngIf=\"!detailHidden\"\n [class.is-open]=\"detailService.isRowOpen(item)\"\n [attr.aria-label]=\"detailService.isRowOpen(item) ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-expanded]=\"detailService.isRowOpen(item)\"\n [attr.aria-controls]=\"detailService.id\"\n aria-haspopup=\"dialog\"\n >\n <cds-icon\n shape=\"angle-double\"\n [attr.direction]=\"detailService.isRowOpen(item) ? 'left' : 'right'\"\n class=\"datagrid-detail-caret-icon\"\n [attr.title]=\"detailService.isRowOpen(item) ? commonStrings.keys.close: commonStrings.keys.open\"\n ></cds-icon>\n </button>\n </div>\n </ng-container>\n <!-- placeholder for projecting other sticky cells as pinned-->\n </div>\n <div class=\"datagrid-row-scrollable\" [ngClass]=\"{'is-replaced': replaced && expanded}\">\n <div class=\"datagrid-scrolling-cells\">\n <ng-content select=\"clr-dg-cell\"></ng-content>\n <ng-container #scrollableCells></ng-container>\n </div>\n <!-- details here when replace, re-visit when sticky container is used for pinned cells -->\n <ng-template *ngIf=\"replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n <ng-template *ngIf=\"!replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n </div>\n </div>\n</ng-template>\n\n<ng-container #calculatedCells></ng-container>\n" }]
21179
+ ], template: "<!--\n We need to wrap the #rowContent in label element if we are in rowSelectionMode.\n Clicking of that wrapper label will equate to clicking on the whole row, which triggers the checkbox to toggle.\n-->\n<div\n class=\"datagrid-row-clickable\"\n *ngIf=\"selection.rowSelectionMode\"\n (mousedown)=\"clearRanges($event)\"\n (click)=\"selectRow(!selected, $event)\"\n>\n <clr-expandable-animation [clrExpandTrigger]=\"expandAnimationTrigger\" *ngIf=\"expand.expandable\">\n <ng-template [ngTemplateOutlet]=\"rowContent\"></ng-template>\n </clr-expandable-animation>\n <ng-template [ngTemplateOutlet]=\"rowContent\" *ngIf=\"!expand.expandable\"></ng-template>\n</div>\n\n<clr-expandable-animation\n *ngIf=\"!selection.rowSelectionMode && expand.expandable\"\n [clrExpandTrigger]=\"expandAnimationTrigger\"\n>\n <ng-template [ngTemplateOutlet]=\"rowContent\"></ng-template>\n</clr-expandable-animation>\n\n<ng-template *ngIf=\"!selection.rowSelectionMode && !expand.expandable\" [ngTemplateOutlet]=\"rowContent\"></ng-template>\n\n<!--\n We need the \"project into template\" hacks because we need this in 2 different places\n depending on whether the details replace the row or not.\n-->\n<ng-template #detail>\n <ng-content select=\"clr-dg-row-detail\"></ng-content>\n</ng-template>\n\n<ng-template #rowContent>\n <div\n role=\"row\"\n [id]=\"id\"\n class=\"datagrid-row-master datagrid-row-flex\"\n [class.datagrid-row-detail-open]=\"detailService.isRowOpen(item)\"\n >\n <div class=\"datagrid-row-sticky\">\n <!-- Sticky elements here -->\n <ng-container #stickyCells>\n <div\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Multi\"\n class=\"datagrid-select datagrid-fixed-column datagrid-cell\"\n [ngClass]=\"{ 'clr-form-control-disabled': !clrDgSelectable }\"\n role=\"gridcell\"\n >\n <div class=\"clr-checkbox-wrapper\">\n <input\n tabindex=\"-1\"\n type=\"checkbox\"\n [ngModel]=\"selected\"\n (ngModelChange)=\"toggle($event)\"\n [id]=\"checkboxId\"\n [disabled]=\"clrDgSelectable ? null : true\"\n [attr.aria-disabled]=\"clrDgSelectable ? null : true\"\n />\n <!-- Usage of class clr-col-null here prevents clr-col-* classes from being added when a datagrid is wrapped inside clrForm -->\n <label [for]=\"checkboxId\" class=\"clr-control-label clr-col-null\" (click)=\"clearRanges($event)\">\n <span class=\"clr-sr-only\">{{clrDgRowSelectionLabel || commonStrings.keys.select}}</span>\n </label>\n </div>\n </div>\n <div\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Single\"\n class=\"datagrid-select datagrid-fixed-column datagrid-cell\"\n [ngClass]=\"{ 'clr-form-control-disabled': !clrDgSelectable }\"\n role=\"gridcell\"\n >\n <clr-radio-wrapper>\n <input\n tabindex=\"-1\"\n type=\"radio\"\n clrRadio\n [id]=\"radioId\"\n [name]=\"selection.id + '-radio'\"\n [value]=\"item\"\n [(ngModel)]=\"selection.currentSingle\"\n [checked]=\"selection.currentSingle === item\"\n [disabled]=\"clrDgSelectable ? null : true\"\n [attr.aria-disabled]=\"clrDgSelectable ? null : true\"\n />\n <label class=\"clr-control-label clr-col-null\" [for]=\"radioId\">\n <span class=\"clr-sr-only\">{{ clrDgRowSelectionLabel || commonStrings.keys.select }}</span>\n </label>\n </clr-radio-wrapper>\n </div>\n <div\n *ngIf=\"rowActionService.hasActionableRow\"\n class=\"datagrid-row-actions datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <ng-content select=\"clr-dg-action-overflow\"></ng-content>\n </div>\n <div\n *ngIf=\"globalExpandable.hasExpandableRow\"\n class=\"datagrid-expandable-caret datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <ng-container *ngIf=\"expand.expandable\">\n <button\n tabindex=\"-1\"\n *ngIf=\"!expand.loading\"\n (click)=\"toggleExpand()\"\n type=\"button\"\n class=\"datagrid-expandable-caret-button\"\n [attr.aria-expanded]=\"expand.expanded\"\n [attr.aria-label]=\"expand.expanded ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-controls]=\"expand.hasExpandTemplate && !expand.expanded ? null : expandableId\"\n >\n <cds-icon\n shape=\"angle\"\n class=\"datagrid-expandable-caret-icon\"\n [attr.direction]=\"expand.expanded ? 'down' : 'right'\"\n [attr.title]=\"expand.expanded ? commonStrings.keys.collapse : commonStrings.keys.expand\"\n ></cds-icon>\n </button>\n <clr-spinner *ngIf=\"expand.loading\" clrSmall>{{ commonStrings.keys.loading }}</clr-spinner>\n </ng-container>\n </div>\n <div\n *ngIf=\"detailService.enabled\"\n class=\"datagrid-detail-caret datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <button\n tabindex=\"-1\"\n (click)=\"detailService.toggle(item, detailButton)\"\n type=\"button\"\n #detailButton\n class=\"datagrid-detail-caret-button\"\n [disabled]=\"detailDisabled\"\n *ngIf=\"!detailHidden\"\n [class.is-open]=\"detailService.isRowOpen(item)\"\n [attr.aria-label]=\"detailService.isRowOpen(item) ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-expanded]=\"detailService.isRowOpen(item)\"\n [attr.aria-controls]=\"detailService.id\"\n aria-haspopup=\"dialog\"\n >\n <cds-icon\n shape=\"angle-double\"\n [attr.direction]=\"detailService.isRowOpen(item) ? 'left' : 'right'\"\n class=\"datagrid-detail-caret-icon\"\n [attr.title]=\"detailService.isRowOpen(item) ? commonStrings.keys.close: commonStrings.keys.open\"\n ></cds-icon>\n </button>\n </div>\n </ng-container>\n <!-- placeholder for projecting other sticky cells as pinned-->\n </div>\n <div class=\"datagrid-row-scrollable\" [ngClass]=\"{'is-replaced': replaced && expanded}\">\n <div class=\"datagrid-scrolling-cells\">\n <ng-content select=\"clr-dg-cell\"></ng-content>\n <ng-container #scrollableCells></ng-container>\n </div>\n <!-- details here when replace, re-visit when sticky container is used for pinned cells -->\n <ng-template *ngIf=\"replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n <ng-template *ngIf=\"!replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n </div>\n </div>\n</ng-template>\n\n<ng-container #calculatedCells></ng-container>\n" }]
20969
21180
  }], ctorParameters: function () { return [{ type: Selection }, { type: RowActionService }, { type: ExpandableRowsCount }, { type: DatagridIfExpandService }, { type: DetailService }, { type: DisplayModeService }, { type: i0.ViewContainerRef }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: ClrCommonStringsService }, { type: Items }, { type: undefined, decorators: [{
20970
21181
  type: Inject,
20971
21182
  args: [DOCUMENT]
@@ -21100,110 +21311,396 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
21100
21311
  * This software is released under MIT license.
21101
21312
  * The full license information can be found in LICENSE in the root directory of this project.
21102
21313
  */
21103
- /**
21104
- * This provider aggregates state changes from the various providers of the Datagrid
21105
- */
21106
- class StateProvider {
21107
- constructor(filters, sort, page, debouncer) {
21108
- this.filters = filters;
21109
- this.sort = sort;
21110
- this.page = page;
21111
- this.debouncer = debouncer;
21112
- /**
21113
- * The Observable that lets other classes subscribe to global state changes
21114
- */
21115
- this.change = this.debouncer.change.pipe(map(() => this.state));
21116
- }
21117
- /*
21118
- * By making this a getter, we open the possibility for a setter in the future.
21119
- * It's been requested a couple times.
21120
- */
21121
- get state() {
21122
- const state = {};
21123
- if (this.page.size > 0) {
21124
- state.page = {
21125
- from: this.page.firstItem,
21126
- to: this.page.lastItem,
21127
- size: this.page.size,
21128
- current: this.page.current,
21129
- };
21130
- }
21131
- if (this.sort.comparator) {
21132
- if (this.sort.comparator instanceof DatagridPropertyComparator) {
21133
- /*
21134
- * Special case for the default object property comparator,
21135
- * we give the property name instead of the actual comparator.
21136
- */
21137
- state.sort = { by: this.sort.comparator.prop, reverse: this.sort.reverse };
21138
- }
21139
- else {
21140
- state.sort = { by: this.sort.comparator, reverse: this.sort.reverse };
21141
- }
21142
- }
21143
- const activeFilters = this.filters.getActiveFilters();
21144
- if (activeFilters.length > 0) {
21145
- state.filters = [];
21146
- for (const filter of activeFilters) {
21147
- if (filter.state) {
21148
- state.filters.push(filter.state);
21149
- }
21150
- else {
21151
- state.filters.push(filter);
21152
- }
21153
- }
21154
- }
21155
- return state;
21156
- }
21157
- }
21158
- StateProvider.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: StateProvider, deps: [{ token: FiltersProvider }, { token: Sort }, { token: Page }, { token: StateDebouncer }], target: i0.ɵɵFactoryTarget.Injectable });
21159
- StateProvider.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: StateProvider });
21160
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: StateProvider, decorators: [{
21161
- type: Injectable
21162
- }], ctorParameters: function () { return [{ type: FiltersProvider }, { type: Sort }, { type: Page }, { type: StateDebouncer }]; } });
21163
-
21164
- /*
21165
- * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
21166
- * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
21167
- * This software is released under MIT license.
21168
- * The full license information can be found in LICENSE in the root directory of this project.
21169
- */
21170
- class DatagridCellRenderer {
21171
- constructor(el, renderer, organizer) {
21172
- this.el = el;
21173
- this.renderer = renderer;
21314
+ const defaultCdkFixedSizeVirtualScrollInputs = {
21315
+ itemSize: 32,
21316
+ minBufferPx: 200,
21317
+ maxBufferPx: 400,
21318
+ };
21319
+ class ClrDatagridVirtualScrollDirective {
21320
+ constructor(changeDetectorRef, iterableDiffers, items, ngZone, renderer2, templateRef, viewContainerRef, directionality, scrollDispatcher, viewportRuler, datagrid, columnsService, injector) {
21321
+ this.changeDetectorRef = changeDetectorRef;
21322
+ this.iterableDiffers = iterableDiffers;
21323
+ this.items = items;
21324
+ this.ngZone = ngZone;
21325
+ this.renderer2 = renderer2;
21326
+ this.templateRef = templateRef;
21327
+ this.viewContainerRef = viewContainerRef;
21328
+ this.directionality = directionality;
21329
+ this.scrollDispatcher = scrollDispatcher;
21330
+ this.viewportRuler = viewportRuler;
21331
+ this.datagrid = datagrid;
21332
+ this.columnsService = columnsService;
21333
+ this.injector = injector;
21334
+ this.renderedRangeChange = new EventEmitter();
21335
+ this._cdkFixedSizeVirtualScrollInputs = { ...defaultCdkFixedSizeVirtualScrollInputs };
21174
21336
  this.subscriptions = [];
21175
- this.subscriptions.push(organizer.filterRenderSteps(DatagridRenderStep.CLEAR_WIDTHS).subscribe(() => this.clearWidth()));
21337
+ this.topIndex = 0;
21338
+ this.mutationChanges = new MutationObserver((mutations) => {
21339
+ mutations.forEach((mutation) => {
21340
+ // it is possible this to be called twice because the old class is removed and the new added
21341
+ if (mutation.target.classList.contains('datagrid-compact') && this.itemSize > 24) {
21342
+ this.itemSize = 24;
21343
+ }
21344
+ });
21345
+ });
21346
+ this.viewRepeater = new _RecycleViewRepeaterStrategy();
21347
+ this.cdkVirtualForInputs = {
21348
+ cdkVirtualForTrackBy: index => index,
21349
+ };
21350
+ items.smartenUp();
21351
+ datagrid.detailService.preventFocusScroll = true;
21352
+ this.datagridElementRef = datagrid.el;
21353
+ // default
21354
+ this.cdkVirtualForTemplateCacheSize = 20;
21355
+ this.mutationChanges.observe(this.datagridElementRef.nativeElement, {
21356
+ attributeFilter: ['class'],
21357
+ attributeOldValue: true,
21358
+ });
21359
+ this.virtualScrollStrategy = new FixedSizeVirtualScrollStrategy(this._cdkFixedSizeVirtualScrollInputs.itemSize, this._cdkFixedSizeVirtualScrollInputs.minBufferPx, this._cdkFixedSizeVirtualScrollInputs.maxBufferPx);
21176
21360
  }
21177
- ngOnDestroy() {
21178
- this.subscriptions.forEach(sub => sub.unsubscribe());
21179
- if (this.stateSubscription) {
21180
- this.stateSubscription.unsubscribe();
21181
- }
21361
+ get cdkVirtualForOf() {
21362
+ return this.cdkVirtualForInputs.cdkVirtualForOf;
21182
21363
  }
21183
- resetState(state) {
21184
- this.setWidth(state);
21185
- this.setHidden(state);
21364
+ set cdkVirtualForOf(value) {
21365
+ this.cdkVirtualForInputs.cdkVirtualForOf = value;
21366
+ this.items.all = value;
21367
+ this.updateCdkVirtualForInputs();
21186
21368
  }
21187
- setWidth(state) {
21188
- if (state.strictWidth) {
21189
- this.renderer.addClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
21190
- }
21191
- else {
21192
- this.renderer.removeClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
21193
- }
21194
- this.renderer.setStyle(this.el.nativeElement, 'width', state.width + 'px');
21369
+ get cdkVirtualForTrackBy() {
21370
+ return this.cdkVirtualForInputs.cdkVirtualForTrackBy;
21195
21371
  }
21196
- setHidden(state) {
21197
- if (state.hidden) {
21198
- this.renderer.addClass(this.el.nativeElement, HIDDEN_COLUMN_CLASS);
21199
- }
21200
- else {
21201
- this.renderer.removeClass(this.el.nativeElement, HIDDEN_COLUMN_CLASS);
21202
- }
21372
+ set cdkVirtualForTrackBy(value) {
21373
+ this.cdkVirtualForInputs.cdkVirtualForTrackBy = value;
21374
+ this.updateCdkVirtualForInputs();
21203
21375
  }
21204
- clearWidth() {
21205
- this.renderer.removeClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
21206
- this.renderer.setStyle(this.el.nativeElement, 'width', null);
21376
+ get cdkVirtualForTemplate() {
21377
+ return this?.cdkVirtualForInputs?.cdkVirtualForTemplate;
21378
+ }
21379
+ set cdkVirtualForTemplate(value) {
21380
+ this.cdkVirtualForInputs.cdkVirtualForTemplate = value;
21381
+ this.updateCdkVirtualForInputs();
21382
+ }
21383
+ get cdkVirtualForTemplateCacheSize() {
21384
+ return this.cdkVirtualForInputs.cdkVirtualForTemplateCacheSize;
21385
+ }
21386
+ set cdkVirtualForTemplateCacheSize(value) {
21387
+ this.cdkVirtualForInputs.cdkVirtualForTemplateCacheSize = coerceNumberProperty(value);
21388
+ this.updateCdkVirtualForInputs();
21389
+ }
21390
+ get itemSize() {
21391
+ return this._cdkFixedSizeVirtualScrollInputs.itemSize;
21392
+ }
21393
+ set itemSize(value) {
21394
+ this._cdkFixedSizeVirtualScrollInputs.itemSize = coerceNumberProperty(value);
21395
+ this.updateFixedSizeVirtualScrollInputs();
21396
+ }
21397
+ get minBufferPx() {
21398
+ return this._cdkFixedSizeVirtualScrollInputs.minBufferPx;
21399
+ }
21400
+ set minBufferPx(value) {
21401
+ this._cdkFixedSizeVirtualScrollInputs.minBufferPx = coerceNumberProperty(value);
21402
+ this.updateFixedSizeVirtualScrollInputs();
21403
+ }
21404
+ get maxBufferPx() {
21405
+ return this._cdkFixedSizeVirtualScrollInputs.maxBufferPx;
21406
+ }
21407
+ set maxBufferPx(value) {
21408
+ this._cdkFixedSizeVirtualScrollInputs.maxBufferPx = coerceNumberProperty(value);
21409
+ this.updateFixedSizeVirtualScrollInputs();
21410
+ }
21411
+ ngAfterViewInit() {
21412
+ this.injector.runInContext(() => {
21413
+ this.virtualScrollViewport = this.createVirtualScrollViewportForDatagrid(this.changeDetectorRef, this.ngZone, this.renderer2, this.directionality, this.scrollDispatcher, this.viewportRuler, this.datagridElementRef, this.virtualScrollStrategy);
21414
+ this.cdkVirtualFor = createCdkVirtualForOfDirective(this.viewContainerRef, this.templateRef, this.iterableDiffers, this.viewRepeater, this.virtualScrollViewport, this.ngZone);
21415
+ this.virtualScrollViewport.ngOnInit();
21416
+ });
21417
+ this.gridRoleElement = this.datagridElementRef.nativeElement.querySelector('[role="grid"]');
21418
+ this.updateCdkVirtualForInputs();
21419
+ this.subscriptions.push(this.items.change.subscribe(newItems => {
21420
+ this.cdkVirtualFor.cdkVirtualForOf = newItems;
21421
+ }), this.cdkVirtualFor.dataStream.subscribe(data => {
21422
+ this.updateAriaRowCount(data.length);
21423
+ }), this.virtualScrollViewport.scrolledIndexChange.subscribe(index => {
21424
+ this.topIndex = index;
21425
+ }), this.virtualScrollViewport.renderedRangeStream.subscribe(renderedRange => {
21426
+ this.renderedRangeChange.emit(renderedRange);
21427
+ }), this.datagrid.refresh.subscribe(datagridState => {
21428
+ if (datagridState.filters) {
21429
+ this.scrollToIndex(0);
21430
+ }
21431
+ }), this.columnsService.columnsStateChange.subscribe(() => {
21432
+ this.viewRepeater.detach();
21433
+ }));
21434
+ }
21435
+ ngDoCheck() {
21436
+ this.cdkVirtualFor?.ngDoCheck();
21437
+ this.updateAriaRowIndexes();
21438
+ }
21439
+ ngOnDestroy() {
21440
+ this.cdkVirtualFor?.ngOnDestroy();
21441
+ this.virtualScrollViewport?.ngOnDestroy();
21442
+ this.mutationChanges?.disconnect();
21443
+ this.subscriptions.forEach(subscription => {
21444
+ subscription.unsubscribe();
21445
+ });
21446
+ }
21447
+ scrollUp(offset, behavior = 'auto') {
21448
+ this.scrollToIndex(this.topIndex - offset, behavior);
21449
+ }
21450
+ scrollDown(offset, behavior = 'auto') {
21451
+ this.scrollToIndex(this.topIndex + offset, behavior);
21452
+ }
21453
+ scrollToIndex(index, behavior = 'auto') {
21454
+ this.virtualScrollViewport?.scrollToIndex(index, behavior);
21455
+ }
21456
+ updateCdkVirtualForInputs() {
21457
+ if (this.cdkVirtualFor) {
21458
+ for (const cdkVirtualForInputKey of Object.keys(this.cdkVirtualForInputs)) {
21459
+ if (this.cdkVirtualFor[cdkVirtualForInputKey] !== this.cdkVirtualForInputs[cdkVirtualForInputKey]) {
21460
+ this.cdkVirtualFor[cdkVirtualForInputKey] = this.cdkVirtualForInputs[cdkVirtualForInputKey];
21461
+ }
21462
+ }
21463
+ }
21464
+ }
21465
+ updateFixedSizeVirtualScrollInputs() {
21466
+ if (this.virtualScrollStrategy) {
21467
+ this.virtualScrollStrategy.updateItemAndBufferSize(this._cdkFixedSizeVirtualScrollInputs.itemSize, this._cdkFixedSizeVirtualScrollInputs.minBufferPx, this._cdkFixedSizeVirtualScrollInputs.maxBufferPx);
21468
+ }
21469
+ }
21470
+ updateAriaRowCount(rowCount) {
21471
+ this.gridRoleElement?.setAttribute('aria-rowcount', rowCount.toString());
21472
+ }
21473
+ updateAriaRowIndexes() {
21474
+ for (let i = 0; i < this.viewContainerRef.length; i++) {
21475
+ const viewRef = this.viewContainerRef.get(i);
21476
+ const rootElements = viewRef.rootNodes;
21477
+ const datagridRowElement = rootElements.find(rowElement => rowElement.tagName === 'CLR-DG-ROW');
21478
+ const rowRoleElement = datagridRowElement?.querySelector('[role="row"]');
21479
+ // aria-rowindex should start with one, not zero, so we have to add one to the zero-based index
21480
+ rowRoleElement?.setAttribute('aria-rowindex', (viewRef.context.index + 1).toString());
21481
+ }
21482
+ }
21483
+ createVirtualScrollViewportForDatagrid(changeDetectorRef, ngZone, renderer2, directionality, scrollDispatcher, viewportRuler, datagridElementRef, virtualScrollStrategy) {
21484
+ const datagridDivElement = datagridElementRef.nativeElement.querySelector('.datagrid');
21485
+ const datagridTableElement = datagridElementRef.nativeElement.querySelector('.datagrid-table');
21486
+ const datagridRowsElement = datagridElementRef.nativeElement.querySelector('.datagrid-rows');
21487
+ const datagridDivElementRef = { nativeElement: datagridDivElement };
21488
+ let topOffset = 0;
21489
+ let totalContentSize = 0;
21490
+ function updateDatagridElementStyles() {
21491
+ datagridRowsElement.style.transform = `translateY(${topOffset}px)`;
21492
+ datagridRowsElement.style.height = `${totalContentSize - topOffset}px`;
21493
+ }
21494
+ const virtualScrollViewport = createCdkVirtualScrollViewport(datagridDivElementRef, changeDetectorRef, ngZone, renderer2, virtualScrollStrategy, directionality, scrollDispatcher, viewportRuler, null);
21495
+ virtualScrollViewport._contentWrapper = {
21496
+ nativeElement: {
21497
+ style: {
21498
+ set transform(value) {
21499
+ topOffset = value === undefined ? 0 : +/translateY\(([0-9]+)px\)/.exec(value)?.[1];
21500
+ updateDatagridElementStyles();
21501
+ },
21502
+ },
21503
+ },
21504
+ };
21505
+ virtualScrollViewport.setTotalContentSize = (value) => {
21506
+ totalContentSize = value;
21507
+ datagridTableElement.style.height = `${totalContentSize}px`;
21508
+ updateDatagridElementStyles();
21509
+ };
21510
+ return virtualScrollViewport;
21511
+ }
21512
+ }
21513
+ ClrDatagridVirtualScrollDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridVirtualScrollDirective, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.IterableDiffers }, { token: Items, skipSelf: true }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: i1$3.Directionality }, { token: i3$1.ScrollDispatcher }, { token: i3$1.ViewportRuler }, { token: ClrDatagrid }, { token: ColumnsService }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Directive });
21514
+ ClrDatagridVirtualScrollDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridVirtualScrollDirective, selector: "[clrVirtualScroll],[ClrVirtualScroll]", inputs: { cdkVirtualForOf: ["clrVirtualRowsOf", "cdkVirtualForOf"], cdkVirtualForTrackBy: ["clrVirtualRowsTrackBy", "cdkVirtualForTrackBy"], cdkVirtualForTemplate: ["clrVirtualRowsTemplate", "cdkVirtualForTemplate"], cdkVirtualForTemplateCacheSize: ["clrVirtualRowsTemplateCacheSize", "cdkVirtualForTemplateCacheSize"], itemSize: ["clrVirtualRowsItemSize", "itemSize"], minBufferPx: ["clrVirtualRowsMinBufferPx", "minBufferPx"], maxBufferPx: ["clrVirtualRowsMaxBufferPx", "maxBufferPx"] }, outputs: { renderedRangeChange: "renderedRangeChange" }, providers: [Items], ngImport: i0 });
21515
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridVirtualScrollDirective, decorators: [{
21516
+ type: Directive,
21517
+ args: [{
21518
+ selector: '[clrVirtualScroll],[ClrVirtualScroll]',
21519
+ providers: [Items],
21520
+ }]
21521
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.IterableDiffers }, { type: Items, decorators: [{
21522
+ type: SkipSelf
21523
+ }] }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.TemplateRef }, { type: i0.ViewContainerRef }, { type: i1$3.Directionality }, { type: i3$1.ScrollDispatcher }, { type: i3$1.ViewportRuler }, { type: ClrDatagrid }, { type: ColumnsService }, { type: i0.EnvironmentInjector }]; }, propDecorators: { renderedRangeChange: [{
21524
+ type: Output
21525
+ }], cdkVirtualForOf: [{
21526
+ type: Input,
21527
+ args: ['clrVirtualRowsOf']
21528
+ }], cdkVirtualForTrackBy: [{
21529
+ type: Input,
21530
+ args: ['clrVirtualRowsTrackBy']
21531
+ }], cdkVirtualForTemplate: [{
21532
+ type: Input,
21533
+ args: ['clrVirtualRowsTemplate']
21534
+ }], cdkVirtualForTemplateCacheSize: [{
21535
+ type: Input,
21536
+ args: ['clrVirtualRowsTemplateCacheSize']
21537
+ }], itemSize: [{
21538
+ type: Input,
21539
+ args: ['clrVirtualRowsItemSize']
21540
+ }], minBufferPx: [{
21541
+ type: Input,
21542
+ args: ['clrVirtualRowsMinBufferPx']
21543
+ }], maxBufferPx: [{
21544
+ type: Input,
21545
+ args: ['clrVirtualRowsMaxBufferPx']
21546
+ }] } });
21547
+ function createCdkVirtualScrollViewport(datagridDivElementRef, changeDetectorRef, ngZone, renderer2, virtualScrollStrategy, directionality, scrollDispatcher, viewportRuler, scrollable) {
21548
+ if (+VERSION.major < 19) {
21549
+ return new CdkVirtualScrollViewport(datagridDivElementRef, changeDetectorRef, ngZone, virtualScrollStrategy, directionality, scrollDispatcher, viewportRuler, scrollable);
21550
+ }
21551
+ else {
21552
+ const virtualScrollViewportInjector = Injector.create({
21553
+ parent: inject(EnvironmentInjector),
21554
+ providers: [
21555
+ { provide: ElementRef, useValue: datagridDivElementRef },
21556
+ { provide: ChangeDetectorRef, useValue: changeDetectorRef },
21557
+ { provide: NgZone, useValue: ngZone },
21558
+ { provide: Renderer2, useValue: renderer2 },
21559
+ { provide: VIRTUAL_SCROLL_STRATEGY, useValue: virtualScrollStrategy },
21560
+ { provide: Directionality, useValue: directionality },
21561
+ { provide: ScrollDispatcher, useValue: scrollDispatcher },
21562
+ { provide: ViewportRuler, useValue: viewportRuler },
21563
+ { provide: CdkVirtualScrollable, useValue: scrollable },
21564
+ { provide: CdkVirtualScrollViewport, useClass: CdkVirtualScrollViewport },
21565
+ ],
21566
+ });
21567
+ return virtualScrollViewportInjector.get(CdkVirtualScrollViewport);
21568
+ }
21569
+ }
21570
+ function createCdkVirtualForOfDirective(viewContainerRef, templateRef, iterableDiffers, viewRepeater, virtualScrollViewport, ngZone) {
21571
+ if (+VERSION.major < 19) {
21572
+ return new CdkVirtualForOf(viewContainerRef, templateRef, iterableDiffers, viewRepeater, virtualScrollViewport, ngZone);
21573
+ }
21574
+ else {
21575
+ const virtualScrollViewportInjector = Injector.create({
21576
+ parent: inject(EnvironmentInjector),
21577
+ providers: [{ provide: CdkVirtualScrollViewport, useValue: virtualScrollViewport }],
21578
+ });
21579
+ const cdkVirtualForInjector = Injector.create({
21580
+ parent: virtualScrollViewportInjector,
21581
+ providers: [
21582
+ { provide: ViewContainerRef, useValue: viewContainerRef },
21583
+ { provide: TemplateRef, useValue: templateRef },
21584
+ { provide: IterableDiffers, useValue: iterableDiffers },
21585
+ { provide: _VIEW_REPEATER_STRATEGY, useValue: viewRepeater },
21586
+ { provide: NgZone, useValue: ngZone },
21587
+ { provide: CdkVirtualForOf, useClass: CdkVirtualForOf },
21588
+ ],
21589
+ });
21590
+ return cdkVirtualForInjector.get(CdkVirtualForOf);
21591
+ }
21592
+ }
21593
+
21594
+ /*
21595
+ * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
21596
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
21597
+ * This software is released under MIT license.
21598
+ * The full license information can be found in LICENSE in the root directory of this project.
21599
+ */
21600
+ /**
21601
+ * This provider aggregates state changes from the various providers of the Datagrid
21602
+ */
21603
+ class StateProvider {
21604
+ constructor(filters, sort, page, debouncer) {
21605
+ this.filters = filters;
21606
+ this.sort = sort;
21607
+ this.page = page;
21608
+ this.debouncer = debouncer;
21609
+ /**
21610
+ * The Observable that lets other classes subscribe to global state changes
21611
+ */
21612
+ this.change = this.debouncer.change.pipe(map(() => this.state));
21613
+ }
21614
+ /*
21615
+ * By making this a getter, we open the possibility for a setter in the future.
21616
+ * It's been requested a couple times.
21617
+ */
21618
+ get state() {
21619
+ const state = {};
21620
+ if (this.page.size > 0) {
21621
+ state.page = {
21622
+ from: this.page.firstItem,
21623
+ to: this.page.lastItem,
21624
+ size: this.page.size,
21625
+ current: this.page.current,
21626
+ };
21627
+ }
21628
+ if (this.sort.comparator) {
21629
+ if (this.sort.comparator instanceof DatagridPropertyComparator) {
21630
+ /*
21631
+ * Special case for the default object property comparator,
21632
+ * we give the property name instead of the actual comparator.
21633
+ */
21634
+ state.sort = { by: this.sort.comparator.prop, reverse: this.sort.reverse };
21635
+ }
21636
+ else {
21637
+ state.sort = { by: this.sort.comparator, reverse: this.sort.reverse };
21638
+ }
21639
+ }
21640
+ const activeFilters = this.filters.getActiveFilters();
21641
+ if (activeFilters.length > 0) {
21642
+ state.filters = [];
21643
+ for (const filter of activeFilters) {
21644
+ if (filter.state) {
21645
+ state.filters.push(filter.state);
21646
+ }
21647
+ else {
21648
+ state.filters.push(filter);
21649
+ }
21650
+ }
21651
+ }
21652
+ return state;
21653
+ }
21654
+ }
21655
+ StateProvider.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: StateProvider, deps: [{ token: FiltersProvider }, { token: Sort }, { token: Page }, { token: StateDebouncer }], target: i0.ɵɵFactoryTarget.Injectable });
21656
+ StateProvider.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: StateProvider });
21657
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: StateProvider, decorators: [{
21658
+ type: Injectable
21659
+ }], ctorParameters: function () { return [{ type: FiltersProvider }, { type: Sort }, { type: Page }, { type: StateDebouncer }]; } });
21660
+
21661
+ /*
21662
+ * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
21663
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
21664
+ * This software is released under MIT license.
21665
+ * The full license information can be found in LICENSE in the root directory of this project.
21666
+ */
21667
+ class DatagridCellRenderer {
21668
+ constructor(el, renderer, organizer) {
21669
+ this.el = el;
21670
+ this.renderer = renderer;
21671
+ this.subscriptions = [];
21672
+ this.subscriptions.push(organizer.filterRenderSteps(DatagridRenderStep.CLEAR_WIDTHS).subscribe(() => this.clearWidth()));
21673
+ }
21674
+ ngOnDestroy() {
21675
+ this.subscriptions.forEach(sub => sub.unsubscribe());
21676
+ if (this.stateSubscription) {
21677
+ this.stateSubscription.unsubscribe();
21678
+ }
21679
+ }
21680
+ resetState(state) {
21681
+ this.setWidth(state);
21682
+ this.setHidden(state);
21683
+ }
21684
+ setWidth(state) {
21685
+ if (state.strictWidth) {
21686
+ this.renderer.addClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
21687
+ }
21688
+ else {
21689
+ this.renderer.removeClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
21690
+ }
21691
+ this.renderer.setStyle(this.el.nativeElement, 'width', state.width + 'px');
21692
+ }
21693
+ setHidden(state) {
21694
+ if (state.hidden) {
21695
+ this.renderer.addClass(this.el.nativeElement, HIDDEN_COLUMN_CLASS);
21696
+ }
21697
+ else {
21698
+ this.renderer.removeClass(this.el.nativeElement, HIDDEN_COLUMN_CLASS);
21699
+ }
21700
+ }
21701
+ clearWidth() {
21702
+ this.renderer.removeClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
21703
+ this.renderer.setStyle(this.el.nativeElement, 'width', null);
21207
21704
  }
21208
21705
  }
21209
21706
  DatagridCellRenderer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: DatagridCellRenderer, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: DatagridRenderOrganizer }], target: i0.ɵɵFactoryTarget.Directive });
@@ -21409,7 +21906,7 @@ class ClrDatagrid {
21409
21906
  });
21410
21907
  this.updateDetailState();
21411
21908
  // retain active cell when navigating with Up/Down Arrows, PageUp and PageDown buttons in virtual scroller
21412
- if (this.hasVirtualScroller) {
21909
+ if (this.virtualScroll) {
21413
21910
  const active = this.keyNavigation.getActiveCell();
21414
21911
  if (active) {
21415
21912
  this.zone.runOutsideAngular(() => {
@@ -21500,7 +21997,7 @@ class ClrDatagrid {
21500
21997
  }
21501
21998
  toggleAllSelected($event) {
21502
21999
  $event.preventDefault();
21503
- if (this.hasVirtualScroller) {
22000
+ if (this.virtualScroll) {
21504
22001
  return;
21505
22002
  }
21506
22003
  this.allSelected = !this.allSelected;
@@ -21523,7 +22020,7 @@ class ClrDatagrid {
21523
22020
  this.detailService.open(row.item, row.detailButton.nativeElement);
21524
22021
  // always keep open when virtual scroll is available otherwise close it
21525
22022
  }
21526
- else if (!this.hasVirtualScroller) {
22023
+ else if (!this.virtualScroll) {
21527
22024
  // Using setTimeout to make sure the inner cycles in rows are done
21528
22025
  setTimeout(() => {
21529
22026
  this.detailService.close();
@@ -21555,7 +22052,7 @@ ClrDatagrid.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
21555
22052
  ColumnsService,
21556
22053
  DisplayModeService,
21557
22054
  KeyNavigationGridController,
21558
- ], queries: [{ propertyName: "iterator", first: true, predicate: ClrDatagridItems, descendants: true }, { propertyName: "placeholder", first: true, predicate: ClrDatagridPlaceholder, descendants: true }, { propertyName: "columns", predicate: ClrDatagridColumn }, { propertyName: "rows", predicate: ClrDatagridRow }], viewQueries: [{ propertyName: "datagrid", first: true, predicate: ["datagrid"], descendants: true, read: ElementRef }, { propertyName: "datagridTable", first: true, predicate: ["datagridTable"], descendants: true, read: ElementRef }, { propertyName: "scrollableColumns", first: true, predicate: ["scrollableColumns"], descendants: true, read: ViewContainerRef }, { propertyName: "_projectedDisplayColumns", first: true, predicate: ["projectedDisplayColumns"], descendants: true, read: ViewContainerRef }, { propertyName: "_projectedCalculationColumns", first: true, predicate: ["projectedCalculationColumns"], descendants: true, read: ViewContainerRef }, { propertyName: "_displayedRows", first: true, predicate: ["displayedRows"], descendants: true, read: ViewContainerRef }, { propertyName: "_calculationRows", first: true, predicate: ["calculationRows"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2025 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<ng-content select=\"clr-dg-action-bar\"></ng-content>\n<div class=\"datagrid-outer-wrapper\">\n <div class=\"datagrid-inner-wrapper\">\n <div class=\"datagrid\" #datagrid [attr.aria-hidden]=\"detailService.isOpen ? true : null\">\n <div class=\"datagrid-table-wrapper\">\n <div role=\"grid\" class=\"datagrid-table\" tabindex=\"-1\" #datagridTable>\n <div role=\"rowgroup\" class=\"datagrid-header\">\n <div role=\"row\" class=\"datagrid-row\">\n <div class=\"datagrid-row-master datagrid-row-flex\">\n <div class=\"datagrid-row-sticky\">\n <!--header for datagrid where you can select multiple rows -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-select datagrid-fixed-column\"\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Multi\"\n (keydown.space)=\"toggleAllSelected($event)\"\n >\n <div *ngIf=\"!hasVirtualScroller\" class=\"clr-checkbox-wrapper\">\n <!-- We need to move focus and space-key handling to the parent because of keyboard arrow key navigation,\n which is not able to transfer focus directly on the input when focused with the tab key -->\n <input\n type=\"checkbox\"\n [id]=\"selectAllId\"\n [(ngModel)]=\"allSelected\"\n [attr.aria-label]=\"commonStrings.keys.selectAll\"\n tabindex=\"-1\"\n />\n <!-- Usage of class clr-col-null here prevents clr-col-* classes from being added when a datagrid is wrapped inside clrForm -->\n <label [for]=\"selectAllId\" class=\"clr-control-label clr-col-null\">\n <span class=\"clr-sr-only\">{{commonStrings.keys.selectAll}}</span>\n </label>\n </div>\n\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for datagrid where you can select one row only -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-select datagrid-fixed-column\"\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Single\"\n >\n <div class=\"clr-sr-only\">{{clrDgSingleSelectionAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for single row action; only displayType if we have at least one actionable row in datagrid -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-row-actions datagrid-fixed-column\"\n *ngIf=\"rowActionService.hasActionableRow\"\n >\n <div class=\"clr-sr-only\">{{clrDgSingleActionableAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for carets; only displayType if we have at least one expandable row in datagrid -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-expandable-caret datagrid-fixed-column\"\n *ngIf=\"expandableRows.hasExpandableRow || detailService.enabled\"\n >\n <div class=\"clr-sr-only\">{{clrDetailExpandableAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n </div>\n <div class=\"datagrid-row-scrollable\">\n <ng-container #projectedDisplayColumns></ng-container>\n </div>\n </div>\n </div>\n </div>\n\n <div role=\"presentation\" class=\"datagrid-rows\">\n <clr-dg-row class=\"datagrid-row-loading\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell>\n <clr-spinner clrMedium></clr-spinner>\n <span>{{ commonStrings.keys.loading }}</span>\n </clr-dg-cell>\n </clr-dg-row>\n\n <ng-container #displayedRows></ng-container>\n\n <clr-dg-row class=\"datagrid-row-loading\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell>\n <clr-spinner clrMedium></clr-spinner>\n <span>{{ commonStrings.keys.loading }}</span>\n </clr-dg-cell>\n </clr-dg-row>\n\n <!-- Custom placeholder overrides the default empty one -->\n <ng-content select=\"clr-dg-placeholder\"></ng-content>\n <clr-dg-placeholder *ngIf=\"!placeholder\"></clr-dg-placeholder>\n </div>\n </div>\n </div>\n </div>\n <ng-content select=\"clr-dg-footer\"></ng-content>\n <div class=\"datagrid-spinner\" *ngIf=\"loading\">\n <clr-spinner clrMedium>Loading</clr-spinner>\n </div>\n </div>\n <ng-content select=\"[clrIfDetail],clr-dg-detail\"></ng-content>\n</div>\n\n<div class=\"datagrid-calculation-table\">\n <div class=\"datagrid-calculation-header\">\n <ng-container #projectedCalculationColumns></ng-container>\n </div>\n <ng-container #calculationRows></ng-container>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: ClrLabel, selector: "label", inputs: ["id", "for"] }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ClrSpinner, selector: "clr-spinner", inputs: ["clrInline", "clrInverse", "clrSmall", "clrMedium"] }, { kind: "component", type: ClrDatagridCell, selector: "clr-dg-cell" }, { kind: "component", type: ClrDatagridPlaceholder, selector: "clr-dg-placeholder" }, { kind: "component", type: ClrDatagridRow, selector: "clr-dg-row", inputs: ["clrDgDetailDisabled", "clrDgDetailHidden", "clrDgItem", "clrDgSelectable", "clrDgSelected", "clrDgExpanded", "clrDgDetailOpenLabel", "clrDgDetailCloseLabel", "clrDgRowSelectionLabel"], outputs: ["clrDgSelectedChange", "clrDgExpandedChange"] }, { kind: "directive", type: ClrDatagridSelectionCellDirective, selector: ".datagrid-select" }, { kind: "directive", type: DatagridCellRenderer, selector: "clr-dg-cell" }, { kind: "directive", type: DatagridRowRenderer, selector: "clr-dg-row, clr-dg-row-detail" }, { kind: "directive", type: ActionableOompaLoompa, selector: "clr-datagrid, clr-dg-row" }, { kind: "directive", type: ExpandableOompaLoompa, selector: "clr-datagrid, clr-dg-row" }] });
22055
+ ], queries: [{ propertyName: "virtualScroll", first: true, predicate: ClrDatagridVirtualScrollDirective, descendants: true }, { propertyName: "iterator", first: true, predicate: ClrDatagridItems, descendants: true }, { propertyName: "placeholder", first: true, predicate: ClrDatagridPlaceholder, descendants: true }, { propertyName: "columns", predicate: ClrDatagridColumn }, { propertyName: "rows", predicate: ClrDatagridRow }], viewQueries: [{ propertyName: "datagrid", first: true, predicate: ["datagrid"], descendants: true, read: ElementRef }, { propertyName: "datagridTable", first: true, predicate: ["datagridTable"], descendants: true, read: ElementRef }, { propertyName: "scrollableColumns", first: true, predicate: ["scrollableColumns"], descendants: true, read: ViewContainerRef }, { propertyName: "_projectedDisplayColumns", first: true, predicate: ["projectedDisplayColumns"], descendants: true, read: ViewContainerRef }, { propertyName: "_projectedCalculationColumns", first: true, predicate: ["projectedCalculationColumns"], descendants: true, read: ViewContainerRef }, { propertyName: "_displayedRows", first: true, predicate: ["displayedRows"], descendants: true, read: ViewContainerRef }, { propertyName: "_calculationRows", first: true, predicate: ["calculationRows"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2025 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<ng-content select=\"clr-dg-action-bar\"></ng-content>\n<div class=\"datagrid-outer-wrapper\">\n <div class=\"datagrid-inner-wrapper\">\n <div class=\"datagrid\" #datagrid [attr.aria-hidden]=\"detailService.isOpen ? true : null\">\n <div class=\"datagrid-table-wrapper\">\n <div role=\"grid\" class=\"datagrid-table\" tabindex=\"-1\" #datagridTable>\n <div role=\"rowgroup\" class=\"datagrid-header\">\n <div role=\"row\" class=\"datagrid-row\">\n <div class=\"datagrid-row-master datagrid-row-flex\">\n <div class=\"datagrid-row-sticky\">\n <!--header for datagrid where you can select multiple rows -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-select datagrid-fixed-column\"\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Multi\"\n (keydown.space)=\"toggleAllSelected($event)\"\n >\n <div *ngIf=\"!virtualScroll\" class=\"clr-checkbox-wrapper\">\n <!-- We need to move focus and space-key handling to the parent because of keyboard arrow key navigation,\n which is not able to transfer focus directly on the input when focused with the tab key -->\n <input\n type=\"checkbox\"\n [id]=\"selectAllId\"\n [(ngModel)]=\"allSelected\"\n [attr.aria-label]=\"commonStrings.keys.selectAll\"\n tabindex=\"-1\"\n />\n <!-- Usage of class clr-col-null here prevents clr-col-* classes from being added when a datagrid is wrapped inside clrForm -->\n <label [for]=\"selectAllId\" class=\"clr-control-label clr-col-null\">\n <span class=\"clr-sr-only\">{{commonStrings.keys.selectAll}}</span>\n </label>\n </div>\n\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for datagrid where you can select one row only -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-select datagrid-fixed-column\"\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Single\"\n >\n <div class=\"clr-sr-only\">{{clrDgSingleSelectionAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for single row action; only displayType if we have at least one actionable row in datagrid -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-row-actions datagrid-fixed-column\"\n *ngIf=\"rowActionService.hasActionableRow\"\n >\n <div class=\"clr-sr-only\">{{clrDgSingleActionableAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for carets; only displayType if we have at least one expandable row in datagrid -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-expandable-caret datagrid-fixed-column\"\n *ngIf=\"expandableRows.hasExpandableRow || detailService.enabled\"\n >\n <div class=\"clr-sr-only\">{{clrDetailExpandableAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n </div>\n <div class=\"datagrid-row-scrollable\">\n <ng-container #projectedDisplayColumns></ng-container>\n </div>\n </div>\n </div>\n </div>\n\n <div role=\"presentation\" class=\"datagrid-rows\">\n <clr-dg-row class=\"datagrid-row-loading\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell>\n <clr-spinner clrMedium></clr-spinner>\n <span>{{ commonStrings.keys.loading }}</span>\n </clr-dg-cell>\n </clr-dg-row>\n\n <ng-container #displayedRows></ng-container>\n\n <clr-dg-row class=\"datagrid-row-loading\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell>\n <clr-spinner clrMedium></clr-spinner>\n <span>{{ commonStrings.keys.loading }}</span>\n </clr-dg-cell>\n </clr-dg-row>\n\n <!-- Custom placeholder overrides the default empty one -->\n <ng-content select=\"clr-dg-placeholder\"></ng-content>\n <clr-dg-placeholder *ngIf=\"!placeholder\"></clr-dg-placeholder>\n </div>\n </div>\n </div>\n </div>\n <ng-content select=\"clr-dg-footer\"></ng-content>\n <div class=\"datagrid-spinner\" *ngIf=\"loading\">\n <clr-spinner clrMedium>Loading</clr-spinner>\n </div>\n </div>\n <ng-content select=\"[clrIfDetail],clr-dg-detail\"></ng-content>\n</div>\n\n<div class=\"datagrid-calculation-table\">\n <div class=\"datagrid-calculation-header\">\n <ng-container #projectedCalculationColumns></ng-container>\n </div>\n <ng-container #calculationRows></ng-container>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: ClrLabel, selector: "label", inputs: ["id", "for"] }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ClrSpinner, selector: "clr-spinner", inputs: ["clrInline", "clrInverse", "clrSmall", "clrMedium"] }, { kind: "component", type: ClrDatagridCell, selector: "clr-dg-cell" }, { kind: "component", type: ClrDatagridPlaceholder, selector: "clr-dg-placeholder" }, { kind: "component", type: ClrDatagridRow, selector: "clr-dg-row", inputs: ["clrDgDetailDisabled", "clrDgDetailHidden", "clrDgItem", "clrDgSelectable", "clrDgSelected", "clrDgExpanded", "clrDgDetailOpenLabel", "clrDgDetailCloseLabel", "clrDgRowSelectionLabel"], outputs: ["clrDgSelectedChange", "clrDgExpandedChange"] }, { kind: "directive", type: ClrDatagridSelectionCellDirective, selector: ".datagrid-select" }, { kind: "directive", type: DatagridCellRenderer, selector: "clr-dg-cell" }, { kind: "directive", type: DatagridRowRenderer, selector: "clr-dg-row, clr-dg-row-detail" }, { kind: "directive", type: ActionableOompaLoompa, selector: "clr-datagrid, clr-dg-row" }, { kind: "directive", type: ExpandableOompaLoompa, selector: "clr-datagrid, clr-dg-row" }] });
21559
22056
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagrid, decorators: [{
21560
22057
  type: Component,
21561
22058
  args: [{ selector: 'clr-datagrid', providers: [
@@ -21577,7 +22074,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
21577
22074
  ], host: {
21578
22075
  '[class.datagrid-host]': 'true',
21579
22076
  '[class.datagrid-detail-open]': 'detailService.isOpen',
21580
- }, template: "<!--\n ~ Copyright (c) 2016-2025 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<ng-content select=\"clr-dg-action-bar\"></ng-content>\n<div class=\"datagrid-outer-wrapper\">\n <div class=\"datagrid-inner-wrapper\">\n <div class=\"datagrid\" #datagrid [attr.aria-hidden]=\"detailService.isOpen ? true : null\">\n <div class=\"datagrid-table-wrapper\">\n <div role=\"grid\" class=\"datagrid-table\" tabindex=\"-1\" #datagridTable>\n <div role=\"rowgroup\" class=\"datagrid-header\">\n <div role=\"row\" class=\"datagrid-row\">\n <div class=\"datagrid-row-master datagrid-row-flex\">\n <div class=\"datagrid-row-sticky\">\n <!--header for datagrid where you can select multiple rows -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-select datagrid-fixed-column\"\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Multi\"\n (keydown.space)=\"toggleAllSelected($event)\"\n >\n <div *ngIf=\"!hasVirtualScroller\" class=\"clr-checkbox-wrapper\">\n <!-- We need to move focus and space-key handling to the parent because of keyboard arrow key navigation,\n which is not able to transfer focus directly on the input when focused with the tab key -->\n <input\n type=\"checkbox\"\n [id]=\"selectAllId\"\n [(ngModel)]=\"allSelected\"\n [attr.aria-label]=\"commonStrings.keys.selectAll\"\n tabindex=\"-1\"\n />\n <!-- Usage of class clr-col-null here prevents clr-col-* classes from being added when a datagrid is wrapped inside clrForm -->\n <label [for]=\"selectAllId\" class=\"clr-control-label clr-col-null\">\n <span class=\"clr-sr-only\">{{commonStrings.keys.selectAll}}</span>\n </label>\n </div>\n\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for datagrid where you can select one row only -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-select datagrid-fixed-column\"\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Single\"\n >\n <div class=\"clr-sr-only\">{{clrDgSingleSelectionAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for single row action; only displayType if we have at least one actionable row in datagrid -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-row-actions datagrid-fixed-column\"\n *ngIf=\"rowActionService.hasActionableRow\"\n >\n <div class=\"clr-sr-only\">{{clrDgSingleActionableAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for carets; only displayType if we have at least one expandable row in datagrid -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-expandable-caret datagrid-fixed-column\"\n *ngIf=\"expandableRows.hasExpandableRow || detailService.enabled\"\n >\n <div class=\"clr-sr-only\">{{clrDetailExpandableAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n </div>\n <div class=\"datagrid-row-scrollable\">\n <ng-container #projectedDisplayColumns></ng-container>\n </div>\n </div>\n </div>\n </div>\n\n <div role=\"presentation\" class=\"datagrid-rows\">\n <clr-dg-row class=\"datagrid-row-loading\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell>\n <clr-spinner clrMedium></clr-spinner>\n <span>{{ commonStrings.keys.loading }}</span>\n </clr-dg-cell>\n </clr-dg-row>\n\n <ng-container #displayedRows></ng-container>\n\n <clr-dg-row class=\"datagrid-row-loading\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell>\n <clr-spinner clrMedium></clr-spinner>\n <span>{{ commonStrings.keys.loading }}</span>\n </clr-dg-cell>\n </clr-dg-row>\n\n <!-- Custom placeholder overrides the default empty one -->\n <ng-content select=\"clr-dg-placeholder\"></ng-content>\n <clr-dg-placeholder *ngIf=\"!placeholder\"></clr-dg-placeholder>\n </div>\n </div>\n </div>\n </div>\n <ng-content select=\"clr-dg-footer\"></ng-content>\n <div class=\"datagrid-spinner\" *ngIf=\"loading\">\n <clr-spinner clrMedium>Loading</clr-spinner>\n </div>\n </div>\n <ng-content select=\"[clrIfDetail],clr-dg-detail\"></ng-content>\n</div>\n\n<div class=\"datagrid-calculation-table\">\n <div class=\"datagrid-calculation-header\">\n <ng-container #projectedCalculationColumns></ng-container>\n </div>\n <ng-container #calculationRows></ng-container>\n</div>\n" }]
22077
+ }, template: "<!--\n ~ Copyright (c) 2016-2025 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<ng-content select=\"clr-dg-action-bar\"></ng-content>\n<div class=\"datagrid-outer-wrapper\">\n <div class=\"datagrid-inner-wrapper\">\n <div class=\"datagrid\" #datagrid [attr.aria-hidden]=\"detailService.isOpen ? true : null\">\n <div class=\"datagrid-table-wrapper\">\n <div role=\"grid\" class=\"datagrid-table\" tabindex=\"-1\" #datagridTable>\n <div role=\"rowgroup\" class=\"datagrid-header\">\n <div role=\"row\" class=\"datagrid-row\">\n <div class=\"datagrid-row-master datagrid-row-flex\">\n <div class=\"datagrid-row-sticky\">\n <!--header for datagrid where you can select multiple rows -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-select datagrid-fixed-column\"\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Multi\"\n (keydown.space)=\"toggleAllSelected($event)\"\n >\n <div *ngIf=\"!virtualScroll\" class=\"clr-checkbox-wrapper\">\n <!-- We need to move focus and space-key handling to the parent because of keyboard arrow key navigation,\n which is not able to transfer focus directly on the input when focused with the tab key -->\n <input\n type=\"checkbox\"\n [id]=\"selectAllId\"\n [(ngModel)]=\"allSelected\"\n [attr.aria-label]=\"commonStrings.keys.selectAll\"\n tabindex=\"-1\"\n />\n <!-- Usage of class clr-col-null here prevents clr-col-* classes from being added when a datagrid is wrapped inside clrForm -->\n <label [for]=\"selectAllId\" class=\"clr-control-label clr-col-null\">\n <span class=\"clr-sr-only\">{{commonStrings.keys.selectAll}}</span>\n </label>\n </div>\n\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for datagrid where you can select one row only -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-select datagrid-fixed-column\"\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Single\"\n >\n <div class=\"clr-sr-only\">{{clrDgSingleSelectionAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for single row action; only displayType if we have at least one actionable row in datagrid -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-row-actions datagrid-fixed-column\"\n *ngIf=\"rowActionService.hasActionableRow\"\n >\n <div class=\"clr-sr-only\">{{clrDgSingleActionableAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for carets; only displayType if we have at least one expandable row in datagrid -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-expandable-caret datagrid-fixed-column\"\n *ngIf=\"expandableRows.hasExpandableRow || detailService.enabled\"\n >\n <div class=\"clr-sr-only\">{{clrDetailExpandableAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n </div>\n <div class=\"datagrid-row-scrollable\">\n <ng-container #projectedDisplayColumns></ng-container>\n </div>\n </div>\n </div>\n </div>\n\n <div role=\"presentation\" class=\"datagrid-rows\">\n <clr-dg-row class=\"datagrid-row-loading\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell>\n <clr-spinner clrMedium></clr-spinner>\n <span>{{ commonStrings.keys.loading }}</span>\n </clr-dg-cell>\n </clr-dg-row>\n\n <ng-container #displayedRows></ng-container>\n\n <clr-dg-row class=\"datagrid-row-loading\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell>\n <clr-spinner clrMedium></clr-spinner>\n <span>{{ commonStrings.keys.loading }}</span>\n </clr-dg-cell>\n </clr-dg-row>\n\n <!-- Custom placeholder overrides the default empty one -->\n <ng-content select=\"clr-dg-placeholder\"></ng-content>\n <clr-dg-placeholder *ngIf=\"!placeholder\"></clr-dg-placeholder>\n </div>\n </div>\n </div>\n </div>\n <ng-content select=\"clr-dg-footer\"></ng-content>\n <div class=\"datagrid-spinner\" *ngIf=\"loading\">\n <clr-spinner clrMedium>Loading</clr-spinner>\n </div>\n </div>\n <ng-content select=\"[clrIfDetail],clr-dg-detail\"></ng-content>\n</div>\n\n<div class=\"datagrid-calculation-table\">\n <div class=\"datagrid-calculation-header\">\n <ng-container #projectedCalculationColumns></ng-container>\n </div>\n <ng-container #calculationRows></ng-container>\n</div>\n" }]
21581
22078
  }], ctorParameters: function () { return [{ type: DatagridRenderOrganizer }, { type: Items }, { type: ExpandableRowsCount }, { type: Selection }, { type: RowActionService }, { type: StateProvider }, { type: DisplayModeService }, { type: i0.Renderer2 }, { type: DetailService }, { type: undefined, decorators: [{
21582
22079
  type: Inject,
21583
22080
  args: [DOCUMENT]
@@ -21601,6 +22098,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
21601
22098
  }], refresh: [{
21602
22099
  type: Output,
21603
22100
  args: ['clrDgRefresh']
22101
+ }], virtualScroll: [{
22102
+ type: ContentChild,
22103
+ args: [ClrDatagridVirtualScrollDirective]
21604
22104
  }], iterator: [{
21605
22105
  type: ContentChild,
21606
22106
  args: [ClrDatagridItems]
@@ -22997,356 +23497,100 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
22997
23497
  /**
22998
23498
  * Generic bland container serving various purposes for Datagrid.
22999
23499
  * For instance, it can help span a text over multiple rows in detail view.
23000
- */
23001
- class ClrDatagridRowDetail {
23002
- constructor(selection, rowActionService, expand, expandableRows, commonStrings) {
23003
- this.selection = selection;
23004
- this.rowActionService = rowActionService;
23005
- this.expand = expand;
23006
- this.expandableRows = expandableRows;
23007
- this.commonStrings = commonStrings;
23008
- this.replacedRow = false;
23009
- /* reference to the enum so that template can access it */
23010
- this.SELECTION_TYPE = SelectionType;
23011
- this.subscriptions = [];
23012
- }
23013
- set replace(value) {
23014
- this.expand.setReplace(!!value);
23015
- }
23016
- get beginningOfExpandableContentAriaText() {
23017
- return (this._beginningOfExpandableContentAriaText ||
23018
- `${this.commonStrings.keys.datagridExpandableBeginningOf} ${this.commonStrings.keys.datagridExpandableRowContent}`);
23019
- }
23020
- get endOfExpandableContentAriaText() {
23021
- return (this._endOfExpandableContentAriaText ||
23022
- `${this.commonStrings.keys.datagridExpandableEndOf} ${this.commonStrings.keys.datagridExpandableRowContent}`);
23023
- }
23024
- ngAfterContentInit() {
23025
- this.subscriptions.push(this.expand.replace.subscribe(replaceChange => {
23026
- this.replacedRow = replaceChange;
23027
- }));
23028
- }
23029
- ngOnDestroy() {
23030
- this.subscriptions.forEach(sub => sub.unsubscribe());
23031
- }
23032
- }
23033
- ClrDatagridRowDetail.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridRowDetail, deps: [{ token: Selection }, { token: RowActionService }, { token: DatagridIfExpandService }, { token: ExpandableRowsCount }, { token: ClrCommonStringsService }], target: i0.ɵɵFactoryTarget.Component });
23034
- ClrDatagridRowDetail.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridRowDetail, selector: "clr-dg-row-detail", inputs: { _beginningOfExpandableContentAriaText: ["clrRowDetailBeginningAriaText", "_beginningOfExpandableContentAriaText"], _endOfExpandableContentAriaText: ["clrRowDetailEndAriaText", "_endOfExpandableContentAriaText"], replace: ["clrDgReplace", "replace"] }, host: { attributes: { "role": "gridcell" }, properties: { "class.datagrid-row-flex": "true", "class.datagrid-row-detail": "true", "class.datagrid-container": "cells.length === 0", "attr.id": "expand.expandableId" } }, queries: [{ propertyName: "cells", predicate: ClrDatagridCell }], ngImport: i0, template: `
23035
- <div class="clr-sr-only">
23036
- {{ beginningOfExpandableContentAriaText }}
23037
- {{ commonStrings.keys.datagridExpandableRowsHelperText }}
23038
- </div>
23039
- <ng-content></ng-content>
23040
- <div class="clr-sr-only">{{ endOfExpandableContentAriaText }}</div>
23041
- `, isInline: true });
23042
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridRowDetail, decorators: [{
23043
- type: Component,
23044
- args: [{
23045
- selector: 'clr-dg-row-detail',
23046
- template: `
23047
- <div class="clr-sr-only">
23048
- {{ beginningOfExpandableContentAriaText }}
23049
- {{ commonStrings.keys.datagridExpandableRowsHelperText }}
23050
- </div>
23051
- <ng-content></ng-content>
23052
- <div class="clr-sr-only">{{ endOfExpandableContentAriaText }}</div>
23053
- `,
23054
- host: {
23055
- '[class.datagrid-row-flex]': 'true',
23056
- '[class.datagrid-row-detail]': 'true',
23057
- '[class.datagrid-container]': 'cells.length === 0',
23058
- '[attr.id]': 'expand.expandableId',
23059
- role: 'gridcell',
23060
- },
23061
- }]
23062
- }], ctorParameters: function () { return [{ type: Selection }, { type: RowActionService }, { type: DatagridIfExpandService }, { type: ExpandableRowsCount }, { type: ClrCommonStringsService }]; }, propDecorators: { _beginningOfExpandableContentAriaText: [{
23063
- type: Input,
23064
- args: ['clrRowDetailBeginningAriaText']
23065
- }], _endOfExpandableContentAriaText: [{
23066
- type: Input,
23067
- args: ['clrRowDetailEndAriaText']
23068
- }], cells: [{
23069
- type: ContentChildren,
23070
- args: [ClrDatagridCell]
23071
- }], replace: [{
23072
- type: Input,
23073
- args: ['clrDgReplace']
23074
- }] } });
23075
-
23076
- /*
23077
- * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
23078
- * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
23079
- * This software is released under MIT license.
23080
- * The full license information can be found in LICENSE in the root directory of this project.
23081
- */
23082
- const defaultCdkFixedSizeVirtualScrollInputs = {
23083
- itemSize: 32,
23084
- minBufferPx: 200,
23085
- maxBufferPx: 400,
23086
- };
23087
- class ClrDatagridVirtualScrollDirective {
23088
- constructor(changeDetectorRef, iterableDiffers, items, ngZone, renderer2, templateRef, viewContainerRef, directionality, scrollDispatcher, viewportRuler, datagrid, columnsService, injector) {
23089
- this.changeDetectorRef = changeDetectorRef;
23090
- this.iterableDiffers = iterableDiffers;
23091
- this.items = items;
23092
- this.ngZone = ngZone;
23093
- this.renderer2 = renderer2;
23094
- this.templateRef = templateRef;
23095
- this.viewContainerRef = viewContainerRef;
23096
- this.directionality = directionality;
23097
- this.scrollDispatcher = scrollDispatcher;
23098
- this.viewportRuler = viewportRuler;
23099
- this.datagrid = datagrid;
23100
- this.columnsService = columnsService;
23101
- this.injector = injector;
23102
- this.renderedRangeChange = new EventEmitter();
23103
- this._cdkFixedSizeVirtualScrollInputs = { ...defaultCdkFixedSizeVirtualScrollInputs };
23104
- this.subscriptions = [];
23105
- this.mutationChanges = new MutationObserver((mutations) => {
23106
- mutations.forEach((mutation) => {
23107
- // it is possible this to be called twice because the old class is removed and the new added
23108
- if (mutation.target.classList.contains('datagrid-compact') && this.itemSize > 24) {
23109
- this.itemSize = 24;
23110
- }
23111
- });
23112
- });
23113
- this.viewRepeater = new _RecycleViewRepeaterStrategy();
23114
- this.cdkVirtualForInputs = {
23115
- cdkVirtualForTrackBy: index => index,
23116
- };
23117
- items.smartenUp();
23118
- datagrid.hasVirtualScroller = true;
23119
- datagrid.detailService.preventFocusScroll = true;
23120
- this.datagridElementRef = datagrid.el;
23121
- // default
23122
- this.cdkVirtualForTemplateCacheSize = 20;
23123
- this.mutationChanges.observe(this.datagridElementRef.nativeElement, {
23124
- attributeFilter: ['class'],
23125
- attributeOldValue: true,
23126
- });
23127
- this.virtualScrollStrategy = new FixedSizeVirtualScrollStrategy(this._cdkFixedSizeVirtualScrollInputs.itemSize, this._cdkFixedSizeVirtualScrollInputs.minBufferPx, this._cdkFixedSizeVirtualScrollInputs.maxBufferPx);
23128
- }
23129
- get cdkVirtualForOf() {
23130
- return this.cdkVirtualForInputs.cdkVirtualForOf;
23131
- }
23132
- set cdkVirtualForOf(value) {
23133
- this.cdkVirtualForInputs.cdkVirtualForOf = value;
23134
- this.items.all = value;
23135
- this.updateCdkVirtualForInputs();
23136
- }
23137
- get cdkVirtualForTrackBy() {
23138
- return this.cdkVirtualForInputs.cdkVirtualForTrackBy;
23139
- }
23140
- set cdkVirtualForTrackBy(value) {
23141
- this.cdkVirtualForInputs.cdkVirtualForTrackBy = value;
23142
- this.updateCdkVirtualForInputs();
23143
- }
23144
- get cdkVirtualForTemplate() {
23145
- return this?.cdkVirtualForInputs?.cdkVirtualForTemplate;
23146
- }
23147
- set cdkVirtualForTemplate(value) {
23148
- this.cdkVirtualForInputs.cdkVirtualForTemplate = value;
23149
- this.updateCdkVirtualForInputs();
23150
- }
23151
- get cdkVirtualForTemplateCacheSize() {
23152
- return this.cdkVirtualForInputs.cdkVirtualForTemplateCacheSize;
23153
- }
23154
- set cdkVirtualForTemplateCacheSize(value) {
23155
- this.cdkVirtualForInputs.cdkVirtualForTemplateCacheSize = coerceNumberProperty(value);
23156
- this.updateCdkVirtualForInputs();
23157
- }
23158
- get itemSize() {
23159
- return this._cdkFixedSizeVirtualScrollInputs.itemSize;
23160
- }
23161
- set itemSize(value) {
23162
- this._cdkFixedSizeVirtualScrollInputs.itemSize = coerceNumberProperty(value);
23163
- this.updateFixedSizeVirtualScrollInputs();
23164
- }
23165
- get minBufferPx() {
23166
- return this._cdkFixedSizeVirtualScrollInputs.minBufferPx;
23500
+ */
23501
+ class ClrDatagridRowDetail {
23502
+ constructor(selection, rowActionService, expand, expandableRows, commonStrings) {
23503
+ this.selection = selection;
23504
+ this.rowActionService = rowActionService;
23505
+ this.expand = expand;
23506
+ this.expandableRows = expandableRows;
23507
+ this.commonStrings = commonStrings;
23508
+ this.replacedRow = false;
23509
+ /* reference to the enum so that template can access it */
23510
+ this.SELECTION_TYPE = SelectionType;
23511
+ this.subscriptions = [];
23167
23512
  }
23168
- set minBufferPx(value) {
23169
- this._cdkFixedSizeVirtualScrollInputs.minBufferPx = coerceNumberProperty(value);
23170
- this.updateFixedSizeVirtualScrollInputs();
23513
+ set replace(value) {
23514
+ this.expand.setReplace(!!value);
23171
23515
  }
23172
- get maxBufferPx() {
23173
- return this._cdkFixedSizeVirtualScrollInputs.maxBufferPx;
23516
+ get beginningOfExpandableContentAriaText() {
23517
+ return (this._beginningOfExpandableContentAriaText ||
23518
+ `${this.commonStrings.keys.datagridExpandableBeginningOf} ${this.commonStrings.keys.datagridExpandableRowContent}`);
23174
23519
  }
23175
- set maxBufferPx(value) {
23176
- this._cdkFixedSizeVirtualScrollInputs.maxBufferPx = coerceNumberProperty(value);
23177
- this.updateFixedSizeVirtualScrollInputs();
23520
+ get endOfExpandableContentAriaText() {
23521
+ return (this._endOfExpandableContentAriaText ||
23522
+ `${this.commonStrings.keys.datagridExpandableEndOf} ${this.commonStrings.keys.datagridExpandableRowContent}`);
23178
23523
  }
23179
- ngAfterViewInit() {
23180
- this.injector.runInContext(() => {
23181
- this.virtualScrollViewport = this.createVirtualScrollViewportForDatagrid(this.changeDetectorRef, this.ngZone, this.renderer2, this.directionality, this.scrollDispatcher, this.viewportRuler, this.datagridElementRef, this.virtualScrollStrategy);
23182
- this.cdkVirtualFor = createCdkVirtualForOfDirective(this.viewContainerRef, this.templateRef, this.iterableDiffers, this.viewRepeater, this.virtualScrollViewport, this.ngZone);
23183
- this.virtualScrollViewport.ngOnInit();
23184
- });
23185
- this.gridRoleElement = this.datagridElementRef.nativeElement.querySelector('[role="grid"]');
23186
- this.updateCdkVirtualForInputs();
23187
- this.subscriptions.push(this.items.change.subscribe(newItems => {
23188
- this.cdkVirtualFor.cdkVirtualForOf = newItems;
23189
- }), this.cdkVirtualFor.dataStream.subscribe(data => {
23190
- this.updateAriaRowCount(data.length);
23191
- }), this.virtualScrollViewport.renderedRangeStream.subscribe(renderedRange => {
23192
- this.renderedRangeChange.emit(renderedRange);
23193
- }), this.datagrid.refresh.subscribe(datagridState => {
23194
- if (datagridState.filters) {
23195
- this.virtualScrollViewport.scrollToIndex(0);
23196
- }
23197
- }), this.columnsService.columnsStateChange.subscribe(() => {
23198
- this.viewRepeater.detach();
23524
+ ngAfterContentInit() {
23525
+ this.subscriptions.push(this.expand.replace.subscribe(replaceChange => {
23526
+ this.replacedRow = replaceChange;
23199
23527
  }));
23200
23528
  }
23201
- ngDoCheck() {
23202
- this.cdkVirtualFor?.ngDoCheck();
23203
- this.updateAriaRowIndexes();
23204
- }
23205
23529
  ngOnDestroy() {
23206
- this.cdkVirtualFor?.ngOnDestroy();
23207
- this.virtualScrollViewport?.ngOnDestroy();
23208
- this.mutationChanges?.disconnect();
23209
- this.subscriptions.forEach(subscription => {
23210
- subscription.unsubscribe();
23211
- });
23212
- }
23213
- updateCdkVirtualForInputs() {
23214
- if (this.cdkVirtualFor) {
23215
- for (const cdkVirtualForInputKey of Object.keys(this.cdkVirtualForInputs)) {
23216
- if (this.cdkVirtualFor[cdkVirtualForInputKey] !== this.cdkVirtualForInputs[cdkVirtualForInputKey]) {
23217
- this.cdkVirtualFor[cdkVirtualForInputKey] = this.cdkVirtualForInputs[cdkVirtualForInputKey];
23218
- }
23219
- }
23220
- }
23221
- }
23222
- updateFixedSizeVirtualScrollInputs() {
23223
- if (this.virtualScrollStrategy) {
23224
- this.virtualScrollStrategy.updateItemAndBufferSize(this._cdkFixedSizeVirtualScrollInputs.itemSize, this._cdkFixedSizeVirtualScrollInputs.minBufferPx, this._cdkFixedSizeVirtualScrollInputs.maxBufferPx);
23225
- }
23226
- }
23227
- updateAriaRowCount(rowCount) {
23228
- this.gridRoleElement?.setAttribute('aria-rowcount', rowCount.toString());
23229
- }
23230
- updateAriaRowIndexes() {
23231
- for (let i = 0; i < this.viewContainerRef.length; i++) {
23232
- const viewRef = this.viewContainerRef.get(i);
23233
- const rootElements = viewRef.rootNodes;
23234
- const datagridRowElement = rootElements.find(rowElement => rowElement.tagName === 'CLR-DG-ROW');
23235
- const rowRoleElement = datagridRowElement?.querySelector('[role="row"]');
23236
- // aria-rowindex should start with one, not zero, so we have to add one to the zero-based index
23237
- rowRoleElement?.setAttribute('aria-rowindex', (viewRef.context.index + 1).toString());
23238
- }
23239
- }
23240
- createVirtualScrollViewportForDatagrid(changeDetectorRef, ngZone, renderer2, directionality, scrollDispatcher, viewportRuler, datagridElementRef, virtualScrollStrategy) {
23241
- const datagridDivElement = datagridElementRef.nativeElement.querySelector('.datagrid');
23242
- const datagridTableElement = datagridElementRef.nativeElement.querySelector('.datagrid-table');
23243
- const datagridRowsElement = datagridElementRef.nativeElement.querySelector('.datagrid-rows');
23244
- const datagridDivElementRef = { nativeElement: datagridDivElement };
23245
- let topOffset = 0;
23246
- let totalContentSize = 0;
23247
- function updateDatagridElementStyles() {
23248
- datagridRowsElement.style.transform = `translateY(${topOffset}px)`;
23249
- datagridRowsElement.style.height = `${totalContentSize - topOffset}px`;
23250
- }
23251
- const virtualScrollViewport = createCdkVirtualScrollViewport(datagridDivElementRef, changeDetectorRef, ngZone, renderer2, virtualScrollStrategy, directionality, scrollDispatcher, viewportRuler, null);
23252
- virtualScrollViewport._contentWrapper = {
23253
- nativeElement: {
23254
- style: {
23255
- set transform(value) {
23256
- topOffset = value === undefined ? 0 : +/translateY\(([0-9]+)px\)/.exec(value)?.[1];
23257
- updateDatagridElementStyles();
23258
- },
23259
- },
23260
- },
23261
- };
23262
- virtualScrollViewport.setTotalContentSize = (value) => {
23263
- totalContentSize = value;
23264
- datagridTableElement.style.height = `${totalContentSize}px`;
23265
- updateDatagridElementStyles();
23266
- };
23267
- return virtualScrollViewport;
23530
+ this.subscriptions.forEach(sub => sub.unsubscribe());
23268
23531
  }
23269
23532
  }
23270
- ClrDatagridVirtualScrollDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridVirtualScrollDirective, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.IterableDiffers }, { token: Items, skipSelf: true }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: i1$3.Directionality }, { token: i3$1.ScrollDispatcher }, { token: i3$1.ViewportRuler }, { token: ClrDatagrid }, { token: ColumnsService }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Directive });
23271
- ClrDatagridVirtualScrollDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridVirtualScrollDirective, selector: "[clrVirtualScroll],[ClrVirtualScroll]", inputs: { cdkVirtualForOf: ["clrVirtualRowsOf", "cdkVirtualForOf"], cdkVirtualForTrackBy: ["clrVirtualRowsTrackBy", "cdkVirtualForTrackBy"], cdkVirtualForTemplate: ["clrVirtualRowsTemplate", "cdkVirtualForTemplate"], cdkVirtualForTemplateCacheSize: ["clrVirtualRowsTemplateCacheSize", "cdkVirtualForTemplateCacheSize"], itemSize: ["clrVirtualRowsItemSize", "itemSize"], minBufferPx: ["clrVirtualRowsMinBufferPx", "minBufferPx"], maxBufferPx: ["clrVirtualRowsMaxBufferPx", "maxBufferPx"] }, outputs: { renderedRangeChange: "renderedRangeChange" }, providers: [Items], ngImport: i0 });
23272
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridVirtualScrollDirective, decorators: [{
23273
- type: Directive,
23533
+ ClrDatagridRowDetail.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridRowDetail, deps: [{ token: Selection }, { token: RowActionService }, { token: DatagridIfExpandService }, { token: ExpandableRowsCount }, { token: ClrCommonStringsService }], target: i0.ɵɵFactoryTarget.Component });
23534
+ ClrDatagridRowDetail.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridRowDetail, selector: "clr-dg-row-detail", inputs: { _beginningOfExpandableContentAriaText: ["clrRowDetailBeginningAriaText", "_beginningOfExpandableContentAriaText"], _endOfExpandableContentAriaText: ["clrRowDetailEndAriaText", "_endOfExpandableContentAriaText"], replace: ["clrDgReplace", "replace"] }, host: { attributes: { "role": "row" }, properties: { "class.datagrid-row-flex": "true", "class.datagrid-row-detail": "true", "attr.id": "expand.expandableId" } }, queries: [{ propertyName: "cells", predicate: ClrDatagridCell }], ngImport: i0, template: `
23535
+ <div class="clr-sr-only">
23536
+ {{ beginningOfExpandableContentAriaText }}
23537
+ {{ commonStrings.keys.datagridExpandableRowsHelperText }}
23538
+ </div>
23539
+ <ng-container *ngIf="this.cells?.length > 0" [ngTemplateOutlet]="noCells"></ng-container>
23540
+
23541
+ <ng-container *ngIf="this.cells?.length === 0">
23542
+ <clr-dg-cell class="datagrid-container">
23543
+ <ng-container [ngTemplateOutlet]="noCells"></ng-container>
23544
+ </clr-dg-cell>
23545
+ </ng-container>
23546
+
23547
+ <ng-template #noCells>
23548
+ <ng-content></ng-content>
23549
+ </ng-template>
23550
+ <div class="clr-sr-only">{{ endOfExpandableContentAriaText }}</div>
23551
+ `, isInline: true, dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ClrDatagridCell, selector: "clr-dg-cell" }, { kind: "directive", type: DatagridCellRenderer, selector: "clr-dg-cell" }] });
23552
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridRowDetail, decorators: [{
23553
+ type: Component,
23274
23554
  args: [{
23275
- selector: '[clrVirtualScroll],[ClrVirtualScroll]',
23276
- providers: [Items],
23555
+ selector: 'clr-dg-row-detail',
23556
+ template: `
23557
+ <div class="clr-sr-only">
23558
+ {{ beginningOfExpandableContentAriaText }}
23559
+ {{ commonStrings.keys.datagridExpandableRowsHelperText }}
23560
+ </div>
23561
+ <ng-container *ngIf="this.cells?.length > 0" [ngTemplateOutlet]="noCells"></ng-container>
23562
+
23563
+ <ng-container *ngIf="this.cells?.length === 0">
23564
+ <clr-dg-cell class="datagrid-container">
23565
+ <ng-container [ngTemplateOutlet]="noCells"></ng-container>
23566
+ </clr-dg-cell>
23567
+ </ng-container>
23568
+
23569
+ <ng-template #noCells>
23570
+ <ng-content></ng-content>
23571
+ </ng-template>
23572
+ <div class="clr-sr-only">{{ endOfExpandableContentAriaText }}</div>
23573
+ `,
23574
+ host: {
23575
+ '[class.datagrid-row-flex]': 'true',
23576
+ '[class.datagrid-row-detail]': 'true',
23577
+ '[attr.id]': 'expand.expandableId',
23578
+ role: 'row',
23579
+ },
23277
23580
  }]
23278
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.IterableDiffers }, { type: Items, decorators: [{
23279
- type: SkipSelf
23280
- }] }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.TemplateRef }, { type: i0.ViewContainerRef }, { type: i1$3.Directionality }, { type: i3$1.ScrollDispatcher }, { type: i3$1.ViewportRuler }, { type: ClrDatagrid }, { type: ColumnsService }, { type: i0.EnvironmentInjector }]; }, propDecorators: { renderedRangeChange: [{
23281
- type: Output
23282
- }], cdkVirtualForOf: [{
23283
- type: Input,
23284
- args: ['clrVirtualRowsOf']
23285
- }], cdkVirtualForTrackBy: [{
23286
- type: Input,
23287
- args: ['clrVirtualRowsTrackBy']
23288
- }], cdkVirtualForTemplate: [{
23289
- type: Input,
23290
- args: ['clrVirtualRowsTemplate']
23291
- }], cdkVirtualForTemplateCacheSize: [{
23292
- type: Input,
23293
- args: ['clrVirtualRowsTemplateCacheSize']
23294
- }], itemSize: [{
23581
+ }], ctorParameters: function () { return [{ type: Selection }, { type: RowActionService }, { type: DatagridIfExpandService }, { type: ExpandableRowsCount }, { type: ClrCommonStringsService }]; }, propDecorators: { _beginningOfExpandableContentAriaText: [{
23295
23582
  type: Input,
23296
- args: ['clrVirtualRowsItemSize']
23297
- }], minBufferPx: [{
23583
+ args: ['clrRowDetailBeginningAriaText']
23584
+ }], _endOfExpandableContentAriaText: [{
23298
23585
  type: Input,
23299
- args: ['clrVirtualRowsMinBufferPx']
23300
- }], maxBufferPx: [{
23586
+ args: ['clrRowDetailEndAriaText']
23587
+ }], cells: [{
23588
+ type: ContentChildren,
23589
+ args: [ClrDatagridCell]
23590
+ }], replace: [{
23301
23591
  type: Input,
23302
- args: ['clrVirtualRowsMaxBufferPx']
23592
+ args: ['clrDgReplace']
23303
23593
  }] } });
23304
- function createCdkVirtualScrollViewport(datagridDivElementRef, changeDetectorRef, ngZone, renderer2, virtualScrollStrategy, directionality, scrollDispatcher, viewportRuler, scrollable) {
23305
- if (+VERSION.major < 19) {
23306
- return new CdkVirtualScrollViewport(datagridDivElementRef, changeDetectorRef, ngZone, virtualScrollStrategy, directionality, scrollDispatcher, viewportRuler, scrollable);
23307
- }
23308
- else {
23309
- const virtualScrollViewportInjector = Injector.create({
23310
- parent: inject(EnvironmentInjector),
23311
- providers: [
23312
- { provide: ElementRef, useValue: datagridDivElementRef },
23313
- { provide: ChangeDetectorRef, useValue: changeDetectorRef },
23314
- { provide: NgZone, useValue: ngZone },
23315
- { provide: Renderer2, useValue: renderer2 },
23316
- { provide: VIRTUAL_SCROLL_STRATEGY, useValue: virtualScrollStrategy },
23317
- { provide: Directionality, useValue: directionality },
23318
- { provide: ScrollDispatcher, useValue: scrollDispatcher },
23319
- { provide: ViewportRuler, useValue: viewportRuler },
23320
- { provide: CdkVirtualScrollable, useValue: scrollable },
23321
- { provide: CdkVirtualScrollViewport, useClass: CdkVirtualScrollViewport },
23322
- ],
23323
- });
23324
- return virtualScrollViewportInjector.get(CdkVirtualScrollViewport);
23325
- }
23326
- }
23327
- function createCdkVirtualForOfDirective(viewContainerRef, templateRef, iterableDiffers, viewRepeater, virtualScrollViewport, ngZone) {
23328
- if (+VERSION.major < 19) {
23329
- return new CdkVirtualForOf(viewContainerRef, templateRef, iterableDiffers, viewRepeater, virtualScrollViewport, ngZone);
23330
- }
23331
- else {
23332
- const virtualScrollViewportInjector = Injector.create({
23333
- parent: inject(EnvironmentInjector),
23334
- providers: [{ provide: CdkVirtualScrollViewport, useValue: virtualScrollViewport }],
23335
- });
23336
- const cdkVirtualForInjector = Injector.create({
23337
- parent: virtualScrollViewportInjector,
23338
- providers: [
23339
- { provide: ViewContainerRef, useValue: viewContainerRef },
23340
- { provide: TemplateRef, useValue: templateRef },
23341
- { provide: IterableDiffers, useValue: iterableDiffers },
23342
- { provide: _VIEW_REPEATER_STRATEGY, useValue: viewRepeater },
23343
- { provide: NgZone, useValue: ngZone },
23344
- { provide: CdkVirtualForOf, useClass: CdkVirtualForOf },
23345
- ],
23346
- });
23347
- return cdkVirtualForInjector.get(CdkVirtualForOf);
23348
- }
23349
- }
23350
23594
 
23351
23595
  /*
23352
23596
  * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
@@ -25244,7 +25488,7 @@ class ClrTreeNode {
25244
25488
  }
25245
25489
  }
25246
25490
  ClrTreeNode.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrTreeNode, deps: [{ token: PLATFORM_ID }, { token: ClrTreeNode, optional: true, skipSelf: true }, { token: TreeFeaturesService }, { token: IfExpandService }, { token: ClrCommonStringsService }, { token: TreeFocusManagerService }, { token: i0.ElementRef }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component });
25247
- ClrTreeNode.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrTreeNode, selector: "clr-tree-node", inputs: { expandable: ["clrExpandable", "expandable"], disabled: ["clrDisabled", "disabled"], selected: ["clrSelected", "selected"], expanded: ["clrExpanded", "expanded"], clrForTypeAhead: "clrForTypeAhead" }, outputs: { selectedChange: "clrSelectedChange", expandedChange: "clrExpandedChange" }, host: { properties: { "class.clr-tree-node": "true", "class.disabled": "this._model.disabled" } }, providers: [TREE_FEATURES_PROVIDER, IfExpandService, { provide: LoadingListener, useExisting: IfExpandService }], queries: [{ propertyName: "treeNodeLinkList", predicate: ClrTreeNodeLink }], viewQueries: [{ propertyName: "contentContainer", first: true, predicate: ["contentContainer"], descendants: true, read: ElementRef, static: true }], ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2025 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<div\n #contentContainer\n role=\"treeitem\"\n class=\"clr-tree-node-content-container\"\n tabindex=\"-1\"\n [class.clr-form-control-disabled]=\"disabled\"\n [attr.aria-disabled]=\"disabled\"\n [attr.aria-expanded]=\"isExpandable() ? expanded : null\"\n [attr.aria-selected]=\"ariaSelected\"\n (keydown)=\"onKeyDown($event)\"\n (focus)=\"broadcastFocusOnContainer()\"\n>\n <button\n *ngIf=\"isExpandable() && !isModelLoading && !expandService.loading\"\n aria-hidden=\"true\"\n type=\"button\"\n tabindex=\"-1\"\n class=\"clr-treenode-caret\"\n (click)=\"expandService.toggle();\"\n (focus)=\"focusTreeNode()\"\n [disabled]=\"disabled\"\n >\n <cds-icon\n class=\"clr-treenode-caret-icon\"\n shape=\"angle\"\n [attr.direction]=\"expandService.expanded ? 'down' : 'right'\"\n ></cds-icon>\n </button>\n <div class=\"clr-treenode-spinner-container\" *ngIf=\"expandService.loading || isModelLoading\">\n <span class=\"clr-treenode-spinner spinner\"></span>\n </div>\n <div class=\"clr-checkbox-wrapper clr-treenode-checkbox\" *ngIf=\"featuresService.selectable\">\n <input\n aria-hidden=\"true\"\n type=\"checkbox\"\n id=\"{{nodeId}}-check\"\n class=\"clr-checkbox\"\n [disabled]=\"disabled\"\n [checked]=\"_model.selected.value === STATES.SELECTED\"\n [indeterminate]=\"_model.selected.value === STATES.INDETERMINATE\"\n (change)=\"_model.toggleSelection(featuresService.eager)\"\n (focus)=\"focusTreeNode()\"\n tabindex=\"-1\"\n />\n <label for=\"{{nodeId}}-check\" class=\"clr-control-label\">\n <ng-container [ngTemplateOutlet]=\"treenodeContent\"></ng-container>\n </label>\n </div>\n <div\n class=\"clr-treenode-content\"\n [class.clr-treenode-text-only]=\"treeNodeContentTextOnly\"\n (mouseup)=\"focusTreeNode()\"\n *ngIf=\"!featuresService.selectable\"\n >\n <ng-container [ngTemplateOutlet]=\"treenodeContent\"></ng-container>\n </div>\n\n <ng-template #treenodeContent>\n <ng-content></ng-content>\n <div class=\"clr-sr-only\" *ngIf=\"featuresService.selectable || ariaSelected\">\n <span> {{ariaSelected ? commonStrings.keys.selectedTreeNode : commonStrings.keys.unselectedTreeNode}}</span>\n </div>\n </ng-template>\n</div>\n<div\n class=\"clr-treenode-children\"\n [@toggleChildrenAnim]=\"expandService.expanded ? 'expanded' : 'collapsed'\"\n [attr.role]=\"isExpandable() && !featuresService.recursion ? 'group' : null\"\n>\n <ng-content select=\"clr-tree-node\"></ng-content>\n <ng-content select=\"[clrIfExpanded]\"></ng-content>\n <clr-recursive-children [parent]=\"_model\"></clr-recursive-children>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }, { kind: "component", type: RecursiveChildren, selector: "clr-recursive-children", inputs: ["parent", "children"] }], animations: [
25491
+ ClrTreeNode.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrTreeNode, selector: "clr-tree-node", inputs: { expandable: ["clrExpandable", "expandable"], disabled: ["clrDisabled", "disabled"], selected: ["clrSelected", "selected"], expanded: ["clrExpanded", "expanded"], clrForTypeAhead: "clrForTypeAhead" }, outputs: { selectedChange: "clrSelectedChange", expandedChange: "clrExpandedChange" }, host: { properties: { "class.clr-tree-node": "true", "class.disabled": "this._model.disabled" } }, providers: [TREE_FEATURES_PROVIDER, IfExpandService, { provide: LoadingListener, useExisting: IfExpandService }], queries: [{ propertyName: "treeNodeLinkList", predicate: ClrTreeNodeLink }], viewQueries: [{ propertyName: "contentContainer", first: true, predicate: ["contentContainer"], descendants: true, read: ElementRef, static: true }], ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2025 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<div\n #contentContainer\n role=\"treeitem\"\n class=\"clr-tree-node-content-container\"\n tabindex=\"-1\"\n [class.clr-form-control-disabled]=\"disabled\"\n [attr.aria-disabled]=\"disabled\"\n [attr.aria-expanded]=\"isExpandable() ? expanded : null\"\n [attr.aria-selected]=\"ariaSelected\"\n (keydown)=\"onKeyDown($event)\"\n (focus)=\"broadcastFocusOnContainer()\"\n>\n <button\n *ngIf=\"isExpandable() && !isModelLoading && !expandService.loading\"\n aria-hidden=\"true\"\n type=\"button\"\n tabindex=\"-1\"\n class=\"clr-treenode-caret\"\n (click)=\"expandService.toggle();\"\n (focus)=\"focusTreeNode()\"\n [disabled]=\"disabled\"\n >\n <cds-icon\n class=\"clr-treenode-caret-icon\"\n shape=\"angle\"\n [attr.direction]=\"expandService.expanded ? 'down' : 'right'\"\n ></cds-icon>\n </button>\n <div class=\"clr-treenode-spinner-container\" *ngIf=\"expandService.loading || isModelLoading\">\n <span class=\"clr-treenode-spinner spinner\"></span>\n </div>\n <div class=\"clr-checkbox-wrapper clr-treenode-checkbox\" *ngIf=\"featuresService.selectable\">\n <input\n aria-hidden=\"true\"\n type=\"checkbox\"\n [id]=\"nodeId + '-check'\"\n class=\"clr-checkbox\"\n [disabled]=\"disabled\"\n [checked]=\"_model.selected.value === STATES.SELECTED\"\n [indeterminate]=\"_model.selected.value === STATES.INDETERMINATE\"\n (change)=\"_model.toggleSelection(featuresService.eager)\"\n (focus)=\"focusTreeNode()\"\n tabindex=\"-1\"\n />\n <label [for]=\"nodeId + '-check'\" class=\"clr-control-label\">\n <ng-container [ngTemplateOutlet]=\"treenodeContent\"></ng-container>\n </label>\n </div>\n <div\n class=\"clr-treenode-content\"\n [class.clr-treenode-text-only]=\"treeNodeContentTextOnly\"\n (mouseup)=\"focusTreeNode()\"\n *ngIf=\"!featuresService.selectable\"\n >\n <ng-container [ngTemplateOutlet]=\"treenodeContent\"></ng-container>\n </div>\n\n <ng-template #treenodeContent>\n <ng-content></ng-content>\n <div class=\"clr-sr-only\" *ngIf=\"featuresService.selectable || ariaSelected\">\n <span> {{ariaSelected ? commonStrings.keys.selectedTreeNode : commonStrings.keys.unselectedTreeNode}}</span>\n </div>\n </ng-template>\n</div>\n<div\n class=\"clr-treenode-children\"\n [@toggleChildrenAnim]=\"expandService.expanded ? 'expanded' : 'collapsed'\"\n [attr.role]=\"isExpandable() && !featuresService.recursion ? 'group' : null\"\n>\n <ng-content select=\"clr-tree-node\"></ng-content>\n <ng-content select=\"[clrIfExpanded]\"></ng-content>\n <clr-recursive-children [parent]=\"_model\"></clr-recursive-children>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }, { kind: "component", type: RecursiveChildren, selector: "clr-recursive-children", inputs: ["parent", "children"] }], animations: [
25248
25492
  trigger('toggleChildrenAnim', [
25249
25493
  transition('collapsed => expanded', [style({ height: 0 }), animate(200, style({ height: '*' }))]),
25250
25494
  transition('expanded => collapsed', [style({ height: '*' }), animate(200, style({ height: 0 }))]),
@@ -25264,7 +25508,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
25264
25508
  ], host: {
25265
25509
  '[class.clr-tree-node]': 'true',
25266
25510
  '[class.disabled]': 'this._model.disabled',
25267
- }, template: "<!--\n ~ Copyright (c) 2016-2025 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<div\n #contentContainer\n role=\"treeitem\"\n class=\"clr-tree-node-content-container\"\n tabindex=\"-1\"\n [class.clr-form-control-disabled]=\"disabled\"\n [attr.aria-disabled]=\"disabled\"\n [attr.aria-expanded]=\"isExpandable() ? expanded : null\"\n [attr.aria-selected]=\"ariaSelected\"\n (keydown)=\"onKeyDown($event)\"\n (focus)=\"broadcastFocusOnContainer()\"\n>\n <button\n *ngIf=\"isExpandable() && !isModelLoading && !expandService.loading\"\n aria-hidden=\"true\"\n type=\"button\"\n tabindex=\"-1\"\n class=\"clr-treenode-caret\"\n (click)=\"expandService.toggle();\"\n (focus)=\"focusTreeNode()\"\n [disabled]=\"disabled\"\n >\n <cds-icon\n class=\"clr-treenode-caret-icon\"\n shape=\"angle\"\n [attr.direction]=\"expandService.expanded ? 'down' : 'right'\"\n ></cds-icon>\n </button>\n <div class=\"clr-treenode-spinner-container\" *ngIf=\"expandService.loading || isModelLoading\">\n <span class=\"clr-treenode-spinner spinner\"></span>\n </div>\n <div class=\"clr-checkbox-wrapper clr-treenode-checkbox\" *ngIf=\"featuresService.selectable\">\n <input\n aria-hidden=\"true\"\n type=\"checkbox\"\n id=\"{{nodeId}}-check\"\n class=\"clr-checkbox\"\n [disabled]=\"disabled\"\n [checked]=\"_model.selected.value === STATES.SELECTED\"\n [indeterminate]=\"_model.selected.value === STATES.INDETERMINATE\"\n (change)=\"_model.toggleSelection(featuresService.eager)\"\n (focus)=\"focusTreeNode()\"\n tabindex=\"-1\"\n />\n <label for=\"{{nodeId}}-check\" class=\"clr-control-label\">\n <ng-container [ngTemplateOutlet]=\"treenodeContent\"></ng-container>\n </label>\n </div>\n <div\n class=\"clr-treenode-content\"\n [class.clr-treenode-text-only]=\"treeNodeContentTextOnly\"\n (mouseup)=\"focusTreeNode()\"\n *ngIf=\"!featuresService.selectable\"\n >\n <ng-container [ngTemplateOutlet]=\"treenodeContent\"></ng-container>\n </div>\n\n <ng-template #treenodeContent>\n <ng-content></ng-content>\n <div class=\"clr-sr-only\" *ngIf=\"featuresService.selectable || ariaSelected\">\n <span> {{ariaSelected ? commonStrings.keys.selectedTreeNode : commonStrings.keys.unselectedTreeNode}}</span>\n </div>\n </ng-template>\n</div>\n<div\n class=\"clr-treenode-children\"\n [@toggleChildrenAnim]=\"expandService.expanded ? 'expanded' : 'collapsed'\"\n [attr.role]=\"isExpandable() && !featuresService.recursion ? 'group' : null\"\n>\n <ng-content select=\"clr-tree-node\"></ng-content>\n <ng-content select=\"[clrIfExpanded]\"></ng-content>\n <clr-recursive-children [parent]=\"_model\"></clr-recursive-children>\n</div>\n" }]
25511
+ }, template: "<!--\n ~ Copyright (c) 2016-2025 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<div\n #contentContainer\n role=\"treeitem\"\n class=\"clr-tree-node-content-container\"\n tabindex=\"-1\"\n [class.clr-form-control-disabled]=\"disabled\"\n [attr.aria-disabled]=\"disabled\"\n [attr.aria-expanded]=\"isExpandable() ? expanded : null\"\n [attr.aria-selected]=\"ariaSelected\"\n (keydown)=\"onKeyDown($event)\"\n (focus)=\"broadcastFocusOnContainer()\"\n>\n <button\n *ngIf=\"isExpandable() && !isModelLoading && !expandService.loading\"\n aria-hidden=\"true\"\n type=\"button\"\n tabindex=\"-1\"\n class=\"clr-treenode-caret\"\n (click)=\"expandService.toggle();\"\n (focus)=\"focusTreeNode()\"\n [disabled]=\"disabled\"\n >\n <cds-icon\n class=\"clr-treenode-caret-icon\"\n shape=\"angle\"\n [attr.direction]=\"expandService.expanded ? 'down' : 'right'\"\n ></cds-icon>\n </button>\n <div class=\"clr-treenode-spinner-container\" *ngIf=\"expandService.loading || isModelLoading\">\n <span class=\"clr-treenode-spinner spinner\"></span>\n </div>\n <div class=\"clr-checkbox-wrapper clr-treenode-checkbox\" *ngIf=\"featuresService.selectable\">\n <input\n aria-hidden=\"true\"\n type=\"checkbox\"\n [id]=\"nodeId + '-check'\"\n class=\"clr-checkbox\"\n [disabled]=\"disabled\"\n [checked]=\"_model.selected.value === STATES.SELECTED\"\n [indeterminate]=\"_model.selected.value === STATES.INDETERMINATE\"\n (change)=\"_model.toggleSelection(featuresService.eager)\"\n (focus)=\"focusTreeNode()\"\n tabindex=\"-1\"\n />\n <label [for]=\"nodeId + '-check'\" class=\"clr-control-label\">\n <ng-container [ngTemplateOutlet]=\"treenodeContent\"></ng-container>\n </label>\n </div>\n <div\n class=\"clr-treenode-content\"\n [class.clr-treenode-text-only]=\"treeNodeContentTextOnly\"\n (mouseup)=\"focusTreeNode()\"\n *ngIf=\"!featuresService.selectable\"\n >\n <ng-container [ngTemplateOutlet]=\"treenodeContent\"></ng-container>\n </div>\n\n <ng-template #treenodeContent>\n <ng-content></ng-content>\n <div class=\"clr-sr-only\" *ngIf=\"featuresService.selectable || ariaSelected\">\n <span> {{ariaSelected ? commonStrings.keys.selectedTreeNode : commonStrings.keys.unselectedTreeNode}}</span>\n </div>\n </ng-template>\n</div>\n<div\n class=\"clr-treenode-children\"\n [@toggleChildrenAnim]=\"expandService.expanded ? 'expanded' : 'collapsed'\"\n [attr.role]=\"isExpandable() && !featuresService.recursion ? 'group' : null\"\n>\n <ng-content select=\"clr-tree-node\"></ng-content>\n <ng-content select=\"[clrIfExpanded]\"></ng-content>\n <clr-recursive-children [parent]=\"_model\"></clr-recursive-children>\n</div>\n" }]
25268
25512
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
25269
25513
  type: Inject,
25270
25514
  args: [PLATFORM_ID]
@@ -25899,10 +26143,10 @@ class ClrAlertsPager {
25899
26143
  }
25900
26144
  }
25901
26145
  ClrAlertsPager.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrAlertsPager, deps: [{ token: MultiAlertService }, { token: ClrCommonStringsService }], target: i0.ɵɵFactoryTarget.Component });
25902
- ClrAlertsPager.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrAlertsPager, selector: "clr-alerts-pager", inputs: { currentAlert: ["clrCurrentAlert", "currentAlert"], currentAlertIndex: ["clrCurrentAlertIndex", "currentAlertIndex"] }, outputs: { currentAlertChange: "clrCurrentAlertChange", currentAlertIndexChange: "clrCurrentAlertIndexChange" }, host: { properties: { "class.alerts-pager": "true" } }, ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2025 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<div class=\"alerts-pager-control\">\n <div class=\"alerts-page-down\">\n <button class=\"alerts-pager-button\" type=\"button\" (click)=\"pageDown()\" [attr.aria-label]=\"previousAlertAriaLabel\">\n <cds-icon shape=\"angle\" direction=\"left\"></cds-icon>\n </button>\n </div>\n <div class=\"alerts-pager-text\">{{this.multiAlertService.current+1}} / {{this.multiAlertService.count}}</div>\n <div class=\"alerts-page-up\">\n <button class=\"alerts-pager-button\" type=\"button\" (click)=\"pageUp()\" [attr.aria-label]=\"nextAlertAriaLabel\">\n <cds-icon shape=\"angle\" direction=\"right\"></cds-icon>\n </button>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }] });
26146
+ ClrAlertsPager.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrAlertsPager, selector: "clr-alerts-pager", inputs: { currentAlert: ["clrCurrentAlert", "currentAlert"], currentAlertIndex: ["clrCurrentAlertIndex", "currentAlertIndex"] }, outputs: { currentAlertChange: "clrCurrentAlertChange", currentAlertIndexChange: "clrCurrentAlertIndexChange" }, host: { properties: { "class.alerts-pager": "true" } }, ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2025 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<div class=\"alerts-pager-control\">\n <div class=\"alerts-page-down\">\n <button class=\"alerts-pager-button\" type=\"button\" (click)=\"pageDown()\" [attr.aria-label]=\"previousAlertAriaLabel\">\n <cds-icon shape=\"angle\" direction=\"left\" [attr.title]=\"commonStrings.keys.previous\"></cds-icon>\n </button>\n </div>\n <div class=\"alerts-pager-text\">{{this.multiAlertService.current+1}} / {{this.multiAlertService.count}}</div>\n <div class=\"alerts-page-up\">\n <button class=\"alerts-pager-button\" type=\"button\" (click)=\"pageUp()\" [attr.aria-label]=\"nextAlertAriaLabel\">\n <cds-icon shape=\"angle\" direction=\"right\" [attr.title]=\"commonStrings.keys.next\"></cds-icon>\n </button>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }] });
25903
26147
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrAlertsPager, decorators: [{
25904
26148
  type: Component,
25905
- args: [{ selector: 'clr-alerts-pager', host: { '[class.alerts-pager]': 'true' }, template: "<!--\n ~ Copyright (c) 2016-2025 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<div class=\"alerts-pager-control\">\n <div class=\"alerts-page-down\">\n <button class=\"alerts-pager-button\" type=\"button\" (click)=\"pageDown()\" [attr.aria-label]=\"previousAlertAriaLabel\">\n <cds-icon shape=\"angle\" direction=\"left\"></cds-icon>\n </button>\n </div>\n <div class=\"alerts-pager-text\">{{this.multiAlertService.current+1}} / {{this.multiAlertService.count}}</div>\n <div class=\"alerts-page-up\">\n <button class=\"alerts-pager-button\" type=\"button\" (click)=\"pageUp()\" [attr.aria-label]=\"nextAlertAriaLabel\">\n <cds-icon shape=\"angle\" direction=\"right\"></cds-icon>\n </button>\n </div>\n</div>\n" }]
26149
+ args: [{ selector: 'clr-alerts-pager', host: { '[class.alerts-pager]': 'true' }, template: "<!--\n ~ Copyright (c) 2016-2025 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<div class=\"alerts-pager-control\">\n <div class=\"alerts-page-down\">\n <button class=\"alerts-pager-button\" type=\"button\" (click)=\"pageDown()\" [attr.aria-label]=\"previousAlertAriaLabel\">\n <cds-icon shape=\"angle\" direction=\"left\" [attr.title]=\"commonStrings.keys.previous\"></cds-icon>\n </button>\n </div>\n <div class=\"alerts-pager-text\">{{this.multiAlertService.current+1}} / {{this.multiAlertService.count}}</div>\n <div class=\"alerts-page-up\">\n <button class=\"alerts-pager-button\" type=\"button\" (click)=\"pageUp()\" [attr.aria-label]=\"nextAlertAriaLabel\">\n <cds-icon shape=\"angle\" direction=\"right\" [attr.title]=\"commonStrings.keys.next\"></cds-icon>\n </button>\n </div>\n</div>\n" }]
25906
26150
  }], ctorParameters: function () { return [{ type: MultiAlertService }, { type: ClrCommonStringsService }]; }, propDecorators: { currentAlertChange: [{
25907
26151
  type: Output,
25908
26152
  args: ['clrCurrentAlertChange']
@@ -26118,6 +26362,7 @@ class ClrModal {
26118
26362
  this._openChanged = new EventEmitter(false);
26119
26363
  this.closable = true;
26120
26364
  this.closeButtonAriaLabel = this.commonStrings.keys.close;
26365
+ this.size = 'md';
26121
26366
  this.staticBackdrop = true;
26122
26367
  this.skipAnimation = false;
26123
26368
  this.stopClose = false;
@@ -26186,7 +26431,7 @@ class ClrModal {
26186
26431
  }
26187
26432
  }
26188
26433
  ClrModal.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModal, deps: [{ token: ScrollingService }, { token: ClrCommonStringsService }, { token: ModalStackService }, { token: ClrModalConfigurationService }], target: i0.ɵɵFactoryTarget.Component });
26189
- ClrModal.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrModal, selector: "clr-modal", inputs: { _open: ["clrModalOpen", "_open"], closable: ["clrModalClosable", "closable"], closeButtonAriaLabel: ["clrModalCloseButtonAriaLabel", "closeButtonAriaLabel"], size: ["clrModalSize", "size"], staticBackdrop: ["clrModalStaticBackdrop", "staticBackdrop"], skipAnimation: ["clrModalSkipAnimation", "skipAnimation"], stopClose: ["clrModalPreventClose", "stopClose"], labelledBy: ["clrModalLabelledById", "labelledBy"], bypassScrollService: ["clrModalOverrideScrollService", "bypassScrollService"] }, outputs: { _openChanged: "clrModalOpenChange", altClose: "clrModalAlternateClose" }, host: { properties: { "class.open": "this._open" } }, viewQueries: [{ propertyName: "title", first: true, predicate: ["title"], descendants: true }, { propertyName: "bodyElementRef", first: true, predicate: ["body"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2025 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<div *ngIf=\"_open\" class=\"modal\" [class.modal-full-screen]=\"size == 'full-screen'\">\n <!--fixme: revisit when ngClass works with exit animation-->\n <div\n cdkTrapFocus\n [cdkTrapFocusAutoCapture]=\"true\"\n [@fadeMove]=\"fadeMove\"\n (@fadeMove.done)=\"fadeDone($event)\"\n class=\"modal-dialog\"\n [class.modal-sm]=\"size == 'sm'\"\n [class.modal-lg]=\"size == 'lg'\"\n [class.modal-xl]=\"size == 'xl'\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-hidden]=\"!_open\"\n [attr.aria-labelledby]=\"labelledBy || modalId\"\n >\n <div class=\"clr-sr-only\">{{commonStrings.keys.modalContentStart}}</div>\n <div class=\"modal-content-wrapper\">\n <!-- only used in wizards -->\n <ng-content select=\".modal-nav\"></ng-content>\n\n <div class=\"modal-content\">\n <div class=\"modal-header--accessible\">\n <ng-content select=\".leading-button\"></ng-content>\n <div class=\"modal-title-wrapper\" #title id=\"{{modalId}}\" cdkFocusInitial tabindex=\"-1\">\n <ng-content select=\".modal-title\"></ng-content>\n </div>\n <button\n type=\"button\"\n [attr.aria-label]=\"closeButtonAriaLabel || commonStrings.keys.close\"\n class=\"close\"\n *ngIf=\"closable\"\n (click)=\"close()\"\n >\n <cds-icon shape=\"window-close\"></cds-icon>\n </button>\n </div>\n <div #body class=\"modal-body-wrapper\">\n <ng-content select=\".modal-body\"></ng-content>\n </div>\n <ng-content select=\".modal-footer\"></ng-content>\n </div>\n </div>\n <div class=\"clr-sr-only\">{{commonStrings.keys.modalContentEnd}}</div>\n </div>\n</div>\n\n<div [@fade] *ngIf=\"backdrop\" class=\"modal-backdrop\" aria-hidden=\"true\" (click)=\"backdropClick()\"></div>\n", styles: [":host{display:none}:host.open{display:inline}\n"], dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: CdkTrapFocusModule_CdkTrapFocus, selector: "[cdkTrapFocus]" }, { kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }], viewProviders: [ScrollingService], animations: [
26434
+ ClrModal.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrModal, selector: "clr-modal", inputs: { _open: ["clrModalOpen", "_open"], closable: ["clrModalClosable", "closable"], closeButtonAriaLabel: ["clrModalCloseButtonAriaLabel", "closeButtonAriaLabel"], size: ["clrModalSize", "size"], staticBackdrop: ["clrModalStaticBackdrop", "staticBackdrop"], skipAnimation: ["clrModalSkipAnimation", "skipAnimation"], stopClose: ["clrModalPreventClose", "stopClose"], labelledBy: ["clrModalLabelledById", "labelledBy"], bypassScrollService: ["clrModalOverrideScrollService", "bypassScrollService"] }, outputs: { _openChanged: "clrModalOpenChange", altClose: "clrModalAlternateClose" }, host: { properties: { "class.open": "this._open" } }, viewQueries: [{ propertyName: "title", first: true, predicate: ["title"], descendants: true }, { propertyName: "bodyElementRef", first: true, predicate: ["body"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2025 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<div *ngIf=\"_open\" class=\"modal\" [class.modal-full-screen]=\"size == 'full-screen'\">\n <!--fixme: revisit when ngClass works with exit animation-->\n <div\n cdkTrapFocus\n [cdkTrapFocusAutoCapture]=\"true\"\n [@fadeMove]=\"fadeMove\"\n (@fadeMove.done)=\"fadeDone($event)\"\n class=\"modal-dialog\"\n [class.modal-sm]=\"size == 'sm'\"\n [class.modal-lg]=\"size == 'lg'\"\n [class.modal-xl]=\"size == 'xl'\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-hidden]=\"!_open\"\n [attr.aria-labelledby]=\"labelledBy || modalId\"\n >\n <div class=\"clr-sr-only\">{{commonStrings.keys.modalContentStart}}</div>\n <div class=\"modal-content-wrapper\">\n <!-- only used in wizards -->\n <ng-content select=\".modal-nav\"></ng-content>\n\n <div class=\"modal-content\">\n <div class=\"modal-header--accessible\">\n <ng-content select=\".leading-button\"></ng-content>\n <div class=\"modal-title-wrapper\" #title [id]=\"modalId\" cdkFocusInitial tabindex=\"-1\">\n <ng-content select=\".modal-title\"></ng-content>\n </div>\n <button\n type=\"button\"\n [attr.aria-label]=\"closeButtonAriaLabel || commonStrings.keys.close\"\n class=\"close\"\n *ngIf=\"closable\"\n (click)=\"close()\"\n >\n <cds-icon shape=\"window-close\"></cds-icon>\n </button>\n </div>\n <div #body class=\"modal-body-wrapper\">\n <ng-content select=\".modal-body\"></ng-content>\n </div>\n <ng-content select=\".modal-footer\"></ng-content>\n </div>\n </div>\n <div class=\"clr-sr-only\">{{commonStrings.keys.modalContentEnd}}</div>\n </div>\n</div>\n\n<div [@fade] *ngIf=\"backdrop\" class=\"modal-backdrop\" aria-hidden=\"true\" (click)=\"backdropClick()\"></div>\n", styles: [":host{display:none}:host.open{display:inline}\n"], dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: CdkTrapFocusModule_CdkTrapFocus, selector: "[cdkTrapFocus]" }, { kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }], viewProviders: [ScrollingService], animations: [
26190
26435
  trigger('fadeMove', [
26191
26436
  transition('* => fadeDown', [
26192
26437
  style({ opacity: 0, transform: 'translate(0, -25%)' }),
@@ -26221,7 +26466,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
26221
26466
  transition('void => *', [style({ opacity: 0 }), animate('0.2s ease-in-out', style({ opacity: 0.85 }))]),
26222
26467
  transition('* => void', [animate('0.2s ease-in-out', style({ opacity: 0 }))]),
26223
26468
  ]),
26224
- ], template: "<!--\n ~ Copyright (c) 2016-2025 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<div *ngIf=\"_open\" class=\"modal\" [class.modal-full-screen]=\"size == 'full-screen'\">\n <!--fixme: revisit when ngClass works with exit animation-->\n <div\n cdkTrapFocus\n [cdkTrapFocusAutoCapture]=\"true\"\n [@fadeMove]=\"fadeMove\"\n (@fadeMove.done)=\"fadeDone($event)\"\n class=\"modal-dialog\"\n [class.modal-sm]=\"size == 'sm'\"\n [class.modal-lg]=\"size == 'lg'\"\n [class.modal-xl]=\"size == 'xl'\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-hidden]=\"!_open\"\n [attr.aria-labelledby]=\"labelledBy || modalId\"\n >\n <div class=\"clr-sr-only\">{{commonStrings.keys.modalContentStart}}</div>\n <div class=\"modal-content-wrapper\">\n <!-- only used in wizards -->\n <ng-content select=\".modal-nav\"></ng-content>\n\n <div class=\"modal-content\">\n <div class=\"modal-header--accessible\">\n <ng-content select=\".leading-button\"></ng-content>\n <div class=\"modal-title-wrapper\" #title id=\"{{modalId}}\" cdkFocusInitial tabindex=\"-1\">\n <ng-content select=\".modal-title\"></ng-content>\n </div>\n <button\n type=\"button\"\n [attr.aria-label]=\"closeButtonAriaLabel || commonStrings.keys.close\"\n class=\"close\"\n *ngIf=\"closable\"\n (click)=\"close()\"\n >\n <cds-icon shape=\"window-close\"></cds-icon>\n </button>\n </div>\n <div #body class=\"modal-body-wrapper\">\n <ng-content select=\".modal-body\"></ng-content>\n </div>\n <ng-content select=\".modal-footer\"></ng-content>\n </div>\n </div>\n <div class=\"clr-sr-only\">{{commonStrings.keys.modalContentEnd}}</div>\n </div>\n</div>\n\n<div [@fade] *ngIf=\"backdrop\" class=\"modal-backdrop\" aria-hidden=\"true\" (click)=\"backdropClick()\"></div>\n", styles: [":host{display:none}:host.open{display:inline}\n"] }]
26469
+ ], template: "<!--\n ~ Copyright (c) 2016-2025 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<div *ngIf=\"_open\" class=\"modal\" [class.modal-full-screen]=\"size == 'full-screen'\">\n <!--fixme: revisit when ngClass works with exit animation-->\n <div\n cdkTrapFocus\n [cdkTrapFocusAutoCapture]=\"true\"\n [@fadeMove]=\"fadeMove\"\n (@fadeMove.done)=\"fadeDone($event)\"\n class=\"modal-dialog\"\n [class.modal-sm]=\"size == 'sm'\"\n [class.modal-lg]=\"size == 'lg'\"\n [class.modal-xl]=\"size == 'xl'\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-hidden]=\"!_open\"\n [attr.aria-labelledby]=\"labelledBy || modalId\"\n >\n <div class=\"clr-sr-only\">{{commonStrings.keys.modalContentStart}}</div>\n <div class=\"modal-content-wrapper\">\n <!-- only used in wizards -->\n <ng-content select=\".modal-nav\"></ng-content>\n\n <div class=\"modal-content\">\n <div class=\"modal-header--accessible\">\n <ng-content select=\".leading-button\"></ng-content>\n <div class=\"modal-title-wrapper\" #title [id]=\"modalId\" cdkFocusInitial tabindex=\"-1\">\n <ng-content select=\".modal-title\"></ng-content>\n </div>\n <button\n type=\"button\"\n [attr.aria-label]=\"closeButtonAriaLabel || commonStrings.keys.close\"\n class=\"close\"\n *ngIf=\"closable\"\n (click)=\"close()\"\n >\n <cds-icon shape=\"window-close\"></cds-icon>\n </button>\n </div>\n <div #body class=\"modal-body-wrapper\">\n <ng-content select=\".modal-body\"></ng-content>\n </div>\n <ng-content select=\".modal-footer\"></ng-content>\n </div>\n </div>\n <div class=\"clr-sr-only\">{{commonStrings.keys.modalContentEnd}}</div>\n </div>\n</div>\n\n<div [@fade] *ngIf=\"backdrop\" class=\"modal-backdrop\" aria-hidden=\"true\" (click)=\"backdropClick()\"></div>\n", styles: [":host{display:none}:host.open{display:inline}\n"] }]
26225
26470
  }], ctorParameters: function () { return [{ type: ScrollingService }, { type: ClrCommonStringsService }, { type: ModalStackService }, { type: ClrModalConfigurationService }]; }, propDecorators: { title: [{
26226
26471
  type: ViewChild,
26227
26472
  args: ['title']
@@ -26390,11 +26635,15 @@ class ClrSidePanel {
26390
26635
  this.altClose = new EventEmitter(false);
26391
26636
  this._pinnable = false;
26392
26637
  this._pinned = false;
26638
+ this._size = 'md';
26393
26639
  }
26394
26640
  get size() {
26395
26641
  return this._size;
26396
26642
  }
26397
26643
  set size(value) {
26644
+ if (!value) {
26645
+ value = 'md';
26646
+ }
26398
26647
  if (this._size !== value) {
26399
26648
  this._size = value;
26400
26649
  if (this.clrSidePanelPinnable && this.pinned) {
@@ -28929,6 +29178,23 @@ class ClrWizardStepnavItem {
28929
29178
  this.pageGuard();
28930
29179
  return this.pageCollection.previousPageIsCompleted(this.page);
28931
29180
  }
29181
+ get stepIconId() {
29182
+ return `${this.id}-step-icon`;
29183
+ }
29184
+ get stepTextId() {
29185
+ return `${this.id}-step-text`;
29186
+ }
29187
+ get stepNumberId() {
29188
+ return `${this.id}-step-number`;
29189
+ }
29190
+ get stepTitleId() {
29191
+ return `${this.id}-step-title`;
29192
+ }
29193
+ get labelledby() {
29194
+ const textIds = [this.stepTextId, this.stepNumberId, this.stepTitleId];
29195
+ const allIds = this.isComplete ? [this.stepIconId, ...textIds] : textIds;
29196
+ return allIds.join(' ');
29197
+ }
28932
29198
  click() {
28933
29199
  this.pageGuard();
28934
29200
  // if we click on our own stepnav or a disabled stepnav, we don't want to do anything
@@ -28950,25 +29216,30 @@ ClrWizardStepnavItem.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", v
28950
29216
  class="btn btn-link clr-wizard-stepnav-link"
28951
29217
  (click)="click()"
28952
29218
  [attr.disabled]="isDisabled ? '' : null"
29219
+ [attr.aria-labelledby]="labelledby"
28953
29220
  >
28954
29221
  <div class="clr-wizard-stepnav-link-icon">
28955
29222
  <cds-icon
28956
29223
  *ngIf="hasError"
29224
+ [id]="stepIconId"
28957
29225
  shape="error-standard"
28958
29226
  role="img"
28959
29227
  [attr.aria-label]="commonStrings.keys.wizardStepError"
28960
29228
  ></cds-icon>
28961
29229
  <cds-icon
28962
29230
  *ngIf="!hasError && isComplete"
29231
+ [id]="stepIconId"
28963
29232
  shape="success-standard"
28964
29233
  role="img"
28965
29234
  [attr.aria-label]="commonStrings.keys.wizardStepSuccess"
28966
29235
  ></cds-icon>
28967
29236
  </div>
28968
29237
 
28969
- <span class="clr-sr-only">{{ commonStrings.keys.wizardStep }}</span>
28970
- <div class="clr-wizard-stepnav-link-page-number"><ng-content></ng-content></div>
28971
- <span class="clr-wizard-stepnav-link-title">
29238
+ <span [id]="stepTextId" class="clr-sr-only">{{ commonStrings.keys.wizardStep }}</span>
29239
+ <div [id]="stepNumberId" class="clr-wizard-stepnav-link-page-number">
29240
+ <ng-content></ng-content>
29241
+ </div>
29242
+ <span [id]="stepTitleId" class="clr-wizard-stepnav-link-title">
28972
29243
  <ng-template [ngTemplateOutlet]="page.navTitle"></ng-template>
28973
29244
  </span>
28974
29245
  </button>
@@ -28983,25 +29254,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
28983
29254
  class="btn btn-link clr-wizard-stepnav-link"
28984
29255
  (click)="click()"
28985
29256
  [attr.disabled]="isDisabled ? '' : null"
29257
+ [attr.aria-labelledby]="labelledby"
28986
29258
  >
28987
29259
  <div class="clr-wizard-stepnav-link-icon">
28988
29260
  <cds-icon
28989
29261
  *ngIf="hasError"
29262
+ [id]="stepIconId"
28990
29263
  shape="error-standard"
28991
29264
  role="img"
28992
29265
  [attr.aria-label]="commonStrings.keys.wizardStepError"
28993
29266
  ></cds-icon>
28994
29267
  <cds-icon
28995
29268
  *ngIf="!hasError && isComplete"
29269
+ [id]="stepIconId"
28996
29270
  shape="success-standard"
28997
29271
  role="img"
28998
29272
  [attr.aria-label]="commonStrings.keys.wizardStepSuccess"
28999
29273
  ></cds-icon>
29000
29274
  </div>
29001
29275
 
29002
- <span class="clr-sr-only">{{ commonStrings.keys.wizardStep }}</span>
29003
- <div class="clr-wizard-stepnav-link-page-number"><ng-content></ng-content></div>
29004
- <span class="clr-wizard-stepnav-link-title">
29276
+ <span [id]="stepTextId" class="clr-sr-only">{{ commonStrings.keys.wizardStep }}</span>
29277
+ <div [id]="stepNumberId" class="clr-wizard-stepnav-link-page-number">
29278
+ <ng-content></ng-content>
29279
+ </div>
29280
+ <span [id]="stepTitleId" class="clr-wizard-stepnav-link-title">
29005
29281
  <ng-template [ngTemplateOutlet]="page.navTitle"></ng-template>
29006
29282
  </span>
29007
29283
  </button>
@@ -29036,37 +29312,43 @@ class ClrWizardStepnav {
29036
29312
  }
29037
29313
  }
29038
29314
  ClrWizardStepnav.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrWizardStepnav, deps: [{ token: PageCollectionService }], target: i0.ɵɵFactoryTarget.Component });
29039
- ClrWizardStepnav.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrWizardStepnav, selector: "clr-wizard-stepnav", host: { classAttribute: "clr-wizard-stepnav" }, ngImport: i0, template: `
29040
- <div class="clr-wizard-stepnav-list">
29041
- <div
29042
- *ngFor="let page of pageService.pages; let i = index"
29043
- clr-wizard-stepnav-item
29044
- [page]="page"
29045
- class="clr-wizard-stepnav-item"
29046
- >
29047
- {{ i + 1 }}
29048
- </div>
29049
- </div>
29315
+ ClrWizardStepnav.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrWizardStepnav, selector: "clr-wizard-stepnav", inputs: { label: "label" }, host: { classAttribute: "clr-wizard-stepnav" }, ngImport: i0, template: `
29316
+ <nav [attr.aria-label]="label">
29317
+ <ol class="clr-wizard-stepnav-list">
29318
+ <li
29319
+ *ngFor="let page of pageService.pages; let i = index"
29320
+ clr-wizard-stepnav-item
29321
+ [page]="page"
29322
+ class="clr-wizard-stepnav-item"
29323
+ >
29324
+ {{ i + 1 }}
29325
+ </li>
29326
+ </ol>
29327
+ </nav>
29050
29328
  `, isInline: true, dependencies: [{ kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ClrWizardStepnavItem, selector: "[clr-wizard-stepnav-item]", inputs: ["page"] }] });
29051
29329
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrWizardStepnav, decorators: [{
29052
29330
  type: Component,
29053
29331
  args: [{
29054
29332
  selector: 'clr-wizard-stepnav',
29055
29333
  template: `
29056
- <div class="clr-wizard-stepnav-list">
29057
- <div
29058
- *ngFor="let page of pageService.pages; let i = index"
29059
- clr-wizard-stepnav-item
29060
- [page]="page"
29061
- class="clr-wizard-stepnav-item"
29062
- >
29063
- {{ i + 1 }}
29064
- </div>
29065
- </div>
29334
+ <nav [attr.aria-label]="label">
29335
+ <ol class="clr-wizard-stepnav-list">
29336
+ <li
29337
+ *ngFor="let page of pageService.pages; let i = index"
29338
+ clr-wizard-stepnav-item
29339
+ [page]="page"
29340
+ class="clr-wizard-stepnav-item"
29341
+ >
29342
+ {{ i + 1 }}
29343
+ </li>
29344
+ </ol>
29345
+ </nav>
29066
29346
  `,
29067
29347
  host: { class: 'clr-wizard-stepnav' },
29068
29348
  }]
29069
- }], ctorParameters: function () { return [{ type: PageCollectionService }]; } });
29349
+ }], ctorParameters: function () { return [{ type: PageCollectionService }]; }, propDecorators: { label: [{
29350
+ type: Input
29351
+ }] } });
29070
29352
 
29071
29353
  /*
29072
29354
  * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
@@ -29467,7 +29749,7 @@ class ClrWizard {
29467
29749
  }
29468
29750
  }
29469
29751
  ClrWizard.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrWizard, deps: [{ token: PLATFORM_ID }, { token: ClrCommonStringsService }, { token: WizardNavigationService }, { token: PageCollectionService }, { token: ButtonHubService }, { token: HeaderActionService }, { token: i0.ElementRef }, { token: i0.IterableDiffers }], target: i0.ɵɵFactoryTarget.Component });
29470
- ClrWizard.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrWizard, selector: "clr-wizard", inputs: { stepnavAriaLabel: ["clrWizardStepnavAriaLabel", "stepnavAriaLabel"], size: ["clrWizardSize", "size"], closable: ["clrWizardClosable", "closable"], _stopModalAnimations: ["clrWizardPreventModalAnimation", "_stopModalAnimations"], forceForward: ["clrWizardForceForwardNavigation", "forceForward"], clrWizardOpen: "clrWizardOpen", stopNext: ["clrWizardPreventDefaultNext", "stopNext"], stopCancel: ["clrWizardPreventDefaultCancel", "stopCancel"], stopNavigation: ["clrWizardPreventNavigation", "stopNavigation"], disableStepnav: ["clrWizardDisableStepnav", "disableStepnav"] }, outputs: { _openChanged: "clrWizardOpenChange", onCancel: "clrWizardOnCancel", wizardFinished: "clrWizardOnFinish", onReset: "clrWizardOnReset", currentPageChanged: "clrWizardCurrentPageChanged", onMoveNext: "clrWizardOnNext", onMovePrevious: "clrWizardOnPrevious" }, host: { properties: { "class.clr-wizard": "true", "class.wizard-md": "size == 'md'", "class.wizard-lg": "size == 'lg'", "class.wizard-xl": "size == 'xl'", "class.lastPage": "navService.currentPageIsLast" } }, providers: [WizardNavigationService, PageCollectionService, ButtonHubService, HeaderActionService], queries: [{ propertyName: "wizardTitle", first: true, predicate: ClrWizardTitle, descendants: true }, { propertyName: "pages", predicate: ClrWizardPage, descendants: true }, { propertyName: "headerActions", predicate: ClrWizardHeaderAction }], viewQueries: [{ propertyName: "pageTitle", first: true, predicate: ["pageTitle"], descendants: true }, { propertyName: "modal", first: true, predicate: ClrModal, descendants: true }], ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2025 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<clr-modal\n [clrModalOpen]=\"_open\"\n [clrModalSize]=\"size\"\n [clrModalClosable]=\"closable\"\n [clrModalStaticBackdrop]=\"true\"\n [clrModalSkipAnimation]=\"stopModalAnimations\"\n [clrModalOverrideScrollService]=\"isInline\"\n [clrModalPreventClose]=\"true\"\n (clrModalAlternateClose)=\"modalCancel()\"\n [clrModalLabelledById]=\"wizardId\"\n>\n <div class=\"modal-nav clr-wizard-stepnav-wrapper\" role=\"region\" [attr.aria-label]=\"stepnavAriaLabel\">\n <div class=\"clr-wizard-title\" id=\"{{wizardId}}\" role=\"heading\" [attr.aria-level]=\"wizardTitle.headingLevel || 1\">\n <ng-content select=\"clr-wizard-title\"></ng-content>\n </div>\n <clr-wizard-stepnav></clr-wizard-stepnav>\n </div>\n\n <div class=\"modal-title\" role=\"heading\" [attr.aria-level]=\"navService.currentPage?.pageTitle.headingLevel || 2\">\n <span tabindex=\"-1\" #pageTitle class=\"modal-title-text\">\n <ng-template [ngTemplateOutlet]=\"navService.currentPageTitle\"></ng-template>\n </span>\n\n <div class=\"modal-header-actions-wrapper\" *ngIf=\"headerActionService.displayHeaderActionsWrapper\">\n <div *ngIf=\"headerActionService.showWizardHeaderActions\">\n <ng-content select=\"clr-wizard-header-action\"></ng-content>\n </div>\n <div *ngIf=\"headerActionService.currentPageHasHeaderActions\">\n <ng-template [ngTemplateOutlet]=\"navService.currentPage.headerActions\"></ng-template>\n </div>\n </div>\n </div>\n\n <div class=\"modal-body\">\n <main clr-wizard-pages-wrapper class=\"clr-wizard-content\">\n <ng-content></ng-content>\n </main>\n </div>\n <div class=\"modal-footer clr-wizard-footer\">\n <div class=\"clr-wizard-footer-buttons\">\n <div\n *ngIf=\"navService.currentPage && !navService.currentPage.hasButtons\"\n class=\"clr-wizard-footer-buttons-wrapper\"\n >\n <ng-content select=\"clr-wizard-button\"></ng-content>\n </div>\n <div\n *ngIf=\"navService.currentPage && navService.currentPage.hasButtons\"\n class=\"clr-wizard-footer-buttons-wrapper\"\n >\n <ng-template [ngTemplateOutlet]=\"navService.currentPage.buttons\"></ng-template>\n </div>\n </div>\n </div>\n</clr-modal>\n", dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ClrModal, selector: "clr-modal", inputs: ["clrModalOpen", "clrModalClosable", "clrModalCloseButtonAriaLabel", "clrModalSize", "clrModalStaticBackdrop", "clrModalSkipAnimation", "clrModalPreventClose", "clrModalLabelledById", "clrModalOverrideScrollService"], outputs: ["clrModalOpenChange", "clrModalAlternateClose"] }, { kind: "directive", type: ClrModalBody, selector: ".modal-body" }, { kind: "component", type: ClrWizardStepnav, selector: "clr-wizard-stepnav" }] });
29752
+ ClrWizard.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrWizard, selector: "clr-wizard", inputs: { stepnavAriaLabel: ["clrWizardStepnavAriaLabel", "stepnavAriaLabel"], size: ["clrWizardSize", "size"], closable: ["clrWizardClosable", "closable"], _stopModalAnimations: ["clrWizardPreventModalAnimation", "_stopModalAnimations"], forceForward: ["clrWizardForceForwardNavigation", "forceForward"], clrWizardOpen: "clrWizardOpen", stopNext: ["clrWizardPreventDefaultNext", "stopNext"], stopCancel: ["clrWizardPreventDefaultCancel", "stopCancel"], stopNavigation: ["clrWizardPreventNavigation", "stopNavigation"], disableStepnav: ["clrWizardDisableStepnav", "disableStepnav"] }, outputs: { _openChanged: "clrWizardOpenChange", onCancel: "clrWizardOnCancel", wizardFinished: "clrWizardOnFinish", onReset: "clrWizardOnReset", currentPageChanged: "clrWizardCurrentPageChanged", onMoveNext: "clrWizardOnNext", onMovePrevious: "clrWizardOnPrevious" }, host: { properties: { "class.clr-wizard": "true", "class.wizard-md": "size == 'md'", "class.wizard-lg": "size == 'lg'", "class.wizard-xl": "size == 'xl'", "class.lastPage": "navService.currentPageIsLast" } }, providers: [WizardNavigationService, PageCollectionService, ButtonHubService, HeaderActionService], queries: [{ propertyName: "wizardTitle", first: true, predicate: ClrWizardTitle, descendants: true }, { propertyName: "pages", predicate: ClrWizardPage, descendants: true }, { propertyName: "headerActions", predicate: ClrWizardHeaderAction }], viewQueries: [{ propertyName: "pageTitle", first: true, predicate: ["pageTitle"], descendants: true }, { propertyName: "modal", first: true, predicate: ClrModal, descendants: true }], ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2025 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<clr-modal\n [clrModalOpen]=\"_open\"\n [clrModalSize]=\"size\"\n [clrModalClosable]=\"closable\"\n [clrModalStaticBackdrop]=\"true\"\n [clrModalSkipAnimation]=\"stopModalAnimations\"\n [clrModalOverrideScrollService]=\"isInline\"\n [clrModalPreventClose]=\"true\"\n (clrModalAlternateClose)=\"modalCancel()\"\n [clrModalLabelledById]=\"wizardId\"\n>\n <div class=\"modal-nav clr-wizard-stepnav-wrapper\" role=\"region\">\n <div class=\"clr-wizard-title\" [id]=\"wizardId\" role=\"heading\" [attr.aria-level]=\"wizardTitle.headingLevel || 1\">\n <ng-content select=\"clr-wizard-title\"></ng-content>\n </div>\n <clr-wizard-stepnav [label]=\"stepnavAriaLabel\"></clr-wizard-stepnav>\n </div>\n\n <div class=\"modal-title\" role=\"heading\" [attr.aria-level]=\"navService.currentPage?.pageTitle.headingLevel || 2\">\n <span tabindex=\"-1\" #pageTitle class=\"modal-title-text\">\n <ng-template [ngTemplateOutlet]=\"navService.currentPageTitle\"></ng-template>\n </span>\n\n <div class=\"modal-header-actions-wrapper\" *ngIf=\"headerActionService.displayHeaderActionsWrapper\">\n <div *ngIf=\"headerActionService.showWizardHeaderActions\">\n <ng-content select=\"clr-wizard-header-action\"></ng-content>\n </div>\n <div *ngIf=\"headerActionService.currentPageHasHeaderActions\">\n <ng-template [ngTemplateOutlet]=\"navService.currentPage.headerActions\"></ng-template>\n </div>\n </div>\n </div>\n\n <div class=\"modal-body\">\n <main clr-wizard-pages-wrapper class=\"clr-wizard-content\">\n <ng-content></ng-content>\n </main>\n </div>\n <div class=\"modal-footer clr-wizard-footer\">\n <div class=\"clr-wizard-footer-buttons\">\n <div\n *ngIf=\"navService.currentPage && !navService.currentPage.hasButtons\"\n class=\"clr-wizard-footer-buttons-wrapper\"\n >\n <ng-content select=\"clr-wizard-button\"></ng-content>\n </div>\n <div\n *ngIf=\"navService.currentPage && navService.currentPage.hasButtons\"\n class=\"clr-wizard-footer-buttons-wrapper\"\n >\n <ng-template [ngTemplateOutlet]=\"navService.currentPage.buttons\"></ng-template>\n </div>\n </div>\n </div>\n</clr-modal>\n", dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ClrModal, selector: "clr-modal", inputs: ["clrModalOpen", "clrModalClosable", "clrModalCloseButtonAriaLabel", "clrModalSize", "clrModalStaticBackdrop", "clrModalSkipAnimation", "clrModalPreventClose", "clrModalLabelledById", "clrModalOverrideScrollService"], outputs: ["clrModalOpenChange", "clrModalAlternateClose"] }, { kind: "directive", type: ClrModalBody, selector: ".modal-body" }, { kind: "component", type: ClrWizardStepnav, selector: "clr-wizard-stepnav", inputs: ["label"] }] });
29471
29753
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrWizard, decorators: [{
29472
29754
  type: Component,
29473
29755
  args: [{ selector: 'clr-wizard', providers: [WizardNavigationService, PageCollectionService, ButtonHubService, HeaderActionService], host: {
@@ -29476,7 +29758,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
29476
29758
  '[class.wizard-lg]': "size == 'lg'",
29477
29759
  '[class.wizard-xl]': "size == 'xl'",
29478
29760
  '[class.lastPage]': 'navService.currentPageIsLast',
29479
- }, template: "<!--\n ~ Copyright (c) 2016-2025 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<clr-modal\n [clrModalOpen]=\"_open\"\n [clrModalSize]=\"size\"\n [clrModalClosable]=\"closable\"\n [clrModalStaticBackdrop]=\"true\"\n [clrModalSkipAnimation]=\"stopModalAnimations\"\n [clrModalOverrideScrollService]=\"isInline\"\n [clrModalPreventClose]=\"true\"\n (clrModalAlternateClose)=\"modalCancel()\"\n [clrModalLabelledById]=\"wizardId\"\n>\n <div class=\"modal-nav clr-wizard-stepnav-wrapper\" role=\"region\" [attr.aria-label]=\"stepnavAriaLabel\">\n <div class=\"clr-wizard-title\" id=\"{{wizardId}}\" role=\"heading\" [attr.aria-level]=\"wizardTitle.headingLevel || 1\">\n <ng-content select=\"clr-wizard-title\"></ng-content>\n </div>\n <clr-wizard-stepnav></clr-wizard-stepnav>\n </div>\n\n <div class=\"modal-title\" role=\"heading\" [attr.aria-level]=\"navService.currentPage?.pageTitle.headingLevel || 2\">\n <span tabindex=\"-1\" #pageTitle class=\"modal-title-text\">\n <ng-template [ngTemplateOutlet]=\"navService.currentPageTitle\"></ng-template>\n </span>\n\n <div class=\"modal-header-actions-wrapper\" *ngIf=\"headerActionService.displayHeaderActionsWrapper\">\n <div *ngIf=\"headerActionService.showWizardHeaderActions\">\n <ng-content select=\"clr-wizard-header-action\"></ng-content>\n </div>\n <div *ngIf=\"headerActionService.currentPageHasHeaderActions\">\n <ng-template [ngTemplateOutlet]=\"navService.currentPage.headerActions\"></ng-template>\n </div>\n </div>\n </div>\n\n <div class=\"modal-body\">\n <main clr-wizard-pages-wrapper class=\"clr-wizard-content\">\n <ng-content></ng-content>\n </main>\n </div>\n <div class=\"modal-footer clr-wizard-footer\">\n <div class=\"clr-wizard-footer-buttons\">\n <div\n *ngIf=\"navService.currentPage && !navService.currentPage.hasButtons\"\n class=\"clr-wizard-footer-buttons-wrapper\"\n >\n <ng-content select=\"clr-wizard-button\"></ng-content>\n </div>\n <div\n *ngIf=\"navService.currentPage && navService.currentPage.hasButtons\"\n class=\"clr-wizard-footer-buttons-wrapper\"\n >\n <ng-template [ngTemplateOutlet]=\"navService.currentPage.buttons\"></ng-template>\n </div>\n </div>\n </div>\n</clr-modal>\n" }]
29761
+ }, template: "<!--\n ~ Copyright (c) 2016-2025 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<clr-modal\n [clrModalOpen]=\"_open\"\n [clrModalSize]=\"size\"\n [clrModalClosable]=\"closable\"\n [clrModalStaticBackdrop]=\"true\"\n [clrModalSkipAnimation]=\"stopModalAnimations\"\n [clrModalOverrideScrollService]=\"isInline\"\n [clrModalPreventClose]=\"true\"\n (clrModalAlternateClose)=\"modalCancel()\"\n [clrModalLabelledById]=\"wizardId\"\n>\n <div class=\"modal-nav clr-wizard-stepnav-wrapper\" role=\"region\">\n <div class=\"clr-wizard-title\" [id]=\"wizardId\" role=\"heading\" [attr.aria-level]=\"wizardTitle.headingLevel || 1\">\n <ng-content select=\"clr-wizard-title\"></ng-content>\n </div>\n <clr-wizard-stepnav [label]=\"stepnavAriaLabel\"></clr-wizard-stepnav>\n </div>\n\n <div class=\"modal-title\" role=\"heading\" [attr.aria-level]=\"navService.currentPage?.pageTitle.headingLevel || 2\">\n <span tabindex=\"-1\" #pageTitle class=\"modal-title-text\">\n <ng-template [ngTemplateOutlet]=\"navService.currentPageTitle\"></ng-template>\n </span>\n\n <div class=\"modal-header-actions-wrapper\" *ngIf=\"headerActionService.displayHeaderActionsWrapper\">\n <div *ngIf=\"headerActionService.showWizardHeaderActions\">\n <ng-content select=\"clr-wizard-header-action\"></ng-content>\n </div>\n <div *ngIf=\"headerActionService.currentPageHasHeaderActions\">\n <ng-template [ngTemplateOutlet]=\"navService.currentPage.headerActions\"></ng-template>\n </div>\n </div>\n </div>\n\n <div class=\"modal-body\">\n <main clr-wizard-pages-wrapper class=\"clr-wizard-content\">\n <ng-content></ng-content>\n </main>\n </div>\n <div class=\"modal-footer clr-wizard-footer\">\n <div class=\"clr-wizard-footer-buttons\">\n <div\n *ngIf=\"navService.currentPage && !navService.currentPage.hasButtons\"\n class=\"clr-wizard-footer-buttons-wrapper\"\n >\n <ng-content select=\"clr-wizard-button\"></ng-content>\n </div>\n <div\n *ngIf=\"navService.currentPage && navService.currentPage.hasButtons\"\n class=\"clr-wizard-footer-buttons-wrapper\"\n >\n <ng-template [ngTemplateOutlet]=\"navService.currentPage.buttons\"></ng-template>\n </div>\n </div>\n </div>\n</clr-modal>\n" }]
29480
29762
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
29481
29763
  type: Inject,
29482
29764
  args: [PLATFORM_ID]