@clr/angular 17.9.0 → 17.11.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 (108) hide show
  1. package/clarity.api.md +183 -87
  2. package/data/datagrid/datagrid-column.d.ts +6 -1
  3. package/data/datagrid/datagrid-filter.d.ts +2 -9
  4. package/data/datagrid/datagrid-row.d.ts +6 -4
  5. package/data/datagrid/datagrid-virtual-scroll.directive.d.ts +5 -7
  6. package/data/datagrid/datagrid.d.ts +15 -4
  7. package/data/datagrid/index.d.ts +1 -0
  8. package/data/datagrid/interfaces/key-nav-grid-strategy.interface.d.ts +11 -0
  9. package/data/datagrid/interfaces/virtual-scroll-data-range.interface.d.ts +5 -0
  10. package/data/datagrid/providers/items.d.ts +1 -0
  11. package/data/datagrid/utils/datagrid-filter-registrar.d.ts +1 -1
  12. package/data/datagrid/utils/key-navigation-grid.controller.d.ts +8 -24
  13. package/data/datagrid/utils/key-navigation-strategies/default.d.ts +15 -0
  14. package/data/datagrid/utils/key-navigation-strategies/expanded-columns-row.d.ts +12 -0
  15. package/data/datagrid/utils/key-navigation-strategies/expanded-row.d.ts +12 -0
  16. package/data/datagrid/utils/key-navigation-utils.d.ts +24 -0
  17. package/esm2020/accordion/stepper/stepper-panel.mjs +3 -3
  18. package/esm2020/button/button-group/button.mjs +20 -4
  19. package/esm2020/data/datagrid/datagrid-column.mjs +40 -28
  20. package/esm2020/data/datagrid/datagrid-detail-header.mjs +3 -3
  21. package/esm2020/data/datagrid/datagrid-filter.mjs +2 -21
  22. package/esm2020/data/datagrid/datagrid-pagination.mjs +35 -31
  23. package/esm2020/data/datagrid/datagrid-row.mjs +23 -11
  24. package/esm2020/data/datagrid/datagrid-virtual-scroll.directive.mjs +52 -51
  25. package/esm2020/data/datagrid/datagrid.mjs +87 -24
  26. package/esm2020/data/datagrid/index.mjs +2 -1
  27. package/esm2020/data/datagrid/interfaces/key-nav-grid-strategy.interface.mjs +8 -0
  28. package/esm2020/data/datagrid/interfaces/virtual-scroll-data-range.interface.mjs +8 -0
  29. package/esm2020/data/datagrid/providers/items.mjs +5 -1
  30. package/esm2020/data/datagrid/utils/datagrid-filter-registrar.mjs +1 -1
  31. package/esm2020/data/datagrid/utils/key-navigation-grid.controller.mjs +44 -271
  32. package/esm2020/data/datagrid/utils/key-navigation-strategies/default.mjs +132 -0
  33. package/esm2020/data/datagrid/utils/key-navigation-strategies/expanded-columns-row.mjs +129 -0
  34. package/esm2020/data/datagrid/utils/key-navigation-strategies/expanded-row.mjs +165 -0
  35. package/esm2020/data/datagrid/utils/key-navigation-utils.mjs +121 -0
  36. package/esm2020/data/stack-view/stack-block.mjs +3 -3
  37. package/esm2020/emphasis/alert/alert.mjs +3 -3
  38. package/esm2020/forms/combobox/combobox.mjs +3 -3
  39. package/esm2020/forms/combobox/combobox.module.mjs +20 -3
  40. package/esm2020/forms/combobox/index.mjs +2 -1
  41. package/esm2020/forms/combobox/option-group.mjs +42 -0
  42. package/esm2020/forms/combobox/option-items.directive.mjs +5 -1
  43. package/esm2020/forms/combobox/options.mjs +3 -3
  44. package/esm2020/forms/common/abstract-control.mjs +1 -1
  45. package/esm2020/forms/common/if-control-state/abstract-if-state.mjs +1 -1
  46. package/esm2020/forms/datepicker/datepicker-view-manager.mjs +3 -3
  47. package/esm2020/forms/file-input/file-input-container.mjs +2 -2
  48. package/esm2020/forms/file-input/file-input.mjs +11 -4
  49. package/esm2020/forms/number-input/number-input-container.mjs +6 -3
  50. package/esm2020/forms/number-input/number-input.mjs +10 -3
  51. package/esm2020/layout/breadcrumbs/breadcrumbs.mjs +2 -2
  52. package/esm2020/modal/index.mjs +2 -2
  53. package/esm2020/modal/modal-host.component.mjs +29 -0
  54. package/esm2020/modal/modal.mjs +11 -4
  55. package/esm2020/modal/modal.module.mjs +4 -4
  56. package/esm2020/modal/side-panel.mjs +102 -47
  57. package/esm2020/popover/common/abstract-popover.mjs +8 -2
  58. package/esm2020/popover/common/popover.mjs +2 -2
  59. package/esm2020/popover/dropdown/dropdown-item.mjs +10 -4
  60. package/esm2020/popover/dropdown/dropdown-trigger.mjs +12 -4
  61. package/esm2020/popover/dropdown/utils/content-wrapping.mjs +22 -0
  62. package/esm2020/utils/animations/constants.mjs +7 -1
  63. package/esm2020/utils/animations/expandable-animation/base-expandable-animation.mjs +46 -0
  64. package/esm2020/utils/animations/expandable-animation/expandable-animation.directive.mjs +56 -0
  65. package/esm2020/utils/animations/expandable-animation/expandable-animation.mjs +13 -36
  66. package/esm2020/utils/animations/expandable-animation/expandable-animation.module.mjs +3 -2
  67. package/esm2020/utils/animations/expandable-animation/index.mjs +4 -2
  68. package/esm2020/utils/chocolate/oompa-loompa.mjs +1 -1
  69. package/esm2020/utils/focus/focusable-item/basic-focusable-item.service.mjs +2 -2
  70. package/esm2020/utils/i18n/common-strings.default.mjs +2 -1
  71. package/esm2020/utils/i18n/common-strings.interface.mjs +1 -1
  72. package/esm2020/wizard/wizard-stepnav-item.mjs +60 -24
  73. package/esm2020/wizard/wizard.mjs +29 -6
  74. package/fesm2015/clr-angular.mjs +1377 -646
  75. package/fesm2015/clr-angular.mjs.map +1 -1
  76. package/fesm2020/clr-angular.mjs +1371 -641
  77. package/fesm2020/clr-angular.mjs.map +1 -1
  78. package/forms/combobox/combobox.module.d.ts +12 -11
  79. package/forms/combobox/index.d.ts +1 -0
  80. package/forms/combobox/option-group.d.ts +9 -0
  81. package/forms/combobox/option-items.directive.d.ts +1 -0
  82. package/forms/common/abstract-control.d.ts +1 -1
  83. package/forms/common/if-control-state/abstract-if-state.d.ts +1 -1
  84. package/forms/file-input/file-input.d.ts +2 -0
  85. package/forms/number-input/number-input-container.d.ts +1 -0
  86. package/forms/number-input/number-input.d.ts +2 -0
  87. package/modal/index.d.ts +1 -1
  88. package/modal/modal-host.component.d.ts +5 -0
  89. package/modal/modal.d.ts +3 -2
  90. package/modal/modal.module.d.ts +2 -2
  91. package/modal/side-panel.d.ts +18 -10
  92. package/package.json +2 -2
  93. package/popover/common/abstract-popover.d.ts +1 -1
  94. package/popover/dropdown/dropdown-item.d.ts +5 -1
  95. package/popover/dropdown/dropdown-trigger.d.ts +5 -2
  96. package/popover/dropdown/utils/content-wrapping.d.ts +2 -0
  97. package/utils/animations/constants.d.ts +1 -0
  98. package/utils/animations/expandable-animation/base-expandable-animation.d.ts +16 -0
  99. package/utils/animations/expandable-animation/expandable-animation.d.ts +2 -9
  100. package/utils/animations/expandable-animation/expandable-animation.directive.d.ts +16 -0
  101. package/utils/animations/expandable-animation/expandable-animation.module.d.ts +3 -2
  102. package/utils/animations/expandable-animation/index.d.ts +1 -0
  103. package/utils/chocolate/oompa-loompa.d.ts +1 -1
  104. package/utils/i18n/common-strings.interface.d.ts +4 -0
  105. package/wizard/wizard-stepnav-item.d.ts +16 -2
  106. package/wizard/wizard.d.ts +12 -2
  107. package/esm2020/modal/modal-host.directive.mjs +0 -20
  108. package/modal/modal-host.directive.d.ts +0 -5
@@ -1,19 +1,20 @@
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, forwardRef, Attribute, TemplateRef, ViewContainerRef, LOCALE_ID, 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, ViewChildren } 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, minusIcon, plusIcon, eyeHideIcon, eyeIcon, ellipsisVerticalIcon, viewColumnsIcon, arrowIcon, stepForward2Icon, filterGridCircleIcon, filterGridIcon, errorStandardIcon, helpIcon, infoStandardIcon, noteIcon, successStandardIcon, warningStandardIcon, circleIcon, dotCircleIcon } from '@cds/core/icon';
6
6
  import { map, tap, startWith, distinctUntilChanged, filter, skipUntil, debounceTime, takeUntil, take, first, switchMap as switchMap$1 } from 'rxjs/operators';
7
7
  import * as i3 from 'rxjs';
8
8
  import { Subject, BehaviorSubject, Observable, fromEvent, isObservable, of, shareReplay, combineLatest, startWith as startWith$1, switchMap, merge, map as map$1, EMPTY, ReplaySubject, tap as tap$1 } from 'rxjs';
9
- import { trigger, transition, style, animate, state, keyframes } from '@angular/animations';
9
+ import * as i2 from '@angular/animations';
10
+ import { animation, style, animate, trigger, transition, state, useAnimation, keyframes } from '@angular/animations';
10
11
  import * as i1 from '@angular/forms';
11
12
  import { FormControl, FormGroup, FormsModule, NG_VALIDATORS, NG_VALUE_ACCESSOR, SelectMultipleControlValueAccessor } from '@angular/forms';
12
13
  import * as i1$1 from '@angular/router';
13
14
  import { RouterModule } from '@angular/router';
14
15
  import * as i1$2 from '@angular/cdk/a11y';
15
16
  import { CdkTrapFocus } from '@angular/cdk/a11y';
16
- import * as i2 from '@angular/cdk/drag-drop';
17
+ import * as i2$1 from '@angular/cdk/drag-drop';
17
18
  import { CdkDrag, CDK_DROP_LIST, CDK_DRAG_CONFIG } from '@angular/cdk/drag-drop';
18
19
  import * as i1$3 from '@angular/cdk/bidi';
19
20
  import { Directionality } from '@angular/cdk/bidi';
@@ -233,6 +234,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
233
234
  * The full license information can be found in LICENSE in the root directory of this project.
234
235
  */
235
236
  const defaultAnimationTiming = '0.2s ease-in-out';
237
+ const defaultExpandAnimation = animation([style({ height: '{{ startHeight }}px' }), animate(defaultAnimationTiming, style({ height: '*' }))], {
238
+ params: {
239
+ startHeight: 0, // default
240
+ },
241
+ });
236
242
 
237
243
  /*
238
244
  * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
@@ -370,6 +376,7 @@ const commonStringsDefault = {
370
376
  datagridExpandableRowsHelperText: `Screen reader table commands may not work for viewing expanded content, please use your screen reader's browse mode to read the content exposed by this button`,
371
377
  // Wizard
372
378
  wizardStep: 'Step',
379
+ wizardStepCurrent: 'Current',
373
380
  wizardStepSuccess: 'Completed',
374
381
  wizardStepError: 'Error',
375
382
  wizardStepnavAriaLabel: 'Wizard steps',
@@ -1246,10 +1253,10 @@ class ClrStepperPanel extends ClrAccordionPanel {
1246
1253
  }
1247
1254
  }
1248
1255
  ClrStepperPanel.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrStepperPanel, deps: [{ token: PLATFORM_ID }, { token: ClrCommonStringsService }, { token: i1.FormGroupName, optional: true }, { token: i1.NgModelGroup, optional: true }, { token: StepperService }, { token: IfExpandService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1249
- ClrStepperPanel.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrStepperPanel, selector: "clr-stepper-panel", host: { properties: { "class.clr-stepper-panel": "true" } }, providers: [IfExpandService], viewQueries: [{ propertyName: "headerButton", first: true, predicate: ["headerButton"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"panel | async; let panel\">\n <div [ngClass]=\"getPanelStateClasses(panel)\">\n <div class=\"clr-accordion-header clr-stepper-header\">\n <button\n type=\"button\"\n class=\"clr-accordion-header-button\"\n (click)=\"togglePanel()\"\n [id]=\"getAccordionHeaderId(panel.templateId)\"\n [attr.aria-disabled]=\"panel.disabled\"\n [attr.aria-controls]=\"getAccordionContentId(panel.templateId)\"\n [attr.aria-expanded]=\"panel.open\"\n [class.clr-accordion-header-has-description]=\"(accordionDescription.changes | async)?.length || accordionDescription.length\"\n #headerButton\n >\n <span class=\"clr-step-status\">\n <cds-icon shape=\"angle\" direction=\"right\" class=\"clr-accordion-angle clr-step-angle\"></cds-icon>\n <cds-icon\n status=\"danger\"\n *ngIf=\"panel.status === AccordionStatus.Error\"\n shape=\"exclamation-circle\"\n class=\"clr-step-error-icon\"\n ></cds-icon>\n <cds-icon\n status=\"success\"\n *ngIf=\"panel.status === AccordionStatus.Complete\"\n shape=\"check-circle\"\n class=\"clr-step-complete-icon\"\n ></cds-icon>\n </span>\n <span class=\"clr-step-title-wrapper\">\n <span class=\"clr-step-number\">{{panelNumber}}.</span>\n <ng-content select=\"clr-step-title\"></ng-content>\n </span>\n <ng-content select=\"clr-step-description\"></ng-content>\n </button>\n <div class=\"clr-sr-only\" role=\"status\">\n <ng-container *ngIf=\"panel.status === AccordionStatus.Error\"> {{ stepErrorText(panelNumber)}} </ng-container>\n <ng-container *ngIf=\"panel.status === AccordionStatus.Complete\">\n {{ stepCompleteText(panelNumber)}}\n </ng-container>\n </div>\n </div>\n <div\n @skipInitialRender\n role=\"region\"\n class=\"clr-accordion-content-region\"\n [id]=\"getAccordionContentId(panel.templateId)\"\n [attr.aria-hidden]=\"!panel.open\"\n [attr.aria-labelledby]=\"getAccordionHeaderId(panel.templateId)\"\n >\n <div\n *ngIf=\"panel.open\"\n @toggle\n (@toggle.done)=\"collapsePanelOnAnimationDone(panel)\"\n class=\"clr-accordion-content\"\n >\n <div class=\"clr-accordion-inner-content\">\n <ng-content></ng-content>\n </div>\n </div>\n </div>\n </div>\n</ng-container>\n", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }], animations: stepAnimation, changeDetection: i0.ChangeDetectionStrategy.OnPush });
1256
+ ClrStepperPanel.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrStepperPanel, selector: "clr-stepper-panel", host: { properties: { "class.clr-stepper-panel": "true" } }, providers: [IfExpandService], viewQueries: [{ propertyName: "headerButton", first: true, predicate: ["headerButton"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"panel | async; let panel\">\n <div [ngClass]=\"getPanelStateClasses(panel)\">\n <div class=\"clr-accordion-header clr-stepper-header\">\n <button\n type=\"button\"\n class=\"clr-accordion-header-button\"\n (click)=\"togglePanel()\"\n [id]=\"getAccordionHeaderId(panel.templateId)\"\n [attr.aria-disabled]=\"panel.disabled\"\n [attr.aria-controls]=\"getAccordionContentId(panel.templateId)\"\n [attr.aria-expanded]=\"panel.open\"\n [class.clr-accordion-header-has-description]=\"(accordionDescription.changes | async)?.length || accordionDescription.length\"\n #headerButton\n >\n <span class=\"clr-step-status\">\n <cds-icon shape=\"angle\" direction=\"right\" class=\"clr-accordion-angle clr-step-angle\"></cds-icon>\n <span class=\"clr-step-status-icon\">\n <cds-icon\n status=\"danger\"\n *ngIf=\"panel.status === AccordionStatus.Error\"\n shape=\"exclamation-circle\"\n class=\"clr-step-error-icon\"\n ></cds-icon>\n <cds-icon\n status=\"success\"\n *ngIf=\"panel.status === AccordionStatus.Complete\"\n shape=\"check-circle\"\n class=\"clr-step-complete-icon\"\n ></cds-icon>\n </span>\n </span>\n <span class=\"clr-step-title-wrapper\">\n <span class=\"clr-step-number\">{{panelNumber}}.</span>\n <ng-content select=\"clr-step-title\"></ng-content>\n </span>\n <ng-content select=\"clr-step-description\"></ng-content>\n </button>\n <div class=\"clr-sr-only\" role=\"status\">\n <ng-container *ngIf=\"panel.status === AccordionStatus.Error\"> {{ stepErrorText(panelNumber)}} </ng-container>\n <ng-container *ngIf=\"panel.status === AccordionStatus.Complete\">\n {{ stepCompleteText(panelNumber)}}\n </ng-container>\n </div>\n </div>\n <div\n @skipInitialRender\n role=\"region\"\n class=\"clr-accordion-content-region\"\n [id]=\"getAccordionContentId(panel.templateId)\"\n [attr.aria-hidden]=\"!panel.open\"\n [attr.aria-labelledby]=\"getAccordionHeaderId(panel.templateId)\"\n >\n <div\n *ngIf=\"panel.open\"\n @toggle\n (@toggle.done)=\"collapsePanelOnAnimationDone(panel)\"\n class=\"clr-accordion-content\"\n >\n <div class=\"clr-accordion-inner-content\">\n <ng-content></ng-content>\n </div>\n </div>\n </div>\n </div>\n</ng-container>\n", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }], animations: stepAnimation, changeDetection: i0.ChangeDetectionStrategy.OnPush });
1250
1257
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrStepperPanel, decorators: [{
1251
1258
  type: Component,
1252
- args: [{ selector: 'clr-stepper-panel', host: { '[class.clr-stepper-panel]': 'true' }, changeDetection: ChangeDetectionStrategy.OnPush, animations: stepAnimation, providers: [IfExpandService], template: "<ng-container *ngIf=\"panel | async; let panel\">\n <div [ngClass]=\"getPanelStateClasses(panel)\">\n <div class=\"clr-accordion-header clr-stepper-header\">\n <button\n type=\"button\"\n class=\"clr-accordion-header-button\"\n (click)=\"togglePanel()\"\n [id]=\"getAccordionHeaderId(panel.templateId)\"\n [attr.aria-disabled]=\"panel.disabled\"\n [attr.aria-controls]=\"getAccordionContentId(panel.templateId)\"\n [attr.aria-expanded]=\"panel.open\"\n [class.clr-accordion-header-has-description]=\"(accordionDescription.changes | async)?.length || accordionDescription.length\"\n #headerButton\n >\n <span class=\"clr-step-status\">\n <cds-icon shape=\"angle\" direction=\"right\" class=\"clr-accordion-angle clr-step-angle\"></cds-icon>\n <cds-icon\n status=\"danger\"\n *ngIf=\"panel.status === AccordionStatus.Error\"\n shape=\"exclamation-circle\"\n class=\"clr-step-error-icon\"\n ></cds-icon>\n <cds-icon\n status=\"success\"\n *ngIf=\"panel.status === AccordionStatus.Complete\"\n shape=\"check-circle\"\n class=\"clr-step-complete-icon\"\n ></cds-icon>\n </span>\n <span class=\"clr-step-title-wrapper\">\n <span class=\"clr-step-number\">{{panelNumber}}.</span>\n <ng-content select=\"clr-step-title\"></ng-content>\n </span>\n <ng-content select=\"clr-step-description\"></ng-content>\n </button>\n <div class=\"clr-sr-only\" role=\"status\">\n <ng-container *ngIf=\"panel.status === AccordionStatus.Error\"> {{ stepErrorText(panelNumber)}} </ng-container>\n <ng-container *ngIf=\"panel.status === AccordionStatus.Complete\">\n {{ stepCompleteText(panelNumber)}}\n </ng-container>\n </div>\n </div>\n <div\n @skipInitialRender\n role=\"region\"\n class=\"clr-accordion-content-region\"\n [id]=\"getAccordionContentId(panel.templateId)\"\n [attr.aria-hidden]=\"!panel.open\"\n [attr.aria-labelledby]=\"getAccordionHeaderId(panel.templateId)\"\n >\n <div\n *ngIf=\"panel.open\"\n @toggle\n (@toggle.done)=\"collapsePanelOnAnimationDone(panel)\"\n class=\"clr-accordion-content\"\n >\n <div class=\"clr-accordion-inner-content\">\n <ng-content></ng-content>\n </div>\n </div>\n </div>\n </div>\n</ng-container>\n" }]
1259
+ args: [{ selector: 'clr-stepper-panel', host: { '[class.clr-stepper-panel]': 'true' }, changeDetection: ChangeDetectionStrategy.OnPush, animations: stepAnimation, providers: [IfExpandService], template: "<ng-container *ngIf=\"panel | async; let panel\">\n <div [ngClass]=\"getPanelStateClasses(panel)\">\n <div class=\"clr-accordion-header clr-stepper-header\">\n <button\n type=\"button\"\n class=\"clr-accordion-header-button\"\n (click)=\"togglePanel()\"\n [id]=\"getAccordionHeaderId(panel.templateId)\"\n [attr.aria-disabled]=\"panel.disabled\"\n [attr.aria-controls]=\"getAccordionContentId(panel.templateId)\"\n [attr.aria-expanded]=\"panel.open\"\n [class.clr-accordion-header-has-description]=\"(accordionDescription.changes | async)?.length || accordionDescription.length\"\n #headerButton\n >\n <span class=\"clr-step-status\">\n <cds-icon shape=\"angle\" direction=\"right\" class=\"clr-accordion-angle clr-step-angle\"></cds-icon>\n <span class=\"clr-step-status-icon\">\n <cds-icon\n status=\"danger\"\n *ngIf=\"panel.status === AccordionStatus.Error\"\n shape=\"exclamation-circle\"\n class=\"clr-step-error-icon\"\n ></cds-icon>\n <cds-icon\n status=\"success\"\n *ngIf=\"panel.status === AccordionStatus.Complete\"\n shape=\"check-circle\"\n class=\"clr-step-complete-icon\"\n ></cds-icon>\n </span>\n </span>\n <span class=\"clr-step-title-wrapper\">\n <span class=\"clr-step-number\">{{panelNumber}}.</span>\n <ng-content select=\"clr-step-title\"></ng-content>\n </span>\n <ng-content select=\"clr-step-description\"></ng-content>\n </button>\n <div class=\"clr-sr-only\" role=\"status\">\n <ng-container *ngIf=\"panel.status === AccordionStatus.Error\"> {{ stepErrorText(panelNumber)}} </ng-container>\n <ng-container *ngIf=\"panel.status === AccordionStatus.Complete\">\n {{ stepCompleteText(panelNumber)}}\n </ng-container>\n </div>\n </div>\n <div\n @skipInitialRender\n role=\"region\"\n class=\"clr-accordion-content-region\"\n [id]=\"getAccordionContentId(panel.templateId)\"\n [attr.aria-hidden]=\"!panel.open\"\n [attr.aria-labelledby]=\"getAccordionHeaderId(panel.templateId)\"\n >\n <div\n *ngIf=\"panel.open\"\n @toggle\n (@toggle.done)=\"collapsePanelOnAnimationDone(panel)\"\n class=\"clr-accordion-content\"\n >\n <div class=\"clr-accordion-inner-content\">\n <ng-content></ng-content>\n </div>\n </div>\n </div>\n </div>\n</ng-container>\n" }]
1253
1260
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
1254
1261
  type: Inject,
1255
1262
  args: [PLATFORM_ID]
@@ -2620,10 +2627,18 @@ ClrButton.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15
2620
2627
  [attr.id]="id"
2621
2628
  >
2622
2629
  <span class="spinner spinner-inline" *ngIf="loading"></span>
2623
- <ng-content></ng-content>
2630
+ <ng-container *ngIf="inMenu; then inMenuTemplate; else defaultTemplate"></ng-container>
2624
2631
  </button>
2625
2632
  </ng-template>
2626
- `, isInline: true, dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
2633
+ <ng-template #defaultTemplate>
2634
+ <ng-content></ng-content>
2635
+ </ng-template>
2636
+ <ng-template #inMenuTemplate>
2637
+ <span class="dropdown-item-content">
2638
+ <ng-container [ngTemplateOutlet]="defaultTemplate"></ng-container>
2639
+ </span>
2640
+ </ng-template>
2641
+ `, 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"] }] });
2627
2642
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrButton, decorators: [{
2628
2643
  type: Component,
2629
2644
  args: [{
@@ -2640,9 +2655,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
2640
2655
  [attr.id]="id"
2641
2656
  >
2642
2657
  <span class="spinner spinner-inline" *ngIf="loading"></span>
2643
- <ng-content></ng-content>
2658
+ <ng-container *ngIf="inMenu; then inMenuTemplate; else defaultTemplate"></ng-container>
2644
2659
  </button>
2645
2660
  </ng-template>
2661
+ <ng-template #defaultTemplate>
2662
+ <ng-content></ng-content>
2663
+ </ng-template>
2664
+ <ng-template #inMenuTemplate>
2665
+ <span class="dropdown-item-content">
2666
+ <ng-container [ngTemplateOutlet]="defaultTemplate"></ng-container>
2667
+ </span>
2668
+ </ng-template>
2646
2669
  `,
2647
2670
  providers: [{ provide: LoadingListener, useExisting: ClrButton }],
2648
2671
  }]
@@ -3104,55 +3127,74 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
3104
3127
  * This software is released under MIT license.
3105
3128
  * The full license information can be found in LICENSE in the root directory of this project.
3106
3129
  */
3107
- class ClrExpandableAnimation {
3130
+ class BaseExpandableAnimation {
3108
3131
  constructor(element, domAdapter, renderer) {
3109
3132
  this.element = element;
3110
3133
  this.domAdapter = domAdapter;
3111
3134
  this.renderer = renderer;
3112
- this.clrExpandTrigger = false;
3113
3135
  this.startHeight = 0;
3114
3136
  }
3137
+ updateStartHeight() {
3138
+ this.startHeight = this.domAdapter.computedHeight(this.element.nativeElement) || 0;
3139
+ }
3140
+ initAnimationEffects() {
3141
+ this.renderer.setStyle(this.element.nativeElement, 'overflow', 'hidden');
3142
+ }
3143
+ cleanupAnimationEffects(cancelAnimations = false) {
3144
+ this.renderer.removeStyle(this.element.nativeElement, 'overflow');
3145
+ // A "safe" auto-update of the height ensuring basic OOTB user experience .
3146
+ // Prone to small jumps in initial animation height if data was changed in the meantime, the window was resized, etc.
3147
+ // For optimal behavior call manually updateStartHeight() from the parent component before initiating the update.
3148
+ this.updateStartHeight();
3149
+ if (cancelAnimations) {
3150
+ this.cancelElementAnimations();
3151
+ }
3152
+ }
3153
+ cancelElementAnimations() {
3154
+ this.element.nativeElement.getAnimations().forEach(animation => {
3155
+ if (animation.playState === 'finished') {
3156
+ animation.cancel(); // clears animation-style set on the element
3157
+ }
3158
+ });
3159
+ }
3160
+ }
3161
+ BaseExpandableAnimation.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: BaseExpandableAnimation, deps: [{ token: i0.ElementRef }, { token: DomAdapter }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
3162
+ BaseExpandableAnimation.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: BaseExpandableAnimation, ngImport: i0 });
3163
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: BaseExpandableAnimation, decorators: [{
3164
+ type: Directive
3165
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: DomAdapter }, { type: i0.Renderer2 }]; } });
3166
+
3167
+ /*
3168
+ * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
3169
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
3170
+ * This software is released under MIT license.
3171
+ * The full license information can be found in LICENSE in the root directory of this project.
3172
+ */
3173
+ class ClrExpandableAnimation extends BaseExpandableAnimation {
3174
+ constructor() {
3175
+ super(...arguments);
3176
+ this.clrExpandTrigger = false;
3177
+ }
3115
3178
  get expandAnimation() {
3116
3179
  return { value: this.clrExpandTrigger, params: { startHeight: this.startHeight } };
3117
3180
  }
3118
3181
  animationStart(event) {
3119
3182
  if (event.fromState !== 'void') {
3120
- this.renderer.setStyle(this.element.nativeElement, 'overflow', 'hidden');
3183
+ this.initAnimationEffects();
3121
3184
  }
3122
3185
  }
3123
3186
  animationDone(event) {
3124
3187
  if (event.fromState !== 'void') {
3125
- this.renderer.removeStyle(this.element.nativeElement, 'overflow');
3126
- // A "safe" auto-update of the height ensuring basic OOTB user experience .
3127
- // Prone to small jumps in initial animation height if data was changed in the meantime, window was resized, etc.
3128
- // For optimal behavior call manually updateStartHeight() from the parent component before initiating the update.
3129
- this.updateStartHeight();
3188
+ this.cleanupAnimationEffects();
3130
3189
  }
3131
3190
  }
3132
- updateStartHeight() {
3133
- this.startHeight = this.domAdapter.computedHeight(this.element.nativeElement) || 0;
3134
- }
3135
3191
  }
3136
- ClrExpandableAnimation.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrExpandableAnimation, deps: [{ token: i0.ElementRef }, { token: DomAdapter }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
3137
- ClrExpandableAnimation.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrExpandableAnimation, selector: "clr-expandable-animation", inputs: { clrExpandTrigger: "clrExpandTrigger" }, host: { listeners: { "@expandAnimation.start": "animationStart($event)", "@expandAnimation.done": "animationDone($event)" }, properties: { "@expandAnimation": "this.expandAnimation" } }, providers: [DomAdapter], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, styles: [":host{display:block}\n"], animations: [
3138
- trigger('expandAnimation', [
3139
- transition('true <=> false', [
3140
- style({ height: '{{startHeight}}px' }),
3141
- animate('0.2s ease-in-out', style({ height: '*' })),
3142
- ]),
3143
- ]),
3144
- ] });
3192
+ ClrExpandableAnimation.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrExpandableAnimation, deps: null, target: i0.ɵɵFactoryTarget.Component });
3193
+ ClrExpandableAnimation.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrExpandableAnimation, selector: "clr-expandable-animation", inputs: { clrExpandTrigger: "clrExpandTrigger" }, host: { listeners: { "@expandAnimation.start": "animationStart($event)", "@expandAnimation.done": "animationDone($event)" }, properties: { "@expandAnimation": "this.expandAnimation" } }, providers: [DomAdapter], usesInheritance: true, ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, styles: [":host{display:block}\n"], animations: [trigger('expandAnimation', [transition('true <=> false', [useAnimation(defaultExpandAnimation)])])] });
3145
3194
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrExpandableAnimation, decorators: [{
3146
3195
  type: Component,
3147
- args: [{ selector: 'clr-expandable-animation', template: `<ng-content></ng-content>`, animations: [
3148
- trigger('expandAnimation', [
3149
- transition('true <=> false', [
3150
- style({ height: '{{startHeight}}px' }),
3151
- animate('0.2s ease-in-out', style({ height: '*' })),
3152
- ]),
3153
- ]),
3154
- ], providers: [DomAdapter], styles: [":host{display:block}\n"] }]
3155
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: DomAdapter }, { type: i0.Renderer2 }]; }, propDecorators: { clrExpandTrigger: [{
3196
+ args: [{ selector: 'clr-expandable-animation', template: `<ng-content></ng-content>`, animations: [trigger('expandAnimation', [transition('true <=> false', [useAnimation(defaultExpandAnimation)])])], providers: [DomAdapter], styles: [":host{display:block}\n"] }]
3197
+ }], propDecorators: { clrExpandTrigger: [{
3156
3198
  type: Input
3157
3199
  }], expandAnimation: [{
3158
3200
  type: HostBinding,
@@ -3171,7 +3213,55 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
3171
3213
  * This software is released under MIT license.
3172
3214
  * The full license information can be found in LICENSE in the root directory of this project.
3173
3215
  */
3174
- const EXPANDABLE_ANIMATION_DIRECTIVES = [ClrExpandableAnimation];
3216
+ class ClrExpandableAnimationDirective extends BaseExpandableAnimation {
3217
+ constructor(element, domAdapter, renderer, builder) {
3218
+ super(element, domAdapter, renderer);
3219
+ this.builder = builder;
3220
+ this.expanded = false;
3221
+ }
3222
+ ngOnChanges(changes) {
3223
+ if (changes['expanded'] && !changes['expanded'].firstChange) {
3224
+ Promise.resolve().then(() => this.playAnimation());
3225
+ }
3226
+ }
3227
+ ngOnDestroy() {
3228
+ this.player?.destroy();
3229
+ }
3230
+ playAnimation() {
3231
+ if (this.player) {
3232
+ this.player.destroy();
3233
+ }
3234
+ this.player = this.builder
3235
+ .build([useAnimation(defaultExpandAnimation, { params: { startHeight: this.startHeight } })])
3236
+ .create(this.element.nativeElement);
3237
+ this.player.onStart(() => this.initAnimationEffects());
3238
+ this.player.onDone(() => this.cleanupAnimationEffects(true));
3239
+ this.player.play();
3240
+ }
3241
+ }
3242
+ ClrExpandableAnimationDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrExpandableAnimationDirective, deps: [{ token: i0.ElementRef }, { token: DomAdapter }, { token: i0.Renderer2 }, { token: i2.AnimationBuilder }], target: i0.ɵɵFactoryTarget.Directive });
3243
+ ClrExpandableAnimationDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: ClrExpandableAnimationDirective, selector: "[clrExpandableAnimation]", inputs: { expanded: ["clrExpandableAnimation", "expanded"] }, host: { properties: { "class.clr-expandable-animation": "true" } }, providers: [DomAdapter], usesInheritance: true, usesOnChanges: true, ngImport: i0 });
3244
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrExpandableAnimationDirective, decorators: [{
3245
+ type: Directive,
3246
+ args: [{
3247
+ selector: '[clrExpandableAnimation]',
3248
+ providers: [DomAdapter],
3249
+ host: {
3250
+ '[class.clr-expandable-animation]': 'true',
3251
+ },
3252
+ }]
3253
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: DomAdapter }, { type: i0.Renderer2 }, { type: i2.AnimationBuilder }]; }, propDecorators: { expanded: [{
3254
+ type: Input,
3255
+ args: ['clrExpandableAnimation']
3256
+ }] } });
3257
+
3258
+ /*
3259
+ * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
3260
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
3261
+ * This software is released under MIT license.
3262
+ * The full license information can be found in LICENSE in the root directory of this project.
3263
+ */
3264
+ const EXPANDABLE_ANIMATION_DIRECTIVES = [ClrExpandableAnimation, ClrExpandableAnimationDirective];
3175
3265
 
3176
3266
  /*
3177
3267
  * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
@@ -5167,7 +5257,7 @@ class Popover {
5167
5257
  this._scroll = new Subject();
5168
5258
  const anchor = e;
5169
5259
  let current = e;
5170
- while (current && current !== document) {
5260
+ while (current && current !== document && current.nodeType === Node.ELEMENT_NODE) {
5171
5261
  if (this.scrolls(current)) {
5172
5262
  current.addEventListener('scroll', this.boundOnScrollListener);
5173
5263
  this.scrollableElements.push(current);
@@ -5220,7 +5310,13 @@ class AbstractPopover {
5220
5310
  this.documentESCListener = null;
5221
5311
  this.closeOnOutsideClickCallback = event => {
5222
5312
  // The anchor element containing the click event origin means, the click wasn't triggered outside.
5223
- if (this.anchorElem.contains(event.target)) {
5313
+ if (event.target.shadowRoot) {
5314
+ const containsNode = event.composedPath().some((element) => element === this.anchorElem);
5315
+ if (containsNode) {
5316
+ return;
5317
+ }
5318
+ }
5319
+ else if (this.anchorElem.contains(event.target)) {
5224
5320
  return;
5225
5321
  }
5226
5322
  this.toggleService.open = false;
@@ -5430,6 +5526,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
5430
5526
  args: ['clrPosition']
5431
5527
  }] } });
5432
5528
 
5529
+ /*
5530
+ * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
5531
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
5532
+ * This software is released under MIT license.
5533
+ * The full license information can be found in LICENSE in the root directory of this project.
5534
+ */
5535
+ function wrapHostContentInsideSpan(hostElement, renderer, wrapperClass) {
5536
+ if (!hostElement || !renderer) {
5537
+ return;
5538
+ }
5539
+ const wrapper = renderer.createElement('span');
5540
+ if (wrapperClass) {
5541
+ renderer.addClass(wrapper, wrapperClass);
5542
+ }
5543
+ // Move all existing children into the wrapper
5544
+ // We must loop while there are child nodes and re-append them to wrapper.
5545
+ while (hostElement.firstChild) {
5546
+ renderer.appendChild(wrapper, hostElement.firstChild);
5547
+ }
5548
+ renderer.appendChild(hostElement, wrapper);
5549
+ }
5550
+
5433
5551
  /*
5434
5552
  * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
5435
5553
  * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
@@ -5437,8 +5555,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
5437
5555
  * The full license information can be found in LICENSE in the root directory of this project.
5438
5556
  */
5439
5557
  class ClrDropdownTrigger {
5440
- constructor(dropdown, toggleService, el, focusHandler) {
5558
+ constructor(dropdown, toggleService, el, focusHandler, renderer) {
5441
5559
  this.toggleService = toggleService;
5560
+ this.el = el;
5561
+ this.renderer = renderer;
5442
5562
  this.isRootLevelToggle = true;
5443
5563
  // if the containing dropdown has a parent, then this is not the root level one
5444
5564
  if (dropdown.parent) {
@@ -5452,8 +5572,13 @@ class ClrDropdownTrigger {
5452
5572
  onDropdownTriggerClick(event) {
5453
5573
  this.toggleService.toggleWithEvent(event);
5454
5574
  }
5575
+ ngAfterViewInit() {
5576
+ if (!this.isRootLevelToggle) {
5577
+ wrapHostContentInsideSpan(this.el.nativeElement, this.renderer, 'dropdown-item-content');
5578
+ }
5579
+ }
5455
5580
  }
5456
- ClrDropdownTrigger.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDropdownTrigger, deps: [{ token: ClrDropdown }, { token: ClrPopoverToggleService }, { token: i0.ElementRef }, { token: DropdownFocusHandler }], target: i0.ɵɵFactoryTarget.Directive });
5581
+ ClrDropdownTrigger.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDropdownTrigger, deps: [{ token: ClrDropdown }, { token: ClrPopoverToggleService }, { token: i0.ElementRef }, { token: DropdownFocusHandler }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
5457
5582
  ClrDropdownTrigger.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: ClrDropdownTrigger, selector: "[clrDropdownTrigger],[clrDropdownToggle]", host: { listeners: { "click": "onDropdownTriggerClick($event)" }, properties: { "class.dropdown-toggle": "isRootLevelToggle", "class.dropdown-item": "!isRootLevelToggle", "class.expandable": "!isRootLevelToggle", "class.active": "active", "attr.aria-haspopup": "\"menu\"", "attr.aria-expanded": "active" } }, ngImport: i0 });
5458
5583
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDropdownTrigger, decorators: [{
5459
5584
  type: Directive,
@@ -5469,7 +5594,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
5469
5594
  '[attr.aria-expanded]': 'active',
5470
5595
  },
5471
5596
  }]
5472
- }], ctorParameters: function () { return [{ type: ClrDropdown }, { type: ClrPopoverToggleService }, { type: i0.ElementRef }, { type: DropdownFocusHandler }]; }, propDecorators: { onDropdownTriggerClick: [{
5597
+ }], ctorParameters: function () { return [{ type: ClrDropdown }, { type: ClrPopoverToggleService }, { type: i0.ElementRef }, { type: DropdownFocusHandler }, { type: i0.Renderer2 }]; }, propDecorators: { onDropdownTriggerClick: [{
5473
5598
  type: HostListener,
5474
5599
  args: ['click', ['$event']]
5475
5600
  }] } });
@@ -5494,7 +5619,7 @@ class BasicFocusableItem {
5494
5619
  if (isPlatformBrowser(this.platformId)) {
5495
5620
  this.renderer.setAttribute(this.el.nativeElement, 'tabindex', '0');
5496
5621
  this.el.nativeElement.focus();
5497
- this.el.nativeElement.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'nearest' });
5622
+ this.el.nativeElement.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' });
5498
5623
  }
5499
5624
  }
5500
5625
  blur() {
@@ -5531,10 +5656,12 @@ const BASIC_FOCUSABLE_ITEM_PROVIDER = [
5531
5656
  * The full license information can be found in LICENSE in the root directory of this project.
5532
5657
  */
5533
5658
  class ClrDropdownItem {
5534
- constructor(dropdown, _dropdownService, focusableItem) {
5659
+ constructor(dropdown, _dropdownService, focusableItem, el, renderer) {
5535
5660
  this.dropdown = dropdown;
5536
5661
  this._dropdownService = _dropdownService;
5537
5662
  this.focusableItem = focusableItem;
5663
+ this.el = el;
5664
+ this.renderer = renderer;
5538
5665
  }
5539
5666
  get disabled() {
5540
5667
  return this.focusableItem.disabled;
@@ -5552,6 +5679,9 @@ class ClrDropdownItem {
5552
5679
  set dropdownItemId(value) {
5553
5680
  this.focusableItem.id = value;
5554
5681
  }
5682
+ ngAfterViewInit() {
5683
+ wrapHostContentInsideSpan(this.el.nativeElement, this.renderer, 'dropdown-item-content');
5684
+ }
5555
5685
  onDropdownItemClick() {
5556
5686
  // Move focus back to the root dropdown trigger.
5557
5687
  // This is done BEFORE the dropdown is closed so that focus gets moved properly if a modal is opened.
@@ -5589,7 +5719,7 @@ class ClrDropdownItem {
5589
5719
  return rootDropdown;
5590
5720
  }
5591
5721
  }
5592
- ClrDropdownItem.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDropdownItem, deps: [{ token: ClrDropdown }, { token: RootDropdownService }, { token: FocusableItem }], target: i0.ɵɵFactoryTarget.Directive });
5722
+ ClrDropdownItem.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDropdownItem, deps: [{ token: ClrDropdown }, { token: RootDropdownService }, { token: FocusableItem }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
5593
5723
  ClrDropdownItem.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: ClrDropdownItem, selector: "[clrDropdownItem]", inputs: { disabled: ["clrDisabled", "disabled"], dropdownItemId: ["id", "dropdownItemId"] }, host: { listeners: { "click": "onDropdownItemClick()", "keydown.space": "onSpaceKeydown($event)", "keydown.enter": "onEnterKeydown($event)" }, properties: { "class.disabled": "disabled", "class.dropdown-item": "true", "attr.role": "\"menuitem\"", "attr.aria-disabled": "disabled", "attr.id": "dropdownItemId" } }, providers: [BASIC_FOCUSABLE_ITEM_PROVIDER], ngImport: i0 });
5594
5724
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDropdownItem, decorators: [{
5595
5725
  type: Directive,
@@ -5604,7 +5734,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
5604
5734
  },
5605
5735
  providers: [BASIC_FOCUSABLE_ITEM_PROVIDER],
5606
5736
  }]
5607
- }], ctorParameters: function () { return [{ type: ClrDropdown }, { type: RootDropdownService }, { type: FocusableItem }]; }, propDecorators: { disabled: [{
5737
+ }], ctorParameters: function () { return [{ type: ClrDropdown }, { type: RootDropdownService }, { type: FocusableItem }, { type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { disabled: [{
5608
5738
  type: Input,
5609
5739
  args: ['clrDisabled']
5610
5740
  }], dropdownItemId: [{
@@ -8929,7 +9059,7 @@ class ClrOptions {
8929
9059
  }
8930
9060
  }
8931
9061
  ClrOptions.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrOptions, deps: [{ token: OptionSelectionService }, { token: IF_ACTIVE_ID }, { token: i0.ElementRef }, { token: ClrCommonStringsService }, { token: ComboboxFocusHandler }, { token: ClrPopoverToggleService }, { token: POPOVER_HOST_ANCHOR, optional: true }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component });
8932
- ClrOptions.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrOptions, selector: "clr-options", inputs: { optionsId: ["id", "optionsId"] }, host: { properties: { "class.clr-combobox-options": "true", "attr.role": "\"listbox\"", "id": "optionsId" } }, providers: [{ provide: LoadingListener, useExisting: ClrOptions }], queries: [{ propertyName: "items", predicate: ClrOption }], ngImport: i0, template: `
9062
+ ClrOptions.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrOptions, selector: "clr-options", inputs: { optionsId: ["id", "optionsId"] }, host: { properties: { "class.clr-combobox-options": "true", "attr.role": "\"listbox\"", "id": "optionsId" } }, providers: [{ provide: LoadingListener, useExisting: ClrOptions }], queries: [{ propertyName: "items", predicate: ClrOption, descendants: true }], ngImport: i0, template: `
8933
9063
  <div *ngIf="optionSelectionService.loading" class="clr-combobox-options-loading">
8934
9064
  <clr-spinner clrInline>
8935
9065
  {{ commonStrings.keys.loading }}
@@ -8996,7 +9126,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
8996
9126
  args: ['id']
8997
9127
  }], items: [{
8998
9128
  type: ContentChildren,
8999
- args: [ClrOption]
9129
+ args: [ClrOption, { descendants: true }]
9000
9130
  }] } });
9001
9131
 
9002
9132
  /*
@@ -9268,7 +9398,7 @@ ClrCombobox.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
9268
9398
  IF_ACTIVE_ID_PROVIDER,
9269
9399
  FOCUS_SERVICE_PROVIDER,
9270
9400
  COMBOBOX_FOCUS_HANDLER_PROVIDER,
9271
- ], queries: [{ propertyName: "optionSelected", first: true, predicate: ClrOptionSelected, descendants: true }, { propertyName: "options", first: true, predicate: ClrOptions, descendants: true }], viewQueries: [{ propertyName: "textbox", first: true, predicate: ["textboxInput"], descendants: true }, { propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true }], usesInheritance: true, hostDirectives: [{ directive: ClrPopoverHostDirective }], 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<!-- The (click) handler is needed to auto-focus on input field which can not currently occupy the whole\n width of the component, after being wrapped to a new line -->\n<div\n class=\"clr-combobox-wrapper\"\n clrPopoverAnchor\n (click)=\"focusInput()\"\n [class.multi]=\"multiSelect\"\n [class.invalid]=\"invalid\"\n [class.disabled]=\"control?.disabled? true: null\"\n>\n <span\n *ngIf=\"multiSelect && optionSelectionService.selectionModel.model\"\n role=\"grid\"\n clrRovingTabindex\n [clrRovingTabindexDisabled]=\"control?.disabled\"\n clrDirection=\"both\"\n [attr.aria-label]=\"getSelectionAriaLabel()\"\n [attr.aria-disabled]=\"control?.disabled? true: null\"\n >\n <span *ngFor=\"let item of multiSelectModel; let i = index\" class=\"label label-combobox-pill\" role=\"row\">\n <span role=\"gridcell\">\n <span class=\"clr-combobox-pill-content\" clrKeyFocusItem>\n <ng-container\n *ngIf=\"optionSelected\"\n [ngTemplateOutlet]=\"optionSelected.template\"\n [ngTemplateOutletContext]=\"{$implicit: optionSelectionService.selectionModel.model[i]}\"\n ></ng-container>\n </span>\n </span>\n <span role=\"gridcell\">\n <button\n clrKeyFocusItem\n type=\"button\"\n class=\"clr-combobox-remove-btn\"\n [disabled]=\"control?.disabled? true: null\"\n [attr.aria-label]=\"commonStrings.keys.comboboxDelete + ' ' + optionSelectionService.selectionModel.toString(displayField, i)\"\n (click)=\"unselect(item)\"\n >\n <cds-icon shape=\"window-close\" size=\"12\"></cds-icon>\n </button>\n </span>\n </span>\n </span>\n\n <span class=\"clr-combobox-input-wrapper\">\n <input\n #textboxInput\n type=\"text\"\n role=\"combobox\"\n [id]=\"inputId()\"\n class=\"clr-input clr-combobox-input\"\n [(ngModel)]=\"searchText\"\n (blur)=\"onBlur()\"\n (focus)=\"onFocus()\"\n [attr.aria-expanded]=\"openState\"\n [attr.aria-owns]=\"ariaOwns\"\n aria-haspopup=\"listbox\"\n aria-autocomplete=\"list\"\n autocomplete=\"off\"\n [attr.aria-invalid]=\"control?.invalid? true: null\"\n [disabled]=\"control?.disabled? true: null\"\n [attr.aria-activedescendant]=\"getActiveDescendant()\"\n [attr.placeholder]=\"placeholder\"\n />\n </span>\n\n <!-- No click handler, as it uses the handler on the .clr-combobox-wrapper -->\n <button\n clrPopoverOpenCloseButton\n #trigger\n type=\"button\"\n class=\"clr-combobox-trigger\"\n tabindex=\"-1\"\n [disabled]=\"control?.disabled || null\"\n [attr.aria-label]=\"commonStrings.keys.comboboxOpen\"\n >\n <cds-icon shape=\"angle\" direction=\"down\"></cds-icon>\n </button>\n\n <div class=\"clr-focus-indicator\" [class.clr-focus]=\"focused\"></div>\n</div>\n\n<!-- Both close handlers are handled manually due to issues in Edge browser.\n Additionally 'outsideClickToClose' has complex handling that's necessary\n to be manual due to the component architecture -->\n<div role=\"dialog\" *clrPopoverContent=\"openState at smartPosition; outsideClickToClose: false; scrollToClose: false\">\n <ng-content></ng-content>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { 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: 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.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: "directive", type: CdsIconCustomTag, selector: "cds-icon" }, { kind: "component", type: ClrRovingTabindex, selector: "[clrRovingTabindex]", inputs: ["clrRovingTabindex", "clrRovingTabindexDisabled"] }, { kind: "directive", type: ClrKeyFocusItem, selector: "[clrKeyFocusItem]" }, { kind: "directive", type: ClrPopoverAnchor, selector: "[clrPopoverAnchor]" }, { kind: "directive", type: ClrPopoverOpenCloseButton, selector: "[clrPopoverOpenCloseButton]", outputs: ["clrPopoverOpenCloseChange"] }, { kind: "directive", type: ClrPopoverContent, selector: "[clrPopoverContent]", inputs: ["clrPopoverContent", "clrPopoverContentAt", "clrPopoverContentOutsideClickToClose", "clrPopoverContentScrollToClose"] }] });
9401
+ ], queries: [{ propertyName: "optionSelected", first: true, predicate: ClrOptionSelected, descendants: true }, { propertyName: "options", first: true, predicate: ClrOptions, descendants: true }], viewQueries: [{ propertyName: "textbox", first: true, predicate: ["textboxInput"], descendants: true }, { propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true }], usesInheritance: true, hostDirectives: [{ directive: ClrPopoverHostDirective }], 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<!-- The (click) handler is needed to auto-focus on input field which can not currently occupy the whole\n width of the component, after being wrapped to a new line -->\n<div\n class=\"clr-combobox-wrapper\"\n clrPopoverAnchor\n (click)=\"focusInput()\"\n [class.multi]=\"multiSelect\"\n [class.invalid]=\"invalid\"\n [class.disabled]=\"control?.disabled? true: null\"\n>\n <span\n *ngIf=\"multiSelect && optionSelectionService.selectionModel.model && multiSelectModel.length > 0\"\n role=\"grid\"\n clrRovingTabindex\n [clrRovingTabindexDisabled]=\"control?.disabled\"\n clrDirection=\"both\"\n [attr.aria-label]=\"getSelectionAriaLabel()\"\n [attr.aria-disabled]=\"control?.disabled? true: null\"\n class=\"clr-combobox-pills\"\n >\n <span *ngFor=\"let item of multiSelectModel; let i = index\" class=\"label label-combobox-pill\" role=\"row\">\n <span role=\"gridcell\">\n <span class=\"clr-combobox-pill-content\" clrKeyFocusItem>\n <ng-container\n *ngIf=\"optionSelected\"\n [ngTemplateOutlet]=\"optionSelected.template\"\n [ngTemplateOutletContext]=\"{$implicit: optionSelectionService.selectionModel.model[i]}\"\n ></ng-container>\n </span>\n </span>\n <span role=\"gridcell\">\n <button\n clrKeyFocusItem\n type=\"button\"\n class=\"clr-combobox-remove-btn\"\n [disabled]=\"control?.disabled? true: null\"\n [attr.aria-label]=\"commonStrings.keys.comboboxDelete + ' ' + optionSelectionService.selectionModel.toString(displayField, i)\"\n (click)=\"unselect(item)\"\n >\n <cds-icon shape=\"window-close\" size=\"12\"></cds-icon>\n </button>\n </span>\n </span>\n </span>\n\n <input\n #textboxInput\n type=\"text\"\n role=\"combobox\"\n [id]=\"inputId()\"\n class=\"clr-input clr-combobox-input\"\n [(ngModel)]=\"searchText\"\n (blur)=\"onBlur()\"\n (focus)=\"onFocus()\"\n [attr.aria-expanded]=\"openState\"\n [attr.aria-owns]=\"ariaOwns\"\n aria-haspopup=\"listbox\"\n aria-autocomplete=\"list\"\n autocomplete=\"off\"\n [attr.aria-invalid]=\"control?.invalid? true: null\"\n [disabled]=\"control?.disabled? true: null\"\n [attr.aria-activedescendant]=\"getActiveDescendant()\"\n [attr.placeholder]=\"placeholder\"\n />\n\n <!-- No click handler, as it uses the handler on the .clr-combobox-wrapper -->\n <button\n clrPopoverOpenCloseButton\n #trigger\n type=\"button\"\n class=\"clr-combobox-trigger\"\n tabindex=\"-1\"\n [disabled]=\"control?.disabled || null\"\n [attr.aria-label]=\"commonStrings.keys.comboboxOpen\"\n >\n <cds-icon shape=\"angle\" direction=\"down\"></cds-icon>\n </button>\n\n <div class=\"clr-focus-indicator\" [class.clr-focus]=\"focused\"></div>\n</div>\n\n<!-- Both close handlers are handled manually due to issues in Edge browser.\n Additionally 'outsideClickToClose' has complex handling that's necessary\n to be manual due to the component architecture -->\n<div role=\"dialog\" *clrPopoverContent=\"openState at smartPosition; outsideClickToClose: false; scrollToClose: false\">\n <ng-content></ng-content>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { 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: 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.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: "directive", type: CdsIconCustomTag, selector: "cds-icon" }, { kind: "component", type: ClrRovingTabindex, selector: "[clrRovingTabindex]", inputs: ["clrRovingTabindex", "clrRovingTabindexDisabled"] }, { kind: "directive", type: ClrKeyFocusItem, selector: "[clrKeyFocusItem]" }, { kind: "directive", type: ClrPopoverAnchor, selector: "[clrPopoverAnchor]" }, { kind: "directive", type: ClrPopoverOpenCloseButton, selector: "[clrPopoverOpenCloseButton]", outputs: ["clrPopoverOpenCloseChange"] }, { kind: "directive", type: ClrPopoverContent, selector: "[clrPopoverContent]", inputs: ["clrPopoverContent", "clrPopoverContentAt", "clrPopoverContentOutsideClickToClose", "clrPopoverContentScrollToClose"] }] });
9272
9402
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrCombobox, decorators: [{
9273
9403
  type: Component,
9274
9404
  args: [{ selector: 'clr-combobox', providers: [
@@ -9281,7 +9411,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
9281
9411
  '[class.aria-required]': 'true',
9282
9412
  '[class.clr-combobox]': 'true',
9283
9413
  '[class.clr-combobox-disabled]': 'control?.disabled',
9284
- }, 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<!-- The (click) handler is needed to auto-focus on input field which can not currently occupy the whole\n width of the component, after being wrapped to a new line -->\n<div\n class=\"clr-combobox-wrapper\"\n clrPopoverAnchor\n (click)=\"focusInput()\"\n [class.multi]=\"multiSelect\"\n [class.invalid]=\"invalid\"\n [class.disabled]=\"control?.disabled? true: null\"\n>\n <span\n *ngIf=\"multiSelect && optionSelectionService.selectionModel.model\"\n role=\"grid\"\n clrRovingTabindex\n [clrRovingTabindexDisabled]=\"control?.disabled\"\n clrDirection=\"both\"\n [attr.aria-label]=\"getSelectionAriaLabel()\"\n [attr.aria-disabled]=\"control?.disabled? true: null\"\n >\n <span *ngFor=\"let item of multiSelectModel; let i = index\" class=\"label label-combobox-pill\" role=\"row\">\n <span role=\"gridcell\">\n <span class=\"clr-combobox-pill-content\" clrKeyFocusItem>\n <ng-container\n *ngIf=\"optionSelected\"\n [ngTemplateOutlet]=\"optionSelected.template\"\n [ngTemplateOutletContext]=\"{$implicit: optionSelectionService.selectionModel.model[i]}\"\n ></ng-container>\n </span>\n </span>\n <span role=\"gridcell\">\n <button\n clrKeyFocusItem\n type=\"button\"\n class=\"clr-combobox-remove-btn\"\n [disabled]=\"control?.disabled? true: null\"\n [attr.aria-label]=\"commonStrings.keys.comboboxDelete + ' ' + optionSelectionService.selectionModel.toString(displayField, i)\"\n (click)=\"unselect(item)\"\n >\n <cds-icon shape=\"window-close\" size=\"12\"></cds-icon>\n </button>\n </span>\n </span>\n </span>\n\n <span class=\"clr-combobox-input-wrapper\">\n <input\n #textboxInput\n type=\"text\"\n role=\"combobox\"\n [id]=\"inputId()\"\n class=\"clr-input clr-combobox-input\"\n [(ngModel)]=\"searchText\"\n (blur)=\"onBlur()\"\n (focus)=\"onFocus()\"\n [attr.aria-expanded]=\"openState\"\n [attr.aria-owns]=\"ariaOwns\"\n aria-haspopup=\"listbox\"\n aria-autocomplete=\"list\"\n autocomplete=\"off\"\n [attr.aria-invalid]=\"control?.invalid? true: null\"\n [disabled]=\"control?.disabled? true: null\"\n [attr.aria-activedescendant]=\"getActiveDescendant()\"\n [attr.placeholder]=\"placeholder\"\n />\n </span>\n\n <!-- No click handler, as it uses the handler on the .clr-combobox-wrapper -->\n <button\n clrPopoverOpenCloseButton\n #trigger\n type=\"button\"\n class=\"clr-combobox-trigger\"\n tabindex=\"-1\"\n [disabled]=\"control?.disabled || null\"\n [attr.aria-label]=\"commonStrings.keys.comboboxOpen\"\n >\n <cds-icon shape=\"angle\" direction=\"down\"></cds-icon>\n </button>\n\n <div class=\"clr-focus-indicator\" [class.clr-focus]=\"focused\"></div>\n</div>\n\n<!-- Both close handlers are handled manually due to issues in Edge browser.\n Additionally 'outsideClickToClose' has complex handling that's necessary\n to be manual due to the component architecture -->\n<div role=\"dialog\" *clrPopoverContent=\"openState at smartPosition; outsideClickToClose: false; scrollToClose: false\">\n <ng-content></ng-content>\n</div>\n" }]
9414
+ }, 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<!-- The (click) handler is needed to auto-focus on input field which can not currently occupy the whole\n width of the component, after being wrapped to a new line -->\n<div\n class=\"clr-combobox-wrapper\"\n clrPopoverAnchor\n (click)=\"focusInput()\"\n [class.multi]=\"multiSelect\"\n [class.invalid]=\"invalid\"\n [class.disabled]=\"control?.disabled? true: null\"\n>\n <span\n *ngIf=\"multiSelect && optionSelectionService.selectionModel.model && multiSelectModel.length > 0\"\n role=\"grid\"\n clrRovingTabindex\n [clrRovingTabindexDisabled]=\"control?.disabled\"\n clrDirection=\"both\"\n [attr.aria-label]=\"getSelectionAriaLabel()\"\n [attr.aria-disabled]=\"control?.disabled? true: null\"\n class=\"clr-combobox-pills\"\n >\n <span *ngFor=\"let item of multiSelectModel; let i = index\" class=\"label label-combobox-pill\" role=\"row\">\n <span role=\"gridcell\">\n <span class=\"clr-combobox-pill-content\" clrKeyFocusItem>\n <ng-container\n *ngIf=\"optionSelected\"\n [ngTemplateOutlet]=\"optionSelected.template\"\n [ngTemplateOutletContext]=\"{$implicit: optionSelectionService.selectionModel.model[i]}\"\n ></ng-container>\n </span>\n </span>\n <span role=\"gridcell\">\n <button\n clrKeyFocusItem\n type=\"button\"\n class=\"clr-combobox-remove-btn\"\n [disabled]=\"control?.disabled? true: null\"\n [attr.aria-label]=\"commonStrings.keys.comboboxDelete + ' ' + optionSelectionService.selectionModel.toString(displayField, i)\"\n (click)=\"unselect(item)\"\n >\n <cds-icon shape=\"window-close\" size=\"12\"></cds-icon>\n </button>\n </span>\n </span>\n </span>\n\n <input\n #textboxInput\n type=\"text\"\n role=\"combobox\"\n [id]=\"inputId()\"\n class=\"clr-input clr-combobox-input\"\n [(ngModel)]=\"searchText\"\n (blur)=\"onBlur()\"\n (focus)=\"onFocus()\"\n [attr.aria-expanded]=\"openState\"\n [attr.aria-owns]=\"ariaOwns\"\n aria-haspopup=\"listbox\"\n aria-autocomplete=\"list\"\n autocomplete=\"off\"\n [attr.aria-invalid]=\"control?.invalid? true: null\"\n [disabled]=\"control?.disabled? true: null\"\n [attr.aria-activedescendant]=\"getActiveDescendant()\"\n [attr.placeholder]=\"placeholder\"\n />\n\n <!-- No click handler, as it uses the handler on the .clr-combobox-wrapper -->\n <button\n clrPopoverOpenCloseButton\n #trigger\n type=\"button\"\n class=\"clr-combobox-trigger\"\n tabindex=\"-1\"\n [disabled]=\"control?.disabled || null\"\n [attr.aria-label]=\"commonStrings.keys.comboboxOpen\"\n >\n <cds-icon shape=\"angle\" direction=\"down\"></cds-icon>\n </button>\n\n <div class=\"clr-focus-indicator\" [class.clr-focus]=\"focused\"></div>\n</div>\n\n<!-- Both close handlers are handled manually due to issues in Edge browser.\n Additionally 'outsideClickToClose' has complex handling that's necessary\n to be manual due to the component architecture -->\n<div role=\"dialog\" *clrPopoverContent=\"openState at smartPosition; outsideClickToClose: false; scrollToClose: false\">\n <ng-content></ng-content>\n</div>\n" }]
9285
9415
  }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.Injector }, { type: i1.NgControl, decorators: [{
9286
9416
  type: Self
9287
9417
  }, {
@@ -9357,6 +9487,10 @@ class ClrOptionItems {
9357
9487
  this._filterField = field;
9358
9488
  this.optionService.displayField = field;
9359
9489
  }
9490
+ get hasResults() {
9491
+ // explicity return `undefined` instead of `false` if the answer is not known
9492
+ return this.filteredItems ? this.filteredItems.length : undefined;
9493
+ }
9360
9494
  ngDoCheck() {
9361
9495
  if (!this.differ) {
9362
9496
  this.differ = this.differs.find(this.filteredItems).create(this.iterableProxy.ngForTrackBy);
@@ -9426,6 +9560,44 @@ function normalizeValue(value) {
9426
9560
  .toLowerCase();
9427
9561
  }
9428
9562
 
9563
+ /*
9564
+ * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
9565
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
9566
+ * This software is released under MIT license.
9567
+ * The full license information can be found in LICENSE in the root directory of this project.
9568
+ */
9569
+ class ClrOptionGroup {
9570
+ constructor() {
9571
+ this.labelId = uniqueIdFactory();
9572
+ }
9573
+ }
9574
+ ClrOptionGroup.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrOptionGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
9575
+ ClrOptionGroup.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrOptionGroup, selector: "clr-option-group", inputs: { label: ["clrOptionGroupLabel", "label"] }, host: { properties: { "attr.role": "\"group\"", "attr.aria-labelledby": "labelId", "style.display": "clrOptionItems.hasResults ? undefined : \"none\"" } }, queries: [{ propertyName: "clrOptionItems", first: true, predicate: ClrOptionItems, descendants: true }], ngImport: i0, template: `
9576
+ <span [id]="labelId" class="clr-option-group-label" role="presentation">{{ label }}</span>
9577
+ <ng-content></ng-content>
9578
+ `, isInline: true });
9579
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrOptionGroup, decorators: [{
9580
+ type: Component,
9581
+ args: [{
9582
+ selector: 'clr-option-group',
9583
+ host: {
9584
+ '[attr.role]': '"group"',
9585
+ '[attr.aria-labelledby]': 'labelId',
9586
+ '[style.display]': 'clrOptionItems.hasResults ? undefined : "none"',
9587
+ },
9588
+ template: `
9589
+ <span [id]="labelId" class="clr-option-group-label" role="presentation">{{ label }}</span>
9590
+ <ng-content></ng-content>
9591
+ `,
9592
+ }]
9593
+ }], propDecorators: { label: [{
9594
+ type: Input,
9595
+ args: ['clrOptionGroupLabel']
9596
+ }], clrOptionItems: [{
9597
+ type: ContentChild,
9598
+ args: [ClrOptionItems]
9599
+ }] } });
9600
+
9429
9601
  /*
9430
9602
  * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
9431
9603
  * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
@@ -9438,7 +9610,13 @@ class ClrComboboxModule {
9438
9610
  }
9439
9611
  }
9440
9612
  ClrComboboxModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrComboboxModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
9441
- ClrComboboxModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.2", ngImport: i0, type: ClrComboboxModule, declarations: [ClrCombobox, ClrComboboxContainer, ClrOptions, ClrOption, ClrOptionSelected, ClrOptionItems], imports: [CommonModule,
9613
+ ClrComboboxModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.2", ngImport: i0, type: ClrComboboxModule, declarations: [ClrCombobox,
9614
+ ClrComboboxContainer,
9615
+ ClrOptions,
9616
+ ClrOption,
9617
+ ClrOptionGroup,
9618
+ ClrOptionSelected,
9619
+ ClrOptionItems], imports: [CommonModule,
9442
9620
  FormsModule,
9443
9621
  ClrIconModule,
9444
9622
  ClrKeyFocusModule,
@@ -9450,6 +9628,7 @@ ClrComboboxModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", versi
9450
9628
  ClrComboboxContainer,
9451
9629
  ClrOptions,
9452
9630
  ClrOption,
9631
+ ClrOptionGroup,
9453
9632
  ClrOptionSelected,
9454
9633
  ClrConditionalModule,
9455
9634
  ClrOptionItems] });
@@ -9475,13 +9654,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
9475
9654
  ClrPopoverModuleNext,
9476
9655
  ClrSpinnerModule,
9477
9656
  ],
9478
- declarations: [ClrCombobox, ClrComboboxContainer, ClrOptions, ClrOption, ClrOptionSelected, ClrOptionItems],
9657
+ declarations: [
9658
+ ClrCombobox,
9659
+ ClrComboboxContainer,
9660
+ ClrOptions,
9661
+ ClrOption,
9662
+ ClrOptionGroup,
9663
+ ClrOptionSelected,
9664
+ ClrOptionItems,
9665
+ ],
9479
9666
  exports: [
9480
9667
  ClrCommonFormsModule,
9481
9668
  ClrCombobox,
9482
9669
  ClrComboboxContainer,
9483
9670
  ClrOptions,
9484
9671
  ClrOption,
9672
+ ClrOptionGroup,
9485
9673
  ClrOptionSelected,
9486
9674
  ClrConditionalModule,
9487
9675
  ClrOptionItems,
@@ -9965,14 +10153,14 @@ class ClrBreadcrumbs {
9965
10153
  }
9966
10154
  }
9967
10155
  ClrBreadcrumbs.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrBreadcrumbs, deps: [{ token: ClrCommonStringsService }], target: i0.ɵɵFactoryTarget.Component });
9968
- ClrBreadcrumbs.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrBreadcrumbs, selector: "clr-breadcrumbs", inputs: { items: "items" }, outputs: { clrBreadcrumbItemClick: "clrBreadcrumbItemClick" }, host: { properties: { "attr.aria-label": "commonStrings.keys.breadcrumbsLabel", "attr.role": "\"navigation\"" }, classAttribute: "clr-breadcrumb" }, ngImport: i0, template: "<div *ngIf=\"items?.length\" role=\"list\" class=\"clr-breadcrumb-menu\">\n <clr-breadcrumb-item *ngIf=\"items.length > max && !isExpanded\">\n <button\n [attr.aria-label]=\"commonStrings.keys.expandBreadcrumbsLabel\"\n class=\"btn btn-link btn-sm clr-breadcrumb-expand\"\n (click)=\"expand()\"\n (keydown)=\"expand()\"\n >\n <cds-icon shape=\"ellipsis-horizontal\"></cds-icon>\n </button>\n </clr-breadcrumb-item>\n <clr-breadcrumb-item *ngFor=\"let breadcrumb of items | slice: -limit : items.length; let isLastItem=last\">\n <span *ngIf=\"isLastItem; else breadcrumbLinks\" aria-current=\"page\">{{ breadcrumb.label }}</span>\n\n <ng-template #breadcrumbLinks>\n <a\n *ngIf=\"breadcrumb.routerLink\"\n [routerLink]=\"breadcrumb.routerLink\"\n [queryParams]=\"breadcrumb.queryParams\"\n [target]=\"breadcrumb.target || '_self'\"\n (click)=\"handleItemClick(breadcrumb)\"\n >\n {{ breadcrumb.label }}\n </a>\n <a\n *ngIf=\"breadcrumb.href\"\n [href]=\"breadcrumb.href\"\n [target]=\"breadcrumb.target || '_self'\"\n (click)=\"handleItemClick(breadcrumb)\"\n >\n {{ breadcrumb.label }}\n </a>\n </ng-template>\n </clr-breadcrumb-item>\n</div>\n", styles: [":root [cds-theme]{--clr-breadcrumb-item-space: var(--cds-global-space-5)}.clr-breadcrumb-menu{display:flex;flex-wrap:wrap;align-items:center}.clr-breadcrumb-menu .clr-breadcrumb-item{display:flex;align-items:center;font-size:var(--cds-alias-typography-secondary-font-size);font-weight:var(--cds-alias-typography-secondary-font-weight);line-height:var(--cds-alias-typography-secondary-line-height);letter-spacing:var(--cds-alias-typography-secondary-letter-spacing)}.clr-breadcrumb-menu .clr-breadcrumb-item a{text-decoration:none;text-align:center;line-height:var(--cds-global-space-9)}.clr-breadcrumb-menu .clr-breadcrumb-item:not(:last-child):after{content:\"/\";margin:0 var(--clr-breadcrumb-item-space);color:var(--cds-alias-typography-color-400)}.clr-breadcrumb-menu .clr-breadcrumb-item:last-child{color:var(--cds-alias-typography-color-400)}.clr-breadcrumb-menu .clr-breadcrumb-expand{margin:0;padding:0;gap:0;min-width:-moz-fit-content;min-width:fit-content}\n"], dependencies: [{ kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }, { kind: "directive", type: i1$1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: ClrBreadcrumbItem, selector: "clr-breadcrumb-item" }, { kind: "pipe", type: i5.SlicePipe, name: "slice" }] });
10156
+ ClrBreadcrumbs.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrBreadcrumbs, selector: "clr-breadcrumbs", inputs: { items: "items" }, outputs: { clrBreadcrumbItemClick: "clrBreadcrumbItemClick" }, host: { properties: { "attr.aria-label": "commonStrings.keys.breadcrumbsLabel", "attr.role": "\"navigation\"" }, classAttribute: "clr-breadcrumb" }, ngImport: i0, template: "<div *ngIf=\"items?.length\" role=\"list\" class=\"clr-breadcrumb-menu\">\n <clr-breadcrumb-item *ngIf=\"items.length > max && !isExpanded\">\n <button\n [attr.aria-label]=\"commonStrings.keys.expandBreadcrumbsLabel\"\n class=\"btn btn-link btn-sm clr-breadcrumb-expand\"\n (click)=\"expand()\"\n (keydown)=\"expand()\"\n >\n <cds-icon shape=\"ellipsis-horizontal\"></cds-icon>\n </button>\n </clr-breadcrumb-item>\n <clr-breadcrumb-item *ngFor=\"let breadcrumb of items | slice: -limit : items.length; let isLastItem=last\">\n <span *ngIf=\"isLastItem; else breadcrumbLinks\" aria-current=\"page\">{{ breadcrumb.label }}</span>\n\n <ng-template #breadcrumbLinks>\n <a\n *ngIf=\"breadcrumb.routerLink\"\n [routerLink]=\"breadcrumb.routerLink\"\n [queryParams]=\"breadcrumb.queryParams\"\n [target]=\"breadcrumb.target || '_self'\"\n (click)=\"handleItemClick(breadcrumb)\"\n >\n {{ breadcrumb.label }}\n </a>\n <a\n *ngIf=\"breadcrumb.href\"\n [href]=\"breadcrumb.href\"\n [target]=\"breadcrumb.target || '_self'\"\n (click)=\"handleItemClick(breadcrumb)\"\n >\n {{ breadcrumb.label }}\n </a>\n </ng-template>\n </clr-breadcrumb-item>\n</div>\n", styles: [":root [cds-theme]{--clr-breadcrumb-item-space: var(--clr-base-gap-s)}.clr-breadcrumb-menu{display:flex;flex-wrap:wrap;align-items:center}.clr-breadcrumb-menu .clr-breadcrumb-item{display:flex;align-items:center;height:var(--clr-base-row-height-s);color:var(--cds-alias-typography-color-400);font-size:var(--clr-base-typography-font-size-inline);font-weight:var(--cds-alias-typography-secondary-font-weight);line-height:var(--clr-base-typography-line-height-16);letter-spacing:calc(-.1 * (1rem / var(--cds-global-base)))}.clr-breadcrumb-menu .clr-breadcrumb-item a{text-decoration:none;text-align:center}.clr-breadcrumb-menu .clr-breadcrumb-item a:visited{color:var(--clr-link-color)}.clr-breadcrumb-menu .clr-breadcrumb-item a:visited:hover{color:var(--clr-link-hover-color)}.clr-breadcrumb-menu .clr-breadcrumb-item a:visited:active{color:var(--clr-link-active-color)}.clr-breadcrumb-menu .clr-breadcrumb-item:not(:last-child):after{content:\"/\";margin:0 var(--clr-breadcrumb-item-space)}.clr-breadcrumb-menu .clr-breadcrumb-expand{height:var(--clr-base-icon-size-l);width:var(--clr-base-icon-size-l);min-height:var(--clr-base-icon-size-l);min-width:var(--clr-base-icon-size-l);margin:0;padding:0;gap:0}\n"], dependencies: [{ kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }, { kind: "directive", type: i1$1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: ClrBreadcrumbItem, selector: "clr-breadcrumb-item" }, { kind: "pipe", type: i5.SlicePipe, name: "slice" }] });
9969
10157
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrBreadcrumbs, decorators: [{
9970
10158
  type: Component,
9971
10159
  args: [{ selector: 'clr-breadcrumbs', host: {
9972
10160
  class: 'clr-breadcrumb',
9973
10161
  '[attr.aria-label]': 'commonStrings.keys.breadcrumbsLabel',
9974
10162
  '[attr.role]': '"navigation"',
9975
- }, template: "<div *ngIf=\"items?.length\" role=\"list\" class=\"clr-breadcrumb-menu\">\n <clr-breadcrumb-item *ngIf=\"items.length > max && !isExpanded\">\n <button\n [attr.aria-label]=\"commonStrings.keys.expandBreadcrumbsLabel\"\n class=\"btn btn-link btn-sm clr-breadcrumb-expand\"\n (click)=\"expand()\"\n (keydown)=\"expand()\"\n >\n <cds-icon shape=\"ellipsis-horizontal\"></cds-icon>\n </button>\n </clr-breadcrumb-item>\n <clr-breadcrumb-item *ngFor=\"let breadcrumb of items | slice: -limit : items.length; let isLastItem=last\">\n <span *ngIf=\"isLastItem; else breadcrumbLinks\" aria-current=\"page\">{{ breadcrumb.label }}</span>\n\n <ng-template #breadcrumbLinks>\n <a\n *ngIf=\"breadcrumb.routerLink\"\n [routerLink]=\"breadcrumb.routerLink\"\n [queryParams]=\"breadcrumb.queryParams\"\n [target]=\"breadcrumb.target || '_self'\"\n (click)=\"handleItemClick(breadcrumb)\"\n >\n {{ breadcrumb.label }}\n </a>\n <a\n *ngIf=\"breadcrumb.href\"\n [href]=\"breadcrumb.href\"\n [target]=\"breadcrumb.target || '_self'\"\n (click)=\"handleItemClick(breadcrumb)\"\n >\n {{ breadcrumb.label }}\n </a>\n </ng-template>\n </clr-breadcrumb-item>\n</div>\n", styles: [":root [cds-theme]{--clr-breadcrumb-item-space: var(--cds-global-space-5)}.clr-breadcrumb-menu{display:flex;flex-wrap:wrap;align-items:center}.clr-breadcrumb-menu .clr-breadcrumb-item{display:flex;align-items:center;font-size:var(--cds-alias-typography-secondary-font-size);font-weight:var(--cds-alias-typography-secondary-font-weight);line-height:var(--cds-alias-typography-secondary-line-height);letter-spacing:var(--cds-alias-typography-secondary-letter-spacing)}.clr-breadcrumb-menu .clr-breadcrumb-item a{text-decoration:none;text-align:center;line-height:var(--cds-global-space-9)}.clr-breadcrumb-menu .clr-breadcrumb-item:not(:last-child):after{content:\"/\";margin:0 var(--clr-breadcrumb-item-space);color:var(--cds-alias-typography-color-400)}.clr-breadcrumb-menu .clr-breadcrumb-item:last-child{color:var(--cds-alias-typography-color-400)}.clr-breadcrumb-menu .clr-breadcrumb-expand{margin:0;padding:0;gap:0;min-width:-moz-fit-content;min-width:fit-content}\n"] }]
10163
+ }, template: "<div *ngIf=\"items?.length\" role=\"list\" class=\"clr-breadcrumb-menu\">\n <clr-breadcrumb-item *ngIf=\"items.length > max && !isExpanded\">\n <button\n [attr.aria-label]=\"commonStrings.keys.expandBreadcrumbsLabel\"\n class=\"btn btn-link btn-sm clr-breadcrumb-expand\"\n (click)=\"expand()\"\n (keydown)=\"expand()\"\n >\n <cds-icon shape=\"ellipsis-horizontal\"></cds-icon>\n </button>\n </clr-breadcrumb-item>\n <clr-breadcrumb-item *ngFor=\"let breadcrumb of items | slice: -limit : items.length; let isLastItem=last\">\n <span *ngIf=\"isLastItem; else breadcrumbLinks\" aria-current=\"page\">{{ breadcrumb.label }}</span>\n\n <ng-template #breadcrumbLinks>\n <a\n *ngIf=\"breadcrumb.routerLink\"\n [routerLink]=\"breadcrumb.routerLink\"\n [queryParams]=\"breadcrumb.queryParams\"\n [target]=\"breadcrumb.target || '_self'\"\n (click)=\"handleItemClick(breadcrumb)\"\n >\n {{ breadcrumb.label }}\n </a>\n <a\n *ngIf=\"breadcrumb.href\"\n [href]=\"breadcrumb.href\"\n [target]=\"breadcrumb.target || '_self'\"\n (click)=\"handleItemClick(breadcrumb)\"\n >\n {{ breadcrumb.label }}\n </a>\n </ng-template>\n </clr-breadcrumb-item>\n</div>\n", styles: [":root [cds-theme]{--clr-breadcrumb-item-space: var(--clr-base-gap-s)}.clr-breadcrumb-menu{display:flex;flex-wrap:wrap;align-items:center}.clr-breadcrumb-menu .clr-breadcrumb-item{display:flex;align-items:center;height:var(--clr-base-row-height-s);color:var(--cds-alias-typography-color-400);font-size:var(--clr-base-typography-font-size-inline);font-weight:var(--cds-alias-typography-secondary-font-weight);line-height:var(--clr-base-typography-line-height-16);letter-spacing:calc(-.1 * (1rem / var(--cds-global-base)))}.clr-breadcrumb-menu .clr-breadcrumb-item a{text-decoration:none;text-align:center}.clr-breadcrumb-menu .clr-breadcrumb-item a:visited{color:var(--clr-link-color)}.clr-breadcrumb-menu .clr-breadcrumb-item a:visited:hover{color:var(--clr-link-hover-color)}.clr-breadcrumb-menu .clr-breadcrumb-item a:visited:active{color:var(--clr-link-active-color)}.clr-breadcrumb-menu .clr-breadcrumb-item:not(:last-child):after{content:\"/\";margin:0 var(--clr-breadcrumb-item-space)}.clr-breadcrumb-menu .clr-breadcrumb-expand{height:var(--clr-base-icon-size-l);width:var(--clr-base-icon-size-l);min-height:var(--clr-base-icon-size-l);min-width:var(--clr-base-icon-size-l);margin:0;padding:0;gap:0}\n"] }]
9976
10164
  }], ctorParameters: function () { return [{ type: ClrCommonStringsService }]; }, propDecorators: { items: [{
9977
10165
  type: Input
9978
10166
  }], clrBreadcrumbItemClick: [{
@@ -14738,7 +14926,7 @@ class ClrDatepickerViewManager {
14738
14926
  }
14739
14927
  }
14740
14928
  ClrDatepickerViewManager.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatepickerViewManager, deps: [{ token: ClrCommonStringsService }, { token: ViewManagerService }, { token: DateNavigationService }, { token: DateIOService }], target: i0.ɵɵFactoryTarget.Component });
14741
- ClrDatepickerViewManager.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatepickerViewManager, selector: "clr-datepicker-view-manager", host: { attributes: { "role": "dialog" }, properties: { "class.datepicker": "true", "class.has-range-option": "hasRangeOptions", "class.has-action-buttons": "hasActionButtons", "attr.aria-modal": "true", "attr.aria-label": "commonStrings.keys.datepickerDialogLabel" } }, providers: [DatepickerFocusService], 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-container *ngIf=\"hasRangeOptions; else calendarView\">\n <clr-vertical-nav class=\"clr-date-range-picker-nav\">\n <ng-container *ngFor=\"let option of dateRangeOptions\">\n <a\n clrVerticalNavLink\n href=\"javascript:void(0)\"\n [attr.aria-label]=\"option?.label\"\n tabindex=\"0\"\n (keyup.enter)=\"onRangeOptionSelect(option)\"\n (click)=\"onRangeOptionSelect(option)\"\n >\n {{option.label}}\n </a>\n </ng-container>\n </clr-vertical-nav>\n\n <div class=\"datepicker-view-manager\">\n <ng-container *ngTemplateOutlet=\"calendarView\"></ng-container>\n </div>\n</ng-container>\n\n<ng-template #calendarView>\n <clr-monthpicker *ngIf=\"isMonthView\"></clr-monthpicker>\n <clr-yearpicker *ngIf=\"isYearView\"></clr-yearpicker>\n <clr-daypicker *ngIf=\"isDayView\"></clr-daypicker>\n <clr-datepicker-actions *ngIf=\"hasActionButtons\"></clr-datepicker-actions>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { 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: ClrVerticalNav, selector: "clr-vertical-nav", inputs: ["clrVerticalNavToggleLabel", "clrVerticalNavCollapsible", "clrVerticalNavCollapsed"], outputs: ["clrVerticalNavCollapsedChange"] }, { kind: "component", type: ClrVerticalNavLink, selector: "[clrVerticalNavLink]" }, { kind: "component", type: ClrMonthpicker, selector: "clr-monthpicker" }, { kind: "component", type: ClrYearpicker, selector: "clr-yearpicker" }, { kind: "component", type: ClrDaypicker, selector: "clr-daypicker" }, { kind: "component", type: ClrDatepickerActions, selector: "clr-datepicker-actions" }] });
14929
+ ClrDatepickerViewManager.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatepickerViewManager, selector: "clr-datepicker-view-manager", host: { attributes: { "role": "dialog" }, properties: { "class.datepicker": "true", "class.has-range-option": "hasRangeOptions", "class.has-action-buttons": "hasActionButtons", "attr.aria-modal": "true", "attr.aria-label": "commonStrings.keys.datepickerDialogLabel" } }, providers: [DatepickerFocusService], 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-container *ngIf=\"hasRangeOptions; else calendarView\">\n <clr-vertical-nav class=\"clr-date-range-picker-nav\">\n <ng-container *ngFor=\"let option of dateRangeOptions\">\n <a\n clrVerticalNavLink\n href=\"javascript:void(0)\"\n [attr.aria-label]=\"option?.label\"\n tabindex=\"0\"\n (keyup.enter)=\"onRangeOptionSelect(option)\"\n (click)=\"onRangeOptionSelect(option)\"\n >\n {{option.label}}\n </a>\n </ng-container>\n </clr-vertical-nav>\n\n <ng-container *ngTemplateOutlet=\"calendarView\"></ng-container>\n</ng-container>\n\n<ng-template #calendarView>\n <div class=\"datepicker-view-manager\">\n <clr-monthpicker *ngIf=\"isMonthView\"></clr-monthpicker>\n <clr-yearpicker *ngIf=\"isYearView\"></clr-yearpicker>\n <clr-daypicker *ngIf=\"isDayView\"></clr-daypicker>\n <clr-datepicker-actions *ngIf=\"hasActionButtons\"></clr-datepicker-actions>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { 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: ClrVerticalNav, selector: "clr-vertical-nav", inputs: ["clrVerticalNavToggleLabel", "clrVerticalNavCollapsible", "clrVerticalNavCollapsed"], outputs: ["clrVerticalNavCollapsedChange"] }, { kind: "component", type: ClrVerticalNavLink, selector: "[clrVerticalNavLink]" }, { kind: "component", type: ClrMonthpicker, selector: "clr-monthpicker" }, { kind: "component", type: ClrYearpicker, selector: "clr-yearpicker" }, { kind: "component", type: ClrDaypicker, selector: "clr-daypicker" }, { kind: "component", type: ClrDatepickerActions, selector: "clr-datepicker-actions" }] });
14742
14930
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatepickerViewManager, decorators: [{
14743
14931
  type: Component,
14744
14932
  args: [{ selector: 'clr-datepicker-view-manager', providers: [DatepickerFocusService], host: {
@@ -14748,7 +14936,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
14748
14936
  '[attr.aria-modal]': 'true',
14749
14937
  '[attr.aria-label]': 'commonStrings.keys.datepickerDialogLabel',
14750
14938
  role: 'dialog',
14751
- }, 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-container *ngIf=\"hasRangeOptions; else calendarView\">\n <clr-vertical-nav class=\"clr-date-range-picker-nav\">\n <ng-container *ngFor=\"let option of dateRangeOptions\">\n <a\n clrVerticalNavLink\n href=\"javascript:void(0)\"\n [attr.aria-label]=\"option?.label\"\n tabindex=\"0\"\n (keyup.enter)=\"onRangeOptionSelect(option)\"\n (click)=\"onRangeOptionSelect(option)\"\n >\n {{option.label}}\n </a>\n </ng-container>\n </clr-vertical-nav>\n\n <div class=\"datepicker-view-manager\">\n <ng-container *ngTemplateOutlet=\"calendarView\"></ng-container>\n </div>\n</ng-container>\n\n<ng-template #calendarView>\n <clr-monthpicker *ngIf=\"isMonthView\"></clr-monthpicker>\n <clr-yearpicker *ngIf=\"isYearView\"></clr-yearpicker>\n <clr-daypicker *ngIf=\"isDayView\"></clr-daypicker>\n <clr-datepicker-actions *ngIf=\"hasActionButtons\"></clr-datepicker-actions>\n</ng-template>\n" }]
14939
+ }, 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-container *ngIf=\"hasRangeOptions; else calendarView\">\n <clr-vertical-nav class=\"clr-date-range-picker-nav\">\n <ng-container *ngFor=\"let option of dateRangeOptions\">\n <a\n clrVerticalNavLink\n href=\"javascript:void(0)\"\n [attr.aria-label]=\"option?.label\"\n tabindex=\"0\"\n (keyup.enter)=\"onRangeOptionSelect(option)\"\n (click)=\"onRangeOptionSelect(option)\"\n >\n {{option.label}}\n </a>\n </ng-container>\n </clr-vertical-nav>\n\n <ng-container *ngTemplateOutlet=\"calendarView\"></ng-container>\n</ng-container>\n\n<ng-template #calendarView>\n <div class=\"datepicker-view-manager\">\n <clr-monthpicker *ngIf=\"isMonthView\"></clr-monthpicker>\n <clr-yearpicker *ngIf=\"isYearView\"></clr-yearpicker>\n <clr-daypicker *ngIf=\"isDayView\"></clr-daypicker>\n <clr-datepicker-actions *ngIf=\"hasActionButtons\"></clr-datepicker-actions>\n </div>\n</ng-template>\n" }]
14752
14940
  }], ctorParameters: function () { return [{ type: ClrCommonStringsService }, { type: ViewManagerService }, { type: DateNavigationService }, { type: DateIOService }]; } });
14753
14941
 
14754
14942
  /*
@@ -15529,7 +15717,7 @@ class ClrFileInputContainer extends ClrAbstractContainer {
15529
15717
  return this.fileInput.elementRef.nativeElement.multiple;
15530
15718
  }
15531
15719
  get disabled() {
15532
- return this.fileInput.elementRef.nativeElement.disabled;
15720
+ return this.fileInput.elementRef.nativeElement.disabled || (this.control && this.control.disabled);
15533
15721
  }
15534
15722
  get browseButtonText() {
15535
15723
  const selectionButtonLabel = this.fileList ? undefined : this.fileInput?.selection?.buttonLabel;
@@ -15751,9 +15939,13 @@ class ClrFileInput extends WrappedFormControl {
15751
15939
  constructor(injector, renderer, viewContainerRef, elementRef, control, commonStrings) {
15752
15940
  super(viewContainerRef, ClrFileInputContainer, injector, control, renderer, elementRef);
15753
15941
  this.elementRef = elementRef;
15942
+ this.control = control;
15754
15943
  this.commonStrings = commonStrings;
15755
15944
  this.selection = undefined;
15756
15945
  }
15946
+ get disabled() {
15947
+ return this.control && this.control.disabled;
15948
+ }
15757
15949
  handleChange() {
15758
15950
  this.updateSelection();
15759
15951
  }
@@ -15785,7 +15977,7 @@ class ClrFileInput extends WrappedFormControl {
15785
15977
  }
15786
15978
  }
15787
15979
  ClrFileInput.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInput, deps: [{ token: i0.Injector }, { token: i0.Renderer2 }, { token: i0.ViewContainerRef }, { token: i0.ElementRef }, { token: i1.NgControl, optional: true, self: true }, { token: ClrCommonStringsService }], target: i0.ɵɵFactoryTarget.Directive });
15788
- ClrFileInput.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: ClrFileInput, selector: "input[type=\"file\"][clrFileInput]", host: { attributes: { "tabindex": "-1", "aria-hidden": "true" }, listeners: { "change": "handleChange()" }, properties: { "class.clr-file-input": "true" } }, usesInheritance: true, ngImport: i0 });
15980
+ ClrFileInput.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: ClrFileInput, selector: "input[type=\"file\"][clrFileInput]", host: { attributes: { "tabindex": "-1", "aria-hidden": "true" }, listeners: { "change": "handleChange()" }, properties: { "class.clr-file-input": "true", "disabled": "this.disabled" } }, usesInheritance: true, ngImport: i0 });
15789
15981
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInput, decorators: [{
15790
15982
  type: Directive,
15791
15983
  args: [{
@@ -15800,7 +15992,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
15800
15992
  type: Self
15801
15993
  }, {
15802
15994
  type: Optional
15803
- }] }, { type: ClrCommonStringsService }]; }, propDecorators: { handleChange: [{
15995
+ }] }, { type: ClrCommonStringsService }]; }, propDecorators: { disabled: [{
15996
+ type: HostBinding,
15997
+ args: ['disabled']
15998
+ }], handleChange: [{
15804
15999
  type: HostListener,
15805
16000
  args: ['change']
15806
16001
  }] } });
@@ -16003,6 +16198,9 @@ class ClrNumberInputContainer extends ClrAbstractContainer {
16003
16198
  this.focus = false;
16004
16199
  this.subscriptions.push(focusService.focusChange.subscribe(state => (this.focus = state)));
16005
16200
  }
16201
+ focusOut() {
16202
+ this.input.dispatchBlur();
16203
+ }
16006
16204
  }
16007
16205
  ClrNumberInputContainer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrNumberInputContainer, deps: [{ token: ControlClassService }, { token: LayoutService, optional: true }, { token: NgControlService }, { token: FocusService }, { token: IfControlStateService }], target: i0.ɵɵFactoryTarget.Component });
16008
16206
  ClrNumberInputContainer.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrNumberInputContainer, selector: "clr-number-input-container", host: { properties: { "class.clr-form-control": "true", "class.clr-form-control-disabled": "control?.disabled", "class.clr-form-control-readonly": "input.readonly", "class.clr-row": "addGrid()" } }, providers: [FocusService, IfControlStateService, NgControlService, ControlIdService, ControlClassService], queries: [{ propertyName: "input", first: true, predicate: i0.forwardRef(function () { return ClrNumberInput; }), descendants: true }], usesInheritance: true, ngImport: i0, template: `
@@ -16010,7 +16208,7 @@ ClrNumberInputContainer.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0"
16010
16208
  <label *ngIf="!label && addGrid()"></label>
16011
16209
  <div class="clr-control-container" [ngClass]="controlClass()">
16012
16210
  <div class="clr-number-input-wrapper">
16013
- <div class="clr-input-group" [class.clr-focus]="focus">
16211
+ <div class="clr-input-group" [class.clr-focus]="focus" (focusout)="focusOut()">
16014
16212
  <ng-content select="[clrNumberInput]"></ng-content>
16015
16213
  <div class="clr-input-group-actions">
16016
16214
  <button
@@ -16061,7 +16259,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
16061
16259
  <label *ngIf="!label && addGrid()"></label>
16062
16260
  <div class="clr-control-container" [ngClass]="controlClass()">
16063
16261
  <div class="clr-number-input-wrapper">
16064
- <div class="clr-input-group" [class.clr-focus]="focus">
16262
+ <div class="clr-input-group" [class.clr-focus]="focus" (focusout)="focusOut()">
16065
16263
  <ng-content select="[clrNumberInput]"></ng-content>
16066
16264
  <div class="clr-input-group-actions">
16067
16265
  <button
@@ -16153,14 +16351,21 @@ class ClrNumberInput extends WrappedFormControl {
16153
16351
  }
16154
16352
  stepUp() {
16155
16353
  this.el.nativeElement.stepUp();
16156
- this.el.nativeElement.dispatchEvent(new Event('input', { bubbles: true, cancelable: true }));
16354
+ this.dispatchStepChangeEvents();
16157
16355
  this.control.control.markAllAsTouched();
16158
16356
  }
16159
16357
  stepDown() {
16160
16358
  this.el.nativeElement.stepDown();
16161
- this.el.nativeElement.dispatchEvent(new Event('input', { bubbles: true, cancelable: true }));
16359
+ this.dispatchStepChangeEvents();
16162
16360
  this.control.control.markAllAsTouched();
16163
16361
  }
16362
+ dispatchBlur() {
16363
+ this.el.nativeElement.dispatchEvent(new Event('blur', { bubbles: true, cancelable: true }));
16364
+ }
16365
+ dispatchStepChangeEvents() {
16366
+ this.el.nativeElement.dispatchEvent(new Event('input', { bubbles: true, cancelable: true }));
16367
+ this.el.nativeElement.dispatchEvent(new Event('change', { bubbles: true, cancelable: true }));
16368
+ }
16164
16369
  }
16165
16370
  ClrNumberInput.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrNumberInput, deps: [{ token: FocusService, optional: true }, { token: i0.ViewContainerRef }, { token: i0.Injector }, { token: i1.NgControl, optional: true, self: true }, { token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
16166
16371
  ClrNumberInput.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: ClrNumberInput, selector: "input[type=\"number\"][clrNumberInput]", host: { listeners: { "focus": "triggerFocus()", "blur": "triggerValidation()" }, properties: { "class.clr-input": "true", "class.clr-number-input": "true" } }, usesInheritance: true, ngImport: i0 });
@@ -17180,7 +17385,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
17180
17385
  class ClrExpandableAnimationModule {
17181
17386
  }
17182
17387
  ClrExpandableAnimationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrExpandableAnimationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
17183
- ClrExpandableAnimationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.2", ngImport: i0, type: ClrExpandableAnimationModule, declarations: [ClrExpandableAnimation], imports: [CommonModule], exports: [ClrExpandableAnimation] });
17388
+ ClrExpandableAnimationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.2", ngImport: i0, type: ClrExpandableAnimationModule, declarations: [ClrExpandableAnimation, ClrExpandableAnimationDirective], imports: [CommonModule], exports: [ClrExpandableAnimation, ClrExpandableAnimationDirective] });
17184
17389
  ClrExpandableAnimationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrExpandableAnimationModule, imports: [CommonModule] });
17185
17390
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrExpandableAnimationModule, decorators: [{
17186
17391
  type: NgModule,
@@ -17204,7 +17409,7 @@ class CdkDragModule_CdkDrag extends CdkDrag {
17204
17409
  super(elementRef, dropContainer, document, ngZone, viewContainerRef, config, dir, dragDrop, changeDetectorRef);
17205
17410
  }
17206
17411
  }
17207
- CdkDragModule_CdkDrag.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: CdkDragModule_CdkDrag, deps: [{ token: i0.ElementRef }, { token: CDK_DROP_LIST, optional: true }, { token: DOCUMENT, optional: true }, { token: i0.NgZone }, { token: i0.ViewContainerRef }, { token: CDK_DRAG_CONFIG, optional: true }, { token: i1$3.Directionality }, { token: i2.DragDrop }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
17412
+ CdkDragModule_CdkDrag.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: CdkDragModule_CdkDrag, deps: [{ token: i0.ElementRef }, { token: CDK_DROP_LIST, optional: true }, { token: DOCUMENT, optional: true }, { token: i0.NgZone }, { token: i0.ViewContainerRef }, { token: CDK_DRAG_CONFIG, optional: true }, { token: i1$3.Directionality }, { token: i2$1.DragDrop }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
17208
17413
  CdkDragModule_CdkDrag.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: CdkDragModule_CdkDrag, selector: "[cdkDrag]", usesInheritance: true, ngImport: i0 });
17209
17414
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: CdkDragModule_CdkDrag, decorators: [{
17210
17415
  type: Directive,
@@ -17226,7 +17431,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
17226
17431
  }, {
17227
17432
  type: Inject,
17228
17433
  args: [CDK_DRAG_CONFIG]
17229
- }] }, { type: i1$3.Directionality }, { type: i2.DragDrop }, { type: i0.ChangeDetectorRef }]; } });
17434
+ }] }, { type: i1$3.Directionality }, { type: i2$1.DragDrop }, { type: i0.ChangeDetectorRef }]; } });
17230
17435
  /**
17231
17436
  * This module allows us to avoid importing all of CdkDragDropModule which results in a smaller application bundle.
17232
17437
  */
@@ -17671,330 +17876,445 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
17671
17876
  * This software is released under MIT license.
17672
17877
  * The full license information can be found in LICENSE in the root directory of this project.
17673
17878
  */
17674
- const actionableItemSelectors = [
17675
- 'a[href]',
17676
- 'area[href]',
17677
- 'input:not([disabled])',
17678
- 'button:not([disabled])',
17679
- 'select:not([disabled])',
17680
- 'textarea:not([disabled])',
17681
- 'iframe',
17682
- 'object',
17683
- 'embed',
17684
- '[contenteditable=true]',
17685
- '[role=button]:not([disabled])',
17686
- ];
17687
- function getTabbableItems(el) {
17688
- const tabbableItemSelectors = [...actionableItemSelectors, '[tabindex="0"]:not([disabled])'];
17689
- const tabbableSelector = tabbableItemSelectors.join(',');
17690
- return Array.from(el.querySelectorAll(tabbableSelector));
17691
- }
17692
- function isActionableItem(el) {
17693
- const actionableSelector = actionableItemSelectors.join(',');
17694
- return el.matches(actionableSelector);
17695
- }
17696
- class KeyNavigationGridController {
17697
- constructor(zone) {
17698
- this.zone = zone;
17699
- this.skipItemFocus = false;
17700
- this.listenersAdded = false;
17701
- this.destroy$ = new Subject();
17702
- this._activeCell = null;
17703
- this.config = {
17704
- keyGridRows: '[role=row]:not(.datagrid-placeholder):not([style*="display: none"])',
17705
- keyGridCells: '[role=gridcell]:not(.datagrid-hidden-column):not(.datagrid-placeholder-content), [role=columnheader]:not(.datagrid-hidden-column):not(.datagrid-placeholder-content), .datagrid-detail-caret',
17706
- keyGrid: '[role=grid]',
17707
- };
17708
- }
17709
- get grid() {
17710
- return this.host?.querySelector(this.config.keyGrid);
17879
+ class DefaultKeyNavigationStrategy {
17880
+ constructor(utils) {
17881
+ this.utils = utils;
17711
17882
  }
17712
- get rows() {
17713
- return this.host?.querySelectorAll(this.config.keyGridRows);
17714
- }
17715
- get cells() {
17716
- return this.host?.querySelectorAll(this.config.keyGridCells);
17717
- }
17718
- ngOnDestroy() {
17719
- this.destroy$.next();
17720
- this.destroy$.complete();
17721
- }
17722
- addListeners() {
17723
- if (this.listenersAdded) {
17724
- return;
17883
+ keyUp(currentCellCoords) {
17884
+ const nextCellCoords = this.utils.createNextCellCoords(currentCellCoords);
17885
+ if (currentCellCoords.y === 0) {
17886
+ return nextCellCoords;
17725
17887
  }
17726
- this.zone.runOutsideAngular(() => {
17727
- fromEvent(this.grid, 'mousedown')
17728
- .pipe(takeUntil(this.destroy$))
17729
- .subscribe((e) => {
17730
- // preserve right click for context menus & keyboard mouse control https://apple.stackexchange.com/questions/32715/how-do-i-open-the-context-menu-from-a-mac-keyboard
17731
- if (e.buttons === 1 && !e.ctrlKey) {
17732
- const activeCell = this.cells
17733
- ? Array.from(this.cells).find(c => c === e.target || c === e.target.closest(this.config.keyGridCells))
17734
- : null;
17735
- if (activeCell) {
17736
- this.setActiveCell(activeCell, { keepFocus: isActionableItem(e.target) });
17737
- }
17738
- }
17739
- });
17740
- fromEvent(this.grid, 'wheel')
17741
- .pipe(takeUntil(this.destroy$))
17742
- .subscribe(() => {
17743
- this.removeActiveCell();
17744
- });
17745
- fromEvent(this.grid, 'focusout')
17746
- .pipe(debounceTime(0), takeUntil(this.destroy$))
17747
- .subscribe(() => {
17748
- if (this.grid.contains(document.activeElement)) {
17749
- return;
17750
- }
17751
- this.removeActiveCell();
17752
- });
17753
- fromEvent(this.grid, 'keydown')
17754
- .pipe(takeUntil(this.destroy$))
17755
- .subscribe((e) => {
17756
- // Skip column resize events
17757
- if (e.target.classList.contains('drag-handle') &&
17758
- (e.key === Keys.ArrowLeft || e.key === Keys.ArrowRight)) {
17759
- return;
17760
- }
17761
- if (e.key === Keys.ArrowUp ||
17762
- e.key === Keys.ArrowDown ||
17763
- e.key === Keys.ArrowLeft ||
17764
- e.key === Keys.ArrowRight ||
17765
- e.key === Keys.End ||
17766
- e.key === Keys.Home ||
17767
- e.key === Keys.PageUp ||
17768
- e.key === Keys.PageDown) {
17769
- const currentCellCoords = this.getCurrentCellCoordinates();
17770
- const nextCellCoords = this.isExpandedRow(currentCellCoords.y) || this.isDetailsRow(currentCellCoords.y)
17771
- ? this.getNextForExpandedRowCoordinate(e, currentCellCoords)
17772
- : this.getNextItemCoordinate(e, currentCellCoords);
17773
- const activeItem = this.rows
17774
- ? Array.from(this.getCellsForRow(nextCellCoords.y))[nextCellCoords.x]
17775
- : null;
17776
- if (activeItem) {
17777
- this.setActiveCell(activeItem);
17778
- }
17779
- e.preventDefault();
17780
- }
17781
- });
17782
- });
17783
- this.listenersAdded = true;
17784
- }
17785
- initializeKeyGrid(host) {
17786
- this.host = host;
17787
- this.addListeners();
17788
- this.resetKeyGrid();
17789
- }
17790
- resetKeyGrid() {
17791
- this.cells?.forEach((i) => i.setAttribute('tabindex', '-1'));
17792
- const firstCell = this.cells ? this.cells[0] : null;
17793
- firstCell?.setAttribute('tabindex', '0');
17794
- }
17795
- removeActiveCell() {
17796
- this._activeCell = null;
17797
- }
17798
- getActiveCell() {
17799
- return this._activeCell;
17800
- }
17801
- setActiveCell(activeCell, { keepFocus } = { keepFocus: false }) {
17802
- const prior = this.cells ? Array.from(this.cells).find(c => c.getAttribute('tabindex') === '0') : null;
17803
- if (prior) {
17804
- prior.setAttribute('tabindex', '-1');
17888
+ nextCellCoords.y = currentCellCoords.y - 1;
17889
+ const isActionCell = this.utils.isActionCell(currentCellCoords);
17890
+ if (this.utils.isSingleCellExpandedRow(nextCellCoords.y) &&
17891
+ !isActionCell &&
17892
+ this.utils.isDetailsRow(nextCellCoords.y)) {
17893
+ nextCellCoords.x = 0;
17805
17894
  }
17806
- activeCell.setAttribute('tabindex', '0');
17807
- this._activeCell = activeCell;
17808
- if (!this.skipItemFocus && !keepFocus) {
17809
- let elementToFocus;
17810
- if (activeCell.getAttribute('role') === 'columnheader') {
17811
- elementToFocus = activeCell;
17895
+ else if (this.utils.isDetailsRow(nextCellCoords.y)) {
17896
+ if (isActionCell) {
17897
+ nextCellCoords.y = nextCellCoords.y - 1;
17812
17898
  }
17813
17899
  else {
17814
- const tabbableElements = getTabbableItems(activeCell);
17815
- elementToFocus = tabbableElements.length ? tabbableElements[0] : activeCell;
17900
+ nextCellCoords.x = nextCellCoords.x - this.utils.actionCellCount(currentCellCoords.y);
17816
17901
  }
17817
- elementToFocus.focus();
17818
17902
  }
17903
+ return nextCellCoords;
17819
17904
  }
17820
- getNextForExpandedRowCoordinate(e, currentCellCoords) {
17821
- if (e.key === Keys.PageUp || e.key === Keys.PageDown) {
17822
- return this.getNextItemCoordinate(e, currentCellCoords);
17905
+ keyDown(currentCellCoords) {
17906
+ const nextCellCoords = this.utils.createNextCellCoords(currentCellCoords);
17907
+ const numOfRows = this.utils.rows ? this.utils.rows.length - 1 : 0;
17908
+ if (currentCellCoords.y >= numOfRows) {
17909
+ return nextCellCoords;
17823
17910
  }
17824
- if (!this.isDetailsRow(currentCellCoords.y) &&
17825
- !this.isRowReplaced(currentCellCoords.y) &&
17826
- (e.key === Keys.Home || e.key === Keys.End || e.key === Keys.ArrowRight || e.key === Keys.ArrowLeft)) {
17827
- return this.getNextItemCoordinate(e, currentCellCoords);
17911
+ const isActionCell = this.utils.isActionCell(currentCellCoords);
17912
+ nextCellCoords.y = currentCellCoords.y + 1;
17913
+ if (!isActionCell && this.utils.isRowReplaced(nextCellCoords.y)) {
17914
+ nextCellCoords.y = nextCellCoords.y + 1;
17915
+ nextCellCoords.x = this.utils.isSingleCellExpandedRow(nextCellCoords.y)
17916
+ ? 0
17917
+ : nextCellCoords.x - this.utils.actionCellCount(currentCellCoords.y);
17828
17918
  }
17829
- const { numOfRows, numOfColumns, inlineStart, inlineEnd, isActionCell, nextCellCoords } = this.getCalcVariables(currentCellCoords);
17830
- const isSingleCellExpandedRow = this.isSingleCellExpandedRow(currentCellCoords.y);
17831
- if (e.key === Keys.ArrowUp && currentCellCoords.y !== 0) {
17832
- nextCellCoords.y = currentCellCoords.y - 1;
17833
- if (isSingleCellExpandedRow && !isActionCell) {
17834
- if (this.isRowReplaced(currentCellCoords.y)) {
17835
- nextCellCoords.y = nextCellCoords.y - 1;
17836
- }
17837
- if (this.isDetailsRow(nextCellCoords.y)) {
17838
- nextCellCoords.x = 0;
17839
- }
17840
- else if (this.isDetailsRow(currentCellCoords.y) === false) {
17841
- // false check is intentional, the ! operator may be missed easily in this case
17842
- nextCellCoords.x = currentCellCoords.x;
17843
- }
17844
- else {
17845
- nextCellCoords.x = this.actionCellCount(nextCellCoords.y);
17846
- }
17847
- return nextCellCoords;
17848
- }
17849
- if (isActionCell && this.isDetailsRow(nextCellCoords.y)) {
17919
+ return nextCellCoords;
17920
+ }
17921
+ keyLeft(currentCellCoords) {
17922
+ const nextCellCoords = this.utils.createNextCellCoords(currentCellCoords);
17923
+ if (currentCellCoords.x === 0) {
17924
+ return nextCellCoords;
17925
+ }
17926
+ nextCellCoords.x = currentCellCoords.x - 1;
17927
+ return nextCellCoords;
17928
+ }
17929
+ keyRight(currentCellCoords) {
17930
+ const nextCellCoords = this.utils.createNextCellCoords(currentCellCoords);
17931
+ // calculate numOfColumns based on header cells.
17932
+ const numOfColumns = this.utils.rows?.length - 1 ? this.utils.getCellsForRow(0).length - 1 : 0;
17933
+ nextCellCoords.x = currentCellCoords.x < numOfColumns ? nextCellCoords.x + 1 : nextCellCoords.x;
17934
+ return nextCellCoords;
17935
+ }
17936
+ keyEnd(currentCellCoords, ctrlKey) {
17937
+ const nextCellCoords = this.utils.createNextCellCoords(currentCellCoords);
17938
+ const numOfRows = this.utils.rows ? this.utils.rows.length - 1 : 0;
17939
+ // calculate X based on header cells.
17940
+ nextCellCoords.x = numOfRows ? this.utils.getCellsForRow(0).length - 1 : 0;
17941
+ if (ctrlKey) {
17942
+ nextCellCoords.y = numOfRows;
17943
+ if (this.utils.isDetailsRow(nextCellCoords.y)) {
17944
+ nextCellCoords.x = this.utils.getCellsForRow(nextCellCoords.y).length - 1;
17945
+ }
17946
+ }
17947
+ return nextCellCoords;
17948
+ }
17949
+ keyHome(currentCellCoords, ctrlKey) {
17950
+ const nextCellCoords = this.utils.createNextCellCoords(currentCellCoords);
17951
+ nextCellCoords.x = 0;
17952
+ if (ctrlKey) {
17953
+ nextCellCoords.y = 0;
17954
+ }
17955
+ return nextCellCoords;
17956
+ }
17957
+ keyPageUp(currentCellCoords) {
17958
+ const nextCellCoords = this.utils.createNextCellCoords(currentCellCoords);
17959
+ const itemsPerPage = this.utils.itemsPerPage;
17960
+ nextCellCoords.y = currentCellCoords.y - itemsPerPage > 0 ? currentCellCoords.y - itemsPerPage + 1 : 1;
17961
+ if (!this.utils.isActionCell(currentCellCoords)) {
17962
+ if (this.utils.isDetailsRow(nextCellCoords.y)) {
17963
+ nextCellCoords.x = this.utils.isSingleCellExpandedRow(nextCellCoords.y)
17964
+ ? 0
17965
+ : nextCellCoords.x - this.utils.actionCellCount(currentCellCoords.y);
17966
+ }
17967
+ else if (this.utils.isRowReplaced(nextCellCoords.y)) {
17968
+ nextCellCoords.y = nextCellCoords.y + 1;
17969
+ nextCellCoords.x = this.utils.isSingleCellExpandedRow(nextCellCoords.y)
17970
+ ? 0
17971
+ : nextCellCoords.x - this.utils.actionCellCount(currentCellCoords.y);
17972
+ }
17973
+ }
17974
+ else {
17975
+ if (this.utils.isDetailsRow(nextCellCoords.y)) {
17850
17976
  nextCellCoords.y = nextCellCoords.y - 1;
17851
17977
  }
17852
- else if (this.isRowReplaced(nextCellCoords.y)) {
17978
+ }
17979
+ return nextCellCoords;
17980
+ }
17981
+ keyPageDown(currentCellCoords) {
17982
+ const nextCellCoords = this.utils.createNextCellCoords(currentCellCoords);
17983
+ const numOfRows = this.utils.rows ? this.utils.rows.length - 1 : 0;
17984
+ const itemsPerPage = this.utils.itemsPerPage;
17985
+ nextCellCoords.y = currentCellCoords.y + itemsPerPage >= numOfRows ? numOfRows : currentCellCoords.y + itemsPerPage;
17986
+ if (this.utils.isActionCell(currentCellCoords) && this.utils.isDetailsRow(nextCellCoords.y)) {
17987
+ nextCellCoords.y = nextCellCoords.y - 1;
17988
+ }
17989
+ else if (this.utils.isDetailsRow(nextCellCoords.y) && this.utils.isSingleCellExpandedRow(nextCellCoords.y)) {
17990
+ nextCellCoords.x = 0;
17991
+ }
17992
+ else if (this.utils.isDetailsRow(nextCellCoords.y)) {
17993
+ nextCellCoords.x = nextCellCoords.x - this.utils.actionCellCount(currentCellCoords.y);
17994
+ }
17995
+ else if (this.utils.isRowReplaced(nextCellCoords.y)) {
17996
+ nextCellCoords.y = nextCellCoords.y + 1;
17997
+ nextCellCoords.x = this.utils.isSingleCellExpandedRow(nextCellCoords.y)
17998
+ ? 0
17999
+ : nextCellCoords.x - this.utils.actionCellCount(currentCellCoords.y);
18000
+ }
18001
+ return nextCellCoords;
18002
+ }
18003
+ }
18004
+
18005
+ /*
18006
+ * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
18007
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
18008
+ * This software is released under MIT license.
18009
+ * The full license information can be found in LICENSE in the root directory of this project.
18010
+ */
18011
+ class ExpandedRowKeyNavigationStrategy extends DefaultKeyNavigationStrategy {
18012
+ keyUp(currentCellCoords) {
18013
+ const nextCellCoords = this.utils.createNextCellCoords(currentCellCoords);
18014
+ if (currentCellCoords.y === 0) {
18015
+ return nextCellCoords;
18016
+ }
18017
+ nextCellCoords.y = currentCellCoords.y - 1;
18018
+ if (!this.utils.isActionCell(currentCellCoords)) {
18019
+ if (this.utils.isRowReplaced(currentCellCoords.y)) {
17853
18020
  nextCellCoords.y = nextCellCoords.y - 1;
17854
- if (!this.isDetailsRow(nextCellCoords.y)) {
17855
- nextCellCoords.x = currentCellCoords.x + this.actionCellCount(nextCellCoords.y);
17856
- }
17857
18021
  }
17858
- else if (this.isDetailsRow(currentCellCoords.y) && !this.isDetailsRow(nextCellCoords.y)) {
17859
- nextCellCoords.x = currentCellCoords.x + this.actionCellCount(nextCellCoords.y);
18022
+ switch (true) {
18023
+ case this.utils.isDetailsRow(nextCellCoords.y):
18024
+ nextCellCoords.x = 0;
18025
+ break;
18026
+ case this.utils.isDetailsRow(currentCellCoords.y) === false:
18027
+ nextCellCoords.x = currentCellCoords.x;
18028
+ break;
18029
+ default:
18030
+ nextCellCoords.x = this.utils.actionCellCount(nextCellCoords.y);
17860
18031
  }
17861
- else if (!isActionCell && this.isDetailsRow(nextCellCoords.y)) {
17862
- nextCellCoords.x = currentCellCoords.x - this.actionCellCount(currentCellCoords.y);
18032
+ }
18033
+ else if (this.utils.isDetailsRow(nextCellCoords.y) && nextCellCoords.y > 0) {
18034
+ nextCellCoords.y = nextCellCoords.y - 1;
18035
+ }
18036
+ return nextCellCoords;
18037
+ }
18038
+ keyDown(currentCellCoords) {
18039
+ const nextCellCoords = this.utils.createNextCellCoords(currentCellCoords);
18040
+ const numOfRows = this.utils.rows ? this.utils.rows.length - 1 : 0;
18041
+ if (currentCellCoords.y >= numOfRows) {
18042
+ return nextCellCoords;
18043
+ }
18044
+ nextCellCoords.y = currentCellCoords.y + 1;
18045
+ if (!this.utils.isActionCell(currentCellCoords)) {
18046
+ if (this.utils.isRowReplaced(nextCellCoords.y)) {
18047
+ nextCellCoords.y = nextCellCoords.y + 1;
18048
+ }
18049
+ if (this.utils.isDetailsRow(nextCellCoords.y)) {
18050
+ nextCellCoords.x = 0;
18051
+ }
18052
+ else {
18053
+ nextCellCoords.x = this.utils.actionCellCount(nextCellCoords.y);
17863
18054
  }
17864
18055
  }
17865
- else if (e.key === Keys.ArrowDown && currentCellCoords.y < numOfRows) {
18056
+ else {
18057
+ nextCellCoords.y = nextCellCoords.y < numOfRows ? nextCellCoords.y + 1 : nextCellCoords.y;
18058
+ }
18059
+ return nextCellCoords;
18060
+ }
18061
+ keyLeft(currentCellCoords) {
18062
+ const nextCellCoords = this.utils.createNextCellCoords(currentCellCoords);
18063
+ if (!this.utils.isDetailsRow(currentCellCoords.y) && !this.utils.isRowReplaced(currentCellCoords.y)) {
18064
+ return super.keyLeft(currentCellCoords);
18065
+ }
18066
+ if (currentCellCoords.x !== 0) {
18067
+ nextCellCoords.x = currentCellCoords.x - 1;
18068
+ }
18069
+ else if (!this.utils.isActionCell(currentCellCoords)) {
18070
+ nextCellCoords.y = currentCellCoords.y - 1;
18071
+ nextCellCoords.x = this.utils.actionCellCount(nextCellCoords.y) - 1;
18072
+ }
18073
+ return nextCellCoords;
18074
+ }
18075
+ keyRight(currentCellCoords) {
18076
+ const nextCellCoords = this.utils.createNextCellCoords(currentCellCoords);
18077
+ if (!this.utils.isDetailsRow(currentCellCoords.y) && !this.utils.isRowReplaced(currentCellCoords.y)) {
18078
+ return super.keyRight(currentCellCoords);
18079
+ }
18080
+ // calculate numOfColumns based on header cells.
18081
+ const numOfColumns = this.utils.rows?.length - 1 ? this.utils.getCellsForRow(0).length - 1 : 0;
18082
+ if (currentCellCoords.x >= numOfColumns) {
18083
+ return nextCellCoords;
18084
+ }
18085
+ if (this.utils.isActionCell(currentCellCoords) &&
18086
+ currentCellCoords.x === this.utils.actionCellCount(currentCellCoords.x) - 1 &&
18087
+ this.utils.isRowReplaced(currentCellCoords.y) &&
18088
+ !this.utils.isDetailsRow(currentCellCoords.y)) {
17866
18089
  nextCellCoords.y = currentCellCoords.y + 1;
17867
- if (isSingleCellExpandedRow && !isActionCell) {
17868
- if (this.isRowReplaced(nextCellCoords.y)) {
18090
+ nextCellCoords.x = 0;
18091
+ }
18092
+ else {
18093
+ nextCellCoords.x = currentCellCoords.x + 1;
18094
+ }
18095
+ return nextCellCoords;
18096
+ }
18097
+ keyEnd(currentCellCoords, ctrlKey) {
18098
+ const nextCellCoords = this.utils.createNextCellCoords(currentCellCoords);
18099
+ if ((!this.utils.isDetailsRow(currentCellCoords.y) && !this.utils.isRowReplaced(currentCellCoords.y)) || ctrlKey) {
18100
+ return super.keyEnd(currentCellCoords, ctrlKey);
18101
+ }
18102
+ nextCellCoords.x = this.utils.getCellsForRow(currentCellCoords.y).length - 1;
18103
+ return nextCellCoords;
18104
+ }
18105
+ keyHome(currentCellCoords, ctrlKey) {
18106
+ const nextCellCoords = this.utils.createNextCellCoords(currentCellCoords);
18107
+ if (!this.utils.isDetailsRow(currentCellCoords.y) && !this.utils.isRowReplaced(currentCellCoords.y)) {
18108
+ return super.keyHome(currentCellCoords, ctrlKey);
18109
+ }
18110
+ nextCellCoords.x = 0;
18111
+ nextCellCoords.y = currentCellCoords.y - 1;
18112
+ if (ctrlKey) {
18113
+ nextCellCoords.y = 0;
18114
+ }
18115
+ return nextCellCoords;
18116
+ }
18117
+ keyPageUp(currentCellCoords) {
18118
+ const nextCellCoords = this.utils.createNextCellCoords(currentCellCoords);
18119
+ const itemsPerPage = this.utils.itemsPerPage;
18120
+ nextCellCoords.y = currentCellCoords.y - itemsPerPage > 0 ? currentCellCoords.y - itemsPerPage + 1 : 1;
18121
+ if (!this.utils.isActionCell(currentCellCoords)) {
18122
+ if (this.utils.isRowReplaced(nextCellCoords.y)) {
18123
+ if (!this.utils.isDetailsRow(nextCellCoords.y)) {
17869
18124
  nextCellCoords.y = nextCellCoords.y + 1;
18125
+ nextCellCoords.x = 0;
17870
18126
  }
17871
- if (this.isDetailsRow(nextCellCoords.y)) {
18127
+ }
18128
+ else if (!this.utils.isDetailsRow(currentCellCoords.y)) {
18129
+ if (this.utils.isDetailsRow(nextCellCoords.y)) {
17872
18130
  nextCellCoords.x = 0;
17873
18131
  }
17874
- else {
17875
- nextCellCoords.x = this.actionCellCount(nextCellCoords.y);
18132
+ }
18133
+ else if (this.utils.isDetailsRow(currentCellCoords.y)) {
18134
+ if (!this.utils.isDetailsRow(nextCellCoords.y)) {
18135
+ nextCellCoords.x = this.utils.actionCellCount(nextCellCoords.y);
17876
18136
  }
17877
- return nextCellCoords;
17878
18137
  }
17879
- if (isActionCell || this.isRowReplaced(nextCellCoords.y)) {
17880
- nextCellCoords.y = nextCellCoords.y + 1;
18138
+ }
18139
+ else if (this.utils.isDetailsRow(nextCellCoords.y)) {
18140
+ nextCellCoords.y = nextCellCoords.y - 1;
18141
+ }
18142
+ return nextCellCoords;
18143
+ }
18144
+ keyPageDown(currentCellCoords) {
18145
+ const nextCellCoords = this.utils.createNextCellCoords(currentCellCoords);
18146
+ const numOfRows = this.utils.rows ? this.utils.rows.length - 1 : 0;
18147
+ const itemsPerPage = this.utils.itemsPerPage;
18148
+ nextCellCoords.y = currentCellCoords.y + itemsPerPage >= numOfRows ? numOfRows : currentCellCoords.y + itemsPerPage;
18149
+ if (!this.utils.isActionCell(currentCellCoords)) {
18150
+ if (this.utils.isRowReplaced(nextCellCoords.y)) {
18151
+ if (nextCellCoords.y < numOfRows && !this.utils.isDetailsRow(nextCellCoords.y)) {
18152
+ nextCellCoords.y = nextCellCoords.y + 1;
18153
+ }
17881
18154
  }
17882
- else if (this.getCellsForRow(currentCellCoords.y).length > numOfColumns) {
17883
- nextCellCoords.x = currentCellCoords.x - this.actionCellCount(currentCellCoords.y);
18155
+ else if (this.utils.isDetailsRow(currentCellCoords.y) && !this.utils.isDetailsRow(nextCellCoords.y)) {
18156
+ nextCellCoords.x = currentCellCoords.x + this.utils.actionCellCount(nextCellCoords.y);
17884
18157
  }
17885
- else {
17886
- nextCellCoords.x = currentCellCoords.x + this.actionCellCount(nextCellCoords.y);
18158
+ else if (this.utils.isDetailsRow(nextCellCoords.y)) {
18159
+ nextCellCoords.x = 0;
17887
18160
  }
17888
18161
  }
17889
- else if (e.key === inlineStart) {
17890
- if (currentCellCoords.x !== 0) {
17891
- nextCellCoords.x = currentCellCoords.x - 1;
17892
- }
17893
- else if (!isActionCell) {
17894
- nextCellCoords.y = currentCellCoords.y - 1;
17895
- nextCellCoords.x = this.actionCellCount(nextCellCoords.y) - 1;
18162
+ else if (this.utils.isDetailsRow(nextCellCoords.y)) {
18163
+ nextCellCoords.y = nextCellCoords.y - 1;
18164
+ }
18165
+ return nextCellCoords;
18166
+ }
18167
+ }
18168
+
18169
+ /*
18170
+ * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
18171
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
18172
+ * This software is released under MIT license.
18173
+ * The full license information can be found in LICENSE in the root directory of this project.
18174
+ */
18175
+ class ExpandedColumnsRowKeyNavigationStrategy extends ExpandedRowKeyNavigationStrategy {
18176
+ keyUp(currentCellCoords) {
18177
+ const nextCellCoords = this.utils.createNextCellCoords(currentCellCoords);
18178
+ if (currentCellCoords.y === 0) {
18179
+ return nextCellCoords;
18180
+ }
18181
+ nextCellCoords.y = currentCellCoords.y - 1;
18182
+ if (this.utils.isSingleCellExpandedRow(nextCellCoords.y)) {
18183
+ return super.keyUp(currentCellCoords);
18184
+ }
18185
+ const isActionCell = this.utils.isActionCell(currentCellCoords);
18186
+ if (isActionCell && this.utils.isDetailsRow(nextCellCoords.y)) {
18187
+ nextCellCoords.y = nextCellCoords.y - 1;
18188
+ }
18189
+ else if (this.utils.isRowReplaced(nextCellCoords.y)) {
18190
+ nextCellCoords.y = nextCellCoords.y - 1;
18191
+ if (!this.utils.isDetailsRow(nextCellCoords.y)) {
18192
+ nextCellCoords.x = currentCellCoords.x + this.utils.actionCellCount(nextCellCoords.y);
17896
18193
  }
17897
18194
  }
17898
- else if (e.key === inlineEnd && currentCellCoords.x < numOfColumns) {
17899
- if (isActionCell &&
17900
- currentCellCoords.x === this.actionCellCount(currentCellCoords.x) - 1 &&
17901
- this.isRowReplaced(currentCellCoords.y) &&
17902
- !this.isDetailsRow(currentCellCoords.y)) {
17903
- nextCellCoords.y = currentCellCoords.y + 1;
17904
- nextCellCoords.x = 0;
18195
+ else if (this.utils.isDetailsRow(currentCellCoords.y) && !this.utils.isDetailsRow(nextCellCoords.y)) {
18196
+ nextCellCoords.x = currentCellCoords.x + this.utils.actionCellCount(nextCellCoords.y);
18197
+ }
18198
+ else if (!isActionCell && this.utils.isDetailsRow(nextCellCoords.y)) {
18199
+ nextCellCoords.x = currentCellCoords.x - this.utils.actionCellCount(currentCellCoords.y);
18200
+ }
18201
+ return nextCellCoords;
18202
+ }
18203
+ keyDown(currentCellCoords) {
18204
+ const nextCellCoords = this.utils.createNextCellCoords(currentCellCoords);
18205
+ const numOfRows = this.utils.rows ? this.utils.rows.length - 1 : 0;
18206
+ const numOfColumns = numOfRows ? this.utils.getCellsForRow(0).length - 1 : 0;
18207
+ if (currentCellCoords.y >= numOfRows) {
18208
+ return nextCellCoords;
18209
+ }
18210
+ nextCellCoords.y = currentCellCoords.y + 1;
18211
+ if (this.utils.isSingleCellExpandedRow(nextCellCoords.y)) {
18212
+ return super.keyDown(currentCellCoords);
18213
+ }
18214
+ if (!this.utils.isActionCell(currentCellCoords)) {
18215
+ if (this.utils.isRowReplaced(nextCellCoords.y)) {
18216
+ nextCellCoords.y = nextCellCoords.y < numOfRows ? nextCellCoords.y + 1 : nextCellCoords.y - 1;
17905
18217
  }
17906
- else {
17907
- nextCellCoords.x = currentCellCoords.x + 1;
18218
+ else if (this.utils.getCellsForRow(currentCellCoords.y).length > numOfColumns) {
18219
+ nextCellCoords.x = currentCellCoords.x - this.utils.actionCellCount(currentCellCoords.y);
17908
18220
  }
17909
- }
17910
- else if (e.key === Keys.End) {
17911
- nextCellCoords.x = this.getCellsForRow(currentCellCoords.y).length - 1;
17912
- if (e.ctrlKey) {
17913
- nextCellCoords.x = numOfColumns;
17914
- nextCellCoords.y = numOfRows;
18221
+ else {
18222
+ nextCellCoords.x = currentCellCoords.x + this.utils.actionCellCount(nextCellCoords.y);
17915
18223
  }
17916
18224
  }
17917
- else if (e.key === Keys.Home) {
17918
- nextCellCoords.x = 0;
17919
- nextCellCoords.y = currentCellCoords.y - 1;
17920
- if (e.ctrlKey) {
17921
- nextCellCoords.y = 0;
17922
- }
18225
+ else {
18226
+ nextCellCoords.y = nextCellCoords.y < numOfRows ? nextCellCoords.y + 1 : nextCellCoords.y - 1;
17923
18227
  }
17924
18228
  return nextCellCoords;
17925
18229
  }
17926
- getNextItemCoordinate(e, currentCellCoords) {
17927
- const { numOfRows, numOfColumns, inlineStart, inlineEnd, itemsPerPage, isActionCell, nextCellCoords } = this.getCalcVariables(currentCellCoords);
17928
- if (e.key === Keys.ArrowUp && currentCellCoords.y !== 0) {
17929
- nextCellCoords.y = currentCellCoords.y - 1;
17930
- if (this.isSingleCellExpandedRow(nextCellCoords.y) && !isActionCell && this.isDetailsRow(nextCellCoords.y)) {
17931
- nextCellCoords.x = 0;
17932
- return nextCellCoords;
17933
- }
17934
- if (this.isDetailsRow(nextCellCoords.y)) {
17935
- if (isActionCell) {
17936
- nextCellCoords.y = nextCellCoords.y - 1;
17937
- }
17938
- else {
17939
- nextCellCoords.x = nextCellCoords.x - this.actionCellCount(currentCellCoords.y);
18230
+ keyLeft(currentCellCoords) {
18231
+ return super.keyLeft(currentCellCoords);
18232
+ }
18233
+ keyRight(currentCellCoords) {
18234
+ return super.keyRight(currentCellCoords);
18235
+ }
18236
+ keyEnd(currentCellCoords, ctrlKey) {
18237
+ return super.keyEnd(currentCellCoords, ctrlKey);
18238
+ }
18239
+ keyHome(currentCellCoords, ctrlKey) {
18240
+ return super.keyHome(currentCellCoords, ctrlKey);
18241
+ }
18242
+ keyPageUp(currentCellCoords) {
18243
+ const nextCellCoords = this.utils.createNextCellCoords(currentCellCoords);
18244
+ const itemsPerPage = this.utils.itemsPerPage;
18245
+ nextCellCoords.y = currentCellCoords.y - itemsPerPage > 0 ? currentCellCoords.y - itemsPerPage + 1 : 1;
18246
+ if (this.utils.isSingleCellExpandedRow(nextCellCoords.y)) {
18247
+ return super.keyPageUp(currentCellCoords);
18248
+ }
18249
+ if (!this.utils.isActionCell(currentCellCoords)) {
18250
+ if (this.utils.isRowReplaced(nextCellCoords.y)) {
18251
+ if (!this.utils.isDetailsRow(nextCellCoords.y)) {
18252
+ nextCellCoords.y = nextCellCoords.y + 1;
18253
+ nextCellCoords.x = currentCellCoords.x + this.utils.actionCellCount(nextCellCoords.y);
17940
18254
  }
17941
18255
  }
17942
- }
17943
- else if (e.key === Keys.ArrowDown && currentCellCoords.y < numOfRows) {
17944
- nextCellCoords.y = currentCellCoords.y + 1;
17945
- if (this.isSingleCellExpandedRow(nextCellCoords.y) && !isActionCell && this.isRowReplaced(nextCellCoords.y)) {
17946
- nextCellCoords.x = 0;
17947
- nextCellCoords.y = nextCellCoords.y + 1;
17948
- return nextCellCoords;
18256
+ else if (this.utils.isDetailsRow(currentCellCoords.y) && !this.utils.isDetailsRow(nextCellCoords.y)) {
18257
+ nextCellCoords.x = currentCellCoords.x + this.utils.actionCellCount(nextCellCoords.y);
17949
18258
  }
17950
- if (!isActionCell && this.isRowReplaced(nextCellCoords.y)) {
17951
- nextCellCoords.y = nextCellCoords.y + 1;
17952
- nextCellCoords.x = nextCellCoords.x - this.actionCellCount(currentCellCoords.y);
18259
+ else if (this.utils.isDetailsRow(nextCellCoords.y)) {
18260
+ nextCellCoords.x = currentCellCoords.x - this.utils.actionCellCount(currentCellCoords.y);
17953
18261
  }
17954
18262
  }
17955
- else if (e.key === inlineStart && currentCellCoords.x !== 0) {
17956
- nextCellCoords.x = currentCellCoords.x - 1;
17957
- }
17958
- else if (e.key === inlineEnd && currentCellCoords.x < numOfColumns) {
17959
- nextCellCoords.x = currentCellCoords.x + 1;
18263
+ else if (this.utils.isDetailsRow(nextCellCoords.y)) {
18264
+ nextCellCoords.y = nextCellCoords.y - 1;
17960
18265
  }
17961
- else if (e.key === Keys.End) {
17962
- nextCellCoords.x = numOfColumns;
17963
- if (e.ctrlKey) {
17964
- nextCellCoords.y = numOfRows;
18266
+ return nextCellCoords;
18267
+ }
18268
+ keyPageDown(currentCellCoords) {
18269
+ const nextCellCoords = this.utils.createNextCellCoords(currentCellCoords);
18270
+ const numOfRows = this.utils.rows ? this.utils.rows.length - 1 : 0;
18271
+ const itemsPerPage = this.utils.itemsPerPage;
18272
+ nextCellCoords.y = currentCellCoords.y + itemsPerPage >= numOfRows ? numOfRows : currentCellCoords.y + itemsPerPage;
18273
+ if (this.utils.isSingleCellExpandedRow(nextCellCoords.y)) {
18274
+ return super.keyPageDown(currentCellCoords);
18275
+ }
18276
+ if (!this.utils.isActionCell(currentCellCoords)) {
18277
+ if (this.utils.isRowReplaced(nextCellCoords.y) && !this.utils.isDetailsRow(nextCellCoords.y)) {
18278
+ if (nextCellCoords.y < numOfRows) {
18279
+ nextCellCoords.y = nextCellCoords.y + 1;
18280
+ nextCellCoords.x = currentCellCoords.x + this.utils.actionCellCount(nextCellCoords.y);
18281
+ }
17965
18282
  }
17966
- }
17967
- else if (e.key === Keys.Home) {
17968
- nextCellCoords.x = 0;
17969
- if (e.ctrlKey) {
17970
- nextCellCoords.y = 0;
18283
+ else if (this.utils.isDetailsRow(currentCellCoords.y) && !this.utils.isDetailsRow(nextCellCoords.y)) {
18284
+ nextCellCoords.x = currentCellCoords.x + this.utils.actionCellCount(nextCellCoords.y);
18285
+ }
18286
+ else if (this.utils.isDetailsRow(nextCellCoords.y)) {
18287
+ nextCellCoords.x = currentCellCoords.x - this.utils.actionCellCount(currentCellCoords.y);
17971
18288
  }
17972
18289
  }
17973
- else if (e.key === Keys.PageUp) {
17974
- nextCellCoords.y = currentCellCoords.y - itemsPerPage > 0 ? currentCellCoords.y - itemsPerPage + 1 : 1;
17975
- }
17976
- else if (e.key === Keys.PageDown) {
17977
- nextCellCoords.y =
17978
- currentCellCoords.y + itemsPerPage < numOfRows ? currentCellCoords.y + itemsPerPage : numOfRows;
18290
+ else if (this.utils.isDetailsRow(nextCellCoords.y)) {
18291
+ nextCellCoords.y = nextCellCoords.y - 1;
17979
18292
  }
17980
18293
  return nextCellCoords;
17981
18294
  }
17982
- getCalcVariables(currentCellCoords) {
17983
- const numOfRows = this.rows ? this.rows.length - 1 : 0;
17984
- // calculate numOfColumns based on header cells.
17985
- const numOfColumns = numOfRows ? this.getCellsForRow(0).length - 1 : 0;
17986
- const dir = this.host.dir;
17987
- const inlineStart = dir === 'rtl' ? Keys.ArrowRight : Keys.ArrowLeft;
17988
- const inlineEnd = dir === 'rtl' ? Keys.ArrowLeft : Keys.ArrowRight;
17989
- const itemsPerPage = Math.floor(this.host?.querySelector('.datagrid').clientHeight / this.rows[0].clientHeight) - 1 || 0;
17990
- const isActionCell = this.isActionCell(currentCellCoords);
17991
- const nextCellCoords = {
17992
- x: currentCellCoords.x,
17993
- y: currentCellCoords.y,
17994
- };
17995
- return { numOfRows, numOfColumns, inlineStart, inlineEnd, itemsPerPage, isActionCell, nextCellCoords };
18295
+ }
18296
+
18297
+ /*
18298
+ * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
18299
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
18300
+ * This software is released under MIT license.
18301
+ * The full license information can be found in LICENSE in the root directory of this project.
18302
+ */
18303
+ class KeyNavigationUtils {
18304
+ constructor(host, config) {
18305
+ this.host = host;
18306
+ this.config = config;
18307
+ }
18308
+ get grid() {
18309
+ return this.host?.querySelector(this.config.keyGrid);
18310
+ }
18311
+ get rows() {
18312
+ return this.host?.querySelectorAll(this.config.keyGridRows);
17996
18313
  }
17997
- getCurrentCellCoordinates() {
18314
+ get cells() {
18315
+ return this.host?.querySelectorAll(this.config.keyGridCells);
18316
+ }
18317
+ get currentCellCoordinates() {
17998
18318
  const currentCell = this.cells ? Array.from(this.cells).find(i => i.getAttribute('tabindex') === '0') : null;
17999
18319
  const currentRow = currentCell ? currentCell.closest(this.config.keyGridRows) : null;
18000
18320
  const coordinates = {
@@ -18005,6 +18325,48 @@ class KeyNavigationGridController {
18005
18325
  };
18006
18326
  return coordinates;
18007
18327
  }
18328
+ get averageRowHeight() {
18329
+ const heightSum = Array.from(this.rows.values()).reduce((sum, row) => {
18330
+ return sum + row.clientHeight;
18331
+ }, 0);
18332
+ return Math.round(heightSum / this.rows.length);
18333
+ }
18334
+ get itemsPerPage() {
18335
+ return Math.floor(this.host?.querySelector('.datagrid').clientHeight / this.averageRowHeight) - 1 || 0;
18336
+ }
18337
+ setAriaRowIndexTo(cellCoords) {
18338
+ let ariaRowIndex = this.rows[cellCoords.y].getAttribute('aria-rowindex');
18339
+ if (!ariaRowIndex) {
18340
+ ariaRowIndex = this.rows[cellCoords.y - 1].getAttribute('aria-rowindex');
18341
+ }
18342
+ cellCoords.ariaRowIndex = ariaRowIndex;
18343
+ }
18344
+ getNextItemCoordinate(e) {
18345
+ const currentCellCoords = this.currentCellCoordinates;
18346
+ const strategy = this.getNavStrategy(currentCellCoords);
18347
+ const inlineStart = this.host.dir === 'rtl' ? Keys.ArrowRight : Keys.ArrowLeft;
18348
+ const inlineEnd = this.host.dir === 'rtl' ? Keys.ArrowLeft : Keys.ArrowRight;
18349
+ switch (e.key) {
18350
+ case Keys.ArrowUp:
18351
+ return strategy.keyUp(currentCellCoords);
18352
+ case Keys.ArrowDown:
18353
+ return strategy.keyDown(currentCellCoords);
18354
+ case inlineStart:
18355
+ return strategy.keyLeft(currentCellCoords);
18356
+ case inlineEnd:
18357
+ return strategy.keyRight(currentCellCoords);
18358
+ case Keys.Home:
18359
+ return strategy.keyHome(currentCellCoords, e.ctrlKey);
18360
+ case Keys.End:
18361
+ return strategy.keyEnd(currentCellCoords, e.ctrlKey);
18362
+ case Keys.PageUp:
18363
+ return strategy.keyPageUp(currentCellCoords);
18364
+ case Keys.PageDown:
18365
+ return strategy.keyPageDown(currentCellCoords);
18366
+ default:
18367
+ return currentCellCoords;
18368
+ }
18369
+ }
18008
18370
  getCellsForRow(index) {
18009
18371
  return this.rows[index].querySelectorAll(this.config.keyGridCells);
18010
18372
  }
@@ -18019,10 +18381,7 @@ class KeyNavigationGridController {
18019
18381
  return !!this.rows[index].closest('clr-dg-row.datagrid-row-replaced');
18020
18382
  }
18021
18383
  isSingleCellExpandedRow(index) {
18022
- const row = this.rows[index].classList.contains('datagrid-row-detail')
18023
- ? this.rows[index]
18024
- : this.rows[index].querySelector('.datagrid-row-detail');
18025
- return row?.querySelectorAll(this.config.keyGridCells).length === 1;
18384
+ return this.rows[index]?.querySelectorAll(this.config.keyGridCells).length === 1;
18026
18385
  }
18027
18386
  actionCellCount(index) {
18028
18387
  return this.actionCellsAsArray(index).length;
@@ -18033,6 +18392,165 @@ class KeyNavigationGridController {
18033
18392
  isActionCell(cellCoords) {
18034
18393
  return !!this.actionCellsAsArray(cellCoords.y)[cellCoords.x];
18035
18394
  }
18395
+ createNextCellCoords(cellCoords) {
18396
+ return {
18397
+ x: cellCoords.x,
18398
+ y: cellCoords.y,
18399
+ };
18400
+ }
18401
+ getNavStrategy(currentCellCoords) {
18402
+ switch (true) {
18403
+ case this.isSingleCellExpandedRow(currentCellCoords.y):
18404
+ return new ExpandedRowKeyNavigationStrategy(this);
18405
+ case this.isDetailsRow(currentCellCoords.y):
18406
+ case this.isExpandedRow(currentCellCoords.y):
18407
+ return new ExpandedColumnsRowKeyNavigationStrategy(this);
18408
+ default:
18409
+ return new DefaultKeyNavigationStrategy(this);
18410
+ }
18411
+ }
18412
+ }
18413
+
18414
+ /*
18415
+ * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
18416
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
18417
+ * This software is released under MIT license.
18418
+ * The full license information can be found in LICENSE in the root directory of this project.
18419
+ */
18420
+ const actionableItemSelectors = [
18421
+ 'a[href]',
18422
+ 'area[href]',
18423
+ 'input:not([disabled])',
18424
+ 'button:not([disabled])',
18425
+ 'select:not([disabled])',
18426
+ 'textarea:not([disabled])',
18427
+ 'iframe',
18428
+ 'object',
18429
+ 'embed',
18430
+ '[contenteditable=true]',
18431
+ '[role=button]:not([disabled])',
18432
+ ];
18433
+ function getTabbableItems(el) {
18434
+ const tabbableItemSelectors = [...actionableItemSelectors, '[tabindex="0"]:not([disabled])'];
18435
+ const tabbableSelector = tabbableItemSelectors.join(',');
18436
+ return Array.from(el.querySelectorAll(tabbableSelector));
18437
+ }
18438
+ function isActionableItem(el) {
18439
+ const actionableSelector = actionableItemSelectors.join(',');
18440
+ return el.matches(actionableSelector);
18441
+ }
18442
+ class KeyNavigationGridController {
18443
+ constructor(zone) {
18444
+ this.zone = zone;
18445
+ this.nextCellCoordsEmitter = new EventEmitter(false);
18446
+ this.skipItemFocus = false;
18447
+ this.preventScrollOnFocus = false;
18448
+ this.config = {
18449
+ keyGridRows: '[role=row]:not(.datagrid-placeholder):not([style*="display: none"])',
18450
+ keyGridCells: '[role=gridcell]:not(.datagrid-hidden-column):not(.datagrid-placeholder-content), [role=columnheader]:not(.datagrid-hidden-column):not(.datagrid-placeholder-content), .datagrid-detail-caret',
18451
+ keyGrid: '[role=grid]',
18452
+ };
18453
+ this.listenersAdded = false;
18454
+ this.destroy$ = new Subject();
18455
+ }
18456
+ ngOnDestroy() {
18457
+ this.destroy$.next();
18458
+ this.destroy$.complete();
18459
+ }
18460
+ addListeners() {
18461
+ if (this.listenersAdded) {
18462
+ return;
18463
+ }
18464
+ this.zone.runOutsideAngular(() => {
18465
+ fromEvent(this.keyNavUtils.grid, 'mousedown')
18466
+ .pipe(takeUntil(this.destroy$))
18467
+ .subscribe((e) => {
18468
+ // preserve right click for context menus & keyboard mouse control https://apple.stackexchange.com/questions/32715/how-do-i-open-the-context-menu-from-a-mac-keyboard
18469
+ if (e.buttons === 1 && !e.ctrlKey) {
18470
+ const activeCell = this.keyNavUtils.cells
18471
+ ? Array.from(this.keyNavUtils.cells).find(c => c === e.target || c === e.target.closest(this.config.keyGridCells))
18472
+ : null;
18473
+ if (activeCell) {
18474
+ this.setActiveCell(activeCell);
18475
+ if (!isActionableItem(e.target)) {
18476
+ this.focusElement(activeCell);
18477
+ }
18478
+ }
18479
+ }
18480
+ });
18481
+ fromEvent(this.keyNavUtils.grid, 'wheel')
18482
+ .pipe(takeUntil(this.destroy$))
18483
+ .subscribe(() => {
18484
+ this.nextCellCoordsEmitter.emit(null);
18485
+ });
18486
+ fromEvent(this.keyNavUtils.grid, 'keydown')
18487
+ .pipe(takeUntil(this.destroy$))
18488
+ .subscribe((e) => {
18489
+ // Skip column resize events
18490
+ if (e.target.classList.contains('drag-handle') &&
18491
+ (e.key === Keys.ArrowLeft || e.key === Keys.ArrowRight)) {
18492
+ return;
18493
+ }
18494
+ if (e.key === Keys.ArrowUp ||
18495
+ e.key === Keys.ArrowDown ||
18496
+ e.key === Keys.ArrowLeft ||
18497
+ e.key === Keys.ArrowRight ||
18498
+ e.key === Keys.End ||
18499
+ e.key === Keys.Home ||
18500
+ e.key === Keys.PageUp ||
18501
+ e.key === Keys.PageDown) {
18502
+ const nextCellCoords = this.keyNavUtils.getNextItemCoordinate(e);
18503
+ if (nextCellCoords.y > 0 &&
18504
+ (e.key === Keys.ArrowUp || e.key === Keys.ArrowDown || e.key === Keys.PageUp || e.key === Keys.PageDown)) {
18505
+ this.keyNavUtils.setAriaRowIndexTo(nextCellCoords);
18506
+ this.nextCellCoordsEmitter.emit(nextCellCoords);
18507
+ }
18508
+ const activeItem = this.keyNavUtils.rows
18509
+ ? Array.from(this.keyNavUtils.getCellsForRow(nextCellCoords.y))[nextCellCoords.x]
18510
+ : null;
18511
+ if (activeItem) {
18512
+ this.setActiveCell(activeItem);
18513
+ this.focusElement(activeItem, { preventScroll: this.preventScrollOnFocus });
18514
+ }
18515
+ e.preventDefault();
18516
+ }
18517
+ });
18518
+ });
18519
+ this.listenersAdded = true;
18520
+ }
18521
+ initializeKeyGrid(host) {
18522
+ this.keyNavUtils = new KeyNavigationUtils(host, this.config);
18523
+ this.addListeners();
18524
+ this.resetKeyGrid();
18525
+ }
18526
+ resetKeyGrid() {
18527
+ this.keyNavUtils.cells?.forEach((i) => i.setAttribute('tabindex', '-1'));
18528
+ const firstCell = this.keyNavUtils.cells ? this.keyNavUtils.cells[0] : null;
18529
+ firstCell?.setAttribute('tabindex', '0');
18530
+ }
18531
+ setActiveCell(activeCell) {
18532
+ const prior = this.keyNavUtils.cells
18533
+ ? Array.from(this.keyNavUtils.cells).find(c => c.getAttribute('tabindex') === '0')
18534
+ : null;
18535
+ if (prior) {
18536
+ prior.setAttribute('tabindex', '-1');
18537
+ }
18538
+ activeCell.setAttribute('tabindex', '0');
18539
+ }
18540
+ focusElement(activeCell, options = { preventScroll: false }) {
18541
+ if (this.skipItemFocus) {
18542
+ return;
18543
+ }
18544
+ let elementToFocus;
18545
+ if (activeCell.getAttribute('role') === 'columnheader') {
18546
+ elementToFocus = activeCell;
18547
+ }
18548
+ else {
18549
+ const tabbableElements = getTabbableItems(activeCell);
18550
+ elementToFocus = tabbableElements.length ? tabbableElements[0] : activeCell;
18551
+ }
18552
+ elementToFocus.focus(options);
18553
+ }
18036
18554
  }
18037
18555
  KeyNavigationGridController.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: KeyNavigationGridController, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
18038
18556
  KeyNavigationGridController.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: KeyNavigationGridController });
@@ -18103,35 +18621,17 @@ class ClrDatagridFilter extends DatagridFilterRegistrar {
18103
18621
  get active() {
18104
18622
  return !!this.filter && this.filter.isActive();
18105
18623
  }
18106
- ngOnChanges() {
18107
- setTimeout(() => {
18108
- this.setToggleButtonAriaLabel();
18109
- });
18110
- }
18111
18624
  ngOnDestroy() {
18112
18625
  super.ngOnDestroy();
18113
18626
  this.subs.forEach(sub => sub.unsubscribe());
18114
18627
  }
18115
- /**
18116
- * This is not in a getter to prevent "expression has changed after it was checked" errors.
18117
- * And it's more performant this way since it only runs on change.
18118
- */
18119
- setToggleButtonAriaLabel() {
18120
- const columnElement = this.elementRef.nativeElement?.closest('clr-dg-column');
18121
- const columnTitleElement = columnElement?.querySelector('.datagrid-column-title');
18122
- const columnTitle = columnTitleElement?.textContent.trim().toLocaleLowerCase();
18123
- this.toggleButtonAriaLabel = this.commonStrings.parse(this.commonStrings.keys.datagridFilterAriaLabel, {
18124
- COLUMN: columnTitle || '',
18125
- });
18126
- }
18127
18628
  }
18128
18629
  ClrDatagridFilter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridFilter, deps: [{ token: FiltersProvider }, { token: ClrCommonStringsService }, { token: ClrPopoverToggleService }, { token: PLATFORM_ID }, { token: i0.ElementRef }, { token: KeyNavigationGridController, optional: true }], target: i0.ɵɵFactoryTarget.Component });
18129
- ClrDatagridFilter.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridFilter, selector: "clr-dg-filter", inputs: { open: ["clrDgFilterOpen", "open"], customFilter: ["clrDgFilter", "customFilter"] }, outputs: { openChange: "clrDgFilterOpenChange" }, providers: [{ provide: CustomFilter, useExisting: ClrDatagridFilter }], viewQueries: [{ propertyName: "anchor", first: true, predicate: ["anchor"], descendants: true, read: ElementRef }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: `
18630
+ ClrDatagridFilter.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridFilter, selector: "clr-dg-filter", inputs: { open: ["clrDgFilterOpen", "open"], customFilter: ["clrDgFilter", "customFilter"] }, outputs: { openChange: "clrDgFilterOpenChange" }, providers: [{ provide: CustomFilter, useExisting: ClrDatagridFilter }], viewQueries: [{ propertyName: "anchor", first: true, predicate: ["anchor"], descendants: true, read: ElementRef }], usesInheritance: true, ngImport: i0, template: `
18130
18631
  <button
18131
18632
  class="datagrid-filter-toggle"
18132
18633
  type="button"
18133
18634
  #anchor
18134
- [attr.aria-label]="toggleButtonAriaLabel"
18135
18635
  [attr.aria-expanded]="ariaExpanded"
18136
18636
  [attr.aria-controls]="popoverId"
18137
18637
  clrPopoverAnchor
@@ -18174,7 +18674,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
18174
18674
  class="datagrid-filter-toggle"
18175
18675
  type="button"
18176
18676
  #anchor
18177
- [attr.aria-label]="toggleButtonAriaLabel"
18178
18677
  [attr.aria-expanded]="ariaExpanded"
18179
18678
  [attr.aria-controls]="popoverId"
18180
18679
  clrPopoverAnchor
@@ -19664,13 +20163,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
19664
20163
  * The full license information can be found in LICENSE in the root directory of this project.
19665
20164
  */
19666
20165
  class ClrDatagridColumn extends DatagridFilterRegistrar {
19667
- constructor(el, _sort, filters, vcr, detailService, changeDetectorRef) {
20166
+ constructor(el, _sort, filters, vcr, detailService, changeDetectorRef, commonStrings) {
19668
20167
  super(filters);
19669
20168
  this.el = el;
19670
20169
  this._sort = _sort;
19671
20170
  this.vcr = vcr;
19672
20171
  this.detailService = detailService;
19673
20172
  this.changeDetectorRef = changeDetectorRef;
20173
+ this.commonStrings = commonStrings;
19674
20174
  this.sortOrderChange = new EventEmitter();
19675
20175
  this.filterValueChange = new EventEmitter();
19676
20176
  /**
@@ -19730,18 +20230,14 @@ class ClrDatagridColumn extends DatagridFilterRegistrar {
19730
20230
  if (typeof comparator === 'string') {
19731
20231
  this._sortBy = new DatagridPropertyComparator(comparator);
19732
20232
  }
20233
+ else if (comparator) {
20234
+ this._sortBy = comparator;
20235
+ }
20236
+ else if (this.field) {
20237
+ this._sortBy = new DatagridPropertyComparator(this.field);
20238
+ }
19733
20239
  else {
19734
- if (comparator) {
19735
- this._sortBy = comparator;
19736
- }
19737
- else {
19738
- if (this.field) {
19739
- this._sortBy = new DatagridPropertyComparator(this.field);
19740
- }
19741
- else {
19742
- delete this._sortBy;
19743
- }
19744
- }
20240
+ delete this._sortBy;
19745
20241
  }
19746
20242
  }
19747
20243
  get sortOrder() {
@@ -19844,6 +20340,9 @@ class ClrDatagridColumn extends DatagridFilterRegistrar {
19844
20340
  ngOnInit() {
19845
20341
  this.wrappedInjector = new HostWrapper(WrappedColumn, this.vcr);
19846
20342
  }
20343
+ ngAfterViewInit() {
20344
+ this.setFilterToggleAriaLabel();
20345
+ }
19847
20346
  ngOnChanges(changes) {
19848
20347
  if (changes.colType &&
19849
20348
  changes.colType.currentValue &&
@@ -19883,6 +20382,14 @@ class ClrDatagridColumn extends DatagridFilterRegistrar {
19883
20382
  }
19884
20383
  });
19885
20384
  }
20385
+ setFilterToggleAriaLabel() {
20386
+ const filterToggle = this.el.nativeElement.querySelector('.datagrid-filter-toggle');
20387
+ if (filterToggle) {
20388
+ filterToggle.ariaLabel = this.commonStrings.parse(this.commonStrings.keys.datagridFilterAriaLabel, {
20389
+ COLUMN: this?.titleContainer?.nativeElement.textContent.trim().toLocaleLowerCase(),
20390
+ });
20391
+ }
20392
+ }
19886
20393
  listenForSortingChanges() {
19887
20394
  return this._sort.change.subscribe(sort => {
19888
20395
  // Need to manually mark the component to be checked
@@ -19912,10 +20419,10 @@ class ClrDatagridColumn extends DatagridFilterRegistrar {
19912
20419
  }
19913
20420
  }
19914
20421
  }
19915
- ClrDatagridColumn.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridColumn, deps: [{ token: i0.ElementRef }, { token: Sort }, { token: FiltersProvider }, { token: i0.ViewContainerRef }, { token: DetailService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
19916
- ClrDatagridColumn.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridColumn, selector: "clr-dg-column", inputs: { filterStringPlaceholder: ["clrFilterStringPlaceholder", "filterStringPlaceholder"], filterNumberMaxPlaceholder: ["clrFilterNumberMaxPlaceholder", "filterNumberMaxPlaceholder"], filterNumberMinPlaceholder: ["clrFilterNumberMinPlaceholder", "filterNumberMinPlaceholder"], colType: ["clrDgColType", "colType"], field: ["clrDgField", "field"], sortBy: ["clrDgSortBy", "sortBy"], sortOrder: ["clrDgSortOrder", "sortOrder"], updateFilterValue: ["clrFilterValue", "updateFilterValue"] }, outputs: { sortOrderChange: "clrDgSortOrderChange", filterValueChange: "clrFilterValueChange" }, host: { attributes: { "role": "columnheader" }, properties: { "class.datagrid-column": "true", "attr.aria-sort": "ariaSort" } }, queries: [{ propertyName: "projectedFilter", first: true, predicate: CustomFilter, descendants: true }], usesInheritance: true, usesOnChanges: true, hostDirectives: [{ directive: ClrPopoverHostDirective }], ngImport: i0, template: `
20422
+ ClrDatagridColumn.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridColumn, deps: [{ token: i0.ElementRef }, { token: Sort }, { token: FiltersProvider }, { token: i0.ViewContainerRef }, { token: DetailService }, { token: i0.ChangeDetectorRef }, { token: ClrCommonStringsService }], target: i0.ɵɵFactoryTarget.Component });
20423
+ ClrDatagridColumn.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridColumn, selector: "clr-dg-column", inputs: { filterStringPlaceholder: ["clrFilterStringPlaceholder", "filterStringPlaceholder"], filterNumberMaxPlaceholder: ["clrFilterNumberMaxPlaceholder", "filterNumberMaxPlaceholder"], filterNumberMinPlaceholder: ["clrFilterNumberMinPlaceholder", "filterNumberMinPlaceholder"], colType: ["clrDgColType", "colType"], field: ["clrDgField", "field"], sortBy: ["clrDgSortBy", "sortBy"], sortOrder: ["clrDgSortOrder", "sortOrder"], updateFilterValue: ["clrFilterValue", "updateFilterValue"] }, outputs: { sortOrderChange: "clrDgSortOrderChange", filterValueChange: "clrFilterValueChange" }, host: { attributes: { "role": "columnheader" }, properties: { "class.datagrid-column": "true", "attr.aria-sort": "ariaSort" } }, queries: [{ propertyName: "projectedFilter", first: true, predicate: CustomFilter, descendants: true }], viewQueries: [{ propertyName: "titleContainer", first: true, predicate: ["titleContainer"], descendants: true, read: ElementRef }], usesInheritance: true, usesOnChanges: true, hostDirectives: [{ directive: ClrPopoverHostDirective }], ngImport: i0, template: `
19917
20424
  <div class="datagrid-column-flex">
19918
- <button class="datagrid-column-title" *ngIf="sortable" (click)="sort()" type="button">
20425
+ <button class="datagrid-column-title" *ngIf="sortable" (click)="sort()" type="button" #titleContainer>
19919
20426
  <ng-container *ngTemplateOutlet="columnTitle"></ng-container>
19920
20427
  <cds-icon
19921
20428
  *ngIf="sortDirection"
@@ -19947,7 +20454,7 @@ ClrDatagridColumn.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", vers
19947
20454
  <ng-content></ng-content>
19948
20455
  </ng-template>
19949
20456
 
19950
- <span class="datagrid-column-title" *ngIf="!sortable">
20457
+ <span class="datagrid-column-title" *ngIf="!sortable" #titleContainer>
19951
20458
  <ng-container *ngTemplateOutlet="columnTitle"></ng-container>
19952
20459
  </span>
19953
20460
 
@@ -19960,7 +20467,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
19960
20467
  selector: 'clr-dg-column',
19961
20468
  template: `
19962
20469
  <div class="datagrid-column-flex">
19963
- <button class="datagrid-column-title" *ngIf="sortable" (click)="sort()" type="button">
20470
+ <button class="datagrid-column-title" *ngIf="sortable" (click)="sort()" type="button" #titleContainer>
19964
20471
  <ng-container *ngTemplateOutlet="columnTitle"></ng-container>
19965
20472
  <cds-icon
19966
20473
  *ngIf="sortDirection"
@@ -19992,7 +20499,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
19992
20499
  <ng-content></ng-content>
19993
20500
  </ng-template>
19994
20501
 
19995
- <span class="datagrid-column-title" *ngIf="!sortable">
20502
+ <span class="datagrid-column-title" *ngIf="!sortable" #titleContainer>
19996
20503
  <ng-container *ngTemplateOutlet="columnTitle"></ng-container>
19997
20504
  </span>
19998
20505
 
@@ -20007,7 +20514,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
20007
20514
  },
20008
20515
  changeDetection: ChangeDetectionStrategy.OnPush,
20009
20516
  }]
20010
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: Sort }, { type: FiltersProvider }, { type: i0.ViewContainerRef }, { type: DetailService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { filterStringPlaceholder: [{
20517
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: Sort }, { type: FiltersProvider }, { type: i0.ViewContainerRef }, { type: DetailService }, { type: i0.ChangeDetectorRef }, { type: ClrCommonStringsService }]; }, propDecorators: { filterStringPlaceholder: [{
20011
20518
  type: Input,
20012
20519
  args: ['clrFilterStringPlaceholder']
20013
20520
  }], filterNumberMaxPlaceholder: [{
@@ -20022,6 +20529,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
20022
20529
  }], filterValueChange: [{
20023
20530
  type: Output,
20024
20531
  args: ['clrFilterValueChange']
20532
+ }], titleContainer: [{
20533
+ type: ViewChild,
20534
+ args: ['titleContainer', { read: ElementRef }]
20025
20535
  }], colType: [{
20026
20536
  type: Input,
20027
20537
  args: ['clrDgColType']
@@ -20124,6 +20634,10 @@ class Items {
20124
20634
  this._pageSub.unsubscribe();
20125
20635
  }
20126
20636
  }
20637
+ smartenDown() {
20638
+ this._smart = false;
20639
+ this.destroy();
20640
+ }
20127
20641
  smartenUp() {
20128
20642
  this._smart = true;
20129
20643
  /*
@@ -20895,77 +21409,23 @@ class ClrDatagridSelectionCellDirective {
20895
21409
  if (this.selection.rowSelectionMode) {
20896
21410
  return;
20897
21411
  }
20898
- // If click was outside the label/input, forward the click to the input.
20899
- if (event.target.tagName !== 'LABEL' && event.target.tagName !== 'INPUT') {
20900
- event.target.querySelector('input')?.click();
20901
- }
20902
- }
20903
- }
20904
- ClrDatagridSelectionCellDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridSelectionCellDirective, deps: [{ token: Selection }], target: i0.ɵɵFactoryTarget.Directive });
20905
- ClrDatagridSelectionCellDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridSelectionCellDirective, selector: ".datagrid-select", host: { listeners: { "click": "onSelectionCellClick($event)" } }, ngImport: i0 });
20906
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridSelectionCellDirective, decorators: [{
20907
- type: Directive,
20908
- args: [{
20909
- selector: '.datagrid-select',
20910
- }]
20911
- }], ctorParameters: function () { return [{ type: Selection }]; }, propDecorators: { onSelectionCellClick: [{
20912
- type: HostListener,
20913
- args: ['click', ['$event']]
20914
- }] } });
20915
-
20916
- /*
20917
- * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
20918
- * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
20919
- * This software is released under MIT license.
20920
- * The full license information can be found in LICENSE in the root directory of this project.
20921
- */
20922
- class DatagridCellRenderer {
20923
- constructor(el, renderer, organizer) {
20924
- this.el = el;
20925
- this.renderer = renderer;
20926
- this.subscriptions = [];
20927
- this.subscriptions.push(organizer.filterRenderSteps(DatagridRenderStep.CLEAR_WIDTHS).subscribe(() => this.clearWidth()));
20928
- }
20929
- ngOnDestroy() {
20930
- this.subscriptions.forEach(sub => sub.unsubscribe());
20931
- if (this.stateSubscription) {
20932
- this.stateSubscription.unsubscribe();
20933
- }
20934
- }
20935
- resetState(state) {
20936
- this.setWidth(state);
20937
- this.setHidden(state);
20938
- }
20939
- setWidth(state) {
20940
- if (state.strictWidth) {
20941
- this.renderer.addClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
20942
- }
20943
- else {
20944
- this.renderer.removeClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
20945
- }
20946
- this.renderer.setStyle(this.el.nativeElement, 'width', state.width + 'px');
20947
- }
20948
- setHidden(state) {
20949
- if (state.hidden) {
20950
- this.renderer.addClass(this.el.nativeElement, HIDDEN_COLUMN_CLASS);
20951
- }
20952
- else {
20953
- this.renderer.removeClass(this.el.nativeElement, HIDDEN_COLUMN_CLASS);
21412
+ // If click was outside the label/input, forward the click to the input.
21413
+ if (event.target.tagName !== 'LABEL' && event.target.tagName !== 'INPUT') {
21414
+ event.target.querySelector('input')?.click();
20954
21415
  }
20955
21416
  }
20956
- clearWidth() {
20957
- this.renderer.removeClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
20958
- this.renderer.setStyle(this.el.nativeElement, 'width', null);
20959
- }
20960
21417
  }
20961
- 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 });
20962
- DatagridCellRenderer.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: DatagridCellRenderer, selector: "clr-dg-cell", ngImport: i0 });
20963
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: DatagridCellRenderer, decorators: [{
21418
+ ClrDatagridSelectionCellDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridSelectionCellDirective, deps: [{ token: Selection }], target: i0.ɵɵFactoryTarget.Directive });
21419
+ ClrDatagridSelectionCellDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridSelectionCellDirective, selector: ".datagrid-select", host: { listeners: { "click": "onSelectionCellClick($event)" } }, ngImport: i0 });
21420
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridSelectionCellDirective, decorators: [{
20964
21421
  type: Directive,
20965
21422
  args: [{
20966
- selector: 'clr-dg-cell',
21423
+ selector: '.datagrid-select',
20967
21424
  }]
20968
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: DatagridRenderOrganizer }]; } });
21425
+ }], ctorParameters: function () { return [{ type: Selection }]; }, propDecorators: { onSelectionCellClick: [{
21426
+ type: HostListener,
21427
+ args: ['click', ['$event']]
21428
+ }] } });
20969
21429
 
20970
21430
  /*
20971
21431
  * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
@@ -20983,6 +21443,7 @@ class ClrDatagridRow {
20983
21443
  this.detailService = detailService;
20984
21444
  this.displayMode = displayMode;
20985
21445
  this.vcr = vcr;
21446
+ this.el = el;
20986
21447
  this.commonStrings = commonStrings;
20987
21448
  this.items = items;
20988
21449
  this.document = document;
@@ -21125,6 +21586,16 @@ class ClrDatagridRow {
21125
21586
  }
21126
21587
  if (viewChange === DatagridDisplayMode.CALCULATE) {
21127
21588
  this.displayCells = false;
21589
+ // Inserts a fixed cell if any of these conditions are true.
21590
+ const fixedCellConditions = [
21591
+ this.selection.selectionType !== this.SELECTION_TYPE.None,
21592
+ this.rowActionService.hasActionableRow,
21593
+ this.globalExpandable.hasExpandableRow,
21594
+ this.detailService.enabled,
21595
+ ];
21596
+ fixedCellConditions
21597
+ .filter(Boolean)
21598
+ .forEach(() => this._calculatedCells.insert(this._fixedCellTemplate.createEmbeddedView(null)));
21128
21599
  this.dgCells.forEach(cell => {
21129
21600
  if (!cell._view.destroyed) {
21130
21601
  this._calculatedCells.insert(cell._view);
@@ -21166,7 +21637,7 @@ class ClrDatagridRow {
21166
21637
  * selection browser functionality, which is inconsistently implemented in browsers anyway.
21167
21638
  */
21168
21639
  clearRanges(event) {
21169
- if (event.shiftKey) {
21640
+ if (this.selection.rowSelectionMode && event.shiftKey) {
21170
21641
  this.document.getSelection().removeAllRanges();
21171
21642
  // Firefox is too persistent about its text-selection behaviour. So we need to add a preventDefault();
21172
21643
  // We should not try to enforce this on the other browsers, though, because their toggle cycle does not get canceled by
@@ -21183,7 +21654,7 @@ class ClrDatagridRow {
21183
21654
  selectRow(selected = !this.selected, $event) {
21184
21655
  // The label also captures clicks that bubble up to the row event listener, causing
21185
21656
  // this handler to run twice. This exits early to prevent toggling the checkbox twice.
21186
- if ($event.target.tagName === 'LABEL') {
21657
+ if (!this.selection.rowSelectionMode || $event.target.tagName === 'LABEL' || !this._selectable) {
21187
21658
  return;
21188
21659
  }
21189
21660
  if (this.selection.selectionType === this.SELECTION_TYPE.Single) {
@@ -21222,7 +21693,7 @@ ClrDatagridRow.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version
21222
21693
  DatagridIfExpandService,
21223
21694
  { provide: IfExpandService, useExisting: DatagridIfExpandService },
21224
21695
  { provide: LoadingListener, useExisting: DatagridIfExpandService },
21225
- ], 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 <clr-dg-cell class=\"skeleton-loading\" *ngIf=\"skeletonLoading\"></clr-dg-cell>\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: "component", type: ClrDatagridCell, selector: "clr-dg-cell" }, { kind: "directive", type: ClrDatagridSelectionCellDirective, selector: ".datagrid-select" }, { kind: "directive", type: DatagridCellRenderer, selector: "clr-dg-cell" }] });
21696
+ ], queries: [{ propertyName: "dgCells", predicate: ClrDatagridCell }], viewQueries: [{ propertyName: "expandAnimation", first: true, predicate: ClrExpandableAnimationDirective, 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 }, { propertyName: "_fixedCellTemplate", first: true, predicate: ["fixedCellTemplate"], descendants: true }], ngImport: i0, template: "<div\n role=\"row\"\n [id]=\"id\"\n class=\"datagrid-row-master datagrid-row-flex\"\n [clrExpandableAnimation]=\"expandAnimationTrigger\"\n (mousedown)=\"clearRanges($event)\"\n (click)=\"selectRow(!selected, $event)\"\n [class.datagrid-row-clickable]=\"selection.rowSelectionMode\"\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<!--\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-container #calculatedCells></ng-container>\n\n<ng-template #fixedCellTemplate>\n <div class=\"datagrid-fixed-column datagrid-cell\" role=\"gridcell\"></div>\n</ng-template>\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: "directive", type: ClrExpandableAnimationDirective, selector: "[clrExpandableAnimation]", inputs: ["clrExpandableAnimation"] }, { kind: "component", type: ClrSpinner, selector: "clr-spinner", inputs: ["clrInline", "clrInverse", "clrSmall", "clrMedium"] }, { kind: "directive", type: ClrDatagridSelectionCellDirective, selector: ".datagrid-select" }] });
21226
21697
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridRow, decorators: [{
21227
21698
  type: Component,
21228
21699
  args: [{ selector: 'clr-dg-row', host: {
@@ -21235,7 +21706,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
21235
21706
  DatagridIfExpandService,
21236
21707
  { provide: IfExpandService, useExisting: DatagridIfExpandService },
21237
21708
  { provide: LoadingListener, useExisting: DatagridIfExpandService },
21238
- ], 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 <clr-dg-cell class=\"skeleton-loading\" *ngIf=\"skeletonLoading\"></clr-dg-cell>\n </div>\n</ng-template>\n\n<ng-container #calculatedCells></ng-container>\n" }]
21709
+ ], template: "<div\n role=\"row\"\n [id]=\"id\"\n class=\"datagrid-row-master datagrid-row-flex\"\n [clrExpandableAnimation]=\"expandAnimationTrigger\"\n (mousedown)=\"clearRanges($event)\"\n (click)=\"selectRow(!selected, $event)\"\n [class.datagrid-row-clickable]=\"selection.rowSelectionMode\"\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<!--\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-container #calculatedCells></ng-container>\n\n<ng-template #fixedCellTemplate>\n <div class=\"datagrid-fixed-column datagrid-cell\" role=\"gridcell\"></div>\n</ng-template>\n" }]
21239
21710
  }], 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: [{
21240
21711
  type: Inject,
21241
21712
  args: [DOCUMENT]
@@ -21259,7 +21730,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
21259
21730
  args: [ClrDatagridCell]
21260
21731
  }], expandAnimation: [{
21261
21732
  type: ViewChild,
21262
- args: [ClrExpandableAnimation]
21733
+ args: [ClrExpandableAnimationDirective]
21263
21734
  }], detailButton: [{
21264
21735
  type: ViewChild,
21265
21736
  args: ['detailButton']
@@ -21272,6 +21743,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
21272
21743
  }], _calculatedCells: [{
21273
21744
  type: ViewChild,
21274
21745
  args: ['calculatedCells', { read: ViewContainerRef }]
21746
+ }], _fixedCellTemplate: [{
21747
+ type: ViewChild,
21748
+ args: ['fixedCellTemplate']
21275
21749
  }], item: [{
21276
21750
  type: Input,
21277
21751
  args: ['clrDgItem']
@@ -21395,9 +21869,11 @@ class ClrDatagridVirtualScrollDirective {
21395
21869
  this.injector = injector;
21396
21870
  this.renderedRangeChange = new EventEmitter();
21397
21871
  this.persistItems = true;
21872
+ this.shouldUpdateAriaRowIndexes = false;
21398
21873
  this._cdkFixedSizeVirtualScrollInputs = { ...defaultCdkFixedSizeVirtualScrollInputs };
21399
21874
  this.subscriptions = [];
21400
21875
  this.topIndex = 0;
21876
+ // @deprecated remove the mutation observer when `datagrid-compact` class is deleted
21401
21877
  this.mutationChanges = new MutationObserver((mutations) => {
21402
21878
  mutations.forEach((mutation) => {
21403
21879
  // it is possible this to be called twice because the old class is removed and the new added
@@ -21415,12 +21891,20 @@ class ClrDatagridVirtualScrollDirective {
21415
21891
  this.datagridElementRef = datagrid.el;
21416
21892
  // default
21417
21893
  this.cdkVirtualForTemplateCacheSize = 20;
21894
+ const rowHeightToken = window.getComputedStyle(document.body).getPropertyValue('--clr-table-row-height');
21895
+ const rowHeightValue = +/calc\(([0-9]+) \* calc\(\(1rem \/ 20\) \* 1\)\)/.exec(rowHeightToken)?.[1];
21896
+ if (rowHeightValue && this.itemSize > rowHeightValue) {
21897
+ this.itemSize = rowHeightValue;
21898
+ }
21418
21899
  this.mutationChanges.observe(this.datagridElementRef.nativeElement, {
21419
21900
  attributeFilter: ['class'],
21420
21901
  attributeOldValue: true,
21421
21902
  });
21422
21903
  this.virtualScrollStrategy = new FixedSizeVirtualScrollStrategy(this._cdkFixedSizeVirtualScrollInputs.itemSize, this._cdkFixedSizeVirtualScrollInputs.minBufferPx, this._cdkFixedSizeVirtualScrollInputs.maxBufferPx);
21423
21904
  }
21905
+ get totalContentHeight() {
21906
+ return this.virtualScrollViewport?._totalContentHeight || '';
21907
+ }
21424
21908
  get cdkVirtualForOf() {
21425
21909
  return this.cdkVirtualForInputs.cdkVirtualForOf;
21426
21910
  }
@@ -21472,6 +21956,12 @@ class ClrDatagridVirtualScrollDirective {
21472
21956
  this.updateFixedSizeVirtualScrollInputs();
21473
21957
  }
21474
21958
  set dataRange(range) {
21959
+ if (!range) {
21960
+ return;
21961
+ }
21962
+ if (this.items.smart) {
21963
+ this.items.smartenDown();
21964
+ }
21475
21965
  this.totalItems = range.total;
21476
21966
  this.updateDataRange(range.skip, range.data);
21477
21967
  }
@@ -21479,11 +21969,7 @@ class ClrDatagridVirtualScrollDirective {
21479
21969
  return this._totalItems;
21480
21970
  }
21481
21971
  set totalItems(value) {
21482
- if (this._totalItems === value) {
21483
- return;
21484
- }
21485
21972
  this._totalItems = value;
21486
- this.populatePlaceholderData();
21487
21973
  }
21488
21974
  ngAfterViewInit() {
21489
21975
  this.injector.runInContext(() => {
@@ -21494,13 +21980,17 @@ class ClrDatagridVirtualScrollDirective {
21494
21980
  this.gridRoleElement = this.datagridElementRef.nativeElement.querySelector('[role="grid"]');
21495
21981
  this.updateCdkVirtualForInputs();
21496
21982
  this.subscriptions.push(this.items.change.subscribe(newItems => {
21497
- this.cdkVirtualFor.cdkVirtualForOf = newItems;
21983
+ if (this.items.smart) {
21984
+ this.cdkVirtualFor.cdkVirtualForOf = newItems;
21985
+ }
21986
+ this.shouldUpdateAriaRowIndexes = true;
21498
21987
  }), this.cdkVirtualFor.dataStream.subscribe(data => {
21499
21988
  this.updateAriaRowCount(data.length);
21500
21989
  }), this.virtualScrollViewport.scrolledIndexChange.subscribe(index => {
21501
21990
  this.topIndex = index;
21502
21991
  }), this.virtualScrollViewport.renderedRangeStream.subscribe(renderedRange => {
21503
21992
  this.renderedRangeChange.emit(renderedRange);
21993
+ this.shouldUpdateAriaRowIndexes = true;
21504
21994
  }), this.datagrid.refresh.subscribe(datagridState => {
21505
21995
  if (datagridState.filters) {
21506
21996
  this.scrollToIndex(0);
@@ -21511,7 +22001,10 @@ class ClrDatagridVirtualScrollDirective {
21511
22001
  }
21512
22002
  ngDoCheck() {
21513
22003
  this.cdkVirtualFor?.ngDoCheck();
21514
- this.updateAriaRowIndexes();
22004
+ if (this.shouldUpdateAriaRowIndexes) {
22005
+ this.updateAriaRowIndexes();
22006
+ this.shouldUpdateAriaRowIndexes = false;
22007
+ }
21515
22008
  }
21516
22009
  ngOnDestroy() {
21517
22010
  this.cdkVirtualFor?.ngOnDestroy();
@@ -21530,16 +22023,13 @@ class ClrDatagridVirtualScrollDirective {
21530
22023
  scrollToIndex(index, behavior = 'auto') {
21531
22024
  this.virtualScrollViewport?.scrollToIndex(index, behavior);
21532
22025
  }
21533
- populatePlaceholderData() {
21534
- this.cdkVirtualForOf = Array(this.totalItems);
21535
- }
21536
22026
  updateDataRange(skip, data) {
21537
- if (!this.persistItems) {
21538
- this.populatePlaceholderData();
22027
+ let items = this.cdkVirtualForOf;
22028
+ if (!this.persistItems || !items || items?.length !== this.totalItems) {
22029
+ items = Array(this.totalItems);
21539
22030
  }
21540
- const items = this.items.all;
21541
22031
  items.splice(skip, data.length, ...data);
21542
- this.items.all = items;
22032
+ this.cdkVirtualForOf = Array.from(items);
21543
22033
  }
21544
22034
  updateCdkVirtualForInputs() {
21545
22035
  if (this.cdkVirtualFor) {
@@ -21564,41 +22054,21 @@ class ClrDatagridVirtualScrollDirective {
21564
22054
  const rootElements = viewRef.rootNodes;
21565
22055
  const datagridRowElement = rootElements.find(rowElement => rowElement.tagName === 'CLR-DG-ROW');
21566
22056
  const rowRoleElement = datagridRowElement?.querySelector('[role="row"]');
21567
- // aria-rowindex should start with one, not zero, so we have to add one to the zero-based index
21568
- rowRoleElement?.setAttribute('aria-rowindex', (viewRef.context.index + 1).toString());
22057
+ const newAriaRowIndex = (viewRef.context.index + 1).toString();
22058
+ if (rowRoleElement?.getAttribute('aria-rowindex') !== newAriaRowIndex) {
22059
+ // aria-rowindex should start with one, not zero, so we have to add one to the zero-based index
22060
+ rowRoleElement?.setAttribute('aria-rowindex', newAriaRowIndex);
22061
+ }
21569
22062
  }
21570
22063
  }
21571
22064
  createVirtualScrollViewportForDatagrid(changeDetectorRef, ngZone, renderer2, directionality, scrollDispatcher, viewportRuler, datagridElementRef, virtualScrollStrategy) {
21572
- const datagridDivElement = datagridElementRef.nativeElement.querySelector('.datagrid');
21573
- const datagridTableElement = datagridElementRef.nativeElement.querySelector('.datagrid-table');
22065
+ const datagridContentElement = datagridElementRef.nativeElement.querySelector('.datagrid-content');
21574
22066
  const datagridRowsElement = datagridElementRef.nativeElement.querySelector('.datagrid-rows');
21575
- const datagridDivElementRef = { nativeElement: datagridDivElement };
21576
- let topOffset = 0;
21577
- let totalContentSize = 0;
21578
- function updateDatagridElementStyles() {
21579
- datagridRowsElement.style.transform = `translateY(${topOffset}px)`;
21580
- datagridRowsElement.style.height = `${totalContentSize - topOffset}px`;
21581
- }
21582
- const virtualScrollViewport = createCdkVirtualScrollViewport(datagridDivElementRef, changeDetectorRef, ngZone, renderer2, virtualScrollStrategy, directionality, scrollDispatcher, viewportRuler, null);
21583
- virtualScrollViewport._contentWrapper = {
21584
- nativeElement: {
21585
- style: {
21586
- set transform(value) {
21587
- topOffset = value === undefined ? 0 : +/translateY\(([0-9]+)px\)/.exec(value)?.[1];
21588
- updateDatagridElementStyles();
21589
- },
21590
- },
21591
- },
21592
- };
21593
- virtualScrollViewport.setTotalContentSize = (value) => {
21594
- totalContentSize = value;
21595
- datagridTableElement.style.height = `${totalContentSize}px`;
21596
- updateDatagridElementStyles();
21597
- };
22067
+ const virtualScrollViewport = createCdkVirtualScrollViewport(new ElementRef(datagridContentElement), new ElementRef(datagridRowsElement), changeDetectorRef, ngZone, renderer2, virtualScrollStrategy, directionality, scrollDispatcher, viewportRuler, null);
21598
22068
  return virtualScrollViewport;
21599
22069
  }
21600
22070
  }
21601
- 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 });
22071
+ 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 }, { 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: forwardRef(() => ClrDatagrid) }, { token: ColumnsService }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Directive });
21602
22072
  ClrDatagridVirtualScrollDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridVirtualScrollDirective, selector: "[clrVirtualScroll],[ClrVirtualScroll]", inputs: { persistItems: ["clrVirtualPersistItems", "persistItems"], cdkVirtualForOf: ["clrVirtualRowsOf", "cdkVirtualForOf"], cdkVirtualForTrackBy: ["clrVirtualRowsTrackBy", "cdkVirtualForTrackBy"], cdkVirtualForTemplate: ["clrVirtualRowsTemplate", "cdkVirtualForTemplate"], cdkVirtualForTemplateCacheSize: ["clrVirtualRowsTemplateCacheSize", "cdkVirtualForTemplateCacheSize"], itemSize: ["clrVirtualRowsItemSize", "itemSize"], minBufferPx: ["clrVirtualRowsMinBufferPx", "minBufferPx"], maxBufferPx: ["clrVirtualRowsMaxBufferPx", "maxBufferPx"], dataRange: ["clrVirtualDataRange", "dataRange"] }, outputs: { renderedRangeChange: "renderedRangeChange" }, providers: [Items], ngImport: i0 });
21603
22073
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridVirtualScrollDirective, decorators: [{
21604
22074
  type: Directive,
@@ -21606,9 +22076,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
21606
22076
  selector: '[clrVirtualScroll],[ClrVirtualScroll]',
21607
22077
  providers: [Items],
21608
22078
  }]
21609
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.IterableDiffers }, { type: Items, decorators: [{
21610
- type: SkipSelf
21611
- }] }, { 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: [{
22079
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.IterableDiffers }, { type: Items }, { 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, decorators: [{
22080
+ type: Inject,
22081
+ args: [forwardRef(() => ClrDatagrid)]
22082
+ }] }, { type: ColumnsService }, { type: i0.EnvironmentInjector }]; }, propDecorators: { renderedRangeChange: [{
21612
22083
  type: Output
21613
22084
  }], persistItems: [{
21614
22085
  type: Input,
@@ -21638,9 +22109,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
21638
22109
  type: Input,
21639
22110
  args: ['clrVirtualDataRange']
21640
22111
  }] } });
21641
- function createCdkVirtualScrollViewport(datagridDivElementRef, changeDetectorRef, ngZone, renderer2, virtualScrollStrategy, directionality, scrollDispatcher, viewportRuler, scrollable) {
22112
+ function createCdkVirtualScrollViewport(datagridDivElementRef, contentWrapper, changeDetectorRef, ngZone, renderer2, virtualScrollStrategy, directionality, scrollDispatcher, viewportRuler, scrollable) {
22113
+ let viewPort;
21642
22114
  if (+VERSION.major < 19) {
21643
- return new CdkVirtualScrollViewport(datagridDivElementRef, changeDetectorRef, ngZone, virtualScrollStrategy, directionality, scrollDispatcher, viewportRuler, scrollable);
22115
+ viewPort = new CdkVirtualScrollViewport(datagridDivElementRef, changeDetectorRef, ngZone, virtualScrollStrategy, directionality, scrollDispatcher, viewportRuler, scrollable);
21644
22116
  }
21645
22117
  else {
21646
22118
  const virtualScrollViewportInjector = Injector.create({
@@ -21658,8 +22130,10 @@ function createCdkVirtualScrollViewport(datagridDivElementRef, changeDetectorRef
21658
22130
  { provide: CdkVirtualScrollViewport, useClass: CdkVirtualScrollViewport },
21659
22131
  ],
21660
22132
  });
21661
- return virtualScrollViewportInjector.get(CdkVirtualScrollViewport);
22133
+ viewPort = virtualScrollViewportInjector.get(CdkVirtualScrollViewport);
21662
22134
  }
22135
+ viewPort._contentWrapper = contentWrapper;
22136
+ return viewPort;
21663
22137
  }
21664
22138
  function createCdkVirtualForOfDirective(viewContainerRef, templateRef, iterableDiffers, viewRepeater, virtualScrollViewport, ngZone) {
21665
22139
  if (+VERSION.major < 19) {
@@ -21752,6 +22226,60 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
21752
22226
  type: Injectable
21753
22227
  }], ctorParameters: function () { return [{ type: FiltersProvider }, { type: Sort }, { type: Page }, { type: StateDebouncer }]; } });
21754
22228
 
22229
+ /*
22230
+ * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
22231
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
22232
+ * This software is released under MIT license.
22233
+ * The full license information can be found in LICENSE in the root directory of this project.
22234
+ */
22235
+ class DatagridCellRenderer {
22236
+ constructor(el, renderer, organizer) {
22237
+ this.el = el;
22238
+ this.renderer = renderer;
22239
+ this.subscriptions = [];
22240
+ this.subscriptions.push(organizer.filterRenderSteps(DatagridRenderStep.CLEAR_WIDTHS).subscribe(() => this.clearWidth()));
22241
+ }
22242
+ ngOnDestroy() {
22243
+ this.subscriptions.forEach(sub => sub.unsubscribe());
22244
+ if (this.stateSubscription) {
22245
+ this.stateSubscription.unsubscribe();
22246
+ }
22247
+ }
22248
+ resetState(state) {
22249
+ this.setWidth(state);
22250
+ this.setHidden(state);
22251
+ }
22252
+ setWidth(state) {
22253
+ if (state.strictWidth) {
22254
+ this.renderer.addClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
22255
+ }
22256
+ else {
22257
+ this.renderer.removeClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
22258
+ }
22259
+ this.renderer.setStyle(this.el.nativeElement, 'width', state.width + 'px');
22260
+ }
22261
+ setHidden(state) {
22262
+ if (state.hidden) {
22263
+ this.renderer.addClass(this.el.nativeElement, HIDDEN_COLUMN_CLASS);
22264
+ }
22265
+ else {
22266
+ this.renderer.removeClass(this.el.nativeElement, HIDDEN_COLUMN_CLASS);
22267
+ }
22268
+ }
22269
+ clearWidth() {
22270
+ this.renderer.removeClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
22271
+ this.renderer.setStyle(this.el.nativeElement, 'width', null);
22272
+ }
22273
+ }
22274
+ 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 });
22275
+ DatagridCellRenderer.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: DatagridCellRenderer, selector: "clr-dg-cell", ngImport: i0 });
22276
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: DatagridCellRenderer, decorators: [{
22277
+ type: Directive,
22278
+ args: [{
22279
+ selector: 'clr-dg-cell',
22280
+ }]
22281
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: DatagridRenderOrganizer }]; } });
22282
+
21755
22283
  /*
21756
22284
  * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
21757
22285
  * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
@@ -21846,6 +22374,11 @@ class ClrDatagrid {
21846
22374
  * Output emitted whenever the data needs to be refreshed, based on user action or external ones
21847
22375
  */
21848
22376
  this.refresh = new EventEmitter(false);
22377
+ /**
22378
+ * The application can provide custom select all logic.
22379
+ */
22380
+ this.customSelectAllEnabled = false;
22381
+ this.customSelectAll = new EventEmitter();
21849
22382
  /* reference to the enum so that template can access */
21850
22383
  this.SELECTION_TYPE = SelectionType;
21851
22384
  /**
@@ -21912,13 +22445,18 @@ class ClrDatagrid {
21912
22445
  get allSelected() {
21913
22446
  return this.selection.isAllSelected();
21914
22447
  }
21915
- set allSelected(_value) {
21916
- /**
21917
- * This is a setter but we ignore the value.
21918
- * It's strange, but it lets us have an indeterminate state where only
21919
- * some of the items are selected.
21920
- */
21921
- this.selection.toggleAll();
22448
+ set allSelected(value) {
22449
+ if (this.customSelectAllEnabled) {
22450
+ this.customSelectAll.emit(value);
22451
+ }
22452
+ else {
22453
+ /**
22454
+ * This is a setter but we ignore the value.
22455
+ * It's strange, but it lets us have an indeterminate state where only
22456
+ * some of the items are selected.
22457
+ */
22458
+ this.selection.toggleAll();
22459
+ }
21922
22460
  }
21923
22461
  ngAfterContentInit() {
21924
22462
  if (!this.items.smart) {
@@ -21946,13 +22484,18 @@ class ClrDatagrid {
21946
22484
  });
21947
22485
  this.updateDetailState();
21948
22486
  // retain active cell when navigating with Up/Down Arrows, PageUp and PageDown buttons in virtual scroller
21949
- if (this.virtualScroll) {
21950
- const active = this.keyNavigation.getActiveCell();
21951
- if (active) {
21952
- this.zone.runOutsideAngular(() => {
21953
- setTimeout(() => this.keyNavigation.setActiveCell(active));
22487
+ if (this.virtualScroll && this.activeCellCoords) {
22488
+ this.zone.runOutsideAngular(() => {
22489
+ const row = Array.from(this.rows).find(row => {
22490
+ return row.el.nativeElement.children[0].ariaRowIndex === this.activeCellCoords.ariaRowIndex;
21954
22491
  });
21955
- }
22492
+ if (!row) {
22493
+ return;
22494
+ }
22495
+ const activeCell = row.el.nativeElement.querySelectorAll(this.keyNavigation.config.keyGridCells)[this.activeCellCoords.x];
22496
+ this.keyNavigation.setActiveCell(activeCell);
22497
+ this.keyNavigation.focusElement(activeCell, { preventScroll: true });
22498
+ });
21956
22499
  }
21957
22500
  }));
21958
22501
  }
@@ -21961,10 +22504,12 @@ class ClrDatagrid {
21961
22504
  */
21962
22505
  ngAfterViewInit() {
21963
22506
  this.keyNavigation.initializeKeyGrid(this.el.nativeElement);
22507
+ // the virtual scroll will handle the scrolling
22508
+ this.keyNavigation.preventScrollOnFocus = !!this.virtualScroll;
21964
22509
  this.updateDetailState();
21965
22510
  // TODO: determine if we can get rid of provider wiring in view init so that subscriptions can be done earlier
21966
22511
  this.refresh.emit(this.stateProvider.state);
21967
- this._subscriptions.push(this.stateProvider.change.subscribe(state => this.refresh.emit(state)), this.selection.change.subscribe(s => {
22512
+ this._subscriptions.push(this.stickyHeaders.changes.subscribe(() => this.resize()), this.stateProvider.change.subscribe(state => this.refresh.emit(state)), this.selection.change.subscribe(s => {
21968
22513
  if (this.selection.selectionType === SelectionType.Single) {
21969
22514
  this.singleSelectedChanged.emit(s);
21970
22515
  }
@@ -22010,6 +22555,15 @@ class ClrDatagrid {
22010
22555
  else {
22011
22556
  // Set state, style for the datagrid to CALCULATE and insert row & columns into containers
22012
22557
  this.renderer.addClass(this.el.nativeElement, 'datagrid-calculate-mode');
22558
+ // Inserts a fixed column if any of these conditions are true.
22559
+ const fixedColumnConditions = [
22560
+ this.rowActionService.hasActionableRow,
22561
+ this.selection.selectionType !== this.SELECTION_TYPE.None,
22562
+ this.expandableRows.hasExpandableRow || this.detailService.enabled,
22563
+ ];
22564
+ fixedColumnConditions
22565
+ .filter(Boolean)
22566
+ .forEach(() => this._projectedCalculationColumns.insert(this._fixedColumnTemplate.createEmbeddedView(null)));
22013
22567
  this.columns.forEach(column => {
22014
22568
  this._projectedCalculationColumns.insert(column._view);
22015
22569
  });
@@ -22031,16 +22585,31 @@ class ClrDatagrid {
22031
22585
  }
22032
22586
  }));
22033
22587
  });
22588
+ if (this.virtualScroll) {
22589
+ this._subscriptions.push(fromEvent(this.contentWrapper.nativeElement, 'scroll').subscribe(() => {
22590
+ this.datagridHeader.nativeElement.scrollLeft = this.contentWrapper.nativeElement.scrollLeft;
22591
+ }), this.keyNavigation.nextCellCoordsEmitter.subscribe(cellCoords => {
22592
+ if (!cellCoords?.ariaRowIndex) {
22593
+ this.activeCellCoords = null;
22594
+ return;
22595
+ }
22596
+ if (cellCoords.ariaRowIndex === this.activeCellCoords?.ariaRowIndex) {
22597
+ this.activeCellCoords = cellCoords;
22598
+ return;
22599
+ }
22600
+ this.activeCellCoords = cellCoords;
22601
+ // aria-rowindex is always + 1. Check virtual scroller updateAriaRowIndexes method.
22602
+ const rowIndex = Number(cellCoords.ariaRowIndex) - 1;
22603
+ this.virtualScroll.scrollToIndex(rowIndex);
22604
+ }));
22605
+ }
22034
22606
  }
22035
22607
  ngOnDestroy() {
22036
22608
  this._subscriptions.forEach((sub) => sub.unsubscribe());
22037
22609
  }
22038
22610
  toggleAllSelected($event) {
22039
22611
  $event.preventDefault();
22040
- if (this.virtualScroll) {
22041
- return;
22042
- }
22043
- this.allSelected = !this.allSelected;
22612
+ this.selectAllCheckbox?.nativeElement.click();
22044
22613
  }
22045
22614
  resize() {
22046
22615
  this.organizer.resize();
@@ -22076,7 +22645,7 @@ class ClrDatagrid {
22076
22645
  }
22077
22646
  }
22078
22647
  ClrDatagrid.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagrid, deps: [{ token: DatagridRenderOrganizer }, { token: Items }, { token: ExpandableRowsCount }, { token: Selection }, { token: RowActionService }, { token: StateProvider }, { token: DisplayModeService }, { token: i0.Renderer2 }, { token: DetailService }, { token: DOCUMENT }, { token: i0.ElementRef }, { token: Page }, { token: ClrCommonStringsService }, { token: KeyNavigationGridController }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
22079
- ClrDatagrid.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagrid, selector: "clr-datagrid", inputs: { loadingMoreItems: ["clrLoadingMoreItems", "loadingMoreItems"], clrDgSingleSelectionAriaLabel: "clrDgSingleSelectionAriaLabel", clrDgSingleActionableAriaLabel: "clrDgSingleActionableAriaLabel", clrDetailExpandableAriaLabel: "clrDetailExpandableAriaLabel", clrDgDisablePageFocus: "clrDgDisablePageFocus", loading: ["clrDgLoading", "loading"], selected: ["clrDgSelected", "selected"], singleSelected: ["clrDgSingleSelected", "singleSelected"], clrDgPreserveSelection: "clrDgPreserveSelection", rowSelectionMode: ["clrDgRowSelection", "rowSelectionMode"], trackBy: ["clrDgItemsTrackBy", "trackBy"] }, outputs: { selectedChanged: "clrDgSelectedChange", singleSelectedChanged: "clrDgSingleSelectedChange", refresh: "clrDgRefresh" }, host: { properties: { "class.datagrid-host": "true", "class.datagrid-detail-open": "detailService.isOpen" } }, providers: [
22648
+ ClrDatagrid.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagrid, selector: "clr-datagrid", inputs: { loadingMoreItems: ["clrLoadingMoreItems", "loadingMoreItems"], clrDgSingleSelectionAriaLabel: "clrDgSingleSelectionAriaLabel", clrDgSingleActionableAriaLabel: "clrDgSingleActionableAriaLabel", clrDetailExpandableAriaLabel: "clrDetailExpandableAriaLabel", clrDgDisablePageFocus: "clrDgDisablePageFocus", customSelectAllEnabled: ["clrDgCustomSelectAllEnabled", "customSelectAllEnabled"], loading: ["clrDgLoading", "loading"], selected: ["clrDgSelected", "selected"], singleSelected: ["clrDgSingleSelected", "singleSelected"], clrDgPreserveSelection: "clrDgPreserveSelection", rowSelectionMode: ["clrDgRowSelection", "rowSelectionMode"], trackBy: ["clrDgItemsTrackBy", "trackBy"] }, outputs: { selectedChanged: "clrDgSelectedChange", singleSelectedChanged: "clrDgSingleSelectedChange", refresh: "clrDgRefresh", customSelectAll: "clrDgCustomSelectAll" }, host: { properties: { "class.datagrid-host": "true", "class.datagrid-detail-open": "detailService.isOpen", "class.datagrid-virtual-scroll": "!!virtualScroll" } }, providers: [
22080
22649
  Selection,
22081
22650
  Sort,
22082
22651
  FiltersProvider,
@@ -22092,7 +22661,7 @@ ClrDatagrid.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
22092
22661
  ColumnsService,
22093
22662
  DisplayModeService,
22094
22663
  KeyNavigationGridController,
22095
- ], 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", "clrDgSkeletonLoading", "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" }] });
22664
+ ], 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, emitDistinctChangesOnly: false }], viewQueries: [{ propertyName: "datagrid", first: true, predicate: ["datagrid"], descendants: true, read: ElementRef }, { propertyName: "datagridTable", first: true, predicate: ["datagridTable"], descendants: true, read: ElementRef }, { propertyName: "datagridHeader", first: true, predicate: ["datagridHeader"], descendants: true, read: ElementRef }, { propertyName: "contentWrapper", first: true, predicate: ["contentWrapper"], 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 }, { propertyName: "_fixedColumnTemplate", first: true, predicate: ["fixedColumnTemplate"], descendants: true }, { propertyName: "selectAllCheckbox", first: true, predicate: ["selectAllCheckbox"], descendants: true }, { propertyName: "stickyHeaders", predicate: ["stickyHeader"], 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<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\" #datagridHeader>\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 #stickyHeader\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 || customSelectAllEnabled\" 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 #selectAllCheckbox\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 #stickyHeader\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 #stickyHeader\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 #stickyHeader\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 *ngIf=\"virtualScroll\" class=\"datagrid-row-sticky datagrid-row-sticky-scroll\">\n <div class=\"datagrid-column\"></div>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"datagrid-content\" [class.datagrid-content-virtual]=\"virtualScroll\" #contentWrapper>\n <div\n *ngIf=\"virtualScroll\"\n class=\"datagrid-content-virtual-spacer\"\n [style.height]=\"virtualScroll?.totalContentHeight\"\n ></div>\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 </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\n<ng-template #fixedColumnTemplate>\n <div class=\"datagrid-column datagrid-fixed-column\"></div>\n</ng-template>\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", "clrDgSkeletonLoading", "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" }] });
22096
22665
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagrid, decorators: [{
22097
22666
  type: Component,
22098
22667
  args: [{ selector: 'clr-datagrid', providers: [
@@ -22114,7 +22683,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
22114
22683
  ], host: {
22115
22684
  '[class.datagrid-host]': 'true',
22116
22685
  '[class.datagrid-detail-open]': 'detailService.isOpen',
22117
- }, 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" }]
22686
+ '[class.datagrid-virtual-scroll]': '!!virtualScroll',
22687
+ }, 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\" #datagridHeader>\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 #stickyHeader\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 || customSelectAllEnabled\" 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 #selectAllCheckbox\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 #stickyHeader\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 #stickyHeader\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 #stickyHeader\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 *ngIf=\"virtualScroll\" class=\"datagrid-row-sticky datagrid-row-sticky-scroll\">\n <div class=\"datagrid-column\"></div>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"datagrid-content\" [class.datagrid-content-virtual]=\"virtualScroll\" #contentWrapper>\n <div\n *ngIf=\"virtualScroll\"\n class=\"datagrid-content-virtual-spacer\"\n [style.height]=\"virtualScroll?.totalContentHeight\"\n ></div>\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 </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\n<ng-template #fixedColumnTemplate>\n <div class=\"datagrid-column datagrid-fixed-column\"></div>\n</ng-template>\n" }]
22118
22688
  }], 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: [{
22119
22689
  type: Inject,
22120
22690
  args: [DOCUMENT]
@@ -22138,6 +22708,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
22138
22708
  }], refresh: [{
22139
22709
  type: Output,
22140
22710
  args: ['clrDgRefresh']
22711
+ }], customSelectAllEnabled: [{
22712
+ type: Input,
22713
+ args: ['clrDgCustomSelectAllEnabled']
22714
+ }], customSelectAll: [{
22715
+ type: Output,
22716
+ args: ['clrDgCustomSelectAll']
22141
22717
  }], virtualScroll: [{
22142
22718
  type: ContentChild,
22143
22719
  args: [ClrDatagridVirtualScrollDirective]
@@ -22152,13 +22728,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
22152
22728
  args: [ClrDatagridColumn]
22153
22729
  }], rows: [{
22154
22730
  type: ContentChildren,
22155
- args: [ClrDatagridRow]
22731
+ args: [ClrDatagridRow, { emitDistinctChangesOnly: false }]
22156
22732
  }], datagrid: [{
22157
22733
  type: ViewChild,
22158
22734
  args: ['datagrid', { read: ElementRef }]
22159
22735
  }], datagridTable: [{
22160
22736
  type: ViewChild,
22161
22737
  args: ['datagridTable', { read: ElementRef }]
22738
+ }], datagridHeader: [{
22739
+ type: ViewChild,
22740
+ args: ['datagridHeader', { read: ElementRef }]
22741
+ }], contentWrapper: [{
22742
+ type: ViewChild,
22743
+ args: ['contentWrapper', { read: ElementRef }]
22162
22744
  }], scrollableColumns: [{
22163
22745
  type: ViewChild,
22164
22746
  args: ['scrollableColumns', { read: ViewContainerRef }]
@@ -22174,6 +22756,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
22174
22756
  }], _calculationRows: [{
22175
22757
  type: ViewChild,
22176
22758
  args: ['calculationRows', { read: ViewContainerRef }]
22759
+ }], _fixedColumnTemplate: [{
22760
+ type: ViewChild,
22761
+ args: ['fixedColumnTemplate']
22762
+ }], stickyHeaders: [{
22763
+ type: ViewChildren,
22764
+ args: ['stickyHeader', { emitDistinctChangesOnly: true }]
22765
+ }], selectAllCheckbox: [{
22766
+ type: ViewChild,
22767
+ args: ['selectAllCheckbox']
22177
22768
  }], loading: [{
22178
22769
  type: Input,
22179
22770
  args: ['clrDgLoading']
@@ -22639,7 +23230,7 @@ ClrDatagridDetailHeader.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0"
22639
23230
  <div class="datagrid-detail-pane-close">
22640
23231
  <button
22641
23232
  type="button"
22642
- class="btn btn-link"
23233
+ class="btn btn-icon btn-link"
22643
23234
  (click)="detailService.close()"
22644
23235
  [attr.aria-label]="commonStrings.keys.close"
22645
23236
  >
@@ -22661,7 +23252,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
22661
23252
  <div class="datagrid-detail-pane-close">
22662
23253
  <button
22663
23254
  type="button"
22664
- class="btn btn-link"
23255
+ class="btn btn-icon btn-link"
22665
23256
  (click)="detailService.close()"
22666
23257
  [attr.aria-label]="commonStrings.keys.close"
22667
23258
  >
@@ -23333,22 +23924,24 @@ ClrDatagridPagination.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0",
23333
23924
  <span class="clr-sr-only">{{ commonStrings.keys.previousPage }}</span>
23334
23925
  <cds-icon shape="angle" direction="left"></cds-icon>
23335
23926
  </button>
23336
- <input
23337
- *ngIf="!disableCurrentPageInput; else readOnly"
23338
- #currentPageInput
23339
- type="text"
23340
- class="pagination-current clr-input"
23341
- [size]="page.last.toString().length"
23342
- [value]="page.current"
23343
- (keydown.enter)="updateCurrentPage($event)"
23344
- (blur)="verifyCurrentPage($event)"
23345
- [attr.aria-label]="commonStrings.keys.currentPage"
23346
- />
23347
- <ng-template #readOnly>
23348
- <span>{{ page.current }}</span>
23349
- </ng-template>
23927
+ <div class="pagination-pages">
23928
+ <input
23929
+ *ngIf="!disableCurrentPageInput; else readOnly"
23930
+ #currentPageInput
23931
+ type="text"
23932
+ class="pagination-current clr-input"
23933
+ [size]="page.last.toString().length"
23934
+ [value]="page.current"
23935
+ (keydown.enter)="updateCurrentPage($event)"
23936
+ (blur)="verifyCurrentPage($event)"
23937
+ [attr.aria-label]="commonStrings.keys.currentPage"
23938
+ />
23939
+ <ng-template #readOnly>
23940
+ <span>{{ page.current }}</span>
23941
+ </ng-template>
23350
23942
 
23351
- &nbsp;/&nbsp;<span [attr.aria-label]="commonStrings.keys.totalPages">{{ page.last }}</span>
23943
+ &nbsp;/&nbsp;<span [attr.aria-label]="commonStrings.keys.totalPages">{{ page.last }}</span>
23944
+ </div>
23352
23945
  <button
23353
23946
  type="button"
23354
23947
  class="pagination-next"
@@ -23433,22 +24026,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
23433
24026
  <span class="clr-sr-only">{{ commonStrings.keys.previousPage }}</span>
23434
24027
  <cds-icon shape="angle" direction="left"></cds-icon>
23435
24028
  </button>
23436
- <input
23437
- *ngIf="!disableCurrentPageInput; else readOnly"
23438
- #currentPageInput
23439
- type="text"
23440
- class="pagination-current clr-input"
23441
- [size]="page.last.toString().length"
23442
- [value]="page.current"
23443
- (keydown.enter)="updateCurrentPage($event)"
23444
- (blur)="verifyCurrentPage($event)"
23445
- [attr.aria-label]="commonStrings.keys.currentPage"
23446
- />
23447
- <ng-template #readOnly>
23448
- <span>{{ page.current }}</span>
23449
- </ng-template>
24029
+ <div class="pagination-pages">
24030
+ <input
24031
+ *ngIf="!disableCurrentPageInput; else readOnly"
24032
+ #currentPageInput
24033
+ type="text"
24034
+ class="pagination-current clr-input"
24035
+ [size]="page.last.toString().length"
24036
+ [value]="page.current"
24037
+ (keydown.enter)="updateCurrentPage($event)"
24038
+ (blur)="verifyCurrentPage($event)"
24039
+ [attr.aria-label]="commonStrings.keys.currentPage"
24040
+ />
24041
+ <ng-template #readOnly>
24042
+ <span>{{ page.current }}</span>
24043
+ </ng-template>
23450
24044
 
23451
- &nbsp;/&nbsp;<span [attr.aria-label]="commonStrings.keys.totalPages">{{ page.last }}</span>
24045
+ &nbsp;/&nbsp;<span [attr.aria-label]="commonStrings.keys.totalPages">{{ page.last }}</span>
24046
+ </div>
23452
24047
  <button
23453
24048
  type="button"
23454
24049
  class="pagination-next"
@@ -24389,7 +24984,7 @@ ClrStackBlock.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version:
24389
24984
  [attr.aria-expanded]="ariaExpanded"
24390
24985
  [attr.aria-controls]="getStackChildrenId()"
24391
24986
  >
24392
- <cds-icon shape="angle" class="stack-block-caret" *ngIf="expandable" [attr.direction]="caretDirection"></cds-icon>
24987
+ <cds-icon shape="angle" class="stack-block-caret" [attr.direction]="caretDirection"></cds-icon>
24393
24988
  <span class="clr-sr-only" *ngIf="getChangedValue">{{ commonStrings.keys.stackViewChanged }}</span>
24394
24989
  <div class="stack-view-key">
24395
24990
  <!-- This structure changed to fix #3567 and the a11y request was to move away from dl's -->
@@ -24432,7 +25027,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
24432
25027
  [attr.aria-expanded]="ariaExpanded"
24433
25028
  [attr.aria-controls]="getStackChildrenId()"
24434
25029
  >
24435
- <cds-icon shape="angle" class="stack-block-caret" *ngIf="expandable" [attr.direction]="caretDirection"></cds-icon>
25030
+ <cds-icon shape="angle" class="stack-block-caret" [attr.direction]="caretDirection"></cds-icon>
24436
25031
  <span class="clr-sr-only" *ngIf="getChangedValue">{{ commonStrings.keys.stackViewChanged }}</span>
24437
25032
  <div class="stack-view-key">
24438
25033
  <!-- This structure changed to fix #3567 and the a11y request was to move away from dl's -->
@@ -26015,10 +26610,10 @@ class ClrAlert {
26015
26610
  }
26016
26611
  }
26017
26612
  ClrAlert.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrAlert, deps: [{ token: AlertIconAndTypesService }, { token: i0.ChangeDetectorRef }, { token: MultiAlertService, optional: true }, { token: ClrCommonStringsService }, { token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
26018
- ClrAlert.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrAlert, selector: "clr-alert", inputs: { isSmall: ["clrAlertSizeSmall", "isSmall"], closable: ["clrAlertClosable", "closable"], isAppLevel: ["clrAlertAppLevel", "isAppLevel"], clrCloseButtonAriaLabel: "clrCloseButtonAriaLabel", isLightweight: ["clrAlertLightweight", "isLightweight"], alertType: ["clrAlertType", "alertType"], alertIconShape: ["clrAlertIcon", "alertIconShape"], closed: ["clrAlertClosed", "closed"] }, outputs: { _closedChanged: "clrAlertClosedChange" }, providers: [AlertIconAndTypesService], 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 *ngIf=\"!_closed\"\n class=\"alert\"\n [ngClass]=\"alertClass\"\n [class.alert-sm]=\"isSmall\"\n [class.alert-lightweight]=\"isLightweight\"\n [class.alert-app-level]=\"isAppLevel\"\n>\n <div class=\"alert-items\">\n <ng-content></ng-content>\n </div>\n <button type=\"button\" class=\"close\" *ngIf=\"closable\" (click)=\"close()\" [attr.aria-label]=\"clrCloseButtonAriaLabel\">\n <cds-icon shape=\"window-close\"></cds-icon>\n </button>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }] });
26613
+ ClrAlert.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrAlert, selector: "clr-alert", inputs: { isSmall: ["clrAlertSizeSmall", "isSmall"], closable: ["clrAlertClosable", "closable"], isAppLevel: ["clrAlertAppLevel", "isAppLevel"], clrCloseButtonAriaLabel: "clrCloseButtonAriaLabel", isLightweight: ["clrAlertLightweight", "isLightweight"], alertType: ["clrAlertType", "alertType"], alertIconShape: ["clrAlertIcon", "alertIconShape"], closed: ["clrAlertClosed", "closed"] }, outputs: { _closedChanged: "clrAlertClosedChange" }, providers: [AlertIconAndTypesService], 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 *ngIf=\"!_closed\"\n class=\"alert\"\n [ngClass]=\"alertClass\"\n [class.alert-sm]=\"isSmall\"\n [class.alert-lightweight]=\"isLightweight\"\n [class.alert-app-level]=\"isAppLevel\"\n>\n <div class=\"alert-items\">\n <ng-content></ng-content>\n </div>\n <button type=\"button\" class=\"close\" *ngIf=\"closable\" (click)=\"close()\" [attr.aria-label]=\"clrCloseButtonAriaLabel\">\n <cds-icon shape=\"times\"></cds-icon>\n </button>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }] });
26019
26614
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrAlert, decorators: [{
26020
26615
  type: Component,
26021
- args: [{ selector: 'clr-alert', providers: [AlertIconAndTypesService], 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 *ngIf=\"!_closed\"\n class=\"alert\"\n [ngClass]=\"alertClass\"\n [class.alert-sm]=\"isSmall\"\n [class.alert-lightweight]=\"isLightweight\"\n [class.alert-app-level]=\"isAppLevel\"\n>\n <div class=\"alert-items\">\n <ng-content></ng-content>\n </div>\n <button type=\"button\" class=\"close\" *ngIf=\"closable\" (click)=\"close()\" [attr.aria-label]=\"clrCloseButtonAriaLabel\">\n <cds-icon shape=\"window-close\"></cds-icon>\n </button>\n</div>\n" }]
26616
+ args: [{ selector: 'clr-alert', providers: [AlertIconAndTypesService], 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 *ngIf=\"!_closed\"\n class=\"alert\"\n [ngClass]=\"alertClass\"\n [class.alert-sm]=\"isSmall\"\n [class.alert-lightweight]=\"isLightweight\"\n [class.alert-app-level]=\"isAppLevel\"\n>\n <div class=\"alert-items\">\n <ng-content></ng-content>\n </div>\n <button type=\"button\" class=\"close\" *ngIf=\"closable\" (click)=\"close()\" [attr.aria-label]=\"clrCloseButtonAriaLabel\">\n <cds-icon shape=\"times\"></cds-icon>\n </button>\n</div>\n" }]
26022
26617
  }], ctorParameters: function () { return [{ type: AlertIconAndTypesService }, { type: i0.ChangeDetectorRef }, { type: MultiAlertService, decorators: [{
26023
26618
  type: Optional
26024
26619
  }] }, { type: ClrCommonStringsService }, { type: i0.Renderer2 }, { type: i0.ElementRef }]; }, propDecorators: { isSmall: [{
@@ -26468,7 +27063,7 @@ class ClrModal {
26468
27063
  }
26469
27064
  }
26470
27065
  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 });
26471
- 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: [
27066
+ 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" } }, queries: [{ propertyName: "modalContentTemplate", first: true, predicate: ["clrInternalModalContentTemplate"], descendants: true }], 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 <!-- This wizard is tightly coupled to the modal styles, so changes here could require changes in the wizard. -->\n <div *ngIf=\"!modalContentTemplate; else modalContentTemplate\" class=\"modal-content-wrapper\">\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 [@fade] *ngIf=\"backdrop\" class=\"modal-backdrop\" aria-hidden=\"true\" (click)=\"backdropClick()\"></div>\n</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: [
26472
27067
  trigger('fadeMove', [
26473
27068
  transition('* => fadeDown', [
26474
27069
  style({ opacity: 0, transform: 'translate(0, -25%)' }),
@@ -26479,6 +27074,8 @@ ClrModal.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.
26479
27074
  ]),
26480
27075
  transition('* => fadeLeft', [style({ opacity: 0, transform: 'translate(25%, 0)' }), animate('0.2s ease-in-out')]),
26481
27076
  transition('fadeLeft => *', [animate('0.2s ease-in-out', style({ opacity: 0, transform: 'translate(25%, 0)' }))]),
27077
+ transition('* => fadeUp', [style({ opacity: 0, transform: 'translate(0, 50%)' }), animate('0.2s ease-in-out')]),
27078
+ transition('fadeUp => *', [animate('0.2s ease-in-out', style({ opacity: 0, transform: 'translate(0, 50%)' }))]),
26482
27079
  ]),
26483
27080
  trigger('fade', [
26484
27081
  transition('void => *', [style({ opacity: 0 }), animate('0.2s ease-in-out', style({ opacity: 0.85 }))]),
@@ -26498,12 +27095,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
26498
27095
  ]),
26499
27096
  transition('* => fadeLeft', [style({ opacity: 0, transform: 'translate(25%, 0)' }), animate('0.2s ease-in-out')]),
26500
27097
  transition('fadeLeft => *', [animate('0.2s ease-in-out', style({ opacity: 0, transform: 'translate(25%, 0)' }))]),
27098
+ transition('* => fadeUp', [style({ opacity: 0, transform: 'translate(0, 50%)' }), animate('0.2s ease-in-out')]),
27099
+ transition('fadeUp => *', [animate('0.2s ease-in-out', style({ opacity: 0, transform: 'translate(0, 50%)' }))]),
26501
27100
  ]),
26502
27101
  trigger('fade', [
26503
27102
  transition('void => *', [style({ opacity: 0 }), animate('0.2s ease-in-out', style({ opacity: 0.85 }))]),
26504
27103
  transition('* => void', [animate('0.2s ease-in-out', style({ opacity: 0 }))]),
26505
27104
  ]),
26506
- ], 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"] }]
27105
+ ], 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 <!-- This wizard is tightly coupled to the modal styles, so changes here could require changes in the wizard. -->\n <div *ngIf=\"!modalContentTemplate; else modalContentTemplate\" class=\"modal-content-wrapper\">\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 [@fade] *ngIf=\"backdrop\" class=\"modal-backdrop\" aria-hidden=\"true\" (click)=\"backdropClick()\"></div>\n</div>\n", styles: [":host{display:none}:host.open{display:inline}\n"] }]
26507
27106
  }], ctorParameters: function () { return [{ type: ScrollingService }, { type: ClrCommonStringsService }, { type: ModalStackService }, { type: ClrModalConfigurationService }]; }, propDecorators: { title: [{
26508
27107
  type: ViewChild,
26509
27108
  args: ['title']
@@ -26543,6 +27142,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
26543
27142
  }], bypassScrollService: [{
26544
27143
  type: Input,
26545
27144
  args: ['clrModalOverrideScrollService']
27145
+ }], modalContentTemplate: [{
27146
+ type: ContentChild,
27147
+ args: ['clrInternalModalContentTemplate']
26546
27148
  }], bodyElementRef: [{
26547
27149
  type: ViewChild,
26548
27150
  args: ['body']
@@ -26617,15 +27219,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
26617
27219
  * This software is released under MIT license.
26618
27220
  * The full license information can be found in LICENSE in the root directory of this project.
26619
27221
  */
26620
- class ClrModalHostDirective {
27222
+ class ClrModalHostComponent {
26621
27223
  }
26622
- ClrModalHostDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModalHostDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
26623
- ClrModalHostDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: ClrModalHostDirective, selector: "[clrModalHost]", host: { properties: { "class.clr-modal-host": "true" } }, ngImport: i0 });
26624
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModalHostDirective, decorators: [{
26625
- type: Directive,
27224
+ ClrModalHostComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModalHostComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
27225
+ ClrModalHostComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrModalHostComponent, selector: "[clrModalHost]", host: { properties: { "class.clr-modal-host": "true" } }, ngImport: i0, template: `
27226
+ <div class="clr-modal-host-scrollable">
27227
+ <ng-content></ng-content>
27228
+ </div>
27229
+ `, isInline: true });
27230
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModalHostComponent, decorators: [{
27231
+ type: Component,
26626
27232
  args: [{
26627
27233
  selector: '[clrModalHost]',
26628
27234
  host: { '[class.clr-modal-host]': 'true' },
27235
+ template: `
27236
+ <div class="clr-modal-host-scrollable">
27237
+ <ng-content></ng-content>
27238
+ </div>
27239
+ `,
26629
27240
  }]
26630
27241
  }] });
26631
27242
 
@@ -26635,14 +27246,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
26635
27246
  * This software is released under MIT license.
26636
27247
  * The full license information can be found in LICENSE in the root directory of this project.
26637
27248
  */
26638
- const CLR_MODAL_DIRECTIVES = [ClrModal, ClrModalBody, ClrModalHostDirective];
27249
+ const CLR_MODAL_DIRECTIVES = [ClrModal, ClrModalBody, ClrModalHostComponent];
26639
27250
  class ClrModalModule {
26640
27251
  constructor() {
26641
27252
  ClarityIcons.addIcons(windowCloseIcon);
26642
27253
  }
26643
27254
  }
26644
27255
  ClrModalModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModalModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
26645
- ClrModalModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.2", ngImport: i0, type: ClrModalModule, declarations: [ClrModal, ClrModalBody, ClrModalHostDirective], imports: [CommonModule, CdkTrapFocusModule, ClrIconModule], exports: [ClrModal, ClrModalBody, ClrModalHostDirective, ClrIconModule] });
27256
+ ClrModalModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.2", ngImport: i0, type: ClrModalModule, declarations: [ClrModal, ClrModalBody, ClrModalHostComponent], imports: [CommonModule, CdkTrapFocusModule, ClrIconModule], exports: [ClrModal, ClrModalBody, ClrModalHostComponent, ClrIconModule] });
26646
27257
  ClrModalModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModalModule, imports: [CommonModule, CdkTrapFocusModule, ClrIconModule, ClrIconModule] });
26647
27258
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModalModule, decorators: [{
26648
27259
  type: NgModule,
@@ -26664,16 +27275,29 @@ class ClrSidePanel {
26664
27275
  this.element = element;
26665
27276
  this.configuration = configuration;
26666
27277
  this.commonStrings = commonStrings;
26667
- this._open = false;
26668
27278
  this.openChange = new EventEmitter(false);
26669
27279
  this.skipAnimation = false;
26670
27280
  this.staticBackdrop = false;
27281
+ this.closable = true;
26671
27282
  this.preventClose = false;
26672
27283
  this.altClose = new EventEmitter(false);
26673
27284
  this._pinnable = false;
26674
27285
  this._pinned = false;
27286
+ this._position = 'right';
27287
+ this.__open = false;
26675
27288
  this._size = 'md';
26676
27289
  }
27290
+ get _open() {
27291
+ return this.__open;
27292
+ }
27293
+ set _open(open) {
27294
+ if (open !== this.__open) {
27295
+ this.__open = open;
27296
+ if (this.pinned) {
27297
+ this.updateModalState();
27298
+ }
27299
+ }
27300
+ }
26677
27301
  get size() {
26678
27302
  return this._size;
26679
27303
  }
@@ -26683,9 +27307,22 @@ class ClrSidePanel {
26683
27307
  }
26684
27308
  if (this._size !== value) {
26685
27309
  this._size = value;
26686
- if (this.clrSidePanelPinnable && this.pinned) {
26687
- this.displayOverlapping();
26688
- this.displaySideBySide();
27310
+ if (this.pinned) {
27311
+ this.updateModalState();
27312
+ }
27313
+ }
27314
+ }
27315
+ get position() {
27316
+ return this._position;
27317
+ }
27318
+ set position(position) {
27319
+ if (position && position !== this._position) {
27320
+ this._position = position;
27321
+ if (this._position === 'right') {
27322
+ this.configuration.fadeMove = 'fadeLeft';
27323
+ }
27324
+ else if (this._position === 'bottom') {
27325
+ this.configuration.fadeMove = 'fadeUp';
26689
27326
  }
26690
27327
  }
26691
27328
  }
@@ -26693,17 +27330,9 @@ class ClrSidePanel {
26693
27330
  return this._pinned;
26694
27331
  }
26695
27332
  set pinned(pinned) {
26696
- if (this.clrSidePanelPinnable) {
26697
- this._pinned = pinned;
26698
- if (pinned) {
26699
- this.originalStopClose = this.modal.stopClose;
26700
- this.modal.stopClose = true;
26701
- this.displaySideBySide();
26702
- }
26703
- else {
26704
- this.modal.stopClose = this.originalStopClose;
26705
- this.displayOverlapping();
26706
- }
27333
+ this._pinned = pinned;
27334
+ if (this.modal) {
27335
+ this.updateModalState();
26707
27336
  }
26708
27337
  }
26709
27338
  get clrSidePanelBackdrop() {
@@ -26720,28 +27349,37 @@ class ClrSidePanel {
26720
27349
  set clrSidePanelPinnable(pinnable) {
26721
27350
  this._pinnable = pinnable;
26722
27351
  }
27352
+ get modal() {
27353
+ return this._modal;
27354
+ }
27355
+ set modal(modal) {
27356
+ this._modal = modal;
27357
+ this.originalStopClose = this.modal.stopClose;
27358
+ this.updateModalState();
27359
+ }
26723
27360
  get hostElement() {
26724
27361
  return this.element.nativeElement.closest('.clr-modal-host') || document.body;
26725
27362
  }
27363
+ get bottomPositionCssClass() {
27364
+ return this.position === 'bottom';
27365
+ }
26726
27366
  ngOnInit() {
26727
27367
  this.configuration.fadeMove = 'fadeLeft';
26728
- }
26729
- ngOnChanges(changes) {
26730
- if (changes && Object.prototype.hasOwnProperty.call(changes, '_open')) {
26731
- if (changes._open.currentValue) {
26732
- if (this.clrSidePanelPinnable && this.pinned) {
26733
- this.displaySideBySide();
26734
- }
26735
- }
26736
- else {
26737
- if (this.clrSidePanelPinnable && this.pinned) {
26738
- this.displayOverlapping();
26739
- }
26740
- }
27368
+ if (this.position === 'bottom') {
27369
+ this.configuration.fadeMove = 'fadeUp';
26741
27370
  }
26742
27371
  }
26743
27372
  ngOnDestroy() {
26744
- this.displayOverlapping();
27373
+ this.cleanupPinnedClasses();
27374
+ }
27375
+ handleModalOpen(open) {
27376
+ if (open) {
27377
+ this.updateModalState();
27378
+ }
27379
+ else {
27380
+ this.cleanupPinnedClasses();
27381
+ }
27382
+ this.openChange.emit(open);
26745
27383
  }
26746
27384
  open() {
26747
27385
  this.modal.open();
@@ -26759,28 +27397,41 @@ class ClrSidePanel {
26759
27397
  this.modal.close();
26760
27398
  }
26761
27399
  }
26762
- displaySideBySide() {
26763
- this.hostElement.classList.add('clr-side-panel-pinned-' + this.size);
27400
+ updateModalState() {
27401
+ if (!this.modal) {
27402
+ return;
27403
+ }
27404
+ if (this.pinned) {
27405
+ this.modal.stopClose = true;
27406
+ this.updatePinnedClasses();
27407
+ }
27408
+ else {
27409
+ this.modal.stopClose = this.originalStopClose;
27410
+ this.cleanupPinnedClasses();
27411
+ }
26764
27412
  }
26765
- displayOverlapping() {
26766
- this.hostElement.classList.forEach(className => {
26767
- if (className.startsWith('clr-side-panel-pinned-')) {
26768
- this.hostElement.classList.remove(className);
26769
- }
27413
+ cleanupPinnedClasses() {
27414
+ [this.hostElement, document.body].forEach(host => {
27415
+ host.classList.forEach(className => {
27416
+ if (className.startsWith('clr-side-panel-pinned-')) {
27417
+ host.classList.remove(className);
27418
+ }
27419
+ });
26770
27420
  });
26771
27421
  }
27422
+ updatePinnedClasses() {
27423
+ this.cleanupPinnedClasses();
27424
+ this.hostElement.classList.add(`clr-side-panel-pinned-${this.position}-${this.size}`);
27425
+ }
26772
27426
  }
26773
27427
  ClrSidePanel.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrSidePanel, deps: [{ token: i0.ElementRef }, { token: ClrModalConfigurationService }, { token: ClrCommonStringsService }], target: i0.ɵɵFactoryTarget.Component });
26774
- ClrSidePanel.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrSidePanel, selector: "clr-side-panel", inputs: { _open: ["clrSidePanelOpen", "_open"], closeButtonAriaLabel: ["clrSidePanelCloseButtonAriaLabel", "closeButtonAriaLabel"], skipAnimation: ["clrSidePanelSkipAnimation", "skipAnimation"], labelledById: ["clrSidePanelLabelledById", "labelledById"], staticBackdrop: ["clrSidePanelStaticBackdrop", "staticBackdrop"], preventClose: ["clrSidePanelPreventClose", "preventClose"], size: ["clrSidePanelSize", "size"], clrSidePanelBackdrop: "clrSidePanelBackdrop", clrSidePanelPinnable: "clrSidePanelPinnable" }, outputs: { openChange: "clrSidePanelOpenChange", altClose: "clrSidePanelAlternateClose" }, host: { listeners: { "document:pointerup": "documentClick($event)" }, properties: { "class.side-panel": "true" } }, viewQueries: [{ propertyName: "modal", first: true, predicate: ClrModal, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<clr-modal\n [clrModalOpen]=\"_open\"\n (clrModalOpenChange)=\"openChange.emit($event)\"\n [clrModalCloseButtonAriaLabel]=\"closeButtonAriaLabel\"\n [clrModalSize]=\"size\"\n [clrModalSkipAnimation]=\"skipAnimation\"\n [clrModalStaticBackdrop]=\"staticBackdrop\"\n [clrModalLabelledById]=\"labelledById\"\n [clrModalPreventClose]=\"preventClose\"\n (clrModalAlternateClose)=\"altClose.emit($event)\"\n [clrModalOverrideScrollService]=\"true\"\n>\n <button\n type=\"button\"\n [attr.aria-label]=\"commonStrings.keys.sidePanelPin\"\n class=\"leading-button pinnable\"\n *ngIf=\"clrSidePanelPinnable\"\n (click)=\"togglePinned()\"\n >\n <cds-icon [attr.shape]=\"pinned ? 'unpin' : 'pin'\"></cds-icon>\n </button>\n <div class=\"modal-title\"><ng-content select=\".side-panel-title\"></ng-content></div>\n <div class=\"modal-body\"><ng-content select=\".side-panel-body\"></ng-content></div>\n <div class=\"modal-footer\"><ng-content select=\".side-panel-footer\"></ng-content></div>\n</clr-modal>\n", dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }, { 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" }] });
27428
+ ClrSidePanel.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrSidePanel, selector: "clr-side-panel", inputs: { closeButtonAriaLabel: ["clrSidePanelCloseButtonAriaLabel", "closeButtonAriaLabel"], skipAnimation: ["clrSidePanelSkipAnimation", "skipAnimation"], labelledById: ["clrSidePanelLabelledById", "labelledById"], staticBackdrop: ["clrSidePanelStaticBackdrop", "staticBackdrop"], closable: ["clrSidePanelClosable", "closable"], preventClose: ["clrSidePanelPreventClose", "preventClose"], _open: ["clrSidePanelOpen", "_open"], size: ["clrSidePanelSize", "size"], position: ["clrSidePanelPosition", "position"], pinned: ["clrSidePanelPinned", "pinned"], clrSidePanelBackdrop: "clrSidePanelBackdrop", clrSidePanelPinnable: "clrSidePanelPinnable" }, outputs: { openChange: "clrSidePanelOpenChange", altClose: "clrSidePanelAlternateClose" }, host: { listeners: { "document:pointerup": "documentClick($event)" }, properties: { "class.side-panel": "true", "class.side-panel-bottom": "this.bottomPositionCssClass" } }, viewQueries: [{ propertyName: "modal", first: true, predicate: ClrModal, descendants: true }], ngImport: i0, template: "<clr-modal\n [clrModalOpen]=\"_open\"\n (clrModalOpenChange)=\"handleModalOpen($event)\"\n [clrModalCloseButtonAriaLabel]=\"closeButtonAriaLabel\"\n [clrModalSize]=\"size\"\n [clrModalSkipAnimation]=\"skipAnimation\"\n [clrModalStaticBackdrop]=\"staticBackdrop\"\n [clrModalLabelledById]=\"labelledById\"\n [clrModalPreventClose]=\"preventClose\"\n [clrModalClosable]=\"closable\"\n (clrModalAlternateClose)=\"altClose.emit($event)\"\n [clrModalOverrideScrollService]=\"true\"\n>\n <button\n type=\"button\"\n [attr.aria-label]=\"commonStrings.keys.sidePanelPin\"\n class=\"leading-button pinnable\"\n *ngIf=\"clrSidePanelPinnable\"\n (click)=\"togglePinned()\"\n >\n <cds-icon [attr.shape]=\"pinned ? 'unpin' : 'pin'\"></cds-icon>\n </button>\n <div class=\"modal-title\"><ng-content select=\".side-panel-title\"></ng-content></div>\n <div class=\"modal-body\"><ng-content select=\".side-panel-body\"></ng-content></div>\n <div class=\"modal-footer\"><ng-content select=\".side-panel-footer\"></ng-content></div>\n</clr-modal>\n", dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }, { 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" }] });
26775
27429
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrSidePanel, decorators: [{
26776
27430
  type: Component,
26777
27431
  args: [{ selector: 'clr-side-panel', host: {
26778
27432
  '[class.side-panel]': 'true',
26779
- }, template: "<clr-modal\n [clrModalOpen]=\"_open\"\n (clrModalOpenChange)=\"openChange.emit($event)\"\n [clrModalCloseButtonAriaLabel]=\"closeButtonAriaLabel\"\n [clrModalSize]=\"size\"\n [clrModalSkipAnimation]=\"skipAnimation\"\n [clrModalStaticBackdrop]=\"staticBackdrop\"\n [clrModalLabelledById]=\"labelledById\"\n [clrModalPreventClose]=\"preventClose\"\n (clrModalAlternateClose)=\"altClose.emit($event)\"\n [clrModalOverrideScrollService]=\"true\"\n>\n <button\n type=\"button\"\n [attr.aria-label]=\"commonStrings.keys.sidePanelPin\"\n class=\"leading-button pinnable\"\n *ngIf=\"clrSidePanelPinnable\"\n (click)=\"togglePinned()\"\n >\n <cds-icon [attr.shape]=\"pinned ? 'unpin' : 'pin'\"></cds-icon>\n </button>\n <div class=\"modal-title\"><ng-content select=\".side-panel-title\"></ng-content></div>\n <div class=\"modal-body\"><ng-content select=\".side-panel-body\"></ng-content></div>\n <div class=\"modal-footer\"><ng-content select=\".side-panel-footer\"></ng-content></div>\n</clr-modal>\n" }]
26780
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: ClrModalConfigurationService }, { type: ClrCommonStringsService }]; }, propDecorators: { _open: [{
26781
- type: Input,
26782
- args: ['clrSidePanelOpen']
26783
- }], openChange: [{
27433
+ }, template: "<clr-modal\n [clrModalOpen]=\"_open\"\n (clrModalOpenChange)=\"handleModalOpen($event)\"\n [clrModalCloseButtonAriaLabel]=\"closeButtonAriaLabel\"\n [clrModalSize]=\"size\"\n [clrModalSkipAnimation]=\"skipAnimation\"\n [clrModalStaticBackdrop]=\"staticBackdrop\"\n [clrModalLabelledById]=\"labelledById\"\n [clrModalPreventClose]=\"preventClose\"\n [clrModalClosable]=\"closable\"\n (clrModalAlternateClose)=\"altClose.emit($event)\"\n [clrModalOverrideScrollService]=\"true\"\n>\n <button\n type=\"button\"\n [attr.aria-label]=\"commonStrings.keys.sidePanelPin\"\n class=\"leading-button pinnable\"\n *ngIf=\"clrSidePanelPinnable\"\n (click)=\"togglePinned()\"\n >\n <cds-icon [attr.shape]=\"pinned ? 'unpin' : 'pin'\"></cds-icon>\n </button>\n <div class=\"modal-title\"><ng-content select=\".side-panel-title\"></ng-content></div>\n <div class=\"modal-body\"><ng-content select=\".side-panel-body\"></ng-content></div>\n <div class=\"modal-footer\"><ng-content select=\".side-panel-footer\"></ng-content></div>\n</clr-modal>\n" }]
27434
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: ClrModalConfigurationService }, { type: ClrCommonStringsService }]; }, propDecorators: { openChange: [{
26784
27435
  type: Output,
26785
27436
  args: ['clrSidePanelOpenChange']
26786
27437
  }], closeButtonAriaLabel: [{
@@ -26795,22 +27446,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
26795
27446
  }], staticBackdrop: [{
26796
27447
  type: Input,
26797
27448
  args: ['clrSidePanelStaticBackdrop']
27449
+ }], closable: [{
27450
+ type: Input,
27451
+ args: ['clrSidePanelClosable']
26798
27452
  }], preventClose: [{
26799
27453
  type: Input,
26800
27454
  args: ['clrSidePanelPreventClose']
26801
27455
  }], altClose: [{
26802
27456
  type: Output,
26803
27457
  args: ['clrSidePanelAlternateClose']
26804
- }], modal: [{
26805
- type: ViewChild,
26806
- args: [ClrModal]
27458
+ }], _open: [{
27459
+ type: Input,
27460
+ args: ['clrSidePanelOpen']
26807
27461
  }], size: [{
26808
27462
  type: Input,
26809
27463
  args: ['clrSidePanelSize']
27464
+ }], position: [{
27465
+ type: Input,
27466
+ args: ['clrSidePanelPosition']
27467
+ }], pinned: [{
27468
+ type: Input,
27469
+ args: ['clrSidePanelPinned']
26810
27470
  }], clrSidePanelBackdrop: [{
26811
27471
  type: Input
26812
27472
  }], clrSidePanelPinnable: [{
26813
27473
  type: Input
27474
+ }], modal: [{
27475
+ type: ViewChild,
27476
+ args: [ClrModal]
27477
+ }], bottomPositionCssClass: [{
27478
+ type: HostBinding,
27479
+ args: ['class.side-panel-bottom']
26814
27480
  }], documentClick: [{
26815
27481
  type: HostListener,
26816
27482
  args: ['document:pointerup', ['$event']]
@@ -29183,10 +29849,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
29183
29849
  * The full license information can be found in LICENSE in the root directory of this project.
29184
29850
  */
29185
29851
  class ClrWizardStepnavItem {
29186
- constructor(navService, pageCollection, commonStrings) {
29852
+ constructor(navService, pageCollection, commonStrings, elementRef) {
29187
29853
  this.navService = navService;
29188
29854
  this.pageCollection = pageCollection;
29189
29855
  this.commonStrings = commonStrings;
29856
+ this.elementRef = elementRef;
29857
+ /**
29858
+ * This is used to prevent the steps from scrolling as the user clicks on the steps.
29859
+ */
29860
+ this.skipNextScroll = false;
29190
29861
  }
29191
29862
  get id() {
29192
29863
  this.pageGuard();
@@ -29232,12 +29903,42 @@ class ClrWizardStepnavItem {
29232
29903
  const allIds = this.isComplete ? [this.stepIconId, ...textIds] : textIds;
29233
29904
  return allIds.join(' ');
29234
29905
  }
29906
+ get icon() {
29907
+ if (this.isCurrent) {
29908
+ return {
29909
+ shape: 'dot-circle',
29910
+ label: this.commonStrings.keys.wizardStepCurrent || this.commonStrings.keys.timelineStepCurrent,
29911
+ };
29912
+ }
29913
+ else if (this.hasError) {
29914
+ return {
29915
+ shape: 'error-standard',
29916
+ label: this.commonStrings.keys.wizardStepError || this.commonStrings.keys.timelineStepError,
29917
+ };
29918
+ }
29919
+ else if (this.isComplete) {
29920
+ return {
29921
+ shape: 'success-standard',
29922
+ label: this.commonStrings.keys.wizardStepSuccess || this.commonStrings.keys.timelineStepSuccess,
29923
+ };
29924
+ }
29925
+ else {
29926
+ return null;
29927
+ }
29928
+ }
29929
+ ngOnInit() {
29930
+ this.subscription = this.ensureCurrentStepIsScrolledIntoView().subscribe();
29931
+ }
29932
+ ngOnDestroy() {
29933
+ this.subscription?.unsubscribe();
29934
+ }
29235
29935
  click() {
29236
29936
  this.pageGuard();
29237
29937
  // if we click on our own stepnav or a disabled stepnav, we don't want to do anything
29238
29938
  if (this.isDisabled || this.isCurrent) {
29239
29939
  return;
29240
29940
  }
29941
+ this.skipNextScroll = true;
29241
29942
  this.navService.goTo(this.page);
29242
29943
  }
29243
29944
  pageGuard() {
@@ -29245,8 +29946,20 @@ class ClrWizardStepnavItem {
29245
29946
  throw new Error('Wizard stepnav item is not associated with a wizard page.');
29246
29947
  }
29247
29948
  }
29949
+ ensureCurrentStepIsScrolledIntoView() {
29950
+ // Don't use "smooth" scrolling when the wizard is first opened to avoid a delay in scrolling the current step into view.
29951
+ // The current step when the wizard is opened might not be the first step. For example, the wizard can be closed and re-opened.
29952
+ let scrollBehavior = 'auto';
29953
+ return this.navService.currentPageChanged.pipe(startWith$1(this.navService.currentPage), tap$1(currentPage => {
29954
+ if (!this.skipNextScroll && currentPage === this.page) {
29955
+ this.elementRef.nativeElement.scrollIntoView({ behavior: scrollBehavior, block: 'center', inline: 'center' });
29956
+ }
29957
+ scrollBehavior = 'smooth';
29958
+ this.skipNextScroll = false;
29959
+ }));
29960
+ }
29248
29961
  }
29249
- ClrWizardStepnavItem.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrWizardStepnavItem, deps: [{ token: WizardNavigationService }, { token: PageCollectionService }, { token: ClrCommonStringsService }], target: i0.ɵɵFactoryTarget.Component });
29962
+ ClrWizardStepnavItem.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrWizardStepnavItem, deps: [{ token: WizardNavigationService }, { token: PageCollectionService }, { token: ClrCommonStringsService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
29250
29963
  ClrWizardStepnavItem.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrWizardStepnavItem, selector: "[clr-wizard-stepnav-item]", inputs: { page: "page" }, host: { properties: { "id": "id", "attr.aria-current": "stepAriaCurrent", "attr.aria-controls": "page.id", "class.clr-nav-link": "true", "class.nav-item": "true", "class.active": "isCurrent", "class.disabled": "isDisabled", "class.no-click": "!canNavigate", "class.complete": "isComplete", "class.error": "hasError" } }, ngImport: i0, template: `
29251
29964
  <button
29252
29965
  type="button"
@@ -29257,18 +29970,12 @@ ClrWizardStepnavItem.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", v
29257
29970
  >
29258
29971
  <div class="clr-wizard-stepnav-link-icon">
29259
29972
  <cds-icon
29260
- *ngIf="hasError"
29261
- [id]="stepIconId"
29262
- shape="error-standard"
29263
- role="img"
29264
- [attr.aria-label]="commonStrings.keys.wizardStepError"
29265
- ></cds-icon>
29266
- <cds-icon
29267
- *ngIf="!hasError && isComplete"
29973
+ *ngIf="icon; let icon"
29268
29974
  [id]="stepIconId"
29269
- shape="success-standard"
29270
29975
  role="img"
29271
- [attr.aria-label]="commonStrings.keys.wizardStepSuccess"
29976
+ class="clr-wizard-stepnav-link-icon"
29977
+ [attr.shape]="icon.shape"
29978
+ [attr.aria-label]="icon.label"
29272
29979
  ></cds-icon>
29273
29980
  </div>
29274
29981
 
@@ -29295,18 +30002,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
29295
30002
  >
29296
30003
  <div class="clr-wizard-stepnav-link-icon">
29297
30004
  <cds-icon
29298
- *ngIf="hasError"
29299
- [id]="stepIconId"
29300
- shape="error-standard"
29301
- role="img"
29302
- [attr.aria-label]="commonStrings.keys.wizardStepError"
29303
- ></cds-icon>
29304
- <cds-icon
29305
- *ngIf="!hasError && isComplete"
30005
+ *ngIf="icon; let icon"
29306
30006
  [id]="stepIconId"
29307
- shape="success-standard"
29308
30007
  role="img"
29309
- [attr.aria-label]="commonStrings.keys.wizardStepSuccess"
30008
+ class="clr-wizard-stepnav-link-icon"
30009
+ [attr.shape]="icon.shape"
30010
+ [attr.aria-label]="icon.label"
29310
30011
  ></cds-icon>
29311
30012
  </div>
29312
30013
 
@@ -29332,7 +30033,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
29332
30033
  '[class.error]': 'hasError',
29333
30034
  },
29334
30035
  }]
29335
- }], ctorParameters: function () { return [{ type: WizardNavigationService }, { type: PageCollectionService }, { type: ClrCommonStringsService }]; }, propDecorators: { page: [{
30036
+ }], ctorParameters: function () { return [{ type: WizardNavigationService }, { type: PageCollectionService }, { type: ClrCommonStringsService }, { type: i0.ElementRef }]; }, propDecorators: { page: [{
29336
30037
  type: Input,
29337
30038
  args: ['page']
29338
30039
  }] } });
@@ -29410,6 +30111,15 @@ class ClrWizard {
29410
30111
  * Set the modal size of the wizard. Set using `[clrWizardSize]` input.
29411
30112
  */
29412
30113
  this.size = 'xl';
30114
+ /**
30115
+ * Enable "in page" wizard. Set using `[clrWizardInPage]` input.
30116
+ */
30117
+ this.inPage = false;
30118
+ /**
30119
+ * Make an "in page" wizard fill the `.content-area`. Set using `[clrWizardInPageFillContentArea]` input.
30120
+ * If you can't use this option, you will likely need to provide custom CSS to set the wizard's height and margins.
30121
+ */
30122
+ this.inPageFillContentArea = false;
29413
30123
  /**
29414
30124
  * Tells the modal part of the wizard whether it should have a close "X"
29415
30125
  * in the top right corner. Set using `[clrWizardClosable]` input.
@@ -29568,6 +30278,9 @@ class ClrWizard {
29568
30278
  ngAfterContentInit() {
29569
30279
  this.pageCollection.pages = this.pages;
29570
30280
  this.headerActionService.wizardHeaderActions = this.headerActions;
30281
+ if (this.inPage) {
30282
+ this.open();
30283
+ }
29571
30284
  this.initializeButtons();
29572
30285
  }
29573
30286
  ngDoCheck() {
@@ -29762,7 +30475,7 @@ class ClrWizard {
29762
30475
  this.pageTitle?.nativeElement.focus();
29763
30476
  this.currentPageChanged.emit();
29764
30477
  // scroll to top of page in case there is long page content
29765
- this.modal?.scrollTop();
30478
+ this.bodyElementRef?.nativeElement.scrollTo(0, 0);
29766
30479
  });
29767
30480
  }
29768
30481
  updateNavOnPageChanges() {
@@ -29786,7 +30499,7 @@ class ClrWizard {
29786
30499
  }
29787
30500
  }
29788
30501
  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 });
29789
- 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"] }] });
30502
+ ClrWizard.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrWizard, selector: "clr-wizard", inputs: { stepnavAriaLabel: ["clrWizardStepnavAriaLabel", "stepnavAriaLabel"], size: ["clrWizardSize", "size"], inPage: ["clrWizardInPage", "inPage"], inPageFillContentArea: ["clrWizardInPageFillContentArea", "inPageFillContentArea"], 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.wizard-in-page": "inPage", "class.wizard-in-page--fill-content-area": "inPage && inPageFillContentArea" } }, 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: "bodyElementRef", first: true, predicate: ["body"], 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<ng-container *ngIf=\"inPage; then wizardTemplate; else wizardModalTemplate\"></ng-container>\n\n<ng-template #wizardModalTemplate>\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 <ng-template #clrInternalModalContentTemplate>\n <ng-container [ngTemplateOutlet]=\"wizardTemplate\"></ng-container>\n </ng-template>\n </clr-modal>\n</ng-template>\n\n<!-- This template is tightly coupled to the modal styles. -->\n<ng-template #wizardTemplate>\n <div class=\"modal-content-wrapper\">\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-content\">\n <div class=\"modal-header--accessible\">\n <div class=\"modal-title-wrapper\" #title cdkFocusInitial tabindex=\"-1\">\n <div\n class=\"modal-title\"\n role=\"heading\"\n [attr.aria-level]=\"navService.currentPage?.pageTitle.headingLevel || 2\"\n >\n <span tabindex=\"-1\" #pageTitle class=\"modal-title-text\">\n <ng-template [ngTemplateOutlet]=\"navService.currentPageTitle\"></ng-template>\n </span>\n </div>\n </div>\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 <button\n *ngIf=\"closable && !inPage\"\n type=\"button\"\n class=\"close\"\n [attr.aria-label]=\"commonStrings.keys.close\"\n (click)=\"modalCancel()\"\n >\n <cds-icon shape=\"window-close\"></cds-icon>\n </button>\n </div>\n <div #body class=\"modal-body-wrapper\">\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>\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 </div>\n </div>\n</ng-template>\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: "directive", type: CdsIconCustomTag, selector: "cds-icon" }, { kind: "component", type: ClrWizardStepnav, selector: "clr-wizard-stepnav", inputs: ["label"] }] });
29790
30503
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrWizard, decorators: [{
29791
30504
  type: Component,
29792
30505
  args: [{ selector: 'clr-wizard', providers: [WizardNavigationService, PageCollectionService, ButtonHubService, HeaderActionService], host: {
@@ -29794,8 +30507,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
29794
30507
  '[class.wizard-md]': "size == 'md'",
29795
30508
  '[class.wizard-lg]': "size == 'lg'",
29796
30509
  '[class.wizard-xl]': "size == 'xl'",
29797
- '[class.lastPage]': 'navService.currentPageIsLast',
29798
- }, 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" }]
30510
+ '[class.wizard-in-page]': 'inPage',
30511
+ '[class.wizard-in-page--fill-content-area]': 'inPage && inPageFillContentArea',
30512
+ }, 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-container *ngIf=\"inPage; then wizardTemplate; else wizardModalTemplate\"></ng-container>\n\n<ng-template #wizardModalTemplate>\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 <ng-template #clrInternalModalContentTemplate>\n <ng-container [ngTemplateOutlet]=\"wizardTemplate\"></ng-container>\n </ng-template>\n </clr-modal>\n</ng-template>\n\n<!-- This template is tightly coupled to the modal styles. -->\n<ng-template #wizardTemplate>\n <div class=\"modal-content-wrapper\">\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-content\">\n <div class=\"modal-header--accessible\">\n <div class=\"modal-title-wrapper\" #title cdkFocusInitial tabindex=\"-1\">\n <div\n class=\"modal-title\"\n role=\"heading\"\n [attr.aria-level]=\"navService.currentPage?.pageTitle.headingLevel || 2\"\n >\n <span tabindex=\"-1\" #pageTitle class=\"modal-title-text\">\n <ng-template [ngTemplateOutlet]=\"navService.currentPageTitle\"></ng-template>\n </span>\n </div>\n </div>\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 <button\n *ngIf=\"closable && !inPage\"\n type=\"button\"\n class=\"close\"\n [attr.aria-label]=\"commonStrings.keys.close\"\n (click)=\"modalCancel()\"\n >\n <cds-icon shape=\"window-close\"></cds-icon>\n </button>\n </div>\n <div #body class=\"modal-body-wrapper\">\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>\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 </div>\n </div>\n</ng-template>\n" }]
29799
30513
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
29800
30514
  type: Inject,
29801
30515
  args: [PLATFORM_ID]
@@ -29805,6 +30519,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
29805
30519
  }], size: [{
29806
30520
  type: Input,
29807
30521
  args: ['clrWizardSize']
30522
+ }], inPage: [{
30523
+ type: Input,
30524
+ args: ['clrWizardInPage']
30525
+ }], inPageFillContentArea: [{
30526
+ type: Input,
30527
+ args: ['clrWizardInPageFillContentArea']
29808
30528
  }], closable: [{
29809
30529
  type: Input,
29810
30530
  args: ['clrWizardClosable']
@@ -29844,6 +30564,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
29844
30564
  }], wizardTitle: [{
29845
30565
  type: ContentChild,
29846
30566
  args: [ClrWizardTitle]
30567
+ }], bodyElementRef: [{
30568
+ type: ViewChild,
30569
+ args: ['body']
29847
30570
  }], modal: [{
29848
30571
  type: ViewChild,
29849
30572
  args: [ClrModal]
@@ -30423,9 +31146,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
30423
31146
  * The full license information can be found in LICENSE in the root directory of this project.
30424
31147
  */
30425
31148
 
31149
+ /*
31150
+ * Copyright (c) 2016-2025 Broadcom. All Rights Reserved.
31151
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
31152
+ * This software is released under MIT license.
31153
+ * The full license information can be found in LICENSE in the root directory of this project.
31154
+ */
31155
+
30426
31156
  /**
30427
31157
  * Generated bundle index. Do not edit.
30428
31158
  */
30429
31159
 
30430
- export { CHANGE_KEYS, CLR_ALERT_DIRECTIVES, CLR_BUTTON_GROUP_DIRECTIVES, CLR_DATAGRID_DIRECTIVES, CLR_DATEPICKER_DIRECTIVES, CLR_DROPDOWN_DIRECTIVES, CLR_FILE_MESSAGES_TEMPLATE_CONTEXT, CLR_ICON_DIRECTIVES, CLR_LAYOUT_DIRECTIVES, CLR_LOADING_BUTTON_DIRECTIVES, CLR_LOADING_DIRECTIVES, CLR_MENU_POSITIONS, CLR_MODAL_DIRECTIVES, CLR_NAVIGATION_DIRECTIVES, CLR_PROGRESS_BAR_DIRECTIVES, CLR_SIDEPANEL_DIRECTIVES, CLR_SIGNPOST_DIRECTIVES, CLR_SPINNER_DIRECTIVES, CLR_STACK_VIEW_DIRECTIVES, CLR_TABS_DIRECTIVES, CLR_TOOLTIP_DIRECTIVES, CLR_TREE_VIEW_DIRECTIVES, CLR_VERTICAL_NAV_DIRECTIVES, CLR_WIZARD_DIRECTIVES, CONDITIONAL_DIRECTIVES, CUSTOM_BUTTON_TYPES, CdsIconCustomTag, ClarityModule, ClrAbstractContainer, ClrAccordion, ClrAccordionContent, ClrAccordionDescription, ClrAccordionModule, ClrAccordionPanel, ClrAccordionTitle, ClrAlert, ClrAlertItem, ClrAlertModule, ClrAlertText, ClrAlerts, ClrAlertsPager, ClrAlignment, ClrAriaCurrentLink, ClrAxis, ClrBreadcrumbItem, ClrBreadcrumbs, ClrBreadcrumbsModule, ClrButton, ClrButtonGroup, ClrButtonGroupModule, ClrButtonModule, ClrCalendar, ClrCheckbox, ClrCheckboxContainer, ClrCheckboxModule, ClrCheckboxWrapper, ClrCombobox, ClrComboboxContainer, ClrComboboxModule, ClrCommonFormsModule, ClrCommonStringsService, ClrConditionalModule, ClrControl, ClrControlContainer, ClrControlError, ClrControlHelper, ClrControlSuccess, ClrDataModule, ClrDatagrid, ClrDatagridActionBar, ClrDatagridActionOverflow, ClrDatagridCell, ClrDatagridColumn, ClrDatagridColumnSeparator, ClrDatagridColumnToggle, ClrDatagridColumnToggleButton, ClrDatagridDetail, ClrDatagridDetailBody, ClrDatagridDetailHeader, ClrDatagridFilter, ClrDatagridFooter, ClrDatagridHideableColumn, ClrDatagridItems, ClrDatagridModule, ClrDatagridPageSize, ClrDatagridPagination, ClrDatagridPlaceholder, ClrDatagridRow, ClrDatagridRowDetail, ClrDatagridSortOrder, ClrDatalist, ClrDatalistContainer, ClrDatalistInput, ClrDatalistModule, ClrDateContainer, ClrDateInput, ClrDateInputBase, ClrDateInputValidator, ClrDatepickerActions, ClrDatepickerModule, ClrDatepickerViewManager, ClrDay, ClrDaypicker, ClrDestroyService, ClrDropdown, ClrDropdownItem, ClrDropdownMenu, ClrDropdownModule, ClrDropdownTrigger, ClrEmphasisModule, ClrEndDateInput, ClrEndDateInputValidator, ClrExpandableAnimation, ClrFileError, ClrFileInfo, ClrFileInput, ClrFileInputContainer, ClrFileInputModule, ClrFileInputValidator, ClrFileInputValueAccessor, ClrFileList, ClrFileMessagesTemplate, ClrFileSuccess, ClrFocusOnViewInit, ClrFocusOnViewInitModule, ClrForm, ClrFormLayout, ClrFormsModule, ClrHeader, ClrIconCustomTag, ClrIconModule, ClrIfActive, ClrIfDetail, ClrIfError, ClrIfExpanded, ClrIfOpen, ClrIfSuccess, ClrInput, ClrInputContainer, ClrInputModule, ClrLabel, ClrLayout, ClrLayoutModule, ClrLoading, ClrLoadingButton, ClrLoadingButtonModule, ClrLoadingModule, ClrLoadingState, ClrMainContainer, ClrMainContainerModule, ClrModal, ClrModalBody, ClrModalConfigurationService, ClrModalHostDirective, ClrModalModule, ClrMonthpicker, ClrNavLevel, ClrNavigationModule, ClrNumberInput, ClrNumberInputContainer, ClrNumberInputModule, ClrOption, ClrOptionItems, ClrOptionSelected, ClrOptions, ClrPassword, ClrPasswordContainer, ClrPasswordModule, ClrPopoverAnchor, ClrPopoverContent, ClrPopoverEventsService, ClrPopoverHostDirective, ClrPopoverModule, ClrPopoverPositionService, ClrPopoverToggleService, ClrProgressBar, ClrProgressBarModule, ClrRadio, ClrRadioContainer, ClrRadioModule, ClrRadioWrapper, ClrRange, ClrRangeContainer, ClrRangeModule, ClrRecursiveForOf, ClrSelect, ClrSelectContainer, ClrSelectModule, ClrSelectedState, ClrSide, ClrSidePanel, ClrSidePanelModule, ClrSignpost, ClrSignpostContent, ClrSignpostModule, ClrSignpostTitle, ClrSignpostTrigger, ClrSpinner, ClrSpinnerModule, ClrStackBlock, ClrStackContentInput, ClrStackHeader, ClrStackView, ClrStackViewCustomTags, ClrStackViewLabel, ClrStackViewModule, ClrStandaloneCdkTrapFocus, ClrStartDateInput, ClrStartDateInputValidator, ClrStepButton, ClrStepButtonType, ClrStepper, ClrStepperModule, ClrStepperPanel, ClrStopEscapePropagationDirective, ClrTab, ClrTabAction, ClrTabContent, ClrTabLink, ClrTabOverflowContent, ClrTabs, ClrTabsActions, ClrTabsModule, ClrTextarea, ClrTextareaContainer, ClrTextareaModule, ClrTimeline, ClrTimelineLayout, ClrTimelineModule, ClrTimelineStep, ClrTimelineStepDescription, ClrTimelineStepHeader, ClrTimelineStepState, ClrTimelineStepTitle, ClrTooltip, ClrTooltipContent, ClrTooltipModule, ClrTooltipTrigger, ClrTree, ClrTreeNode, ClrTreeNodeLink, ClrTreeViewModule, ClrVerticalNav, ClrVerticalNavGroup, ClrVerticalNavGroupChildren, ClrVerticalNavIcon, ClrVerticalNavLink, ClrVerticalNavModule, ClrWizard, ClrWizardButton, ClrWizardHeaderAction, ClrWizardModule, ClrWizardPage, ClrWizardPageButtons, ClrWizardPageHeaderActions, ClrWizardPageNavTitle, ClrWizardPageTitle, ClrWizardStepnav, ClrWizardStepnavItem, ClrWizardTitle, ClrYearpicker, DEFAULT_BUTTON_TYPES, DatagridNumericFilter, DatagridPropertyComparator, DatagridPropertyNumericFilter, DatagridPropertyStringFilter, DatagridStringFilter, EXPANDABLE_ANIMATION_DIRECTIVES, FOCUS_ON_VIEW_INIT, FOCUS_ON_VIEW_INIT_DIRECTIVES, IS_TOGGLE, IS_TOGGLE_PROVIDER, LoadingListener, MainContainerWillyWonka, NavDetectionOompaLoompa, TOGGLE_SERVICE, TOGGLE_SERVICE_PROVIDER, ToggleServiceFactory, WrappedFormControl, collapse, commonStringsDefault, fade, fadeSlide, isToggleFactory, slide, AccordionOompaLoompa as ÇlrAccordionOompaLoompa, AccordionWillyWonka as ÇlrAccordionWillyWonka, ActionableOompaLoompa as ÇlrActionableOompaLoompa, ActiveOompaLoompa as ÇlrActiveOompaLoompa, ClrPopoverCloseButton as ÇlrClrPopoverCloseButton, ClrPopoverModuleNext as ÇlrClrPopoverModuleNext, ClrPopoverOpenCloseButton as ÇlrClrPopoverOpenCloseButton, DatagridCellRenderer as ÇlrDatagridCellRenderer, DatagridDetailRegisterer as ÇlrDatagridDetailRegisterer, DatagridHeaderRenderer as ÇlrDatagridHeaderRenderer, DatagridMainRenderer as ÇlrDatagridMainRenderer, DatagridRowRenderer as ÇlrDatagridRowRenderer, ClrDatagridSelectionCellDirective as ÇlrDatagridSelectionCellDirective, ClrDatagridVirtualScrollDirective as ÇlrDatagridVirtualScrollDirective, DatagridWillyWonka as ÇlrDatagridWillyWonka, ExpandableOompaLoompa as ÇlrExpandableOompaLoompa, StepperOompaLoompa as ÇlrStepperOompaLoompa, StepperWillyWonka as ÇlrStepperWillyWonka, TabsWillyWonka as ÇlrTabsWillyWonka, WrappedCell as ÇlrWrappedCell, WrappedColumn as ÇlrWrappedColumn, WrappedRow as ÇlrWrappedRow };
31160
+ export { BaseExpandableAnimation, CHANGE_KEYS, CLR_ALERT_DIRECTIVES, CLR_BUTTON_GROUP_DIRECTIVES, CLR_DATAGRID_DIRECTIVES, CLR_DATEPICKER_DIRECTIVES, CLR_DROPDOWN_DIRECTIVES, CLR_FILE_MESSAGES_TEMPLATE_CONTEXT, CLR_ICON_DIRECTIVES, CLR_LAYOUT_DIRECTIVES, CLR_LOADING_BUTTON_DIRECTIVES, CLR_LOADING_DIRECTIVES, CLR_MENU_POSITIONS, CLR_MODAL_DIRECTIVES, CLR_NAVIGATION_DIRECTIVES, CLR_PROGRESS_BAR_DIRECTIVES, CLR_SIDEPANEL_DIRECTIVES, CLR_SIGNPOST_DIRECTIVES, CLR_SPINNER_DIRECTIVES, CLR_STACK_VIEW_DIRECTIVES, CLR_TABS_DIRECTIVES, CLR_TOOLTIP_DIRECTIVES, CLR_TREE_VIEW_DIRECTIVES, CLR_VERTICAL_NAV_DIRECTIVES, CLR_WIZARD_DIRECTIVES, CONDITIONAL_DIRECTIVES, CUSTOM_BUTTON_TYPES, CdsIconCustomTag, ClarityModule, ClrAbstractContainer, ClrAccordion, ClrAccordionContent, ClrAccordionDescription, ClrAccordionModule, ClrAccordionPanel, ClrAccordionTitle, ClrAlert, ClrAlertItem, ClrAlertModule, ClrAlertText, ClrAlerts, ClrAlertsPager, ClrAlignment, ClrAriaCurrentLink, ClrAxis, ClrBreadcrumbItem, ClrBreadcrumbs, ClrBreadcrumbsModule, ClrButton, ClrButtonGroup, ClrButtonGroupModule, ClrButtonModule, ClrCalendar, ClrCheckbox, ClrCheckboxContainer, ClrCheckboxModule, ClrCheckboxWrapper, ClrCombobox, ClrComboboxContainer, ClrComboboxModule, ClrCommonFormsModule, ClrCommonStringsService, ClrConditionalModule, ClrControl, ClrControlContainer, ClrControlError, ClrControlHelper, ClrControlSuccess, ClrDataModule, ClrDatagrid, ClrDatagridActionBar, ClrDatagridActionOverflow, ClrDatagridCell, ClrDatagridColumn, ClrDatagridColumnSeparator, ClrDatagridColumnToggle, ClrDatagridColumnToggleButton, ClrDatagridDetail, ClrDatagridDetailBody, ClrDatagridDetailHeader, ClrDatagridFilter, ClrDatagridFooter, ClrDatagridHideableColumn, ClrDatagridItems, ClrDatagridModule, ClrDatagridPageSize, ClrDatagridPagination, ClrDatagridPlaceholder, ClrDatagridRow, ClrDatagridRowDetail, ClrDatagridSortOrder, ClrDatalist, ClrDatalistContainer, ClrDatalistInput, ClrDatalistModule, ClrDateContainer, ClrDateInput, ClrDateInputBase, ClrDateInputValidator, ClrDatepickerActions, ClrDatepickerModule, ClrDatepickerViewManager, ClrDay, ClrDaypicker, ClrDestroyService, ClrDropdown, ClrDropdownItem, ClrDropdownMenu, ClrDropdownModule, ClrDropdownTrigger, ClrEmphasisModule, ClrEndDateInput, ClrEndDateInputValidator, ClrExpandableAnimation, ClrFileError, ClrFileInfo, ClrFileInput, ClrFileInputContainer, ClrFileInputModule, ClrFileInputValidator, ClrFileInputValueAccessor, ClrFileList, ClrFileMessagesTemplate, ClrFileSuccess, ClrFocusOnViewInit, ClrFocusOnViewInitModule, ClrForm, ClrFormLayout, ClrFormsModule, ClrHeader, ClrIconCustomTag, ClrIconModule, ClrIfActive, ClrIfDetail, ClrIfError, ClrIfExpanded, ClrIfOpen, ClrIfSuccess, ClrInput, ClrInputContainer, ClrInputModule, ClrLabel, ClrLayout, ClrLayoutModule, ClrLoading, ClrLoadingButton, ClrLoadingButtonModule, ClrLoadingModule, ClrLoadingState, ClrMainContainer, ClrMainContainerModule, ClrModal, ClrModalBody, ClrModalConfigurationService, ClrModalHostComponent, ClrModalModule, ClrMonthpicker, ClrNavLevel, ClrNavigationModule, ClrNumberInput, ClrNumberInputContainer, ClrNumberInputModule, ClrOption, ClrOptionGroup, ClrOptionItems, ClrOptionSelected, ClrOptions, ClrPassword, ClrPasswordContainer, ClrPasswordModule, ClrPopoverAnchor, ClrPopoverContent, ClrPopoverEventsService, ClrPopoverHostDirective, ClrPopoverModule, ClrPopoverPositionService, ClrPopoverToggleService, ClrProgressBar, ClrProgressBarModule, ClrRadio, ClrRadioContainer, ClrRadioModule, ClrRadioWrapper, ClrRange, ClrRangeContainer, ClrRangeModule, ClrRecursiveForOf, ClrSelect, ClrSelectContainer, ClrSelectModule, ClrSelectedState, ClrSide, ClrSidePanel, ClrSidePanelModule, ClrSignpost, ClrSignpostContent, ClrSignpostModule, ClrSignpostTitle, ClrSignpostTrigger, ClrSpinner, ClrSpinnerModule, ClrStackBlock, ClrStackContentInput, ClrStackHeader, ClrStackView, ClrStackViewCustomTags, ClrStackViewLabel, ClrStackViewModule, ClrStandaloneCdkTrapFocus, ClrStartDateInput, ClrStartDateInputValidator, ClrStepButton, ClrStepButtonType, ClrStepper, ClrStepperModule, ClrStepperPanel, ClrStopEscapePropagationDirective, ClrTab, ClrTabAction, ClrTabContent, ClrTabLink, ClrTabOverflowContent, ClrTabs, ClrTabsActions, ClrTabsModule, ClrTextarea, ClrTextareaContainer, ClrTextareaModule, ClrTimeline, ClrTimelineLayout, ClrTimelineModule, ClrTimelineStep, ClrTimelineStepDescription, ClrTimelineStepHeader, ClrTimelineStepState, ClrTimelineStepTitle, ClrTooltip, ClrTooltipContent, ClrTooltipModule, ClrTooltipTrigger, ClrTree, ClrTreeNode, ClrTreeNodeLink, ClrTreeViewModule, ClrVerticalNav, ClrVerticalNavGroup, ClrVerticalNavGroupChildren, ClrVerticalNavIcon, ClrVerticalNavLink, ClrVerticalNavModule, ClrWizard, ClrWizardButton, ClrWizardHeaderAction, ClrWizardModule, ClrWizardPage, ClrWizardPageButtons, ClrWizardPageHeaderActions, ClrWizardPageNavTitle, ClrWizardPageTitle, ClrWizardStepnav, ClrWizardStepnavItem, ClrWizardTitle, ClrYearpicker, DEFAULT_BUTTON_TYPES, DatagridNumericFilter, DatagridPropertyComparator, DatagridPropertyNumericFilter, DatagridPropertyStringFilter, DatagridStringFilter, EXPANDABLE_ANIMATION_DIRECTIVES, FOCUS_ON_VIEW_INIT, FOCUS_ON_VIEW_INIT_DIRECTIVES, IS_TOGGLE, IS_TOGGLE_PROVIDER, LoadingListener, MainContainerWillyWonka, NavDetectionOompaLoompa, TOGGLE_SERVICE, TOGGLE_SERVICE_PROVIDER, ToggleServiceFactory, WrappedFormControl, collapse, commonStringsDefault, fade, fadeSlide, isToggleFactory, slide, AccordionOompaLoompa as ÇlrAccordionOompaLoompa, AccordionWillyWonka as ÇlrAccordionWillyWonka, ActionableOompaLoompa as ÇlrActionableOompaLoompa, ActiveOompaLoompa as ÇlrActiveOompaLoompa, ClrPopoverCloseButton as ÇlrClrPopoverCloseButton, ClrPopoverModuleNext as ÇlrClrPopoverModuleNext, ClrPopoverOpenCloseButton as ÇlrClrPopoverOpenCloseButton, DatagridCellRenderer as ÇlrDatagridCellRenderer, DatagridDetailRegisterer as ÇlrDatagridDetailRegisterer, DatagridHeaderRenderer as ÇlrDatagridHeaderRenderer, DatagridMainRenderer as ÇlrDatagridMainRenderer, DatagridRowRenderer as ÇlrDatagridRowRenderer, ClrDatagridSelectionCellDirective as ÇlrDatagridSelectionCellDirective, ClrDatagridVirtualScrollDirective as ÇlrDatagridVirtualScrollDirective, DatagridWillyWonka as ÇlrDatagridWillyWonka, ExpandableOompaLoompa as ÇlrExpandableOompaLoompa, StepperOompaLoompa as ÇlrStepperOompaLoompa, StepperWillyWonka as ÇlrStepperWillyWonka, TabsWillyWonka as ÇlrTabsWillyWonka, WrappedCell as ÇlrWrappedCell, WrappedColumn as ÇlrWrappedColumn, WrappedRow as ÇlrWrappedRow };
30431
31161
  //# sourceMappingURL=clr-angular.mjs.map