@clr/angular 17.1.0 → 17.2.1

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 (91) hide show
  1. package/clarity.api.md +401 -145
  2. package/clr-angular.module.d.ts +7 -6
  3. package/data/datagrid/datagrid-detail-header.d.ts +4 -1
  4. package/data/datagrid/datagrid-detail.d.ts +5 -1
  5. package/data/datagrid/datagrid-filter.d.ts +4 -2
  6. package/data/datagrid/datagrid-if-detail.d.ts +9 -0
  7. package/data/datagrid/datagrid-virtual-scroll.directive.d.ts +62 -0
  8. package/data/datagrid/datagrid.d.ts +8 -4
  9. package/data/datagrid/datagrid.module.d.ts +31 -30
  10. package/data/datagrid/enums/column-changes.enum.d.ts +2 -1
  11. package/data/datagrid/index.d.ts +1 -0
  12. package/data/datagrid/interfaces/column-state.interface.d.ts +1 -0
  13. package/data/datagrid/providers/columns.service.d.ts +1 -0
  14. package/data/datagrid/providers/detail.service.d.ts +4 -0
  15. package/data/datagrid/render/cell-renderer.d.ts +3 -6
  16. package/data/datagrid/render/header-renderer.d.ts +2 -3
  17. package/data/datagrid/render/main-renderer.d.ts +5 -1
  18. package/data/datagrid/render/row-renderer.d.ts +4 -3
  19. package/data/datagrid/utils/key-navigation-grid.controller.d.ts +5 -1
  20. package/esm2020/accordion/accordion-panel.mjs +3 -3
  21. package/esm2020/accordion/stepper/stepper-panel.mjs +8 -4
  22. package/esm2020/clr-angular.module.mjs +5 -1
  23. package/esm2020/data/datagrid/datagrid-action-overflow.mjs +3 -1
  24. package/esm2020/data/datagrid/datagrid-detail-header.mjs +12 -6
  25. package/esm2020/data/datagrid/datagrid-detail.mjs +36 -8
  26. package/esm2020/data/datagrid/datagrid-filter.mjs +22 -13
  27. package/esm2020/data/datagrid/datagrid-if-detail.mjs +30 -7
  28. package/esm2020/data/datagrid/datagrid-row.mjs +3 -3
  29. package/esm2020/data/datagrid/datagrid-selection-cell.directive.mjs +2 -2
  30. package/esm2020/data/datagrid/datagrid-virtual-scroll.directive.mjs +233 -0
  31. package/esm2020/data/datagrid/datagrid.mjs +43 -10
  32. package/esm2020/data/datagrid/datagrid.module.mjs +5 -1
  33. package/esm2020/data/datagrid/enums/column-changes.enum.mjs +3 -2
  34. package/esm2020/data/datagrid/index.mjs +2 -1
  35. package/esm2020/data/datagrid/interfaces/column-state.interface.mjs +1 -1
  36. package/esm2020/data/datagrid/providers/columns.service.mjs +9 -3
  37. package/esm2020/data/datagrid/providers/detail.service.mjs +12 -2
  38. package/esm2020/data/datagrid/render/cell-renderer.mjs +8 -33
  39. package/esm2020/data/datagrid/render/header-renderer.mjs +25 -43
  40. package/esm2020/data/datagrid/render/main-renderer.mjs +59 -9
  41. package/esm2020/data/datagrid/render/render-organizer.mjs +2 -2
  42. package/esm2020/data/datagrid/render/row-renderer.mjs +5 -5
  43. package/esm2020/data/datagrid/utils/key-navigation-grid.controller.mjs +21 -5
  44. package/esm2020/forms/combobox/combobox.mjs +3 -3
  45. package/esm2020/forms/common/abstract-container.mjs +5 -2
  46. package/esm2020/forms/datalist/datalist-container.mjs +1 -4
  47. package/esm2020/forms/datepicker/datepicker-view-manager.mjs +3 -3
  48. package/esm2020/forms/file-input/file-input-container.mjs +157 -0
  49. package/esm2020/forms/file-input/file-input-validator.mjs +72 -0
  50. package/esm2020/forms/file-input/file-input-value-accessor.mjs +53 -0
  51. package/esm2020/forms/file-input/file-input.helpers.mjs +22 -0
  52. package/esm2020/forms/file-input/file-input.mjs +68 -0
  53. package/esm2020/forms/file-input/file-input.module.mjs +43 -0
  54. package/esm2020/forms/file-input/index.mjs +12 -0
  55. package/esm2020/forms/forms.module.mjs +5 -1
  56. package/esm2020/forms/index.mjs +2 -1
  57. package/esm2020/modal/index.mjs +3 -1
  58. package/esm2020/modal/modal-configuration.service.mjs +20 -0
  59. package/esm2020/modal/modal.mjs +47 -18
  60. package/esm2020/modal/modal.module.mjs +4 -2
  61. package/esm2020/modal/side-panel.mjs +90 -0
  62. package/esm2020/modal/side-panel.module.mjs +28 -0
  63. package/esm2020/timeline/timeline-step.mjs +3 -3
  64. package/esm2020/timeline/timeline.mjs +3 -3
  65. package/esm2020/utils/animations/expandable-animation/expandable-animation.mjs +17 -12
  66. package/esm2020/utils/dom-adapter/dom-adapter.mjs +13 -4
  67. package/esm2020/utils/i18n/common-strings.default.mjs +7 -2
  68. package/esm2020/utils/i18n/common-strings.interface.mjs +1 -1
  69. package/esm2020/wizard/wizard.mjs +29 -6
  70. package/fesm2015/clr-angular.mjs +1435 -468
  71. package/fesm2015/clr-angular.mjs.map +1 -1
  72. package/fesm2020/clr-angular.mjs +1418 -463
  73. package/fesm2020/clr-angular.mjs.map +1 -1
  74. package/forms/file-input/file-input-container.d.ts +16 -0
  75. package/forms/file-input/file-input-validator.d.ts +12 -0
  76. package/forms/file-input/file-input-value-accessor.d.ts +15 -0
  77. package/forms/file-input/file-input.d.ts +21 -0
  78. package/forms/file-input/file-input.helpers.d.ts +3 -0
  79. package/forms/file-input/file-input.module.d.ts +14 -0
  80. package/forms/file-input/index.d.ts +5 -0
  81. package/forms/forms.module.d.ts +9 -8
  82. package/forms/index.d.ts +1 -0
  83. package/modal/index.d.ts +2 -0
  84. package/modal/modal-configuration.service.d.ts +7 -0
  85. package/modal/modal.d.ts +8 -2
  86. package/modal/side-panel.d.ts +26 -0
  87. package/modal/side-panel.module.d.ts +13 -0
  88. package/package.json +2 -2
  89. package/utils/animations/expandable-animation/expandable-animation.d.ts +5 -4
  90. package/utils/i18n/common-strings.interface.d.ts +4 -0
  91. package/wizard/wizard.d.ts +12 -2
@@ -1,19 +1,23 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Directive, NgModule, Optional, Input, Injectable, Component, ChangeDetectionStrategy, EventEmitter, HostBinding, Output, ContentChildren, PLATFORM_ID, Inject, ViewChild, HostListener, SkipSelf, Renderer2, InjectionToken, ElementRef, ContentChild, ComponentFactoryResolver, KeyValueDiffers, Self, Attribute, LOCALE_ID, ViewContainerRef, NgZone, ChangeDetectorRef, TemplateRef } from '@angular/core';
2
+ import { Directive, NgModule, Optional, Input, Injectable, Component, ChangeDetectionStrategy, EventEmitter, HostBinding, Output, ContentChildren, PLATFORM_ID, Inject, ViewChild, HostListener, SkipSelf, Renderer2, InjectionToken, ElementRef, ContentChild, ComponentFactoryResolver, KeyValueDiffers, Self, Attribute, LOCALE_ID, inject, forwardRef, ViewContainerRef, NgZone, ChangeDetectorRef, TemplateRef } 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
- import { ClarityIcons, angleIcon, exclamationCircleIcon, checkCircleIcon, ellipsisHorizontalIcon, windowCloseIcon, eventIcon, calendarIcon, eyeHideIcon, eyeIcon, ellipsisVerticalIcon, viewColumnsIcon, arrowIcon, timesIcon, stepForward2Icon, angleDoubleIcon, filterGridCircleIcon, filterGridIcon, errorStandardIcon, helpIcon, infoStandardIcon, noteIcon, successStandardIcon, warningStandardIcon, infoCircleIcon, circleIcon, dotCircleIcon } from '@cds/core/icon';
5
+ import { ClarityIcons, angleIcon, exclamationCircleIcon, checkCircleIcon, ellipsisHorizontalIcon, windowCloseIcon, eventIcon, calendarIcon, folderOpenIcon, eyeHideIcon, eyeIcon, ellipsisVerticalIcon, viewColumnsIcon, arrowIcon, timesIcon, stepForward2Icon, angleDoubleIcon, filterGridCircleIcon, filterGridIcon, errorStandardIcon, helpIcon, infoStandardIcon, noteIcon, successStandardIcon, warningStandardIcon, infoCircleIcon, circleIcon, dotCircleIcon } from '@cds/core/icon';
6
6
  import { map, tap, startWith, distinctUntilChanged, filter, skipUntil, debounceTime, takeUntil, take, first, switchMap } from 'rxjs/operators';
7
7
  import * as i3 from 'rxjs';
8
8
  import { Subject, BehaviorSubject, Observable, fromEvent, isObservable, of, ReplaySubject, combineLatest, merge } from 'rxjs';
9
9
  import { trigger, transition, style, animate, state, keyframes } from '@angular/animations';
10
10
  import * as i1 from '@angular/forms';
11
- import { FormControl, FormGroup, FormsModule, NG_VALIDATORS, SelectMultipleControlValueAccessor } from '@angular/forms';
11
+ import { FormControl, FormGroup, FormsModule, NG_VALIDATORS, NG_VALUE_ACCESSOR, SelectMultipleControlValueAccessor } from '@angular/forms';
12
12
  import * as i1$1 from '@angular/cdk/a11y';
13
13
  import { CdkTrapFocus } from '@angular/cdk/a11y';
14
14
  import * as i2 from '@angular/cdk/drag-drop';
15
15
  import { CdkDrag, CDK_DROP_LIST, CDK_DRAG_CONFIG } from '@angular/cdk/drag-drop';
16
16
  import * as i1$2 from '@angular/cdk/bidi';
17
+ import { coerceNumberProperty } from '@angular/cdk/coercion';
18
+ import { _RecycleViewRepeaterStrategy } from '@angular/cdk/collections';
19
+ import * as i3$1 from '@angular/cdk/scrolling';
20
+ import { FixedSizeVirtualScrollStrategy, CdkVirtualForOf, CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
17
21
  import * as i1$3 from '@angular/router';
18
22
  import '@cds/core/internal-components/close-button/register.js';
19
23
  import '@cds/core/icon/register';
@@ -321,7 +325,7 @@ const commonStringsDefault = {
321
325
  singleSelectionAriaLabel: 'Single selection header',
322
326
  singleActionableAriaLabel: 'Single actionable header',
323
327
  detailExpandableAriaLabel: 'Toggle more row content',
324
- datagridFilterAriaLabel: 'Toggle {COLUMN} filter',
328
+ datagridFilterAriaLabel: '{COLUMN} filter',
325
329
  datagridFilterDialogAriaLabel: 'Filter dialog',
326
330
  columnSeparatorAriaLabel: 'Column resize handle',
327
331
  columnSeparatorDescription: 'Use left or right key to resize the column',
@@ -386,6 +390,11 @@ const commonStringsDefault = {
386
390
  // Accordion/Stepper
387
391
  stepComplete: 'Step {STEP} complete',
388
392
  stepError: 'Error in step {STEP}',
393
+ // File input
394
+ browse: 'Browse',
395
+ fileCount: '{COUNT} files',
396
+ clearFile: 'Clear {FILE}',
397
+ clearFiles: 'Clear {COUNT} files',
389
398
  };
390
399
 
391
400
  /*
@@ -639,10 +648,10 @@ class ClrAccordionPanel {
639
648
  }
640
649
  }
641
650
  ClrAccordionPanel.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrAccordionPanel, deps: [{ token: ClrCommonStringsService }, { token: AccordionService }, { token: IfExpandService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
642
- ClrAccordionPanel.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrAccordionPanel, selector: "clr-accordion-panel", inputs: { disabled: ["clrAccordionPanelDisabled", "disabled"], panelOpen: ["clrAccordionPanelOpen", "panelOpen"] }, outputs: { panelOpenChange: "clrAccordionPanelOpenChange" }, host: { properties: { "class.clr-accordion-panel": "true", "class.clr-accordion-panel-disabled": "this.disabled" } }, providers: [IfExpandService], queries: [{ propertyName: "accordionDescription", predicate: ClrAccordionDescription }], usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"panel | async; let panel\">\n <div [ngClass]=\"getPanelStateClasses(panel)\">\n <div class=\"clr-accordion-header\">\n <button\n type=\"button\"\n class=\"clr-accordion-header-button\"\n (click)=\"togglePanel()\"\n [id]=\"getAccordionHeaderId(panel.templateId)\"\n [disabled]=\"isAccordion && panel.disabled\"\n [attr.aria-disabled]=\"!isAccordion && 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-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 </span>\n <span class=\"clr-accordion-status\">\n <cds-icon shape=\"angle\" direction=\"right\" class=\"clr-accordion-angle\"></cds-icon>\n <span class=\"clr-accordion-number\">{{panelNumber}}.</span>\n <cds-icon status=\"danger\" shape=\"exclamation-circle\" class=\"clr-accordion-error-icon\"></cds-icon>\n <cds-icon status=\"success\" shape=\"check-circle\" class=\"clr-accordion-complete-icon\"></cds-icon>\n </span>\n <ng-content select=\"clr-accordion-title, clr-step-title\"></ng-content>\n <ng-content select=\"clr-accordion-description, clr-step-description\"></ng-content>\n </button>\n </div>\n <div\n @skipInitialRender\n role=\"region\"\n class=\"clr-accordion-content-region\"\n [id]=\"getAccordionContentId(panel.templateId)\"\n [attr.aria-hidden]=\"!panel.open\"\n [attr.aria-labelledby]=\"getAccordionHeaderId(panel.templateId)\"\n >\n <div\n *ngIf=\"panel.open\"\n @toggle\n (@toggle.done)=\"collapsePanelOnAnimationDone(panel)\"\n class=\"clr-accordion-content\"\n >\n <div class=\"clr-accordion-inner-content\">\n <ng-content></ng-content>\n </div>\n </div>\n </div>\n </div>\n</ng-container>\n", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }], animations: panelAnimation, changeDetection: i0.ChangeDetectionStrategy.OnPush });
651
+ ClrAccordionPanel.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrAccordionPanel, selector: "clr-accordion-panel", inputs: { disabled: ["clrAccordionPanelDisabled", "disabled"], panelOpen: ["clrAccordionPanelOpen", "panelOpen"] }, outputs: { panelOpenChange: "clrAccordionPanelOpenChange" }, host: { properties: { "class.clr-accordion-panel": "true", "class.clr-accordion-panel-disabled": "this.disabled" } }, providers: [IfExpandService], queries: [{ propertyName: "accordionDescription", predicate: ClrAccordionDescription }], usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"panel | async; let panel\">\n <div [ngClass]=\"getPanelStateClasses(panel)\">\n <div class=\"clr-accordion-header\">\n <button\n type=\"button\"\n class=\"clr-accordion-header-button\"\n (click)=\"togglePanel()\"\n [id]=\"getAccordionHeaderId(panel.templateId)\"\n [disabled]=\"isAccordion && panel.disabled\"\n [attr.aria-disabled]=\"!isAccordion && 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-accordion-status\">\n <cds-icon shape=\"angle\" direction=\"right\" class=\"clr-accordion-angle\"></cds-icon>\n <span class=\"clr-accordion-number\">{{panelNumber}}.</span>\n <cds-icon status=\"danger\" shape=\"exclamation-circle\" class=\"clr-accordion-error-icon\"></cds-icon>\n <cds-icon status=\"success\" shape=\"check-circle\" class=\"clr-accordion-complete-icon\"></cds-icon>\n </span>\n <ng-content select=\"clr-accordion-title, clr-step-title\"></ng-content>\n <ng-content select=\"clr-accordion-description, clr-step-description\"></ng-content>\n </button>\n <div 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: panelAnimation, changeDetection: i0.ChangeDetectionStrategy.OnPush });
643
652
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrAccordionPanel, decorators: [{
644
653
  type: Component,
645
- args: [{ selector: 'clr-accordion-panel', host: { '[class.clr-accordion-panel]': 'true' }, changeDetection: ChangeDetectionStrategy.OnPush, animations: panelAnimation, providers: [IfExpandService], template: "<ng-container *ngIf=\"panel | async; let panel\">\n <div [ngClass]=\"getPanelStateClasses(panel)\">\n <div class=\"clr-accordion-header\">\n <button\n type=\"button\"\n class=\"clr-accordion-header-button\"\n (click)=\"togglePanel()\"\n [id]=\"getAccordionHeaderId(panel.templateId)\"\n [disabled]=\"isAccordion && panel.disabled\"\n [attr.aria-disabled]=\"!isAccordion && 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-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 </span>\n <span class=\"clr-accordion-status\">\n <cds-icon shape=\"angle\" direction=\"right\" class=\"clr-accordion-angle\"></cds-icon>\n <span class=\"clr-accordion-number\">{{panelNumber}}.</span>\n <cds-icon status=\"danger\" shape=\"exclamation-circle\" class=\"clr-accordion-error-icon\"></cds-icon>\n <cds-icon status=\"success\" shape=\"check-circle\" class=\"clr-accordion-complete-icon\"></cds-icon>\n </span>\n <ng-content select=\"clr-accordion-title, clr-step-title\"></ng-content>\n <ng-content select=\"clr-accordion-description, clr-step-description\"></ng-content>\n </button>\n </div>\n <div\n @skipInitialRender\n role=\"region\"\n class=\"clr-accordion-content-region\"\n [id]=\"getAccordionContentId(panel.templateId)\"\n [attr.aria-hidden]=\"!panel.open\"\n [attr.aria-labelledby]=\"getAccordionHeaderId(panel.templateId)\"\n >\n <div\n *ngIf=\"panel.open\"\n @toggle\n (@toggle.done)=\"collapsePanelOnAnimationDone(panel)\"\n class=\"clr-accordion-content\"\n >\n <div class=\"clr-accordion-inner-content\">\n <ng-content></ng-content>\n </div>\n </div>\n </div>\n </div>\n</ng-container>\n" }]
654
+ args: [{ selector: 'clr-accordion-panel', host: { '[class.clr-accordion-panel]': 'true' }, changeDetection: ChangeDetectionStrategy.OnPush, animations: panelAnimation, providers: [IfExpandService], template: "<ng-container *ngIf=\"panel | async; let panel\">\n <div [ngClass]=\"getPanelStateClasses(panel)\">\n <div class=\"clr-accordion-header\">\n <button\n type=\"button\"\n class=\"clr-accordion-header-button\"\n (click)=\"togglePanel()\"\n [id]=\"getAccordionHeaderId(panel.templateId)\"\n [disabled]=\"isAccordion && panel.disabled\"\n [attr.aria-disabled]=\"!isAccordion && 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-accordion-status\">\n <cds-icon shape=\"angle\" direction=\"right\" class=\"clr-accordion-angle\"></cds-icon>\n <span class=\"clr-accordion-number\">{{panelNumber}}.</span>\n <cds-icon status=\"danger\" shape=\"exclamation-circle\" class=\"clr-accordion-error-icon\"></cds-icon>\n <cds-icon status=\"success\" shape=\"check-circle\" class=\"clr-accordion-complete-icon\"></cds-icon>\n </span>\n <ng-content select=\"clr-accordion-title, clr-step-title\"></ng-content>\n <ng-content select=\"clr-accordion-description, clr-step-description\"></ng-content>\n </button>\n <div 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" }]
646
655
  }], ctorParameters: function () { return [{ type: ClrCommonStringsService }, { type: AccordionService }, { type: IfExpandService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { disabled: [{
647
656
  type: Input,
648
657
  args: ['clrAccordionPanelDisabled']
@@ -1166,7 +1175,11 @@ class ClrStepperPanel extends ClrAccordionPanel {
1166
1175
  listenToFocusChanges() {
1167
1176
  this.subscriptions.push(this.stepperService.activeStep
1168
1177
  .pipe(filter(panelId => isPlatformBrowser(this.platformId) && panelId === this.id))
1169
- .subscribe(() => this.headerButton.nativeElement.focus()));
1178
+ .subscribe(() => {
1179
+ //Adding timeout so that the status of the previous step is read by Voice Over on Safari,
1180
+ //before focusing on the next stepper panel header
1181
+ setTimeout(() => this.headerButton.nativeElement.focus(), 1500);
1182
+ }));
1170
1183
  }
1171
1184
  triggerAllFormControlValidationIfError(panel) {
1172
1185
  if (panel.status === AccordionStatus.Error) {
@@ -1175,10 +1188,10 @@ class ClrStepperPanel extends ClrAccordionPanel {
1175
1188
  }
1176
1189
  }
1177
1190
  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 });
1178
- ClrStepperPanel.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrStepperPanel, selector: "clr-stepper-panel", host: { properties: { "class.clr-accordion-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\">\n <button\n type=\"button\"\n class=\"clr-accordion-header-button\"\n (click)=\"togglePanel()\"\n [id]=\"getAccordionHeaderId(panel.templateId)\"\n [disabled]=\"isAccordion && panel.disabled\"\n [attr.aria-disabled]=\"!isAccordion && 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-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 </span>\n <span class=\"clr-accordion-status\">\n <cds-icon shape=\"angle\" direction=\"right\" class=\"clr-accordion-angle\"></cds-icon>\n <span class=\"clr-accordion-number\">{{panelNumber}}.</span>\n <cds-icon status=\"danger\" shape=\"exclamation-circle\" class=\"clr-accordion-error-icon\"></cds-icon>\n <cds-icon status=\"success\" shape=\"check-circle\" class=\"clr-accordion-complete-icon\"></cds-icon>\n </span>\n <ng-content select=\"clr-accordion-title, clr-step-title\"></ng-content>\n <ng-content select=\"clr-accordion-description, clr-step-description\"></ng-content>\n </button>\n </div>\n <div\n @skipInitialRender\n role=\"region\"\n class=\"clr-accordion-content-region\"\n [id]=\"getAccordionContentId(panel.templateId)\"\n [attr.aria-hidden]=\"!panel.open\"\n [attr.aria-labelledby]=\"getAccordionHeaderId(panel.templateId)\"\n >\n <div\n *ngIf=\"panel.open\"\n @toggle\n (@toggle.done)=\"collapsePanelOnAnimationDone(panel)\"\n class=\"clr-accordion-content\"\n >\n <div class=\"clr-accordion-inner-content\">\n <ng-content></ng-content>\n </div>\n </div>\n </div>\n </div>\n</ng-container>\n", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }], animations: stepAnimation, changeDetection: i0.ChangeDetectionStrategy.OnPush });
1191
+ ClrStepperPanel.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrStepperPanel, selector: "clr-stepper-panel", host: { properties: { "class.clr-accordion-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\">\n <button\n type=\"button\"\n class=\"clr-accordion-header-button\"\n (click)=\"togglePanel()\"\n [id]=\"getAccordionHeaderId(panel.templateId)\"\n [disabled]=\"isAccordion && panel.disabled\"\n [attr.aria-disabled]=\"!isAccordion && 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-accordion-status\">\n <cds-icon shape=\"angle\" direction=\"right\" class=\"clr-accordion-angle\"></cds-icon>\n <span class=\"clr-accordion-number\">{{panelNumber}}.</span>\n <cds-icon status=\"danger\" shape=\"exclamation-circle\" class=\"clr-accordion-error-icon\"></cds-icon>\n <cds-icon status=\"success\" shape=\"check-circle\" class=\"clr-accordion-complete-icon\"></cds-icon>\n </span>\n <ng-content select=\"clr-accordion-title, clr-step-title\"></ng-content>\n <ng-content select=\"clr-accordion-description, clr-step-description\"></ng-content>\n </button>\n <div 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 });
1179
1192
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrStepperPanel, decorators: [{
1180
1193
  type: Component,
1181
- args: [{ selector: 'clr-stepper-panel', host: { '[class.clr-accordion-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\">\n <button\n type=\"button\"\n class=\"clr-accordion-header-button\"\n (click)=\"togglePanel()\"\n [id]=\"getAccordionHeaderId(panel.templateId)\"\n [disabled]=\"isAccordion && panel.disabled\"\n [attr.aria-disabled]=\"!isAccordion && 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-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 </span>\n <span class=\"clr-accordion-status\">\n <cds-icon shape=\"angle\" direction=\"right\" class=\"clr-accordion-angle\"></cds-icon>\n <span class=\"clr-accordion-number\">{{panelNumber}}.</span>\n <cds-icon status=\"danger\" shape=\"exclamation-circle\" class=\"clr-accordion-error-icon\"></cds-icon>\n <cds-icon status=\"success\" shape=\"check-circle\" class=\"clr-accordion-complete-icon\"></cds-icon>\n </span>\n <ng-content select=\"clr-accordion-title, clr-step-title\"></ng-content>\n <ng-content select=\"clr-accordion-description, clr-step-description\"></ng-content>\n </button>\n </div>\n <div\n @skipInitialRender\n role=\"region\"\n class=\"clr-accordion-content-region\"\n [id]=\"getAccordionContentId(panel.templateId)\"\n [attr.aria-hidden]=\"!panel.open\"\n [attr.aria-labelledby]=\"getAccordionHeaderId(panel.templateId)\"\n >\n <div\n *ngIf=\"panel.open\"\n @toggle\n (@toggle.done)=\"collapsePanelOnAnimationDone(panel)\"\n class=\"clr-accordion-content\"\n >\n <div class=\"clr-accordion-inner-content\">\n <ng-content></ng-content>\n </div>\n </div>\n </div>\n </div>\n</ng-container>\n" }]
1194
+ args: [{ selector: 'clr-stepper-panel', host: { '[class.clr-accordion-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\">\n <button\n type=\"button\"\n class=\"clr-accordion-header-button\"\n (click)=\"togglePanel()\"\n [id]=\"getAccordionHeaderId(panel.templateId)\"\n [disabled]=\"isAccordion && panel.disabled\"\n [attr.aria-disabled]=\"!isAccordion && 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-accordion-status\">\n <cds-icon shape=\"angle\" direction=\"right\" class=\"clr-accordion-angle\"></cds-icon>\n <span class=\"clr-accordion-number\">{{panelNumber}}.</span>\n <cds-icon status=\"danger\" shape=\"exclamation-circle\" class=\"clr-accordion-error-icon\"></cds-icon>\n <cds-icon status=\"success\" shape=\"check-circle\" class=\"clr-accordion-complete-icon\"></cds-icon>\n </span>\n <ng-content select=\"clr-accordion-title, clr-step-title\"></ng-content>\n <ng-content select=\"clr-accordion-description, clr-step-description\"></ng-content>\n </button>\n <div 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" }]
1182
1195
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
1183
1196
  type: Inject,
1184
1197
  args: [PLATFORM_ID]
@@ -2955,10 +2968,19 @@ function collapse() {
2955
2968
  * The full license information can be found in LICENSE in the root directory of this project.
2956
2969
  */
2957
2970
  class DomAdapter {
2971
+ /*
2972
+ We clone the element and take its measurements from outside the grid
2973
+ so we don't trigger reflow for the whole datagrid.
2974
+ */
2958
2975
  userDefinedWidth(element) {
2959
- element.classList.add('datagrid-cell-width-zero');
2960
- const userDefinedWidth = this.clientRect(element).width;
2961
- element.classList.remove('datagrid-cell-width-zero');
2976
+ const clonedElement = element.cloneNode(true);
2977
+ if (clonedElement.id) {
2978
+ clonedElement.id = clonedElement.id + '-clone';
2979
+ }
2980
+ clonedElement.classList.add('datagrid-cell-width-zero');
2981
+ document.body.appendChild(clonedElement);
2982
+ const userDefinedWidth = this.clientRect(clonedElement).width;
2983
+ clonedElement.remove();
2962
2984
  return userDefinedWidth;
2963
2985
  }
2964
2986
  scrollBarWidth(element) {
@@ -3005,27 +3027,32 @@ class ClrExpandableAnimation {
3005
3027
  this.element = element;
3006
3028
  this.domAdapter = domAdapter;
3007
3029
  this.renderer = renderer;
3030
+ this.clrExpandTrigger = false;
3008
3031
  this.startHeight = 0;
3009
3032
  }
3010
3033
  get expandAnimation() {
3011
3034
  return { value: this.clrExpandTrigger, params: { startHeight: this.startHeight } };
3012
3035
  }
3013
- animationStart() {
3014
- this.renderer.setStyle(this.element.nativeElement, 'overflow', 'hidden');
3036
+ animationStart(event) {
3037
+ if (event.fromState !== 'void') {
3038
+ this.renderer.setStyle(this.element.nativeElement, 'overflow', 'hidden');
3039
+ }
3015
3040
  }
3016
- animationDone() {
3017
- this.renderer.removeStyle(this.element.nativeElement, 'overflow');
3018
- // A "safe" auto-update of the height ensuring basic OOTB user experience .
3019
- // Prone to small jumps in initial animation height if data was changed in the meantime, window was resized, etc.
3020
- // For optimal behavior call manually updateStartHeight() from the parent component before initiating the update.
3021
- this.updateStartHeight();
3041
+ animationDone(event) {
3042
+ if (event.fromState !== 'void') {
3043
+ this.renderer.removeStyle(this.element.nativeElement, 'overflow');
3044
+ // A "safe" auto-update of the height ensuring basic OOTB user experience .
3045
+ // Prone to small jumps in initial animation height if data was changed in the meantime, window was resized, etc.
3046
+ // For optimal behavior call manually updateStartHeight() from the parent component before initiating the update.
3047
+ this.updateStartHeight();
3048
+ }
3022
3049
  }
3023
3050
  updateStartHeight() {
3024
3051
  this.startHeight = this.domAdapter.computedHeight(this.element.nativeElement) || 0;
3025
3052
  }
3026
3053
  }
3027
3054
  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 });
3028
- 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()", "@expandAnimation.done": "animationDone()" }, properties: { "@expandAnimation": "this.expandAnimation" } }, providers: [DomAdapter], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, styles: [":host{display:block}\n"], animations: [
3055
+ 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: [
3029
3056
  trigger('expandAnimation', [
3030
3057
  transition('true <=> false', [
3031
3058
  style({ height: '{{startHeight}}px' }),
@@ -3050,10 +3077,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
3050
3077
  args: ['@expandAnimation']
3051
3078
  }], animationStart: [{
3052
3079
  type: HostListener,
3053
- args: ['@expandAnimation.start']
3080
+ args: ['@expandAnimation.start', ['$event']]
3054
3081
  }], animationDone: [{
3055
3082
  type: HostListener,
3056
- args: ['@expandAnimation.done']
3083
+ args: ['@expandAnimation.done', ['$event']]
3057
3084
  }] } });
3058
3085
 
3059
3086
  /*
@@ -4728,7 +4755,10 @@ class ClrAbstractContainer {
4728
4755
  this.subscriptions = [];
4729
4756
  this.subscriptions.push(this.ifControlStateService.statusChanges.subscribe((state) => {
4730
4757
  this.state = state;
4731
- this.updateHelpers();
4758
+ // Make sure everything is updated before dispatching the values for helpers
4759
+ setTimeout(() => {
4760
+ this.updateHelpers();
4761
+ });
4732
4762
  }));
4733
4763
  this.subscriptions.push(this.ngControlService.controlChanges.subscribe(control => {
4734
4764
  this.control = control;
@@ -7255,7 +7285,7 @@ ClrCombobox.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
7255
7285
  IF_ACTIVE_ID_PROVIDER,
7256
7286
  FOCUS_SERVICE_PROVIDER,
7257
7287
  COMBOBOX_FOCUS_HANDLER_PROVIDER,
7258
- ], 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-2023 VMware, Inc. All Rights Reserved.\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"] }] });
7288
+ ], 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-2024 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"] }] });
7259
7289
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrCombobox, decorators: [{
7260
7290
  type: Component,
7261
7291
  args: [{ selector: 'clr-combobox', providers: [
@@ -7268,7 +7298,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
7268
7298
  '[class.aria-required]': 'true',
7269
7299
  '[class.clr-combobox]': 'true',
7270
7300
  '[class.clr-combobox-disabled]': 'control?.disabled',
7271
- }, template: "<!--\n* Copyright (c) 2016-2023 VMware, Inc. All Rights Reserved.\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" }]
7301
+ }, template: "<!--\n ~ Copyright (c) 2016-2024 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" }]
7272
7302
  }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.Injector }, { type: i1.NgControl, decorators: [{
7273
7303
  type: Self
7274
7304
  }, {
@@ -7717,7 +7747,6 @@ class ClrDatalistContainer extends ClrAbstractContainer {
7717
7747
  ClrDatalistContainer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatalistContainer, deps: [{ token: ControlClassService }, { token: LayoutService, optional: true }, { token: NgControlService }, { token: FocusService }, { token: IfControlStateService }], target: i0.ɵɵFactoryTarget.Component });
7718
7748
  ClrDatalistContainer.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatalistContainer, selector: "clr-datalist-container", host: { properties: { "class.clr-form-control": "true", "class.clr-form-control-disabled": "control?.disabled", "class.clr-row": "addGrid()" } }, providers: [
7719
7749
  ControlClassService,
7720
- LayoutService,
7721
7750
  ControlIdService,
7722
7751
  FocusService,
7723
7752
  NgControlService,
@@ -7794,7 +7823,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
7794
7823
  },
7795
7824
  providers: [
7796
7825
  ControlClassService,
7797
- LayoutService,
7798
7826
  ControlIdService,
7799
7827
  FocusService,
7800
7828
  NgControlService,
@@ -9593,7 +9621,7 @@ class ClrDatepickerViewManager {
9593
9621
  }
9594
9622
  }
9595
9623
  ClrDatepickerViewManager.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatepickerViewManager, deps: [{ token: ClrCommonStringsService }, { token: ViewManagerService }], target: i0.ɵɵFactoryTarget.Component });
9596
- 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", "attr.aria-modal": "true", "attr.aria-label": "commonStrings.keys.datepickerDialogLabel" } }, providers: [DatepickerFocusService], ngImport: i0, template: "<!--\n* Copyright (c) 2016-2023 VMware, Inc. All Rights Reserved.\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-monthpicker *ngIf=\"isMonthView\"></clr-monthpicker>\n<clr-yearpicker *ngIf=\"isYearView\"></clr-yearpicker>\n<clr-daypicker *ngIf=\"isDayView\"></clr-daypicker>\n", dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ClrMonthpicker, selector: "clr-monthpicker" }, { kind: "component", type: ClrYearpicker, selector: "clr-yearpicker" }, { kind: "component", type: ClrDaypicker, selector: "clr-daypicker" }] });
9624
+ 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", "attr.aria-modal": "true", "attr.aria-label": "commonStrings.keys.datepickerDialogLabel" } }, providers: [DatepickerFocusService], ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2024 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-monthpicker *ngIf=\"isMonthView\"></clr-monthpicker>\n<clr-yearpicker *ngIf=\"isYearView\"></clr-yearpicker>\n<clr-daypicker *ngIf=\"isDayView\"></clr-daypicker>\n", dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ClrMonthpicker, selector: "clr-monthpicker" }, { kind: "component", type: ClrYearpicker, selector: "clr-yearpicker" }, { kind: "component", type: ClrDaypicker, selector: "clr-daypicker" }] });
9597
9625
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatepickerViewManager, decorators: [{
9598
9626
  type: Component,
9599
9627
  args: [{ selector: 'clr-datepicker-view-manager', providers: [DatepickerFocusService], host: {
@@ -9601,7 +9629,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
9601
9629
  '[attr.aria-modal]': 'true',
9602
9630
  '[attr.aria-label]': 'commonStrings.keys.datepickerDialogLabel',
9603
9631
  role: 'dialog',
9604
- }, template: "<!--\n* Copyright (c) 2016-2023 VMware, Inc. All Rights Reserved.\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-monthpicker *ngIf=\"isMonthView\"></clr-monthpicker>\n<clr-yearpicker *ngIf=\"isYearView\"></clr-yearpicker>\n<clr-daypicker *ngIf=\"isDayView\"></clr-daypicker>\n" }]
9632
+ }, template: "<!--\n ~ Copyright (c) 2016-2024 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-monthpicker *ngIf=\"isMonthView\"></clr-monthpicker>\n<clr-yearpicker *ngIf=\"isYearView\"></clr-yearpicker>\n<clr-daypicker *ngIf=\"isDayView\"></clr-daypicker>\n" }]
9605
9633
  }], ctorParameters: function () { return [{ type: ClrCommonStringsService }, { type: ViewManagerService }]; } });
9606
9634
 
9607
9635
  /*
@@ -10223,6 +10251,393 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
10223
10251
  }]
10224
10252
  }], ctorParameters: function () { return []; } });
10225
10253
 
10254
+ /*
10255
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
10256
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
10257
+ * This software is released under MIT license.
10258
+ * The full license information can be found in LICENSE in the root directory of this project.
10259
+ */
10260
+ class ClrFileInputContainer extends ClrAbstractContainer {
10261
+ constructor() {
10262
+ super(...arguments);
10263
+ this.commonStrings = inject(ClrCommonStringsService);
10264
+ }
10265
+ get disabled() {
10266
+ return this.fileInput.elementRef.nativeElement.disabled;
10267
+ }
10268
+ get browseButtonDescribedBy() {
10269
+ return this.fileInput.elementRef.nativeElement.getAttribute('aria-describedby');
10270
+ }
10271
+ browse() {
10272
+ this.fileInput.elementRef.nativeElement.click();
10273
+ }
10274
+ clearSelectedFiles() {
10275
+ this.fileInput.elementRef.nativeElement.value = '';
10276
+ this.fileInput.elementRef.nativeElement.dispatchEvent(new Event('change', { bubbles: true, cancelable: true }));
10277
+ this.browseButtonElementRef.nativeElement.focus();
10278
+ }
10279
+ }
10280
+ ClrFileInputContainer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInputContainer, deps: null, target: i0.ɵɵFactoryTarget.Component });
10281
+ ClrFileInputContainer.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrFileInputContainer, selector: "clr-file-input-container", inputs: { customButtonLabel: ["clrButtonLabel", "customButtonLabel"] }, host: { properties: { "class.clr-form-control": "true", "class.clr-form-control-disabled": "disabled", "class.clr-row": "addGrid()" } }, providers: [IfControlStateService, NgControlService, ControlIdService, ControlClassService], queries: [{ propertyName: "fileInput", first: true, predicate: i0.forwardRef(function () { return ClrFileInput; }), descendants: true }], viewQueries: [{ propertyName: "browseButtonElementRef", first: true, predicate: ["browseButton"], descendants: true }], usesInheritance: true, ngImport: i0, template: `
10282
+ <ng-content select="label"></ng-content>
10283
+ <label *ngIf="!label && addGrid()"></label>
10284
+ <div class="clr-control-container" [ngClass]="controlClass()">
10285
+ <div class="clr-file-input-wrapper">
10286
+ <ng-content select="[clrFileInput]"></ng-content>
10287
+ <button
10288
+ #browseButton
10289
+ type="button"
10290
+ class="btn btn-sm clr-file-input-browse-button"
10291
+ [attr.aria-describedby]="browseButtonDescribedBy"
10292
+ [disabled]="disabled"
10293
+ (click)="browse()"
10294
+ >
10295
+ <cds-icon shape="folder-open"></cds-icon>
10296
+ <span class="clr-file-input-browse-button-text">
10297
+ {{ fileInput?.selection?.buttonLabel || customButtonLabel || commonStrings.keys.browse }}
10298
+ </span>
10299
+ </button>
10300
+ <button
10301
+ *ngIf="fileInput?.selection?.fileCount"
10302
+ type="button"
10303
+ class="btn btn-sm clr-file-input-clear-button"
10304
+ [attr.aria-label]="fileInput?.selection?.clearFilesButtonLabel"
10305
+ (click)="clearSelectedFiles()"
10306
+ >
10307
+ <cds-icon shape="times" status="neutral" size="md"></cds-icon>
10308
+ </button>
10309
+ <cds-icon
10310
+ *ngIf="showInvalid"
10311
+ class="clr-validate-icon"
10312
+ shape="exclamation-circle"
10313
+ status="danger"
10314
+ aria-hidden="true"
10315
+ ></cds-icon>
10316
+ <cds-icon
10317
+ *ngIf="showValid"
10318
+ class="clr-validate-icon"
10319
+ shape="check-circle"
10320
+ status="success"
10321
+ aria-hidden="true"
10322
+ ></cds-icon>
10323
+ </div>
10324
+ <ng-content select="clr-control-helper" *ngIf="showHelper"></ng-content>
10325
+ <ng-content select="clr-control-error" *ngIf="showInvalid"></ng-content>
10326
+ <ng-content select="clr-control-success" *ngIf="showValid"></ng-content>
10327
+ </div>
10328
+ `, isInline: true, 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: "directive", type: ClrLabel, selector: "label", inputs: ["for"] }] });
10329
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInputContainer, decorators: [{
10330
+ type: Component,
10331
+ args: [{
10332
+ selector: 'clr-file-input-container',
10333
+ template: `
10334
+ <ng-content select="label"></ng-content>
10335
+ <label *ngIf="!label && addGrid()"></label>
10336
+ <div class="clr-control-container" [ngClass]="controlClass()">
10337
+ <div class="clr-file-input-wrapper">
10338
+ <ng-content select="[clrFileInput]"></ng-content>
10339
+ <button
10340
+ #browseButton
10341
+ type="button"
10342
+ class="btn btn-sm clr-file-input-browse-button"
10343
+ [attr.aria-describedby]="browseButtonDescribedBy"
10344
+ [disabled]="disabled"
10345
+ (click)="browse()"
10346
+ >
10347
+ <cds-icon shape="folder-open"></cds-icon>
10348
+ <span class="clr-file-input-browse-button-text">
10349
+ {{ fileInput?.selection?.buttonLabel || customButtonLabel || commonStrings.keys.browse }}
10350
+ </span>
10351
+ </button>
10352
+ <button
10353
+ *ngIf="fileInput?.selection?.fileCount"
10354
+ type="button"
10355
+ class="btn btn-sm clr-file-input-clear-button"
10356
+ [attr.aria-label]="fileInput?.selection?.clearFilesButtonLabel"
10357
+ (click)="clearSelectedFiles()"
10358
+ >
10359
+ <cds-icon shape="times" status="neutral" size="md"></cds-icon>
10360
+ </button>
10361
+ <cds-icon
10362
+ *ngIf="showInvalid"
10363
+ class="clr-validate-icon"
10364
+ shape="exclamation-circle"
10365
+ status="danger"
10366
+ aria-hidden="true"
10367
+ ></cds-icon>
10368
+ <cds-icon
10369
+ *ngIf="showValid"
10370
+ class="clr-validate-icon"
10371
+ shape="check-circle"
10372
+ status="success"
10373
+ aria-hidden="true"
10374
+ ></cds-icon>
10375
+ </div>
10376
+ <ng-content select="clr-control-helper" *ngIf="showHelper"></ng-content>
10377
+ <ng-content select="clr-control-error" *ngIf="showInvalid"></ng-content>
10378
+ <ng-content select="clr-control-success" *ngIf="showValid"></ng-content>
10379
+ </div>
10380
+ `,
10381
+ host: {
10382
+ '[class.clr-form-control]': 'true',
10383
+ '[class.clr-form-control-disabled]': 'disabled',
10384
+ '[class.clr-row]': 'addGrid()',
10385
+ },
10386
+ providers: [IfControlStateService, NgControlService, ControlIdService, ControlClassService],
10387
+ }]
10388
+ }], propDecorators: { customButtonLabel: [{
10389
+ type: Input,
10390
+ args: ['clrButtonLabel']
10391
+ }], fileInput: [{
10392
+ type: ContentChild,
10393
+ args: [forwardRef(() => ClrFileInput)]
10394
+ }], browseButtonElementRef: [{
10395
+ type: ViewChild,
10396
+ args: ['browseButton']
10397
+ }] } });
10398
+
10399
+ /*
10400
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
10401
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
10402
+ * This software is released under MIT license.
10403
+ * The full license information can be found in LICENSE in the root directory of this project.
10404
+ */
10405
+ class ClrFileInput extends WrappedFormControl {
10406
+ constructor(injector, renderer, viewContainerRef, elementRef, control, commonStrings) {
10407
+ super(viewContainerRef, ClrFileInputContainer, injector, control, renderer, elementRef);
10408
+ this.elementRef = elementRef;
10409
+ this.commonStrings = commonStrings;
10410
+ this.selection = undefined;
10411
+ }
10412
+ handleChange() {
10413
+ this.updateSelection();
10414
+ }
10415
+ updateSelection() {
10416
+ const files = this.elementRef.nativeElement.files;
10417
+ let selectionButtonLabel;
10418
+ let clearFilesButtonLabel;
10419
+ if (files?.length === 1) {
10420
+ const filename = files[0].name;
10421
+ selectionButtonLabel = filename;
10422
+ clearFilesButtonLabel = this.commonStrings.parse(this.commonStrings.keys.clearFile, {
10423
+ FILE: filename,
10424
+ });
10425
+ }
10426
+ else if (files?.length > 1) {
10427
+ const fileCount = files.length.toString();
10428
+ selectionButtonLabel = this.commonStrings.parse(this.commonStrings.keys.fileCount, {
10429
+ COUNT: fileCount,
10430
+ });
10431
+ clearFilesButtonLabel = this.commonStrings.parse(this.commonStrings.keys.clearFiles, {
10432
+ COUNT: fileCount,
10433
+ });
10434
+ }
10435
+ this.selection = {
10436
+ fileCount: files.length,
10437
+ buttonLabel: selectionButtonLabel,
10438
+ clearFilesButtonLabel,
10439
+ };
10440
+ }
10441
+ }
10442
+ 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 });
10443
+ ClrFileInput.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: ClrFileInput, selector: "input[type=\"file\"][clrFileInput]", host: { listeners: { "change": "handleChange()" }, properties: { "class.clr-file-input": "true" } }, usesInheritance: true, ngImport: i0 });
10444
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInput, decorators: [{
10445
+ type: Directive,
10446
+ args: [{
10447
+ selector: 'input[type="file"][clrFileInput]',
10448
+ host: {
10449
+ '[class.clr-file-input]': 'true',
10450
+ },
10451
+ }]
10452
+ }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i0.Renderer2 }, { type: i0.ViewContainerRef }, { type: i0.ElementRef }, { type: i1.NgControl, decorators: [{
10453
+ type: Self
10454
+ }, {
10455
+ type: Optional
10456
+ }] }, { type: ClrCommonStringsService }]; }, propDecorators: { handleChange: [{
10457
+ type: HostListener,
10458
+ args: ['change']
10459
+ }] } });
10460
+
10461
+ /*
10462
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
10463
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
10464
+ * This software is released under MIT license.
10465
+ * The full license information can be found in LICENSE in the root directory of this project.
10466
+ */
10467
+ class ClrFileInputValidator {
10468
+ constructor(elementRef) {
10469
+ this.elementRef = elementRef;
10470
+ }
10471
+ validate(control) {
10472
+ const files = control.value;
10473
+ const fileInputElement = this.elementRef.nativeElement;
10474
+ const errors = {};
10475
+ // required validation (native attribute)
10476
+ if (fileInputElement.required && files?.length === 0) {
10477
+ errors.required = true;
10478
+ }
10479
+ // accept validation (native attribute)
10480
+ if (fileInputElement.accept && files?.length > 0) {
10481
+ const accept = fileInputElement.accept.split(',').map(type => type.trim());
10482
+ for (let i = 0; i < files.length; i++) {
10483
+ const file = files.item(i);
10484
+ const [fileExtension] = file.name.match(/\..+$/);
10485
+ if (!accept.includes(file.type) && !accept.includes(fileExtension)) {
10486
+ errors.accept = errors.accept || [];
10487
+ errors.accept.push({ name: file.name, accept, type: file.type, extension: fileExtension });
10488
+ }
10489
+ }
10490
+ }
10491
+ // min file validation (custom input)
10492
+ if (this.minFileSize && files?.length > 0) {
10493
+ for (let i = 0; i < files.length; i++) {
10494
+ const file = files.item(i);
10495
+ if (file.size < this.minFileSize) {
10496
+ errors.minFileSize = errors.minFileSize || [];
10497
+ errors.minFileSize.push({ name: file.name, minFileSize: this.minFileSize, actualFileSize: file.size });
10498
+ }
10499
+ }
10500
+ }
10501
+ // max file validation (custom input)
10502
+ if (this.maxFileSize && files?.length > 0) {
10503
+ for (let i = 0; i < files.length; i++) {
10504
+ const file = files.item(i);
10505
+ if (file.size > this.maxFileSize) {
10506
+ errors.maxFileSize = errors.maxFileSize || [];
10507
+ errors.maxFileSize.push({ name: file.name, maxFileSize: this.maxFileSize, actualFileSize: file.size });
10508
+ }
10509
+ }
10510
+ }
10511
+ return Object.keys(errors).length ? errors : null;
10512
+ }
10513
+ }
10514
+ ClrFileInputValidator.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInputValidator, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
10515
+ ClrFileInputValidator.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: ClrFileInputValidator, selector: "input[type=\"file\"][clrFileInput]", inputs: { minFileSize: ["clrMinFileSize", "minFileSize"], maxFileSize: ["clrMaxFileSize", "maxFileSize"] }, providers: [{ provide: NG_VALIDATORS, useExisting: ClrFileInputValidator, multi: true }], ngImport: i0 });
10516
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInputValidator, decorators: [{
10517
+ type: Directive,
10518
+ args: [{
10519
+ selector: 'input[type="file"][clrFileInput]',
10520
+ providers: [{ provide: NG_VALIDATORS, useExisting: ClrFileInputValidator, multi: true }],
10521
+ }]
10522
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { minFileSize: [{
10523
+ type: Input,
10524
+ args: ['clrMinFileSize']
10525
+ }], maxFileSize: [{
10526
+ type: Input,
10527
+ args: ['clrMaxFileSize']
10528
+ }] } });
10529
+
10530
+ /*
10531
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
10532
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
10533
+ * This software is released under MIT license.
10534
+ * The full license information can be found in LICENSE in the root directory of this project.
10535
+ */
10536
+ function buildFileList(files) {
10537
+ const dataTransfer = new DataTransfer();
10538
+ for (const file of files) {
10539
+ dataTransfer.items.add(file);
10540
+ }
10541
+ return dataTransfer.files;
10542
+ }
10543
+ function selectFiles(fileInputElement, files) {
10544
+ fileInputElement.files = files instanceof FileList ? files : buildFileList(files);
10545
+ fileInputElement.dispatchEvent(new Event('change', { bubbles: true, cancelable: true }));
10546
+ }
10547
+ function clearFiles(fileInputElement) {
10548
+ fileInputElement.value = '';
10549
+ fileInputElement.dispatchEvent(new Event('change', { bubbles: true, cancelable: true }));
10550
+ }
10551
+
10552
+ /*
10553
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
10554
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
10555
+ * This software is released under MIT license.
10556
+ * The full license information can be found in LICENSE in the root directory of this project.
10557
+ */
10558
+ class ClrFileInputValueAccessor {
10559
+ constructor(elementRef) {
10560
+ this.elementRef = elementRef;
10561
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
10562
+ this.onChange = (_value) => { };
10563
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
10564
+ this.onTouched = () => { };
10565
+ }
10566
+ writeValue(value) {
10567
+ if (value !== undefined && value !== null && !(value instanceof FileList)) {
10568
+ throw new Error('The value of a file input control must be a FileList.');
10569
+ }
10570
+ if (value) {
10571
+ selectFiles(this.elementRef.nativeElement, value);
10572
+ }
10573
+ else if (this.elementRef.nativeElement.files.length) {
10574
+ clearFiles(this.elementRef.nativeElement);
10575
+ }
10576
+ }
10577
+ registerOnChange(fn) {
10578
+ this.onChange = fn;
10579
+ }
10580
+ registerOnTouched(fn) {
10581
+ this.onTouched = fn;
10582
+ }
10583
+ handleChange() {
10584
+ this.onTouched();
10585
+ this.onChange(this.elementRef.nativeElement.files);
10586
+ }
10587
+ }
10588
+ ClrFileInputValueAccessor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInputValueAccessor, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
10589
+ ClrFileInputValueAccessor.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: ClrFileInputValueAccessor, selector: "input[type=\"file\"][clrFileInput]", host: { listeners: { "change": "handleChange()" } }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: ClrFileInputValueAccessor, multi: true }], ngImport: i0 });
10590
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInputValueAccessor, decorators: [{
10591
+ type: Directive,
10592
+ args: [{
10593
+ selector: 'input[type="file"][clrFileInput]',
10594
+ providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: ClrFileInputValueAccessor, multi: true }],
10595
+ }]
10596
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { handleChange: [{
10597
+ type: HostListener,
10598
+ args: ['change']
10599
+ }] } });
10600
+
10601
+ /*
10602
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
10603
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
10604
+ * This software is released under MIT license.
10605
+ * The full license information can be found in LICENSE in the root directory of this project.
10606
+ */
10607
+ class ClrFileInputModule {
10608
+ constructor() {
10609
+ ClarityIcons.addIcons(folderOpenIcon);
10610
+ }
10611
+ }
10612
+ ClrFileInputModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInputModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
10613
+ ClrFileInputModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInputModule, declarations: [ClrFileInput, ClrFileInputContainer, ClrFileInputValidator, ClrFileInputValueAccessor], imports: [CommonModule, ClrIconModule, ClrCommonFormsModule], exports: [ClrCommonFormsModule,
10614
+ ClrFileInput,
10615
+ ClrFileInputContainer,
10616
+ ClrFileInputValidator,
10617
+ ClrFileInputValueAccessor] });
10618
+ ClrFileInputModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInputModule, imports: [CommonModule, ClrIconModule, ClrCommonFormsModule, ClrCommonFormsModule] });
10619
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInputModule, decorators: [{
10620
+ type: NgModule,
10621
+ args: [{
10622
+ imports: [CommonModule, ClrIconModule, ClrCommonFormsModule],
10623
+ declarations: [ClrFileInput, ClrFileInputContainer, ClrFileInputValidator, ClrFileInputValueAccessor],
10624
+ exports: [
10625
+ ClrCommonFormsModule,
10626
+ ClrFileInput,
10627
+ ClrFileInputContainer,
10628
+ ClrFileInputValidator,
10629
+ ClrFileInputValueAccessor,
10630
+ ],
10631
+ }]
10632
+ }], ctorParameters: function () { return []; } });
10633
+
10634
+ /*
10635
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
10636
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
10637
+ * This software is released under MIT license.
10638
+ * The full license information can be found in LICENSE in the root directory of this project.
10639
+ */
10640
+
10226
10641
  /*
10227
10642
  * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
10228
10643
  * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
@@ -11146,6 +11561,7 @@ ClrFormsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version:
11146
11561
  ClrCheckboxModule,
11147
11562
  ClrComboboxModule,
11148
11563
  ClrDatepickerModule,
11564
+ ClrFileInputModule,
11149
11565
  ClrInputModule,
11150
11566
  ClrPasswordModule,
11151
11567
  ClrRadioModule,
@@ -11157,6 +11573,7 @@ ClrFormsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version:
11157
11573
  ClrCheckboxModule,
11158
11574
  ClrComboboxModule,
11159
11575
  ClrDatepickerModule,
11576
+ ClrFileInputModule,
11160
11577
  ClrInputModule,
11161
11578
  ClrPasswordModule,
11162
11579
  ClrRadioModule,
@@ -11173,6 +11590,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
11173
11590
  ClrCheckboxModule,
11174
11591
  ClrComboboxModule,
11175
11592
  ClrDatepickerModule,
11593
+ ClrFileInputModule,
11176
11594
  ClrInputModule,
11177
11595
  ClrPasswordModule,
11178
11596
  ClrRadioModule,
@@ -11684,51 +12102,240 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
11684
12102
  * This software is released under MIT license.
11685
12103
  * The full license information can be found in LICENSE in the root directory of this project.
11686
12104
  */
11687
- /**
11688
- * Custom filter that can be added in any column to override the default object property string filter.
11689
- * The reason this is not just an input on DatagridColumn is because we need the filter's template to be projected,
11690
- * since it can be anything (not just a text input).
11691
- */
11692
- class ClrDatagridFilter extends DatagridFilterRegistrar {
11693
- constructor(_filters, commonStrings, smartToggleService, platformId, elementRef) {
11694
- super(_filters);
11695
- this.commonStrings = commonStrings;
11696
- this.smartToggleService = smartToggleService;
11697
- this.platformId = platformId;
11698
- this.elementRef = elementRef;
11699
- this.openChange = new EventEmitter(false);
11700
- this.ariaExpanded = false;
11701
- this.popoverId = uniqueIdFactory();
11702
- // Smart Popover
11703
- this.smartPosition = {
11704
- axis: ClrAxis.VERTICAL,
11705
- side: ClrSide.AFTER,
11706
- anchor: ClrAlignment.END,
11707
- content: ClrAlignment.END,
11708
- };
11709
- this._open = false;
11710
- this.subs = [];
11711
- this.subs.push(smartToggleService.openChange.subscribe(change => {
11712
- this.open = change;
11713
- this.ariaExpanded = change;
11714
- }));
11715
- }
11716
- get open() {
11717
- return this._open;
11718
- }
11719
- set open(open) {
11720
- open = !!open;
11721
- if (this.open !== open) {
11722
- this.smartToggleService.open = open;
11723
- this.openChange.emit(open);
11724
- if (!open && isPlatformBrowser(this.platformId)) {
11725
- this.anchor.nativeElement.focus();
11726
- }
11727
- // keep track of the state
11728
- this._open = open;
11729
- }
11730
- }
11731
- set customFilter(filter) {
12105
+ function getTabableItems(el) {
12106
+ const tabableSelector = [
12107
+ 'a[href]',
12108
+ 'area[href]',
12109
+ 'input:not([disabled])',
12110
+ 'button:not([disabled])',
12111
+ 'select:not([disabled])',
12112
+ 'textarea:not([disabled])',
12113
+ 'iframe',
12114
+ 'object',
12115
+ 'embed',
12116
+ '*[tabindex]',
12117
+ '*[contenteditable=true]',
12118
+ '[role=button]:not([disabled])',
12119
+ ].join(',');
12120
+ return Array.from(el.querySelectorAll(tabableSelector));
12121
+ }
12122
+ class KeyNavigationGridController {
12123
+ constructor(zone) {
12124
+ this.zone = zone;
12125
+ this.skipItemFocus = false;
12126
+ this.listenersAdded = false;
12127
+ this.destroy$ = new Subject();
12128
+ this._activeCell = null;
12129
+ this.config = {
12130
+ keyGridRows: '[role=row]:not(.datagrid-placeholder)',
12131
+ keyGridCells: '[role=gridcell]:not(.datagrid-hidden-column):not(.datagrid-placeholder-content), [role=columnheader]:not(.datagrid-hidden-column):not(.datagrid-placeholder-content), .datagrid-detail-caret',
12132
+ keyGrid: '[role=grid]',
12133
+ };
12134
+ }
12135
+ get grid() {
12136
+ return this.host?.querySelector(this.config.keyGrid);
12137
+ }
12138
+ get rows() {
12139
+ return this.host?.querySelectorAll(this.config.keyGridRows);
12140
+ }
12141
+ get cells() {
12142
+ return this.host?.querySelectorAll(this.config.keyGridCells);
12143
+ }
12144
+ ngOnDestroy() {
12145
+ this.destroy$.next();
12146
+ this.destroy$.complete();
12147
+ }
12148
+ addListeners() {
12149
+ if (this.listenersAdded) {
12150
+ return;
12151
+ }
12152
+ this.zone.runOutsideAngular(() => {
12153
+ fromEvent(this.grid, 'mousedown')
12154
+ .pipe(takeUntil(this.destroy$))
12155
+ .subscribe((e) => {
12156
+ // 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
12157
+ if (e.buttons === 1 && !e.ctrlKey) {
12158
+ const activeCell = this.cells
12159
+ ? Array.from(this.cells).find(c => c === e.target || c === e.target.closest(this.config.keyGridCells))
12160
+ : null;
12161
+ if (activeCell) {
12162
+ this.setActiveCell(activeCell);
12163
+ }
12164
+ }
12165
+ });
12166
+ fromEvent(this.grid, 'wheel')
12167
+ .pipe(takeUntil(this.destroy$))
12168
+ .subscribe(() => {
12169
+ this.removeActiveCell();
12170
+ });
12171
+ fromEvent(this.grid, 'keydown')
12172
+ .pipe(takeUntil(this.destroy$))
12173
+ .subscribe((e) => {
12174
+ // Skip column resize events
12175
+ if (e.target.classList.contains('drag-handle') &&
12176
+ (e.code === 'ArrowLeft' || e.code === 'ArrowRight')) {
12177
+ return;
12178
+ }
12179
+ if (e.code === 'ArrowUp' ||
12180
+ e.code === 'ArrowDown' ||
12181
+ e.code === 'ArrowLeft' ||
12182
+ e.code === 'ArrowRight' ||
12183
+ e.code === 'End' ||
12184
+ e.code === 'Home' ||
12185
+ e.code === 'PageUp' ||
12186
+ e.code === 'PageDown') {
12187
+ const { x, y } = this.getNextItemCoordinate(e);
12188
+ const activeItem = this.rows
12189
+ ? Array.from(this.rows[y].querySelectorAll(this.config.keyGridCells))[x]
12190
+ : null;
12191
+ if (activeItem) {
12192
+ this.setActiveCell(activeItem);
12193
+ }
12194
+ e.preventDefault();
12195
+ }
12196
+ });
12197
+ });
12198
+ this.listenersAdded = true;
12199
+ }
12200
+ initializeKeyGrid(host) {
12201
+ this.host = host;
12202
+ this.addListeners();
12203
+ this.resetKeyGrid();
12204
+ }
12205
+ resetKeyGrid() {
12206
+ this.cells?.forEach((i) => i.setAttribute('tabindex', '-1'));
12207
+ const firstCell = this.cells ? this.cells[0] : null;
12208
+ firstCell?.setAttribute('tabindex', '0');
12209
+ }
12210
+ removeActiveCell() {
12211
+ this._activeCell = null;
12212
+ }
12213
+ getActiveCell() {
12214
+ return this._activeCell;
12215
+ }
12216
+ setActiveCell(activeCell) {
12217
+ const prior = this.cells ? Array.from(this.cells).find(c => c.getAttribute('tabindex') === '0') : null;
12218
+ if (prior) {
12219
+ prior.setAttribute('tabindex', '-1');
12220
+ }
12221
+ activeCell.setAttribute('tabindex', '0');
12222
+ this._activeCell = activeCell;
12223
+ const items = getTabableItems(activeCell);
12224
+ const item = activeCell.getAttribute('role') !== 'columnheader' && items[0] ? items[0] : activeCell;
12225
+ if (!this.skipItemFocus) {
12226
+ item.focus();
12227
+ }
12228
+ }
12229
+ getNextItemCoordinate(e) {
12230
+ let currentCell = this.cells ? Array.from(this.cells).find(i => i.getAttribute('tabindex') === '0') : null;
12231
+ if (e.code === 'Tab') {
12232
+ currentCell = document.activeElement;
12233
+ }
12234
+ const currentRow = this.rows && currentCell ? Array.from(this.rows).find(r => r.contains(currentCell)) : null;
12235
+ const numOfRows = this.rows ? this.rows.length - 1 : 0;
12236
+ const numOfColumns = this.cells ? Math.floor(this.cells.length / this.rows.length - 1) : 0;
12237
+ let x = currentRow && currentCell
12238
+ ? Array.from(currentRow.querySelectorAll(this.config.keyGridCells)).indexOf(currentCell)
12239
+ : 0;
12240
+ let y = currentRow && currentCell && this.rows ? Array.from(this.rows).indexOf(currentRow) : 0;
12241
+ const dir = this.host.dir;
12242
+ const inlineStart = dir === 'rtl' ? 'ArrowRight' : 'ArrowLeft';
12243
+ const inlineEnd = dir === 'rtl' ? 'ArrowLeft' : 'ArrowRight';
12244
+ const itemsPerPage = Math.floor(this.host?.querySelector('.datagrid').clientHeight / this.rows[0].clientHeight) - 1 || 0;
12245
+ if (e.code === 'ArrowUp' && y !== 0) {
12246
+ y = y - 1;
12247
+ }
12248
+ else if (e.code === 'ArrowDown' && y < numOfRows) {
12249
+ y = y + 1;
12250
+ }
12251
+ else if (e.code === inlineStart && x !== 0) {
12252
+ x = x - 1;
12253
+ }
12254
+ else if (e.code === inlineEnd && x < numOfColumns) {
12255
+ x = x + 1;
12256
+ }
12257
+ else if (e.code === 'End') {
12258
+ x = numOfColumns;
12259
+ if (e.ctrlKey) {
12260
+ y = numOfRows;
12261
+ }
12262
+ }
12263
+ else if (e.code === 'Home') {
12264
+ x = 0;
12265
+ if (e.ctrlKey) {
12266
+ y = 0;
12267
+ }
12268
+ }
12269
+ else if (e.code === 'PageUp') {
12270
+ y = y - itemsPerPage > 0 ? y - itemsPerPage + 1 : 1;
12271
+ }
12272
+ else if (e.code === 'PageDown') {
12273
+ y = y + itemsPerPage < numOfRows ? y + itemsPerPage : numOfRows;
12274
+ }
12275
+ return { x, y };
12276
+ }
12277
+ }
12278
+ KeyNavigationGridController.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: KeyNavigationGridController, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
12279
+ KeyNavigationGridController.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: KeyNavigationGridController });
12280
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: KeyNavigationGridController, decorators: [{
12281
+ type: Injectable
12282
+ }], ctorParameters: function () { return [{ type: i0.NgZone }]; } });
12283
+
12284
+ /*
12285
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
12286
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
12287
+ * This software is released under MIT license.
12288
+ * The full license information can be found in LICENSE in the root directory of this project.
12289
+ */
12290
+ /**
12291
+ * Custom filter that can be added in any column to override the default object property string filter.
12292
+ * The reason this is not just an input on DatagridColumn is because we need the filter's template to be projected,
12293
+ * since it can be anything (not just a text input).
12294
+ */
12295
+ class ClrDatagridFilter extends DatagridFilterRegistrar {
12296
+ constructor(_filters, commonStrings, smartToggleService, platformId, elementRef, keyNavigation) {
12297
+ super(_filters);
12298
+ this.commonStrings = commonStrings;
12299
+ this.smartToggleService = smartToggleService;
12300
+ this.platformId = platformId;
12301
+ this.elementRef = elementRef;
12302
+ this.keyNavigation = keyNavigation;
12303
+ this.openChange = new EventEmitter(false);
12304
+ this.ariaExpanded = false;
12305
+ this.popoverId = uniqueIdFactory();
12306
+ // Smart Popover
12307
+ this.smartPosition = {
12308
+ axis: ClrAxis.VERTICAL,
12309
+ side: ClrSide.AFTER,
12310
+ anchor: ClrAlignment.END,
12311
+ content: ClrAlignment.END,
12312
+ };
12313
+ this._open = false;
12314
+ this.subs = [];
12315
+ this.subs.push(smartToggleService.openChange.subscribe(change => {
12316
+ this.open = change;
12317
+ this.ariaExpanded = change;
12318
+ }));
12319
+ }
12320
+ get open() {
12321
+ return this._open;
12322
+ }
12323
+ set open(open) {
12324
+ open = !!open;
12325
+ if (this.open !== open) {
12326
+ this.smartToggleService.open = open;
12327
+ this.openChange.emit(open);
12328
+ if (!open && isPlatformBrowser(this.platformId)) {
12329
+ this.anchor.nativeElement.focus();
12330
+ }
12331
+ if (this.keyNavigation) {
12332
+ this.keyNavigation.skipItemFocus = open;
12333
+ }
12334
+ // keep track of the state
12335
+ this._open = open;
12336
+ }
12337
+ }
12338
+ set customFilter(filter) {
11732
12339
  this.setFilter(filter);
11733
12340
  }
11734
12341
  /**
@@ -11738,7 +12345,9 @@ class ClrDatagridFilter extends DatagridFilterRegistrar {
11738
12345
  return !!this.filter && this.filter.isActive();
11739
12346
  }
11740
12347
  ngOnChanges() {
11741
- this.setToggleButtonAriaLabel();
12348
+ setTimeout(() => {
12349
+ this.setToggleButtonAriaLabel();
12350
+ });
11742
12351
  }
11743
12352
  ngOnDestroy() {
11744
12353
  super.ngOnDestroy();
@@ -11757,7 +12366,7 @@ class ClrDatagridFilter extends DatagridFilterRegistrar {
11757
12366
  });
11758
12367
  }
11759
12368
  }
11760
- 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 }], target: i0.ɵɵFactoryTarget.Component });
12369
+ 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 });
11761
12370
  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: `
11762
12371
  <button
11763
12372
  class="datagrid-filter-toggle"
@@ -11842,7 +12451,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
11842
12451
  }], ctorParameters: function () { return [{ type: FiltersProvider }, { type: ClrCommonStringsService }, { type: ClrPopoverToggleService }, { type: undefined, decorators: [{
11843
12452
  type: Inject,
11844
12453
  args: [PLATFORM_ID]
11845
- }] }, { type: i0.ElementRef }]; }, propDecorators: { openChange: [{
12454
+ }] }, { type: i0.ElementRef }, { type: KeyNavigationGridController, decorators: [{
12455
+ type: Optional
12456
+ }] }]; }, propDecorators: { openChange: [{
11846
12457
  type: Output,
11847
12458
  args: ['clrDgFilterOpenChange']
11848
12459
  }], anchor: [{
@@ -12600,6 +13211,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
12600
13211
  class DetailService {
12601
13212
  constructor(modalStackService) {
12602
13213
  this.modalStackService = modalStackService;
13214
+ this.preventScroll = false;
12603
13215
  this.toggleState = false;
12604
13216
  this._enabled = false;
12605
13217
  this._state = new BehaviorSubject(this.toggleState);
@@ -12610,6 +13222,12 @@ class DetailService {
12610
13222
  set enabled(state) {
12611
13223
  this._enabled = state;
12612
13224
  }
13225
+ get preventFocusScroll() {
13226
+ return this.preventScroll;
13227
+ }
13228
+ set preventFocusScroll(preventScroll) {
13229
+ this.preventScroll = preventScroll;
13230
+ }
12613
13231
  get state() {
12614
13232
  return this.cache;
12615
13233
  }
@@ -12628,10 +13246,13 @@ class DetailService {
12628
13246
  }
12629
13247
  close() {
12630
13248
  this.toggleState = false;
13249
+ this.returnFocus();
12631
13250
  this._state.next(this.toggleState);
12632
13251
  this.modalStackService.trackModalClose(this);
13252
+ }
13253
+ returnFocus() {
12633
13254
  if (this.button) {
12634
- this.button.focus();
13255
+ this.button.focus({ preventScroll: this.preventFocusScroll });
12635
13256
  this.button = null;
12636
13257
  }
12637
13258
  }
@@ -12937,7 +13558,7 @@ class DatagridRenderOrganizer {
12937
13558
  this._renderStep.next(DatagridRenderStep.CLEAR_WIDTHS);
12938
13559
  }
12939
13560
  this._renderStep.next(DatagridRenderStep.COMPUTE_COLUMN_WIDTHS);
12940
- this._renderStep.next(DatagridRenderStep.ALIGN_COLUMNS);
13561
+ this._renderStep.next(DatagridRenderStep.ALIGN_COLUMNS); // NOT USED
12941
13562
  this.alreadySized = true;
12942
13563
  this._renderStep.next(DatagridRenderStep.CALCULATE_MODE_OFF);
12943
13564
  }
@@ -14653,7 +15274,7 @@ class ClrDatagridSelectionCellDirective {
14653
15274
  }
14654
15275
  // If click was outside the label/input, forward the click to the input.
14655
15276
  if (event.target.tagName !== 'LABEL' && event.target.tagName !== 'INPUT') {
14656
- event.target.querySelector('input').click();
15277
+ event.target.querySelector('input')?.click();
14657
15278
  }
14658
15279
  }
14659
15280
  }
@@ -14923,7 +15544,7 @@ ClrDatagridRow.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version
14923
15544
  DatagridIfExpandService,
14924
15545
  { provide: IfExpandService, useExisting: DatagridIfExpandService },
14925
15546
  { provide: LoadingListener, useExisting: DatagridIfExpandService },
14926
- ], 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 <clr-checkbox-wrapper>\n <input\n type=\"checkbox\"\n clrCheckbox\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 </clr-checkbox-wrapper>\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 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 *ngIf=\"!expand.loading\"\n (click)=\"toggleExpand()\"\n type=\"button\"\n class=\"datagrid-expandable-caret-button\"\n [attr.aria-expanded]=\"expand.expanded\"\n [attr.aria-label]=\"expand.expanded ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-controls]=\"expandableId\"\n >\n <cds-icon\n shape=\"angle\"\n class=\"datagrid-expandable-caret-icon\"\n [attr.direction]=\"expand.expanded ? 'down' : 'right'\"\n [attr.title]=\"expand.expanded ? commonStrings.keys.collapse : commonStrings.keys.expand\"\n ></cds-icon>\n </button>\n <clr-spinner *ngIf=\"expand.loading\" clrSmall>{{ commonStrings.keys.loading }}</clr-spinner>\n </ng-container>\n </div>\n <div *ngIf=\"detailService.enabled\" class=\"datagrid-detail-caret datagrid-fixed-column datagrid-cell\">\n <button\n (click)=\"detailService.toggle(item, detailButton)\"\n type=\"button\"\n #detailButton\n class=\"datagrid-detail-caret-button\"\n [class.is-open]=\"detailService.isRowOpen(item)\"\n [attr.aria-label]=\"detailService.isRowOpen(item) ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-expanded]=\"detailService.isOpen\"\n [attr.aria-controls]=\"detailService.id\"\n aria-haspopup=\"dialog\"\n >\n <cds-icon\n shape=\"angle-double\"\n [attr.direction]=\"detailService.isRowOpen(item) ? 'left' : 'right'\"\n class=\"datagrid-detail-caret-icon\"\n [attr.title]=\"detailService.isRowOpen(item) ? commonStrings.keys.close: commonStrings.keys.open\"\n ></cds-icon>\n </button>\n </div>\n </ng-container>\n <!-- placeholder for projecting other sticky cells as pinned-->\n </div>\n <div class=\"datagrid-row-scrollable\" [ngClass]=\"{'is-replaced': replaced && expanded}\">\n <div class=\"datagrid-scrolling-cells\">\n <ng-content select=\"clr-dg-cell\"></ng-content>\n <ng-container #scrollableCells></ng-container>\n </div>\n <!-- details here when replace, re-visit when sticky container is used for pinned cells -->\n <ng-template *ngIf=\"replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n <ng-template *ngIf=\"!replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n </div>\n </div>\n</ng-template>\n\n<ng-container #calculatedCells></ng-container>\n", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }, { kind: "directive", type: ClrLabel, selector: "label", inputs: ["for"] }, { kind: "directive", type: ClrCheckbox, selector: "[clrCheckbox],[clrToggle]" }, { kind: "component", type: ClrCheckboxWrapper, selector: "clr-checkbox-wrapper,clr-toggle-wrapper" }, { kind: "directive", type: ClrRadio, selector: "[clrRadio]" }, { kind: "component", type: ClrRadioWrapper, selector: "clr-radio-wrapper" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ClrExpandableAnimation, selector: "clr-expandable-animation", inputs: ["clrExpandTrigger"] }, { kind: "component", type: ClrSpinner, selector: "clr-spinner", inputs: ["clrInline", "clrInverse", "clrSmall", "clrMedium"] }, { kind: "directive", type: ClrDatagridSelectionCellDirective, selector: ".datagrid-select" }] });
15547
+ ], 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 <clr-checkbox-wrapper>\n <input\n tabindex=\"-1\"\n type=\"checkbox\"\n clrCheckbox\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 </clr-checkbox-wrapper>\n </div>\n <div\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Single\"\n class=\"datagrid-select datagrid-fixed-column datagrid-cell\"\n [ngClass]=\"{ 'clr-form-control-disabled': !clrDgSelectable }\"\n role=\"gridcell\"\n >\n <clr-radio-wrapper>\n <input\n tabindex=\"-1\"\n type=\"radio\"\n clrRadio\n [id]=\"radioId\"\n [name]=\"selection.id + '-radio'\"\n [value]=\"item\"\n [(ngModel)]=\"selection.currentSingle\"\n [checked]=\"selection.currentSingle === item\"\n [disabled]=\"clrDgSelectable ? null : true\"\n [attr.aria-disabled]=\"clrDgSelectable ? null : true\"\n />\n <label class=\"clr-control-label clr-col-null\" [for]=\"radioId\">\n <span class=\"clr-sr-only\">{{ clrDgRowSelectionLabel || commonStrings.keys.select }}</span>\n </label>\n </clr-radio-wrapper>\n </div>\n <div\n *ngIf=\"rowActionService.hasActionableRow\"\n class=\"datagrid-row-actions datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <ng-content select=\"clr-dg-action-overflow\"></ng-content>\n </div>\n <div\n *ngIf=\"globalExpandable.hasExpandableRow\"\n class=\"datagrid-expandable-caret datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <ng-container *ngIf=\"expand.expandable\">\n <button\n tabindex=\"-1\"\n *ngIf=\"!expand.loading\"\n (click)=\"toggleExpand()\"\n type=\"button\"\n class=\"datagrid-expandable-caret-button\"\n [attr.aria-expanded]=\"expand.expanded\"\n [attr.aria-label]=\"expand.expanded ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-controls]=\"expandableId\"\n >\n <cds-icon\n shape=\"angle\"\n class=\"datagrid-expandable-caret-icon\"\n [attr.direction]=\"expand.expanded ? 'down' : 'right'\"\n [attr.title]=\"expand.expanded ? commonStrings.keys.collapse : commonStrings.keys.expand\"\n ></cds-icon>\n </button>\n <clr-spinner *ngIf=\"expand.loading\" clrSmall>{{ commonStrings.keys.loading }}</clr-spinner>\n </ng-container>\n </div>\n <div\n *ngIf=\"detailService.enabled\"\n class=\"datagrid-detail-caret datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <button\n tabindex=\"-1\"\n (click)=\"detailService.toggle(item, detailButton)\"\n type=\"button\"\n #detailButton\n class=\"datagrid-detail-caret-button\"\n [class.is-open]=\"detailService.isRowOpen(item)\"\n [attr.aria-label]=\"detailService.isRowOpen(item) ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-expanded]=\"detailService.isRowOpen(item)\"\n [attr.aria-controls]=\"detailService.id\"\n aria-haspopup=\"dialog\"\n >\n <cds-icon\n shape=\"angle-double\"\n [attr.direction]=\"detailService.isRowOpen(item) ? 'left' : 'right'\"\n class=\"datagrid-detail-caret-icon\"\n [attr.title]=\"detailService.isRowOpen(item) ? commonStrings.keys.close: commonStrings.keys.open\"\n ></cds-icon>\n </button>\n </div>\n </ng-container>\n <!-- placeholder for projecting other sticky cells as pinned-->\n </div>\n <div class=\"datagrid-row-scrollable\" [ngClass]=\"{'is-replaced': replaced && expanded}\">\n <div class=\"datagrid-scrolling-cells\">\n <ng-content select=\"clr-dg-cell\"></ng-content>\n <ng-container #scrollableCells></ng-container>\n </div>\n <!-- details here when replace, re-visit when sticky container is used for pinned cells -->\n <ng-template *ngIf=\"replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n <ng-template *ngIf=\"!replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n </div>\n </div>\n</ng-template>\n\n<ng-container #calculatedCells></ng-container>\n", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }, { kind: "directive", type: ClrLabel, selector: "label", inputs: ["for"] }, { kind: "directive", type: ClrCheckbox, selector: "[clrCheckbox],[clrToggle]" }, { kind: "component", type: ClrCheckboxWrapper, selector: "clr-checkbox-wrapper,clr-toggle-wrapper" }, { kind: "directive", type: ClrRadio, selector: "[clrRadio]" }, { kind: "component", type: ClrRadioWrapper, selector: "clr-radio-wrapper" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ClrExpandableAnimation, selector: "clr-expandable-animation", inputs: ["clrExpandTrigger"] }, { kind: "component", type: ClrSpinner, selector: "clr-spinner", inputs: ["clrInline", "clrInverse", "clrSmall", "clrMedium"] }, { kind: "directive", type: ClrDatagridSelectionCellDirective, selector: ".datagrid-select" }] });
14927
15548
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridRow, decorators: [{
14928
15549
  type: Component,
14929
15550
  args: [{ selector: 'clr-dg-row', host: {
@@ -14935,7 +15556,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
14935
15556
  DatagridIfExpandService,
14936
15557
  { provide: IfExpandService, useExisting: DatagridIfExpandService },
14937
15558
  { provide: LoadingListener, useExisting: DatagridIfExpandService },
14938
- ], 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 <clr-checkbox-wrapper>\n <input\n type=\"checkbox\"\n clrCheckbox\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 </clr-checkbox-wrapper>\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 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 *ngIf=\"!expand.loading\"\n (click)=\"toggleExpand()\"\n type=\"button\"\n class=\"datagrid-expandable-caret-button\"\n [attr.aria-expanded]=\"expand.expanded\"\n [attr.aria-label]=\"expand.expanded ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-controls]=\"expandableId\"\n >\n <cds-icon\n shape=\"angle\"\n class=\"datagrid-expandable-caret-icon\"\n [attr.direction]=\"expand.expanded ? 'down' : 'right'\"\n [attr.title]=\"expand.expanded ? commonStrings.keys.collapse : commonStrings.keys.expand\"\n ></cds-icon>\n </button>\n <clr-spinner *ngIf=\"expand.loading\" clrSmall>{{ commonStrings.keys.loading }}</clr-spinner>\n </ng-container>\n </div>\n <div *ngIf=\"detailService.enabled\" class=\"datagrid-detail-caret datagrid-fixed-column datagrid-cell\">\n <button\n (click)=\"detailService.toggle(item, detailButton)\"\n type=\"button\"\n #detailButton\n class=\"datagrid-detail-caret-button\"\n [class.is-open]=\"detailService.isRowOpen(item)\"\n [attr.aria-label]=\"detailService.isRowOpen(item) ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-expanded]=\"detailService.isOpen\"\n [attr.aria-controls]=\"detailService.id\"\n aria-haspopup=\"dialog\"\n >\n <cds-icon\n shape=\"angle-double\"\n [attr.direction]=\"detailService.isRowOpen(item) ? 'left' : 'right'\"\n class=\"datagrid-detail-caret-icon\"\n [attr.title]=\"detailService.isRowOpen(item) ? commonStrings.keys.close: commonStrings.keys.open\"\n ></cds-icon>\n </button>\n </div>\n </ng-container>\n <!-- placeholder for projecting other sticky cells as pinned-->\n </div>\n <div class=\"datagrid-row-scrollable\" [ngClass]=\"{'is-replaced': replaced && expanded}\">\n <div class=\"datagrid-scrolling-cells\">\n <ng-content select=\"clr-dg-cell\"></ng-content>\n <ng-container #scrollableCells></ng-container>\n </div>\n <!-- details here when replace, re-visit when sticky container is used for pinned cells -->\n <ng-template *ngIf=\"replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n <ng-template *ngIf=\"!replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n </div>\n </div>\n</ng-template>\n\n<ng-container #calculatedCells></ng-container>\n" }]
15559
+ ], 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 <clr-checkbox-wrapper>\n <input\n tabindex=\"-1\"\n type=\"checkbox\"\n clrCheckbox\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 </clr-checkbox-wrapper>\n </div>\n <div\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Single\"\n class=\"datagrid-select datagrid-fixed-column datagrid-cell\"\n [ngClass]=\"{ 'clr-form-control-disabled': !clrDgSelectable }\"\n role=\"gridcell\"\n >\n <clr-radio-wrapper>\n <input\n tabindex=\"-1\"\n type=\"radio\"\n clrRadio\n [id]=\"radioId\"\n [name]=\"selection.id + '-radio'\"\n [value]=\"item\"\n [(ngModel)]=\"selection.currentSingle\"\n [checked]=\"selection.currentSingle === item\"\n [disabled]=\"clrDgSelectable ? null : true\"\n [attr.aria-disabled]=\"clrDgSelectable ? null : true\"\n />\n <label class=\"clr-control-label clr-col-null\" [for]=\"radioId\">\n <span class=\"clr-sr-only\">{{ clrDgRowSelectionLabel || commonStrings.keys.select }}</span>\n </label>\n </clr-radio-wrapper>\n </div>\n <div\n *ngIf=\"rowActionService.hasActionableRow\"\n class=\"datagrid-row-actions datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <ng-content select=\"clr-dg-action-overflow\"></ng-content>\n </div>\n <div\n *ngIf=\"globalExpandable.hasExpandableRow\"\n class=\"datagrid-expandable-caret datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <ng-container *ngIf=\"expand.expandable\">\n <button\n tabindex=\"-1\"\n *ngIf=\"!expand.loading\"\n (click)=\"toggleExpand()\"\n type=\"button\"\n class=\"datagrid-expandable-caret-button\"\n [attr.aria-expanded]=\"expand.expanded\"\n [attr.aria-label]=\"expand.expanded ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-controls]=\"expandableId\"\n >\n <cds-icon\n shape=\"angle\"\n class=\"datagrid-expandable-caret-icon\"\n [attr.direction]=\"expand.expanded ? 'down' : 'right'\"\n [attr.title]=\"expand.expanded ? commonStrings.keys.collapse : commonStrings.keys.expand\"\n ></cds-icon>\n </button>\n <clr-spinner *ngIf=\"expand.loading\" clrSmall>{{ commonStrings.keys.loading }}</clr-spinner>\n </ng-container>\n </div>\n <div\n *ngIf=\"detailService.enabled\"\n class=\"datagrid-detail-caret datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <button\n tabindex=\"-1\"\n (click)=\"detailService.toggle(item, detailButton)\"\n type=\"button\"\n #detailButton\n class=\"datagrid-detail-caret-button\"\n [class.is-open]=\"detailService.isRowOpen(item)\"\n [attr.aria-label]=\"detailService.isRowOpen(item) ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-expanded]=\"detailService.isRowOpen(item)\"\n [attr.aria-controls]=\"detailService.id\"\n aria-haspopup=\"dialog\"\n >\n <cds-icon\n shape=\"angle-double\"\n [attr.direction]=\"detailService.isRowOpen(item) ? 'left' : 'right'\"\n class=\"datagrid-detail-caret-icon\"\n [attr.title]=\"detailService.isRowOpen(item) ? commonStrings.keys.close: commonStrings.keys.open\"\n ></cds-icon>\n </button>\n </div>\n </ng-container>\n <!-- placeholder for projecting other sticky cells as pinned-->\n </div>\n <div class=\"datagrid-row-scrollable\" [ngClass]=\"{'is-replaced': replaced && expanded}\">\n <div class=\"datagrid-scrolling-cells\">\n <ng-content select=\"clr-dg-cell\"></ng-content>\n <ng-container #scrollableCells></ng-container>\n </div>\n <!-- details here when replace, re-visit when sticky container is used for pinned cells -->\n <ng-template *ngIf=\"replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n <ng-template *ngIf=\"!replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n </div>\n </div>\n</ng-template>\n\n<ng-container #calculatedCells></ng-container>\n" }]
14939
15560
  }], 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: [{
14940
15561
  type: Inject,
14941
15562
  args: [DOCUMENT]
@@ -14993,10 +15614,11 @@ var DatagridColumnChanges;
14993
15614
  (function (DatagridColumnChanges) {
14994
15615
  DatagridColumnChanges[DatagridColumnChanges["WIDTH"] = 0] = "WIDTH";
14995
15616
  DatagridColumnChanges[DatagridColumnChanges["HIDDEN"] = 1] = "HIDDEN";
15617
+ DatagridColumnChanges[DatagridColumnChanges["INITIALIZE"] = 2] = "INITIALIZE";
14996
15618
  })(DatagridColumnChanges || (DatagridColumnChanges = {}));
14997
15619
  const ALL_COLUMN_CHANGES = Object.keys(DatagridColumnChanges)
14998
15620
  .map(key => DatagridColumnChanges[key])
14999
- .filter(key => key === parseInt(key, 10)); // extracts only integer keys
15621
+ .filter(key => key === parseInt(key, 10) && key !== DatagridColumnChanges.INITIALIZE); // extracts only integer keys
15000
15622
 
15001
15623
  /*
15002
15624
  * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
@@ -15007,6 +15629,7 @@ const ALL_COLUMN_CHANGES = Object.keys(DatagridColumnChanges)
15007
15629
  class ColumnsService {
15008
15630
  constructor() {
15009
15631
  this.columns = [];
15632
+ this.columnsStateChange = new BehaviorSubject(null);
15010
15633
  this._cache = [];
15011
15634
  }
15012
15635
  get columnStates() {
@@ -15028,7 +15651,9 @@ class ColumnsService {
15028
15651
  resetToLastCache() {
15029
15652
  this._cache.forEach((state, index) => {
15030
15653
  // Just emit the exact value from the cache
15031
- this.columns[index].next({ ...state, changes: ALL_COLUMN_CHANGES });
15654
+ const cachedState = { ...state, changes: ALL_COLUMN_CHANGES };
15655
+ this.columns[index].next(cachedState);
15656
+ this.columnsStateChange.next(cachedState);
15032
15657
  });
15033
15658
  this._cache = [];
15034
15659
  }
@@ -15040,7 +15665,9 @@ class ColumnsService {
15040
15665
  this.emitStateChange(this.columns[columnIndex], diff);
15041
15666
  }
15042
15667
  emitStateChange(column, diff) {
15043
- column.next({ ...column.value, ...diff });
15668
+ const changedState = { ...column.value, ...diff };
15669
+ column.next(changedState);
15670
+ this.columnsStateChange.next(changedState);
15044
15671
  }
15045
15672
  }
15046
15673
  ColumnsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ColumnsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
@@ -15122,168 +15749,123 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
15122
15749
  * This software is released under MIT license.
15123
15750
  * The full license information can be found in LICENSE in the root directory of this project.
15124
15751
  */
15125
- function getTabableItems(el) {
15126
- const tabableSelector = [
15127
- 'a[href]',
15128
- 'area[href]',
15129
- 'input:not([disabled])',
15130
- 'button:not([disabled])',
15131
- 'select:not([disabled])',
15132
- 'textarea:not([disabled])',
15133
- 'iframe',
15134
- 'object',
15135
- 'embed',
15136
- '*[tabindex]',
15137
- '*[contenteditable=true]',
15138
- '[role=button]:not([disabled])',
15139
- ].join(',');
15140
- return Array.from(el.querySelectorAll(tabableSelector));
15141
- }
15142
- class KeyNavigationGridController {
15143
- constructor(zone) {
15144
- this.zone = zone;
15145
- this.listenersAdded = false;
15146
- this.destroy$ = new Subject();
15147
- this.config = {
15148
- keyGridRows: '[role=row]:not(.datagrid-placeholder)',
15149
- keyGridCells: '[role=gridcell]:not(.datagrid-hidden-column):not(.datagrid-placeholder-content), [role=columnheader]:not(.datagrid-hidden-column):not(.datagrid-placeholder-content), .datagrid-detail-caret',
15150
- keyGrid: '[role=grid]',
15151
- };
15152
- }
15153
- get grid() {
15154
- return this.host?.querySelector(this.config.keyGrid);
15155
- }
15156
- get rows() {
15157
- return this.host?.querySelectorAll(this.config.keyGridRows);
15158
- }
15159
- get cells() {
15160
- return this.host?.querySelectorAll(this.config.keyGridCells);
15752
+ // @TODO The top two are not used now, which is probably a performance drag that was broken along the way.
15753
+ // There was a previous pattern to hide everything to do computation then display, for Firefox, needs revisiting.
15754
+ const NO_LAYOUT_CLASS = 'datagrid-no-layout';
15755
+ const COMPUTE_WIDTH_CLASS = 'datagrid-computing-columns-width';
15756
+ const STRICT_WIDTH_CLASS = 'datagrid-fixed-width';
15757
+ const HIDDEN_COLUMN_CLASS = 'datagrid-hidden-column';
15758
+
15759
+ /*
15760
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
15761
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
15762
+ * This software is released under MIT license.
15763
+ * The full license information can be found in LICENSE in the root directory of this project.
15764
+ */
15765
+ class DatagridCellRenderer {
15766
+ constructor(el, renderer, organizer) {
15767
+ this.el = el;
15768
+ this.renderer = renderer;
15769
+ this.subscriptions = [];
15770
+ this.subscriptions.push(organizer.filterRenderSteps(DatagridRenderStep.CLEAR_WIDTHS).subscribe(() => this.clearWidth()));
15161
15771
  }
15162
15772
  ngOnDestroy() {
15163
- this.destroy$.next();
15164
- this.destroy$.complete();
15165
- }
15166
- addListeners() {
15167
- if (this.listenersAdded) {
15168
- return;
15773
+ this.subscriptions.forEach(sub => sub.unsubscribe());
15774
+ if (this.stateSubscription) {
15775
+ this.stateSubscription.unsubscribe();
15169
15776
  }
15170
- this.zone.runOutsideAngular(() => {
15171
- fromEvent(this.grid, 'mousedown')
15172
- .pipe(takeUntil(this.destroy$))
15173
- .subscribe((e) => {
15174
- // 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
15175
- if (e.buttons === 1 && !e.ctrlKey) {
15176
- const activeCell = this.cells
15177
- ? Array.from(this.cells).find(c => c === e.target || c === e.target.closest(this.config.keyGridCells))
15178
- : null;
15179
- if (activeCell) {
15180
- this.setActiveCell(activeCell);
15181
- }
15182
- }
15183
- });
15184
- fromEvent(this.grid, 'keydown')
15185
- .pipe(takeUntil(this.destroy$))
15186
- .subscribe((e) => {
15187
- // Skip column resize events
15188
- if (e.target.classList.contains('drag-handle') &&
15189
- (e.code === 'ArrowLeft' || e.code === 'ArrowRight')) {
15190
- return;
15191
- }
15192
- if (e.code === 'ArrowUp' ||
15193
- e.code === 'ArrowDown' ||
15194
- e.code === 'ArrowLeft' ||
15195
- e.code === 'ArrowRight' ||
15196
- e.code === 'End' ||
15197
- e.code === 'Home' ||
15198
- e.code === 'PageUp' ||
15199
- e.code === 'PageDown') {
15200
- const { x, y } = this.getNextItemCoordinate(e);
15201
- const activeItem = this.rows
15202
- ? Array.from(this.rows[y].querySelectorAll(this.config.keyGridCells))[x]
15203
- : null;
15204
- if (activeItem) {
15205
- this.setActiveCell(activeItem);
15206
- }
15207
- e.preventDefault();
15208
- }
15209
- });
15210
- });
15211
- this.listenersAdded = true;
15212
15777
  }
15213
- initializeKeyGrid(host) {
15214
- this.host = host;
15215
- this.addListeners();
15216
- this.resetKeyGrid();
15217
- }
15218
- resetKeyGrid() {
15219
- this.cells?.forEach((i) => i.setAttribute('tabindex', '-1'));
15220
- const firstCell = this.cells ? this.cells[0] : null;
15221
- firstCell?.setAttribute('tabindex', '0');
15222
- }
15223
- setActiveCell(activeCell) {
15224
- const prior = this.cells ? Array.from(this.cells).find(c => c.getAttribute('tabindex') === '0') : null;
15225
- if (prior) {
15226
- prior.setAttribute('tabindex', '-1');
15227
- }
15228
- activeCell.setAttribute('tabindex', '0');
15229
- const items = getTabableItems(activeCell);
15230
- const item = activeCell.getAttribute('role') !== 'columnheader' && items[0] ? items[0] : activeCell;
15231
- item.focus();
15778
+ resetState(state) {
15779
+ this.setWidth(state);
15780
+ this.setHidden(state);
15232
15781
  }
15233
- getNextItemCoordinate(e) {
15234
- let currentCell = this.cells ? Array.from(this.cells).find(i => i.getAttribute('tabindex') === '0') : null;
15235
- if (e.code === 'Tab') {
15236
- currentCell = document.activeElement;
15237
- }
15238
- const currentRow = this.rows && currentCell ? Array.from(this.rows).find(r => r.contains(currentCell)) : null;
15239
- const numOfRows = this.rows ? this.rows.length - 1 : 0;
15240
- const numOfColumns = this.cells ? this.cells.length / this.rows.length - 1 : 0;
15241
- let x = currentRow && currentCell
15242
- ? Array.from(currentRow.querySelectorAll(this.config.keyGridCells)).indexOf(currentCell)
15243
- : 0;
15244
- let y = currentRow && currentCell && this.rows ? Array.from(this.rows).indexOf(currentRow) : 0;
15245
- const dir = this.host.dir;
15246
- const inlineStart = dir === 'rtl' ? 'ArrowRight' : 'ArrowLeft';
15247
- const inlineEnd = dir === 'rtl' ? 'ArrowLeft' : 'ArrowRight';
15248
- const itemsPerPage = this.rows.length || 0;
15249
- if (e.code === 'ArrowUp' && y !== 0) {
15250
- y = y - 1;
15251
- }
15252
- else if (e.code === 'ArrowDown' && y < numOfRows) {
15253
- y = y + 1;
15254
- }
15255
- else if (e.code === inlineStart && x !== 0) {
15256
- x = x - 1;
15257
- }
15258
- else if (e.code === inlineEnd && x < numOfColumns) {
15259
- x = x + 1;
15782
+ setWidth(state) {
15783
+ if (state.strictWidth) {
15784
+ this.renderer.addClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
15260
15785
  }
15261
- else if (e.code === 'End') {
15262
- x = numOfColumns;
15263
- if (e.ctrlKey) {
15264
- y = numOfRows;
15265
- }
15786
+ else {
15787
+ this.renderer.removeClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
15266
15788
  }
15267
- else if (e.code === 'Home') {
15268
- x = 0;
15269
- if (e.ctrlKey) {
15270
- y = 0;
15271
- }
15789
+ this.renderer.setStyle(this.el.nativeElement, 'width', state.width + 'px');
15790
+ }
15791
+ setHidden(state) {
15792
+ if (state.hidden) {
15793
+ this.renderer.addClass(this.el.nativeElement, HIDDEN_COLUMN_CLASS);
15272
15794
  }
15273
- else if (e.code === 'PageUp') {
15274
- y = y - itemsPerPage > 0 ? y - itemsPerPage : 0;
15795
+ else {
15796
+ this.renderer.removeClass(this.el.nativeElement, HIDDEN_COLUMN_CLASS);
15275
15797
  }
15276
- else if (e.code === 'PageDown') {
15277
- y = y + itemsPerPage < numOfRows ? y + itemsPerPage : numOfRows;
15798
+ }
15799
+ clearWidth() {
15800
+ this.renderer.removeClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
15801
+ this.renderer.setStyle(this.el.nativeElement, 'width', null);
15802
+ }
15803
+ }
15804
+ 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 });
15805
+ DatagridCellRenderer.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: DatagridCellRenderer, selector: "clr-dg-cell", ngImport: i0 });
15806
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: DatagridCellRenderer, decorators: [{
15807
+ type: Directive,
15808
+ args: [{
15809
+ selector: 'clr-dg-cell',
15810
+ }]
15811
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: DatagridRenderOrganizer }]; } });
15812
+
15813
+ /*
15814
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
15815
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
15816
+ * This software is released under MIT license.
15817
+ * The full license information can be found in LICENSE in the root directory of this project.
15818
+ */
15819
+ class DatagridRowRenderer {
15820
+ constructor(columnsService) {
15821
+ this.columnsService = columnsService;
15822
+ this.subscriptions = [];
15823
+ }
15824
+ ngAfterContentInit() {
15825
+ this.setCellsState(); // case #3 and #4
15826
+ this.subscriptions.push(this.cells.changes.subscribe(() => {
15827
+ this.setCellsState(); // case #2
15828
+ // Note on case #2: In the case of dynamic columns, when one column (header/cell together) gets deleted,
15829
+ // this.cells.changes emits before this.columnsService.columns gets updated in MainRenderer
15830
+ // when this.headers.changes emits as well. So that means there will be n+1 column state providers
15831
+ // when this.cells.changes emits. Hence, we should quit earlier there. But this method will be called
15832
+ // right after again when this.headers.changes emits. By then, there will be the same number of column state
15833
+ // providers as column headers.
15834
+ }));
15835
+ }
15836
+ ngOnDestroy() {
15837
+ this.subscriptions.forEach(sub => sub.unsubscribe());
15838
+ }
15839
+ setCellsState() {
15840
+ // This method runs in four cases:
15841
+ // 1. When the initial rows appear on the first page.
15842
+ // In this case, the method will be called in DatagridMainRenderer.
15843
+ // 2. When columns (corresponding header/cells) get added and deleted.
15844
+ // In this case, the method will be called in DatagridMainRenderer. (Read the note on this case above).
15845
+ // 3. When rows load asynchronously.
15846
+ // In this case, the method will be called in this class.
15847
+ // 4. When rows load after switching pages.
15848
+ // In this case, the method will be called in this class (Basically, same as the case 3).
15849
+ if (this.cells.length === this.columnsService.columns.length) {
15850
+ this.cells.forEach((cell, index) => {
15851
+ if (this.columnsService.columns[index]) {
15852
+ cell.resetState(this.columnsService.columns[index].value);
15853
+ }
15854
+ });
15278
15855
  }
15279
- return { x, y };
15280
15856
  }
15281
15857
  }
15282
- KeyNavigationGridController.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: KeyNavigationGridController, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
15283
- KeyNavigationGridController.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: KeyNavigationGridController });
15284
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: KeyNavigationGridController, decorators: [{
15285
- type: Injectable
15286
- }], ctorParameters: function () { return [{ type: i0.NgZone }]; } });
15858
+ DatagridRowRenderer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: DatagridRowRenderer, deps: [{ token: ColumnsService }], target: i0.ɵɵFactoryTarget.Directive });
15859
+ DatagridRowRenderer.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: DatagridRowRenderer, selector: "clr-dg-row, clr-dg-row-detail", queries: [{ propertyName: "cells", predicate: DatagridCellRenderer }], ngImport: i0 });
15860
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: DatagridRowRenderer, decorators: [{
15861
+ type: Directive,
15862
+ args: [{
15863
+ selector: 'clr-dg-row, clr-dg-row-detail',
15864
+ }]
15865
+ }], ctorParameters: function () { return [{ type: ColumnsService }]; }, propDecorators: { cells: [{
15866
+ type: ContentChildren,
15867
+ args: [DatagridCellRenderer]
15868
+ }] } });
15287
15869
 
15288
15870
  /*
15289
15871
  * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
@@ -15424,7 +16006,23 @@ class ClrDatagrid {
15424
16006
  /**
15425
16007
  * Reopen updated row or close it
15426
16008
  */
15427
- row ? this.detailService.open(row.item, row.detailButton.nativeElement) : this.detailService.close();
16009
+ if (row) {
16010
+ this.detailService.open(row.item, row.detailButton.nativeElement);
16011
+ // always keep open when virtual scroll is available otherwise close it
16012
+ }
16013
+ else if (!this.hasVirtualScroller) {
16014
+ // Using setTimeout to make sure the inner cycles in rows are done
16015
+ setTimeout(() => {
16016
+ this.detailService.close();
16017
+ });
16018
+ }
16019
+ }
16020
+ // retain active cell when navigating with Up/Down Arrows, PageUp and PageDown buttons in virtual scroller
16021
+ const active = this.keyNavigation.getActiveCell();
16022
+ if (active) {
16023
+ this.zone.runOutsideAngular(() => {
16024
+ setTimeout(() => this.keyNavigation.setActiveCell(active));
16025
+ });
15428
16026
  }
15429
16027
  }));
15430
16028
  }
@@ -15450,8 +16048,6 @@ class ClrDatagrid {
15450
16048
  this.datagridTable.nativeElement.focus();
15451
16049
  }
15452
16050
  }),
15453
- // Reinitialize arrow key navigation on hide/unhide columns
15454
- combineLatest(this.columnsService.columns).subscribe(() => this.keyNavigation?.resetKeyGrid()),
15455
16051
  // A subscription that listens for displayMode changes on the datagrid
15456
16052
  this.displayMode.view.subscribe(viewChange => {
15457
16053
  // Remove any projected columns from the projectedDisplayColumns container
@@ -15508,6 +16104,13 @@ class ClrDatagrid {
15508
16104
  ngOnDestroy() {
15509
16105
  this._subscriptions.forEach((sub) => sub.unsubscribe());
15510
16106
  }
16107
+ toggleAllSelected($event) {
16108
+ $event.preventDefault();
16109
+ if (this.hasVirtualScroller) {
16110
+ return;
16111
+ }
16112
+ this.allSelected = !this.allSelected;
16113
+ }
15511
16114
  resize() {
15512
16115
  this.organizer.resize();
15513
16116
  }
@@ -15519,7 +16122,7 @@ class ClrDatagrid {
15519
16122
  }
15520
16123
  }
15521
16124
  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: ColumnsService }, { token: KeyNavigationGridController }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
15522
- ClrDatagrid.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagrid, selector: "clr-datagrid", inputs: { 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: [
16125
+ 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: [
15523
16126
  Selection,
15524
16127
  Sort,
15525
16128
  FiltersProvider,
@@ -15535,7 +16138,7 @@ ClrDatagrid.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
15535
16138
  ColumnsService,
15536
16139
  DisplayModeService,
15537
16140
  KeyNavigationGridController,
15538
- ], queries: [{ propertyName: "iterator", first: true, predicate: ClrDatagridItems, descendants: true }, { propertyName: "placeholder", first: true, predicate: ClrDatagridPlaceholder, descendants: true }, { propertyName: "columns", predicate: ClrDatagridColumn }, { propertyName: "rows", predicate: ClrDatagridRow }], viewQueries: [{ propertyName: "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-2024 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)=\"allSelected = !allSelected; $event.preventDefault()\"\n >\n <div 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 [attr.aria-label]=\"clrDgSingleSelectionAriaLabel\"\n >\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 [attr.aria-label]=\"clrDgSingleActionableAriaLabel\"\n >\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 [attr.aria-label]=\"clrDetailExpandableAriaLabel\"\n >\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 <ng-container #displayedRows></ng-container>\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 <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: ["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: ClrDatagridPlaceholder, selector: "clr-dg-placeholder" }, { kind: "directive", type: ClrDatagridSelectionCellDirective, selector: ".datagrid-select" }] });
16141
+ ], queries: [{ propertyName: "iterator", first: true, predicate: ClrDatagridItems, descendants: true }, { propertyName: "placeholder", first: true, predicate: ClrDatagridPlaceholder, descendants: true }, { propertyName: "columns", predicate: ClrDatagridColumn }, { propertyName: "rows", predicate: ClrDatagridRow }], viewQueries: [{ propertyName: "datagrid", first: true, predicate: ["datagrid"], descendants: true, read: ElementRef }, { propertyName: "datagridTable", first: true, predicate: ["datagridTable"], descendants: true, read: ElementRef }, { propertyName: "scrollableColumns", first: true, predicate: ["scrollableColumns"], descendants: true, read: ViewContainerRef }, { propertyName: "_projectedDisplayColumns", first: true, predicate: ["projectedDisplayColumns"], descendants: true, read: ViewContainerRef }, { propertyName: "_projectedCalculationColumns", first: true, predicate: ["projectedCalculationColumns"], descendants: true, read: ViewContainerRef }, { propertyName: "_displayedRows", first: true, predicate: ["displayedRows"], descendants: true, read: ViewContainerRef }, { propertyName: "_calculationRows", first: true, predicate: ["calculationRows"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2024 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<ng-content select=\"clr-dg-action-bar\"></ng-content>\n<div class=\"datagrid-outer-wrapper\">\n <div class=\"datagrid-inner-wrapper\">\n <div class=\"datagrid\" #datagrid [attr.aria-hidden]=\"detailService.isOpen ? true : null\">\n <div class=\"datagrid-table-wrapper\">\n <div role=\"grid\" class=\"datagrid-table\" tabindex=\"-1\" #datagridTable>\n <div role=\"rowgroup\" class=\"datagrid-header\">\n <div role=\"row\" class=\"datagrid-row\">\n <div class=\"datagrid-row-master datagrid-row-flex\">\n <div class=\"datagrid-row-sticky\">\n <!--header for datagrid where you can select multiple rows -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-select datagrid-fixed-column\"\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Multi\"\n (keydown.space)=\"toggleAllSelected($event)\"\n >\n <div *ngIf=\"!hasVirtualScroller\" class=\"clr-checkbox-wrapper\">\n <!-- We need to move focus and space-key handling to the parent because of keyboard arrow key navigation,\n which is not able to transfer focus directly on the input when focused with the tab key -->\n <input\n type=\"checkbox\"\n [id]=\"selectAllId\"\n [(ngModel)]=\"allSelected\"\n [attr.aria-label]=\"commonStrings.keys.selectAll\"\n tabindex=\"-1\"\n />\n <!-- Usage of class clr-col-null here prevents clr-col-* classes from being added when a datagrid is wrapped inside clrForm -->\n <label [for]=\"selectAllId\" class=\"clr-control-label clr-col-null\">\n <span class=\"clr-sr-only\">{{commonStrings.keys.selectAll}}</span>\n </label>\n </div>\n\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for datagrid where you can select one row only -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-select datagrid-fixed-column\"\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Single\"\n >\n <div class=\"clr-sr-only\">{{clrDgSingleSelectionAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for single row action; only displayType if we have at least one actionable row in datagrid -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-row-actions datagrid-fixed-column\"\n *ngIf=\"rowActionService.hasActionableRow\"\n >\n <div class=\"clr-sr-only\">{{clrDgSingleActionableAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for carets; only displayType if we have at least one expandable row in datagrid -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-expandable-caret datagrid-fixed-column\"\n *ngIf=\"expandableRows.hasExpandableRow || detailService.enabled\"\n >\n <div class=\"clr-sr-only\">{{clrDetailExpandableAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n </div>\n <div class=\"datagrid-row-scrollable\">\n <ng-container #projectedDisplayColumns></ng-container>\n </div>\n </div>\n </div>\n </div>\n\n <div role=\"presentation\" class=\"datagrid-rows\">\n <clr-dg-row class=\"datagrid-row-loading\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell>\n <clr-spinner clrMedium></clr-spinner>\n <span>{{ commonStrings.keys.loading }}</span>\n </clr-dg-cell>\n </clr-dg-row>\n\n <ng-container #displayedRows></ng-container>\n\n <clr-dg-row class=\"datagrid-row-loading\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell>\n <clr-spinner clrMedium></clr-spinner>\n <span>{{ commonStrings.keys.loading }}</span>\n </clr-dg-cell>\n </clr-dg-row>\n\n <!-- Custom placeholder overrides the default empty one -->\n <ng-content select=\"clr-dg-placeholder\"></ng-content>\n <clr-dg-placeholder *ngIf=\"!placeholder\"></clr-dg-placeholder>\n </div>\n </div>\n </div>\n </div>\n <ng-content select=\"clr-dg-footer\"></ng-content>\n <div class=\"datagrid-spinner\" *ngIf=\"loading\">\n <clr-spinner clrMedium>Loading</clr-spinner>\n </div>\n </div>\n <ng-content select=\"[clrIfDetail],clr-dg-detail\"></ng-content>\n</div>\n\n<div class=\"datagrid-calculation-table\">\n <div class=\"datagrid-calculation-header\">\n <ng-container #projectedCalculationColumns></ng-container>\n </div>\n <ng-container #calculationRows></ng-container>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: ClrLabel, selector: "label", inputs: ["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: ["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" }] });
15539
16142
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagrid, decorators: [{
15540
16143
  type: Component,
15541
16144
  args: [{ selector: 'clr-datagrid', providers: [
@@ -15557,11 +16160,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
15557
16160
  ], host: {
15558
16161
  '[class.datagrid-host]': 'true',
15559
16162
  '[class.datagrid-detail-open]': 'detailService.isOpen',
15560
- }, template: "<!--\n ~ Copyright (c) 2016-2024 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)=\"allSelected = !allSelected; $event.preventDefault()\"\n >\n <div 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 [attr.aria-label]=\"clrDgSingleSelectionAriaLabel\"\n >\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 [attr.aria-label]=\"clrDgSingleActionableAriaLabel\"\n >\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 [attr.aria-label]=\"clrDetailExpandableAriaLabel\"\n >\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 <ng-container #displayedRows></ng-container>\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 <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" }]
16163
+ }, template: "<!--\n ~ Copyright (c) 2016-2024 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<ng-content select=\"clr-dg-action-bar\"></ng-content>\n<div class=\"datagrid-outer-wrapper\">\n <div class=\"datagrid-inner-wrapper\">\n <div class=\"datagrid\" #datagrid [attr.aria-hidden]=\"detailService.isOpen ? true : null\">\n <div class=\"datagrid-table-wrapper\">\n <div role=\"grid\" class=\"datagrid-table\" tabindex=\"-1\" #datagridTable>\n <div role=\"rowgroup\" class=\"datagrid-header\">\n <div role=\"row\" class=\"datagrid-row\">\n <div class=\"datagrid-row-master datagrid-row-flex\">\n <div class=\"datagrid-row-sticky\">\n <!--header for datagrid where you can select multiple rows -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-select datagrid-fixed-column\"\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Multi\"\n (keydown.space)=\"toggleAllSelected($event)\"\n >\n <div *ngIf=\"!hasVirtualScroller\" class=\"clr-checkbox-wrapper\">\n <!-- We need to move focus and space-key handling to the parent because of keyboard arrow key navigation,\n which is not able to transfer focus directly on the input when focused with the tab key -->\n <input\n type=\"checkbox\"\n [id]=\"selectAllId\"\n [(ngModel)]=\"allSelected\"\n [attr.aria-label]=\"commonStrings.keys.selectAll\"\n tabindex=\"-1\"\n />\n <!-- Usage of class clr-col-null here prevents clr-col-* classes from being added when a datagrid is wrapped inside clrForm -->\n <label [for]=\"selectAllId\" class=\"clr-control-label clr-col-null\">\n <span class=\"clr-sr-only\">{{commonStrings.keys.selectAll}}</span>\n </label>\n </div>\n\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for datagrid where you can select one row only -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-select datagrid-fixed-column\"\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Single\"\n >\n <div class=\"clr-sr-only\">{{clrDgSingleSelectionAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for single row action; only displayType if we have at least one actionable row in datagrid -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-row-actions datagrid-fixed-column\"\n *ngIf=\"rowActionService.hasActionableRow\"\n >\n <div class=\"clr-sr-only\">{{clrDgSingleActionableAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for carets; only displayType if we have at least one expandable row in datagrid -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-expandable-caret datagrid-fixed-column\"\n *ngIf=\"expandableRows.hasExpandableRow || detailService.enabled\"\n >\n <div class=\"clr-sr-only\">{{clrDetailExpandableAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n </div>\n <div class=\"datagrid-row-scrollable\">\n <ng-container #projectedDisplayColumns></ng-container>\n </div>\n </div>\n </div>\n </div>\n\n <div role=\"presentation\" class=\"datagrid-rows\">\n <clr-dg-row class=\"datagrid-row-loading\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell>\n <clr-spinner clrMedium></clr-spinner>\n <span>{{ commonStrings.keys.loading }}</span>\n </clr-dg-cell>\n </clr-dg-row>\n\n <ng-container #displayedRows></ng-container>\n\n <clr-dg-row class=\"datagrid-row-loading\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell>\n <clr-spinner clrMedium></clr-spinner>\n <span>{{ commonStrings.keys.loading }}</span>\n </clr-dg-cell>\n </clr-dg-row>\n\n <!-- Custom placeholder overrides the default empty one -->\n <ng-content select=\"clr-dg-placeholder\"></ng-content>\n <clr-dg-placeholder *ngIf=\"!placeholder\"></clr-dg-placeholder>\n </div>\n </div>\n </div>\n </div>\n <ng-content select=\"clr-dg-footer\"></ng-content>\n <div class=\"datagrid-spinner\" *ngIf=\"loading\">\n <clr-spinner clrMedium>Loading</clr-spinner>\n </div>\n </div>\n <ng-content select=\"[clrIfDetail],clr-dg-detail\"></ng-content>\n</div>\n\n<div class=\"datagrid-calculation-table\">\n <div class=\"datagrid-calculation-header\">\n <ng-container #projectedCalculationColumns></ng-container>\n </div>\n <ng-container #calculationRows></ng-container>\n</div>\n" }]
15561
16164
  }], 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: [{
15562
16165
  type: Inject,
15563
16166
  args: [DOCUMENT]
15564
- }] }, { type: i0.ElementRef }, { type: Page }, { type: ClrCommonStringsService }, { type: ColumnsService }, { type: KeyNavigationGridController }, { type: i0.NgZone }]; }, propDecorators: { clrDgSingleSelectionAriaLabel: [{
16167
+ }] }, { type: i0.ElementRef }, { type: Page }, { type: ClrCommonStringsService }, { type: ColumnsService }, { type: KeyNavigationGridController }, { type: i0.NgZone }]; }, propDecorators: { loadingMoreItems: [{
16168
+ type: Input,
16169
+ args: ['clrLoadingMoreItems']
16170
+ }], clrDgSingleSelectionAriaLabel: [{
15565
16171
  type: Input
15566
16172
  }], clrDgSingleActionableAriaLabel: [{
15567
16173
  type: Input
@@ -15590,6 +16196,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
15590
16196
  }], rows: [{
15591
16197
  type: ContentChildren,
15592
16198
  args: [ClrDatagridRow]
16199
+ }], datagrid: [{
16200
+ type: ViewChild,
16201
+ args: ['datagrid', { read: ElementRef }]
15593
16202
  }], datagridTable: [{
15594
16203
  type: ViewChild,
15595
16204
  args: ['datagridTable', { read: ElementRef }]
@@ -15720,6 +16329,7 @@ class ClrDatagridActionOverflow {
15720
16329
  ClrDatagridActionOverflow.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridActionOverflow, deps: [{ token: RowActionService }, { token: ClrCommonStringsService }, { token: PLATFORM_ID }, { token: i0.NgZone }, { token: ClrPopoverToggleService }], target: i0.ɵɵFactoryTarget.Component });
15721
16330
  ClrDatagridActionOverflow.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridActionOverflow, selector: "clr-dg-action-overflow", inputs: { buttonLabel: ["clrDgActionOverflowButtonLabel", "buttonLabel"], open: ["clrDgActionOverflowOpen", "open"] }, outputs: { openChange: "clrDgActionOverflowOpenChange" }, viewQueries: [{ propertyName: "keyFocus", first: true, predicate: ClrKeyFocus, descendants: true }], hostDirectives: [{ directive: ClrPopoverHostDirective }], ngImport: i0, template: `
15722
16331
  <button
16332
+ tabindex="-1"
15723
16333
  class="datagrid-action-toggle"
15724
16334
  type="button"
15725
16335
  role="button"
@@ -15754,6 +16364,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
15754
16364
  hostDirectives: [ClrPopoverHostDirective],
15755
16365
  template: `
15756
16366
  <button
16367
+ tabindex="-1"
15757
16368
  class="datagrid-action-toggle"
15758
16369
  type="button"
15759
16370
  role="button"
@@ -16059,10 +16670,13 @@ class ClrDatagridDetailHeader {
16059
16670
  get titleId() {
16060
16671
  return `${this.detailService.id}-title`;
16061
16672
  }
16673
+ ngAfterViewInit() {
16674
+ this.title.nativeElement.focus();
16675
+ }
16062
16676
  }
16063
16677
  ClrDatagridDetailHeader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridDetailHeader, deps: [{ token: DetailService }, { token: ClrCommonStringsService }], target: i0.ɵɵFactoryTarget.Component });
16064
- ClrDatagridDetailHeader.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridDetailHeader, selector: "clr-dg-detail-header", host: { properties: { "class.datagrid-detail-header": "true" } }, ngImport: i0, template: `
16065
- <div class="datagrid-detail-header-title" cdkFocusInitial tabindex="-1" [id]="titleId">
16678
+ ClrDatagridDetailHeader.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridDetailHeader, selector: "clr-dg-detail-header", host: { properties: { "class.datagrid-detail-header": "true" } }, viewQueries: [{ propertyName: "title", first: true, predicate: ["title"], descendants: true }], ngImport: i0, template: `
16679
+ <div #title class="datagrid-detail-header-title" tabindex="-1" [id]="titleId">
16066
16680
  <ng-content></ng-content>
16067
16681
  </div>
16068
16682
  <div class="datagrid-detail-pane-close">
@@ -16084,7 +16698,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
16084
16698
  '[class.datagrid-detail-header]': 'true',
16085
16699
  },
16086
16700
  template: `
16087
- <div class="datagrid-detail-header-title" cdkFocusInitial tabindex="-1" [id]="titleId">
16701
+ <div #title class="datagrid-detail-header-title" tabindex="-1" [id]="titleId">
16088
16702
  <ng-content></ng-content>
16089
16703
  </div>
16090
16704
  <div class="datagrid-detail-pane-close">
@@ -16099,7 +16713,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
16099
16713
  </div>
16100
16714
  `,
16101
16715
  }]
16102
- }], ctorParameters: function () { return [{ type: DetailService }, { type: ClrCommonStringsService }]; } });
16716
+ }], ctorParameters: function () { return [{ type: DetailService }, { type: ClrCommonStringsService }]; }, propDecorators: { title: [{
16717
+ type: ViewChild,
16718
+ args: ['title']
16719
+ }] } });
16103
16720
 
16104
16721
  /*
16105
16722
  * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
@@ -16112,21 +16729,42 @@ class ClrDatagridDetail {
16112
16729
  this.detailService = detailService;
16113
16730
  this.commonStrings = commonStrings;
16114
16731
  }
16732
+ get labelledBy() {
16733
+ if (this.ariaLabelledBy) {
16734
+ return this.header ? `${this.header.titleId} ${this.ariaLabelledBy}` : this.ariaLabelledBy;
16735
+ }
16736
+ else if (this.ariaLabel) {
16737
+ // If aria-label is set by the end user, do not set aria-labelledby
16738
+ return null;
16739
+ }
16740
+ else {
16741
+ return this.header?.titleId || '';
16742
+ }
16743
+ }
16744
+ get label() {
16745
+ if (!this.ariaLabelledBy) {
16746
+ return this.ariaLabel || null;
16747
+ }
16748
+ else {
16749
+ return null;
16750
+ }
16751
+ }
16115
16752
  close() {
16116
16753
  this.detailService.close();
16117
16754
  }
16118
16755
  }
16119
16756
  ClrDatagridDetail.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridDetail, deps: [{ token: DetailService }, { token: ClrCommonStringsService }], target: i0.ɵɵFactoryTarget.Component });
16120
- ClrDatagridDetail.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridDetail, selector: "clr-dg-detail", host: { properties: { "class.datagrid-detail-pane": "true" } }, queries: [{ propertyName: "header", first: true, predicate: ClrDatagridDetailHeader, descendants: true }], ngImport: i0, template: `
16757
+ ClrDatagridDetail.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridDetail, selector: "clr-dg-detail", inputs: { ariaLabelledBy: ["clrDetailAriaLabelledBy", "ariaLabelledBy"], ariaLabel: ["clrDetailAriaLabel", "ariaLabel"] }, host: { properties: { "class.datagrid-detail-pane": "true" } }, queries: [{ propertyName: "header", first: true, predicate: ClrDatagridDetailHeader, descendants: true }], ngImport: i0, template: `
16121
16758
  <div
16122
16759
  cdkTrapFocus
16123
- [cdkTrapFocusAutoCapture]="true"
16760
+ [cdkTrapFocusAutoCapture]="!header"
16124
16761
  class="datagrid-detail-pane-content"
16125
16762
  *ngIf="detailService.isOpen"
16126
16763
  role="dialog"
16127
16764
  [id]="detailService.id"
16128
16765
  aria-modal="true"
16129
- [attr.aria-describedby]="header ? header.titleId : ''"
16766
+ [attr.aria-labelledby]="labelledBy"
16767
+ [attr.aria-label]="label"
16130
16768
  >
16131
16769
  <div class="clr-sr-only">{{ commonStrings.keys.detailPaneStart }}</div>
16132
16770
  <ng-content></ng-content>
@@ -16145,13 +16783,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
16145
16783
  template: `
16146
16784
  <div
16147
16785
  cdkTrapFocus
16148
- [cdkTrapFocusAutoCapture]="true"
16786
+ [cdkTrapFocusAutoCapture]="!header"
16149
16787
  class="datagrid-detail-pane-content"
16150
16788
  *ngIf="detailService.isOpen"
16151
16789
  role="dialog"
16152
16790
  [id]="detailService.id"
16153
16791
  aria-modal="true"
16154
- [attr.aria-describedby]="header ? header.titleId : ''"
16792
+ [attr.aria-labelledby]="labelledBy"
16793
+ [attr.aria-label]="label"
16155
16794
  >
16156
16795
  <div class="clr-sr-only">{{ commonStrings.keys.detailPaneStart }}</div>
16157
16796
  <ng-content></ng-content>
@@ -16159,7 +16798,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
16159
16798
  </div>
16160
16799
  `,
16161
16800
  }]
16162
- }], ctorParameters: function () { return [{ type: DetailService }, { type: ClrCommonStringsService }]; }, propDecorators: { header: [{
16801
+ }], ctorParameters: function () { return [{ type: DetailService }, { type: ClrCommonStringsService }]; }, propDecorators: { ariaLabelledBy: [{
16802
+ type: Input,
16803
+ args: ['clrDetailAriaLabelledBy']
16804
+ }], ariaLabel: [{
16805
+ type: Input,
16806
+ args: ['clrDetailAriaLabel']
16807
+ }], header: [{
16163
16808
  type: ContentChild,
16164
16809
  args: [ClrDatagridDetailHeader]
16165
16810
  }] } });
@@ -16433,6 +17078,9 @@ class ClrIfDetail {
16433
17078
  }
16434
17079
  this.skip = false;
16435
17080
  }
17081
+ get viewContext() {
17082
+ return { $implicit: this.detailService.state };
17083
+ }
16436
17084
  ngOnInit() {
16437
17085
  this.subscriptions.push(this.detailService.stateChange.subscribe(state => {
16438
17086
  if (state === true) {
@@ -16449,12 +17097,11 @@ class ClrIfDetail {
16449
17097
  togglePanel(showPanel) {
16450
17098
  let stateChangeParams = null;
16451
17099
  if (showPanel === true) {
16452
- const embeddedViewContext = { $implicit: this.detailService.state };
16453
- if (this.embeddedViewRef) {
16454
- this.embeddedViewRef.context = embeddedViewContext;
16455
- }
16456
- else {
16457
- this.embeddedViewRef = this.viewContainer.createEmbeddedView(this.templateRef, embeddedViewContext);
17100
+ if (!this.embeddedViewRef) {
17101
+ // Create a context forward `Proxy` that will always bind to the user-specified context,
17102
+ // without having to re-assign it whenever changes.
17103
+ const viewContext = this._createContextForwardProxy();
17104
+ this.embeddedViewRef = this.viewContainer.createEmbeddedView(this.templateRef, viewContext);
16458
17105
  }
16459
17106
  this.skip = true;
16460
17107
  stateChangeParams = this.detailService.state;
@@ -16465,6 +17112,27 @@ class ClrIfDetail {
16465
17112
  }
16466
17113
  this.stateChange.emit(stateChangeParams);
16467
17114
  }
17115
+ /**
17116
+ * For a given outlet instance, we create a proxy object that delegates
17117
+ * to the user-specified context. This allows changing, or swapping out
17118
+ * the context object completely without having to destroy/re-create the view.
17119
+ */
17120
+ _createContextForwardProxy() {
17121
+ return new Proxy({}, {
17122
+ set: (_target, prop, newValue) => {
17123
+ if (!this.viewContext) {
17124
+ return false;
17125
+ }
17126
+ return Reflect.set(this.viewContext, prop, newValue);
17127
+ },
17128
+ get: (_target, prop, receiver) => {
17129
+ if (!this.viewContext) {
17130
+ return undefined;
17131
+ }
17132
+ return Reflect.get(this.viewContext, prop, receiver);
17133
+ },
17134
+ });
17135
+ }
16468
17136
  }
16469
17137
  ClrIfDetail.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrIfDetail, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: DetailService }], target: i0.ɵɵFactoryTarget.Directive });
16470
17138
  ClrIfDetail.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: ClrIfDetail, selector: "[clrIfDetail]", inputs: { state: ["clrIfDetail", "state"] }, outputs: { stateChange: "clrIfDetailChange" }, ngImport: i0 });
@@ -16991,96 +17659,227 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
16991
17659
  args: ['clrDgReplace']
16992
17660
  }] } });
16993
17661
 
16994
- /*
16995
- * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
16996
- * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
16997
- * This software is released under MIT license.
16998
- * The full license information can be found in LICENSE in the root directory of this project.
16999
- */
17000
- // @TODO The top two are not used now, which is probably a performance drag that was broken along the way.
17001
- // There was a previous pattern to hide everything to do computation then display, for Firefox, needs revisiting.
17002
- const NO_LAYOUT_CLASS = 'datagrid-no-layout';
17003
- const COMPUTE_WIDTH_CLASS = 'datagrid-computing-columns-width';
17004
- const STRICT_WIDTH_CLASS = 'datagrid-fixed-width';
17005
- const HIDDEN_COLUMN_CLASS = 'datagrid-hidden-column';
17006
-
17007
- /*
17008
- * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
17009
- * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
17010
- * This software is released under MIT license.
17011
- * The full license information can be found in LICENSE in the root directory of this project.
17012
- */
17013
- class DatagridCellRenderer {
17014
- constructor(el, renderer, organizer) {
17015
- this.el = el;
17016
- this.renderer = renderer;
17662
+ const defaultCdkFixedSizeVirtualScrollInputs = {
17663
+ itemSize: 32,
17664
+ minBufferPx: 200,
17665
+ maxBufferPx: 400,
17666
+ };
17667
+ class ClrDatagridVirtualScrollDirective {
17668
+ constructor(changeDetectorRef, iterableDiffers, items, ngZone, templateRef, viewContainerRef, directionality, scrollDispatcher, viewportRuler, datagrid, columnsService, injector) {
17669
+ this.changeDetectorRef = changeDetectorRef;
17670
+ this.iterableDiffers = iterableDiffers;
17671
+ this.items = items;
17672
+ this.ngZone = ngZone;
17673
+ this.templateRef = templateRef;
17674
+ this.viewContainerRef = viewContainerRef;
17675
+ this.directionality = directionality;
17676
+ this.scrollDispatcher = scrollDispatcher;
17677
+ this.viewportRuler = viewportRuler;
17678
+ this.datagrid = datagrid;
17679
+ this.columnsService = columnsService;
17680
+ this.injector = injector;
17681
+ this.renderedRangeChange = new EventEmitter();
17682
+ this._cdkFixedSizeVirtualScrollInputs = { ...defaultCdkFixedSizeVirtualScrollInputs };
17017
17683
  this.subscriptions = [];
17018
- this.subscriptions.push(organizer.filterRenderSteps(DatagridRenderStep.CLEAR_WIDTHS).subscribe(() => this.clearWidth()));
17684
+ this.mutationChanges = new MutationObserver((mutations) => {
17685
+ mutations.forEach((mutation) => {
17686
+ // it is possible this to be called twice because the old class is removed and the new added
17687
+ if (mutation.target.classList.contains('datagrid-compact') && this.itemSize > 24) {
17688
+ this.itemSize = 24;
17689
+ }
17690
+ });
17691
+ });
17692
+ this.viewRepeater = new _RecycleViewRepeaterStrategy();
17693
+ this.cdkVirtualForInputs = {
17694
+ cdkVirtualForTrackBy: index => index,
17695
+ };
17696
+ this.items.smartenUp();
17697
+ this.datagrid.hasVirtualScroller = true;
17698
+ this.datagrid.detailService.preventFocusScroll = true;
17699
+ this.datagridElementRef = this.datagrid.el;
17700
+ // default
17701
+ this.cdkVirtualForTemplateCacheSize = 20;
17702
+ this.mutationChanges.observe(this.datagridElementRef.nativeElement, {
17703
+ attributeFilter: ['class'],
17704
+ attributeOldValue: true,
17705
+ });
17706
+ this.virtualScrollStrategy = new FixedSizeVirtualScrollStrategy(this._cdkFixedSizeVirtualScrollInputs.itemSize, this._cdkFixedSizeVirtualScrollInputs.minBufferPx, this._cdkFixedSizeVirtualScrollInputs.maxBufferPx);
17019
17707
  }
17020
- // @TODO(JEREMY) Work out how to dedupe some of this code between header and cell renderers
17021
- set columnState(columnState) {
17022
- if (this.stateSubscription) {
17023
- this.stateSubscription.unsubscribe();
17024
- }
17025
- this.runAllChanges = ALL_COLUMN_CHANGES;
17026
- this.stateSubscription = columnState.subscribe(state => this.stateChanges(state));
17708
+ get cdkVirtualForOf() {
17709
+ return this.cdkVirtualForInputs.cdkVirtualForOf;
17710
+ }
17711
+ set cdkVirtualForOf(value) {
17712
+ this.cdkVirtualForInputs.cdkVirtualForOf = value;
17713
+ this.items.all = value;
17714
+ this.updateCdkVirtualForInputs();
17715
+ }
17716
+ get cdkVirtualForTrackBy() {
17717
+ return this.cdkVirtualForInputs.cdkVirtualForTrackBy;
17718
+ }
17719
+ set cdkVirtualForTrackBy(value) {
17720
+ this.cdkVirtualForInputs.cdkVirtualForTrackBy = value;
17721
+ this.updateCdkVirtualForInputs();
17722
+ }
17723
+ get cdkVirtualForTemplate() {
17724
+ return this?.cdkVirtualForInputs?.cdkVirtualForTemplate;
17725
+ }
17726
+ set cdkVirtualForTemplate(value) {
17727
+ this.cdkVirtualForInputs.cdkVirtualForTemplate = value;
17728
+ this.updateCdkVirtualForInputs();
17729
+ }
17730
+ get cdkVirtualForTemplateCacheSize() {
17731
+ return this.cdkVirtualForInputs.cdkVirtualForTemplateCacheSize;
17732
+ }
17733
+ set cdkVirtualForTemplateCacheSize(value) {
17734
+ this.cdkVirtualForInputs.cdkVirtualForTemplateCacheSize = coerceNumberProperty(value);
17735
+ this.updateCdkVirtualForInputs();
17736
+ }
17737
+ get itemSize() {
17738
+ return this._cdkFixedSizeVirtualScrollInputs.itemSize;
17739
+ }
17740
+ set itemSize(value) {
17741
+ this._cdkFixedSizeVirtualScrollInputs.itemSize = coerceNumberProperty(value);
17742
+ this.updateFixedSizeVirtualScrollInputs();
17743
+ }
17744
+ get minBufferPx() {
17745
+ return this._cdkFixedSizeVirtualScrollInputs.minBufferPx;
17746
+ }
17747
+ set minBufferPx(value) {
17748
+ this._cdkFixedSizeVirtualScrollInputs.minBufferPx = coerceNumberProperty(value);
17749
+ this.updateFixedSizeVirtualScrollInputs();
17750
+ }
17751
+ get maxBufferPx() {
17752
+ return this._cdkFixedSizeVirtualScrollInputs.maxBufferPx;
17753
+ }
17754
+ set maxBufferPx(value) {
17755
+ this._cdkFixedSizeVirtualScrollInputs.maxBufferPx = coerceNumberProperty(value);
17756
+ this.updateFixedSizeVirtualScrollInputs();
17757
+ }
17758
+ ngAfterViewInit() {
17759
+ this.injector.runInContext(() => {
17760
+ this.virtualScrollViewport = this.createVirtualScrollViewportForDatagrid(this.changeDetectorRef, this.ngZone, this.directionality, this.scrollDispatcher, this.viewportRuler, this.datagridElementRef, this.virtualScrollStrategy);
17761
+ this.cdkVirtualFor = new CdkVirtualForOf(this.viewContainerRef, this.templateRef, this.iterableDiffers, this.viewRepeater, this.virtualScrollViewport, this.ngZone);
17762
+ this.virtualScrollViewport.ngOnInit();
17763
+ });
17764
+ this.gridRoleElement = this.datagridElementRef.nativeElement.querySelector('[role="grid"]');
17765
+ this.updateCdkVirtualForInputs();
17766
+ this.subscriptions.push(this.items.change.subscribe(newItems => {
17767
+ this.cdkVirtualFor.cdkVirtualForOf = newItems;
17768
+ }), this.cdkVirtualFor.dataStream.subscribe(data => {
17769
+ this.updateAriaRowCount(data.length);
17770
+ }), this.virtualScrollViewport.renderedRangeStream.subscribe(renderedRange => {
17771
+ this.renderedRangeChange.emit(renderedRange);
17772
+ }), this.datagrid.refresh.subscribe(datagridState => {
17773
+ if (datagridState.filters) {
17774
+ this.virtualScrollViewport.scrollToIndex(0);
17775
+ }
17776
+ }), this.columnsService.columnsStateChange.subscribe(() => {
17777
+ this.viewRepeater.detach();
17778
+ }));
17779
+ }
17780
+ ngDoCheck() {
17781
+ this.cdkVirtualFor?.ngDoCheck();
17782
+ this.updateAriaRowIndexes();
17027
17783
  }
17028
17784
  ngOnDestroy() {
17029
- this.subscriptions.forEach(sub => sub.unsubscribe());
17030
- if (this.stateSubscription) {
17031
- this.stateSubscription.unsubscribe();
17032
- }
17785
+ this.cdkVirtualFor?.ngOnDestroy();
17786
+ this.virtualScrollViewport?.ngOnDestroy();
17787
+ this.mutationChanges?.disconnect();
17788
+ this.subscriptions.forEach(subscription => {
17789
+ subscription.unsubscribe();
17790
+ });
17033
17791
  }
17034
- stateChanges(state) {
17035
- if (this.runAllChanges) {
17036
- state.changes = this.runAllChanges;
17037
- delete this.runAllChanges;
17038
- }
17039
- if (state.changes && state.changes.length) {
17040
- state.changes.forEach(change => {
17041
- switch (change) {
17042
- case DatagridColumnChanges.WIDTH:
17043
- this.setWidth(state);
17044
- break;
17045
- case DatagridColumnChanges.HIDDEN:
17046
- this.setHidden(state);
17047
- break;
17048
- default:
17049
- break;
17792
+ updateCdkVirtualForInputs() {
17793
+ if (this.cdkVirtualFor) {
17794
+ for (const cdkVirtualForInputKey of Object.keys(this.cdkVirtualForInputs)) {
17795
+ if (this.cdkVirtualFor[cdkVirtualForInputKey] !== this.cdkVirtualForInputs[cdkVirtualForInputKey]) {
17796
+ this.cdkVirtualFor[cdkVirtualForInputKey] = this.cdkVirtualForInputs[cdkVirtualForInputKey];
17050
17797
  }
17051
- });
17798
+ }
17052
17799
  }
17053
17800
  }
17054
- clearWidth() {
17055
- this.renderer.removeClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
17056
- this.renderer.setStyle(this.el.nativeElement, 'width', null);
17057
- }
17058
- setWidth(state) {
17059
- if (state.strictWidth) {
17060
- this.renderer.addClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
17061
- }
17062
- else {
17063
- this.renderer.removeClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
17801
+ updateFixedSizeVirtualScrollInputs() {
17802
+ if (this.virtualScrollStrategy) {
17803
+ this.virtualScrollStrategy.updateItemAndBufferSize(this._cdkFixedSizeVirtualScrollInputs.itemSize, this._cdkFixedSizeVirtualScrollInputs.minBufferPx, this._cdkFixedSizeVirtualScrollInputs.maxBufferPx);
17064
17804
  }
17065
- this.renderer.setStyle(this.el.nativeElement, 'width', state.width + 'px');
17066
17805
  }
17067
- setHidden(state) {
17068
- if (state.hidden) {
17069
- this.renderer.addClass(this.el.nativeElement, HIDDEN_COLUMN_CLASS);
17806
+ updateAriaRowCount(rowCount) {
17807
+ this.gridRoleElement?.setAttribute('aria-rowcount', rowCount.toString());
17808
+ }
17809
+ updateAriaRowIndexes() {
17810
+ for (let i = 0; i < this.viewContainerRef.length; i++) {
17811
+ const viewRef = this.viewContainerRef.get(i);
17812
+ const rootElements = viewRef.rootNodes;
17813
+ const datagridRowElement = rootElements.find(rowElement => rowElement.tagName === 'CLR-DG-ROW');
17814
+ const rowRoleElement = datagridRowElement?.querySelector('[role="row"]');
17815
+ // aria-rowindex should start with one, not zero, so we have to add one to the zero-based index
17816
+ rowRoleElement?.setAttribute('aria-rowindex', (viewRef.context.index + 1).toString());
17070
17817
  }
17071
- else {
17072
- this.renderer.removeClass(this.el.nativeElement, HIDDEN_COLUMN_CLASS);
17818
+ }
17819
+ createVirtualScrollViewportForDatagrid(changeDetectorRef, ngZone, directionality, scrollDispatcher, viewportRuler, datagridElementRef, virtualScrollStrategy) {
17820
+ const datagridDivElement = datagridElementRef.nativeElement.querySelector('.datagrid');
17821
+ const datagridTableElement = datagridElementRef.nativeElement.querySelector('.datagrid-table');
17822
+ const datagridRowsElement = datagridElementRef.nativeElement.querySelector('.datagrid-rows');
17823
+ const datagridDivElementRef = { nativeElement: datagridDivElement };
17824
+ let topOffset = 0;
17825
+ let totalContentSize = 0;
17826
+ function updateDatagridElementStyles() {
17827
+ datagridRowsElement.style.transform = `translateY(${topOffset}px)`;
17828
+ datagridRowsElement.style.height = `${totalContentSize - topOffset}px`;
17073
17829
  }
17830
+ const virtualScrollViewport = new CdkVirtualScrollViewport(datagridDivElementRef, changeDetectorRef, ngZone, virtualScrollStrategy, directionality, scrollDispatcher, viewportRuler, null);
17831
+ virtualScrollViewport._contentWrapper = {
17832
+ nativeElement: {
17833
+ style: {
17834
+ set transform(value) {
17835
+ topOffset = value === undefined ? 0 : +/translateY\(([0-9]+)px\)/.exec(value)?.[1];
17836
+ updateDatagridElementStyles();
17837
+ },
17838
+ },
17839
+ },
17840
+ };
17841
+ virtualScrollViewport.setTotalContentSize = (value) => {
17842
+ totalContentSize = value;
17843
+ datagridTableElement.style.height = `${totalContentSize}px`;
17844
+ updateDatagridElementStyles();
17845
+ };
17846
+ return virtualScrollViewport;
17074
17847
  }
17075
17848
  }
17076
- 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 });
17077
- DatagridCellRenderer.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: DatagridCellRenderer, selector: "clr-dg-cell", ngImport: i0 });
17078
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: DatagridCellRenderer, decorators: [{
17849
+ 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.TemplateRef }, { token: i0.ViewContainerRef }, { token: i1$2.Directionality }, { token: i3$1.ScrollDispatcher }, { token: i3$1.ViewportRuler }, { token: ClrDatagrid }, { token: ColumnsService }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Directive });
17850
+ ClrDatagridVirtualScrollDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridVirtualScrollDirective, selector: "[ClrVirtualScroll]", inputs: { cdkVirtualForOf: ["clrVirtualRowsOf", "cdkVirtualForOf"], cdkVirtualForTrackBy: ["clrVirtualRowsTrackBy", "cdkVirtualForTrackBy"], cdkVirtualForTemplate: ["clrVirtualRowsTemplate", "cdkVirtualForTemplate"], cdkVirtualForTemplateCacheSize: ["clrVirtualRowsTemplateCacheSize", "cdkVirtualForTemplateCacheSize"], itemSize: ["clrVirtualRowsItemSize", "itemSize"], minBufferPx: ["clrVirtualRowsMinBufferPx", "minBufferPx"], maxBufferPx: ["clrVirtualRowsMaxBufferPx", "maxBufferPx"] }, outputs: { renderedRangeChange: "renderedRangeChange" }, providers: [Items], ngImport: i0 });
17851
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridVirtualScrollDirective, decorators: [{
17079
17852
  type: Directive,
17080
17853
  args: [{
17081
- selector: 'clr-dg-cell',
17854
+ selector: '[ClrVirtualScroll]',
17855
+ providers: [Items],
17082
17856
  }]
17083
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: DatagridRenderOrganizer }]; } });
17857
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.IterableDiffers }, { type: Items, decorators: [{
17858
+ type: SkipSelf
17859
+ }] }, { type: i0.NgZone }, { type: i0.TemplateRef }, { type: i0.ViewContainerRef }, { type: i1$2.Directionality }, { type: i3$1.ScrollDispatcher }, { type: i3$1.ViewportRuler }, { type: ClrDatagrid }, { type: ColumnsService }, { type: i0.EnvironmentInjector }]; }, propDecorators: { renderedRangeChange: [{
17860
+ type: Output
17861
+ }], cdkVirtualForOf: [{
17862
+ type: Input,
17863
+ args: ['clrVirtualRowsOf']
17864
+ }], cdkVirtualForTrackBy: [{
17865
+ type: Input,
17866
+ args: ['clrVirtualRowsTrackBy']
17867
+ }], cdkVirtualForTemplate: [{
17868
+ type: Input,
17869
+ args: ['clrVirtualRowsTemplate']
17870
+ }], cdkVirtualForTemplateCacheSize: [{
17871
+ type: Input,
17872
+ args: ['clrVirtualRowsTemplateCacheSize']
17873
+ }], itemSize: [{
17874
+ type: Input,
17875
+ args: ['clrVirtualRowsItemSize']
17876
+ }], minBufferPx: [{
17877
+ type: Input,
17878
+ args: ['clrVirtualRowsMinBufferPx']
17879
+ }], maxBufferPx: [{
17880
+ type: Input,
17881
+ args: ['clrVirtualRowsMaxBufferPx']
17882
+ }] } });
17084
17883
 
17085
17884
  /*
17086
17885
  * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
@@ -17105,7 +17904,6 @@ class DatagridHeaderRenderer {
17105
17904
  this.autoSet = false;
17106
17905
  this.subscriptions = [];
17107
17906
  this.subscriptions.push(this.organizer.filterRenderSteps(DatagridRenderStep.CLEAR_WIDTHS).subscribe(() => this.clearWidth()));
17108
- this.subscriptions.push(columnState.subscribe(state => this.stateChanges(state)));
17109
17907
  }
17110
17908
  ngOnDestroy() {
17111
17909
  this.subscriptions.forEach(sub => sub.unsubscribe());
@@ -17120,20 +17918,30 @@ class DatagridHeaderRenderer {
17120
17918
  setColumnState(index) {
17121
17919
  this.columnsService.columns[index] = this.columnState;
17122
17920
  }
17123
- stateChanges(state) {
17124
- if (state.changes && state.changes.length) {
17125
- state.changes.forEach(change => {
17126
- switch (change) {
17127
- case DatagridColumnChanges.WIDTH:
17128
- this.setWidth(state);
17129
- break;
17130
- case DatagridColumnChanges.HIDDEN:
17131
- this.setHidden(state);
17132
- break;
17133
- default:
17134
- break;
17135
- }
17136
- });
17921
+ setWidth(state) {
17922
+ if (state.strictWidth) {
17923
+ if (this.columnResizerService.resizedBy) {
17924
+ this.resizeEmitter.emit(state.width);
17925
+ this.renderer.setStyle(this.el.nativeElement, 'width', state.width + 'px');
17926
+ this.widthSet = false;
17927
+ }
17928
+ // Don't set width if there is a user-defined one. Just add the strict width class.
17929
+ this.renderer.addClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
17930
+ this.autoSet = false;
17931
+ }
17932
+ else {
17933
+ this.renderer.removeClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
17934
+ this.renderer.setStyle(this.el.nativeElement, 'width', state.width + 'px');
17935
+ this.widthSet = true;
17936
+ this.autoSet = true;
17937
+ }
17938
+ }
17939
+ setHidden(state) {
17940
+ if (state.hidden) {
17941
+ this.renderer.addClass(this.el.nativeElement, HIDDEN_COLUMN_CLASS);
17942
+ }
17943
+ else {
17944
+ this.renderer.removeClass(this.el.nativeElement, HIDDEN_COLUMN_CLASS);
17137
17945
  }
17138
17946
  }
17139
17947
  clearWidth() {
@@ -17163,32 +17971,6 @@ class DatagridHeaderRenderer {
17163
17971
  }
17164
17972
  return width;
17165
17973
  }
17166
- setWidth(state) {
17167
- if (state.strictWidth) {
17168
- if (this.columnResizerService.resizedBy) {
17169
- this.resizeEmitter.emit(state.width);
17170
- this.renderer.setStyle(this.el.nativeElement, 'width', state.width + 'px');
17171
- this.widthSet = false;
17172
- }
17173
- // Don't set width if there is a user-defined one. Just add the strict width class.
17174
- this.renderer.addClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
17175
- this.autoSet = false;
17176
- }
17177
- else {
17178
- this.renderer.removeClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
17179
- this.renderer.setStyle(this.el.nativeElement, 'width', state.width + 'px');
17180
- this.widthSet = true;
17181
- this.autoSet = true;
17182
- }
17183
- }
17184
- setHidden(state) {
17185
- if (state.hidden) {
17186
- this.renderer.addClass(this.el.nativeElement, HIDDEN_COLUMN_CLASS);
17187
- }
17188
- else {
17189
- this.renderer.removeClass(this.el.nativeElement, HIDDEN_COLUMN_CLASS);
17190
- }
17191
- }
17192
17974
  }
17193
17975
  DatagridHeaderRenderer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: DatagridHeaderRenderer, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: DatagridRenderOrganizer }, { token: DomAdapter }, { token: ColumnResizerService }, { token: ColumnsService }, { token: COLUMN_STATE }], target: i0.ɵɵFactoryTarget.Directive });
17194
17976
  DatagridHeaderRenderer.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: DatagridHeaderRenderer, selector: "clr-dg-column", outputs: { resizeEmitter: "clrDgColumnResize" }, providers: [ColumnResizerService, COLUMN_STATE_PROVIDER], ngImport: i0 });
@@ -17248,63 +18030,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
17248
18030
  type: Injectable
17249
18031
  }] });
17250
18032
 
17251
- /*
17252
- * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
17253
- * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
17254
- * This software is released under MIT license.
17255
- * The full license information can be found in LICENSE in the root directory of this project.
17256
- */
17257
- class DatagridRowRenderer {
17258
- constructor(columnsService) {
17259
- this.columnsService = columnsService;
17260
- this.subscriptions = [];
17261
- }
17262
- ngAfterContentInit() {
17263
- this.setColumnState(); // case #3 and #4
17264
- this.subscriptions.push(this.cells.changes.subscribe(() => {
17265
- this.setColumnState(); // case #2
17266
- // Note on case #2: In the case of dynamic columns, when one column (header/cell together) gets deleted,
17267
- // this.cells.changes emits before this.columnsService.columns gets updated in MainRenderer
17268
- // when this.headers.changes emits as well. So that means there will be n+1 column state providers
17269
- // when this.cells.changes emits. Hence, we should quit earlier there. But this method will be called
17270
- // right after again when this.headers.changes emits. By then, there will be the same number of column state
17271
- // providers as column headers.
17272
- }));
17273
- }
17274
- ngOnDestroy() {
17275
- this.subscriptions.forEach(sub => sub.unsubscribe());
17276
- }
17277
- setColumnState() {
17278
- // This method runs in four cases:
17279
- // 1. When the initial rows appear on the first page.
17280
- // In this case, the method will be called in DatagridMainRenderer.
17281
- // 2. When columns (corresponding header/cells) get added and deleted.
17282
- // In this case, the method will be called in DatagridMainRenderer. (Read the note on this case above).
17283
- // 3. When rows load asynchronously.
17284
- // In this case, the method will be called in this class.
17285
- // 4. When rows load after switching pages.
17286
- // In this case, the method will be called in this class (Basically, same as the case 3).
17287
- if (this.cells.length === this.columnsService.columns.length) {
17288
- this.cells.forEach((cell, index) => {
17289
- if (this.columnsService.columns[index]) {
17290
- cell.columnState = this.columnsService.columns[index];
17291
- }
17292
- });
17293
- }
17294
- }
17295
- }
17296
- DatagridRowRenderer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: DatagridRowRenderer, deps: [{ token: ColumnsService }], target: i0.ɵɵFactoryTarget.Directive });
17297
- DatagridRowRenderer.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: DatagridRowRenderer, selector: "clr-dg-row, clr-dg-row-detail", queries: [{ propertyName: "cells", predicate: DatagridCellRenderer }], ngImport: i0 });
17298
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: DatagridRowRenderer, decorators: [{
17299
- type: Directive,
17300
- args: [{
17301
- selector: 'clr-dg-row, clr-dg-row-detail',
17302
- }]
17303
- }], ctorParameters: function () { return [{ type: ColumnsService }]; }, propDecorators: { cells: [{
17304
- type: ContentChildren,
17305
- args: [DatagridCellRenderer]
17306
- }] } });
17307
-
17308
18033
  /*
17309
18034
  * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
17310
18035
  * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
@@ -17324,7 +18049,7 @@ const domAdapterFactory = (platformId) => {
17324
18049
  // Fixes build error
17325
18050
  // @dynamic (https://github.com/angular/angular/issues/19698#issuecomment-338340211)
17326
18051
  class DatagridMainRenderer {
17327
- constructor(organizer, items, page, domAdapter, el, renderer, detailService, tableSizeService, columnsService, ngZone) {
18052
+ constructor(organizer, items, page, domAdapter, el, renderer, detailService, tableSizeService, columnsService, ngZone, keyNavigation) {
17328
18053
  this.organizer = organizer;
17329
18054
  this.items = items;
17330
18055
  this.page = page;
@@ -17335,6 +18060,7 @@ class DatagridMainRenderer {
17335
18060
  this.tableSizeService = tableSizeService;
17336
18061
  this.columnsService = columnsService;
17337
18062
  this.ngZone = ngZone;
18063
+ this.keyNavigation = keyNavigation;
17338
18064
  this._heightSet = false;
17339
18065
  this.shouldStabilizeColumns = true;
17340
18066
  this.subscriptions = [];
@@ -17355,6 +18081,9 @@ class DatagridMainRenderer {
17355
18081
  this.subscriptions.push(this.detailService.stateChange.subscribe(state => this.toggleDetailPane(state)));
17356
18082
  this.subscriptions.push(this.items.change.subscribe(() => (this.shouldStabilizeColumns = true)));
17357
18083
  }
18084
+ ngOnInit() {
18085
+ this.columnsService.columnsStateChange.subscribe(change => this.columnStateChanged(change));
18086
+ }
17358
18087
  ngAfterContentInit() {
17359
18088
  this.setupColumns();
17360
18089
  this.subscriptions.push(this.headers.changes.subscribe(() => {
@@ -17405,7 +18134,10 @@ class DatagridMainRenderer {
17405
18134
  setupColumns() {
17406
18135
  this.headers.forEach((header, index) => header.setColumnState(index));
17407
18136
  this.columnsService.columns.splice(this.headers.length); // Trim any old columns
17408
- this.rows.forEach(row => row.setColumnState());
18137
+ // Sets columnIndex for each column
18138
+ this.columnsService.columns.forEach((column, index) => {
18139
+ this.columnsService.emitStateChange(column, { changes: [DatagridColumnChanges.INITIALIZE], columnIndex: index });
18140
+ });
17409
18141
  }
17410
18142
  shouldComputeHeight() {
17411
18143
  if (!this._heightSet && this.page.size > 0) {
@@ -17426,9 +18158,8 @@ class DatagridMainRenderer {
17426
18158
  * Refer: http://stackoverflow.com/questions/24396205/flex-grow-not-working-in-internet-explorer-11-0
17427
18159
  */
17428
18160
  computeDatagridHeight() {
17429
- // IE doesn't return correct value for getComputedStyle(element).getPropertyValue("height")
17430
- const value = this.domAdapter.clientRect(this.el.nativeElement).height;
17431
- this.renderer.setStyle(this.el.nativeElement, 'height', value + 'px');
18161
+ const height = window.getComputedStyle(this.el.nativeElement).height;
18162
+ this.renderer.setStyle(this.el.nativeElement, 'height', height);
17432
18163
  this._heightSet = true;
17433
18164
  }
17434
18165
  resetDatagridHeight() {
@@ -17440,6 +18171,9 @@ class DatagridMainRenderer {
17440
18171
  */
17441
18172
  computeHeadersWidth() {
17442
18173
  const nbColumns = this.headers.length;
18174
+ const headerWidths = this.headers.map(header => {
18175
+ return header.getColumnWidthState();
18176
+ });
17443
18177
  let allStrict = true;
17444
18178
  this.headers.forEach((header, index) => {
17445
18179
  // On the last header column check whether all columns have strict widths.
@@ -17448,7 +18182,7 @@ class DatagridMainRenderer {
17448
18182
  // gap in the Datagrid.
17449
18183
  const state = {
17450
18184
  changes: [DatagridColumnChanges.WIDTH],
17451
- ...header.getColumnWidthState(),
18185
+ ...headerWidths[index],
17452
18186
  };
17453
18187
  if (!state.strictWidth) {
17454
18188
  allStrict = false;
@@ -17459,6 +18193,46 @@ class DatagridMainRenderer {
17459
18193
  this.columnsService.emitStateChangeAt(index, state);
17460
18194
  });
17461
18195
  }
18196
+ columnStateChanged(state) {
18197
+ // eslint-disable-next-line eqeqeq
18198
+ if (!this.headers || state.columnIndex == null) {
18199
+ return;
18200
+ }
18201
+ const columnIndex = state.columnIndex;
18202
+ if (state.changes && state.changes.length) {
18203
+ state.changes.forEach(change => {
18204
+ switch (change) {
18205
+ case DatagridColumnChanges.WIDTH:
18206
+ this.headers.get(columnIndex).setWidth(state);
18207
+ this.rows.forEach(row => {
18208
+ if (row?.cells.length === this.columnsService.columns.length) {
18209
+ row.cells.get(columnIndex).setWidth(state);
18210
+ }
18211
+ });
18212
+ break;
18213
+ case DatagridColumnChanges.HIDDEN:
18214
+ this.headers.get(columnIndex).setHidden(state);
18215
+ this.rows.forEach(row => {
18216
+ if (row.cells && row.cells.length) {
18217
+ row.cells.get(columnIndex).setHidden(state);
18218
+ }
18219
+ });
18220
+ this.keyNavigation.resetKeyGrid();
18221
+ break;
18222
+ case DatagridColumnChanges.INITIALIZE:
18223
+ if (state.hideable && state.hidden) {
18224
+ this.headers.get(columnIndex).setHidden(state);
18225
+ this.rows.forEach(row => {
18226
+ row.setCellsState();
18227
+ });
18228
+ }
18229
+ break;
18230
+ default:
18231
+ break;
18232
+ }
18233
+ });
18234
+ }
18235
+ }
17462
18236
  /**
17463
18237
  * Triggers a whole re-rendring cycle to set column sizes, if needed.
17464
18238
  */
@@ -17475,7 +18249,7 @@ class DatagridMainRenderer {
17475
18249
  }
17476
18250
  }
17477
18251
  }
17478
- DatagridMainRenderer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: DatagridMainRenderer, deps: [{ token: DatagridRenderOrganizer }, { token: Items }, { token: Page }, { token: DomAdapter }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: DetailService }, { token: TableSizeService }, { token: ColumnsService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
18252
+ DatagridMainRenderer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: DatagridMainRenderer, deps: [{ token: DatagridRenderOrganizer }, { token: Items }, { token: Page }, { token: DomAdapter }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: DetailService }, { token: TableSizeService }, { token: ColumnsService }, { token: i0.NgZone }, { token: KeyNavigationGridController }], target: i0.ɵɵFactoryTarget.Directive });
17479
18253
  DatagridMainRenderer.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: DatagridMainRenderer, selector: "clr-datagrid", providers: [{ provide: DomAdapter, useFactory: domAdapterFactory, deps: [PLATFORM_ID] }], queries: [{ propertyName: "headers", predicate: DatagridHeaderRenderer }, { propertyName: "rows", predicate: DatagridRowRenderer, descendants: true }], ngImport: i0 });
17480
18254
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: DatagridMainRenderer, decorators: [{
17481
18255
  type: Directive,
@@ -17483,7 +18257,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
17483
18257
  selector: 'clr-datagrid',
17484
18258
  providers: [{ provide: DomAdapter, useFactory: domAdapterFactory, deps: [PLATFORM_ID] }],
17485
18259
  }]
17486
- }], ctorParameters: function () { return [{ type: DatagridRenderOrganizer }, { type: Items }, { type: Page }, { type: DomAdapter }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: DetailService }, { type: TableSizeService }, { type: ColumnsService }, { type: i0.NgZone }]; }, propDecorators: { headers: [{
18260
+ }], ctorParameters: function () { return [{ type: DatagridRenderOrganizer }, { type: Items }, { type: Page }, { type: DomAdapter }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: DetailService }, { type: TableSizeService }, { type: ColumnsService }, { type: i0.NgZone }, { type: KeyNavigationGridController }]; }, propDecorators: { headers: [{
17487
18261
  type: ContentChildren,
17488
18262
  args: [DatagridHeaderRenderer]
17489
18263
  }], rows: [{
@@ -17518,6 +18292,7 @@ const CLR_DATAGRID_DIRECTIVES = [
17518
18292
  ClrDatagridRow,
17519
18293
  ClrDatagridRowDetail,
17520
18294
  ClrDatagridSelectionCellDirective,
18295
+ ClrDatagridVirtualScrollDirective,
17521
18296
  ClrIfDetail,
17522
18297
  DatagridDetailRegisterer,
17523
18298
  WrappedCell,
@@ -17564,6 +18339,7 @@ ClrDatagridModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", versi
17564
18339
  ClrDatagridRow,
17565
18340
  ClrDatagridRowDetail,
17566
18341
  ClrDatagridSelectionCellDirective,
18342
+ ClrDatagridVirtualScrollDirective,
17567
18343
  ClrIfDetail,
17568
18344
  DatagridDetailRegisterer,
17569
18345
  WrappedCell,
@@ -17613,6 +18389,7 @@ ClrDatagridModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", versi
17613
18389
  ClrDatagridRow,
17614
18390
  ClrDatagridRowDetail,
17615
18391
  ClrDatagridSelectionCellDirective,
18392
+ ClrDatagridVirtualScrollDirective,
17616
18393
  ClrIfDetail,
17617
18394
  DatagridDetailRegisterer,
17618
18395
  WrappedCell,
@@ -22638,6 +23415,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
22638
23415
  args: [DOCUMENT]
22639
23416
  }] }]; } });
22640
23417
 
23418
+ /*
23419
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
23420
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
23421
+ * This software is released under MIT license.
23422
+ * The full license information can be found in LICENSE in the root directory of this project.
23423
+ */
23424
+ class ClrModalConfigurationService {
23425
+ constructor() {
23426
+ this.fadeMove = 'fadeDown';
23427
+ this.backdrop = true;
23428
+ }
23429
+ }
23430
+ ClrModalConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModalConfigurationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
23431
+ ClrModalConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModalConfigurationService });
23432
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModalConfigurationService, decorators: [{
23433
+ type: Injectable
23434
+ }] });
23435
+
22641
23436
  /*
22642
23437
  * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
22643
23438
  * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
@@ -22645,10 +23440,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
22645
23440
  * The full license information can be found in LICENSE in the root directory of this project.
22646
23441
  */
22647
23442
  class ClrModal {
22648
- constructor(_scrollingService, commonStrings, modalStackService) {
23443
+ constructor(_scrollingService, commonStrings, modalStackService, configuration) {
22649
23444
  this._scrollingService = _scrollingService;
22650
23445
  this.commonStrings = commonStrings;
22651
23446
  this.modalStackService = modalStackService;
23447
+ this.configuration = configuration;
22652
23448
  this.modalId = uniqueIdFactory();
22653
23449
  this._open = false;
22654
23450
  this._openChanged = new EventEmitter(false);
@@ -22658,13 +23454,23 @@ class ClrModal {
22658
23454
  this.skipAnimation = 'false';
22659
23455
  this.stopClose = false;
22660
23456
  this.altClose = new EventEmitter(false);
22661
- this.labelledBy = this.modalId;
23457
+ // presently this is only used by inline wizards
23458
+ this.bypassScrollService = false;
23459
+ }
23460
+ get fadeMove() {
23461
+ return this.skipAnimation ? '' : this.configuration.fadeMove;
23462
+ }
23463
+ set fadeMove(move) {
23464
+ this.configuration.fadeMove = move;
23465
+ }
23466
+ get backdrop() {
23467
+ return this.configuration.backdrop;
22662
23468
  }
22663
23469
  // Detect when _open is set to true and set no-scrolling to true
22664
23470
  ngOnChanges(changes) {
22665
- if (changes && Object.prototype.hasOwnProperty.call(changes, '_open')) {
23471
+ if (!this.bypassScrollService && changes && Object.prototype.hasOwnProperty.call(changes, '_open')) {
22666
23472
  if (changes._open.currentValue) {
22667
- this._scrollingService.stopScrolling();
23473
+ this.backdrop && this._scrollingService.stopScrolling();
22668
23474
  this.modalStackService.trackModalOpen(this);
22669
23475
  }
22670
23476
  else {
@@ -22701,11 +23507,18 @@ class ClrModal {
22701
23507
  }
22702
23508
  }
22703
23509
  }
22704
- ClrModal.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModal, deps: [{ token: ScrollingService }, { token: ClrCommonStringsService }, { token: ModalStackService }], target: i0.ɵɵFactoryTarget.Component });
22705
- 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"] }, outputs: { _openChanged: "clrModalOpenChange", altClose: "clrModalAlternateClose" }, host: { properties: { "class.open": "this._open" } }, usesOnChanges: true, ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2024 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 [@fadeDown]=\"skipAnimation\"\n (@fadeDown.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\"\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 <div class=\"modal-title-wrapper\" 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 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\n <div [@fade] class=\"modal-backdrop\" aria-hidden=\"true\" (click)=\"staticBackdrop || close()\"></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: [
22706
- trigger('fadeDown', [
22707
- transition('* => false', [style({ opacity: 0, transform: 'translate(0, -25%)' }), animate('0.2s ease-in-out')]),
22708
- transition('false => *', [animate('0.2s ease-in-out', style({ opacity: 0, transform: 'translate(0, -25%)' }))]),
23510
+ 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 });
23511
+ 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" } }, usesOnChanges: true, ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2024 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 <div class=\"modal-title-wrapper\" 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 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\n <div [@fade] *ngIf=\"backdrop\" class=\"modal-backdrop\" aria-hidden=\"true\" (click)=\"staticBackdrop || close()\"></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: [
23512
+ trigger('fadeMove', [
23513
+ transition('* => fadeDown', [
23514
+ style({ opacity: 0, transform: 'translate(0, -25%)' }),
23515
+ animate('0.2s ease-in-out'),
23516
+ ]),
23517
+ transition('fadeDown => *', [
23518
+ animate('0.2s ease-in-out', style({ opacity: 0, transform: 'translate(0, -25%)' })),
23519
+ ]),
23520
+ transition('* => fadeLeft', [style({ opacity: 0, transform: 'translate(25%, 0)' }), animate('0.2s ease-in-out')]),
23521
+ transition('fadeLeft => *', [animate('0.2s ease-in-out', style({ opacity: 0, transform: 'translate(25%, 0)' }))]),
22709
23522
  ]),
22710
23523
  trigger('fade', [
22711
23524
  transition('void => *', [style({ opacity: 0 }), animate('0.2s ease-in-out', style({ opacity: 0.85 }))]),
@@ -22715,16 +23528,23 @@ ClrModal.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.
22715
23528
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModal, decorators: [{
22716
23529
  type: Component,
22717
23530
  args: [{ selector: 'clr-modal', viewProviders: [ScrollingService], animations: [
22718
- trigger('fadeDown', [
22719
- transition('* => false', [style({ opacity: 0, transform: 'translate(0, -25%)' }), animate('0.2s ease-in-out')]),
22720
- transition('false => *', [animate('0.2s ease-in-out', style({ opacity: 0, transform: 'translate(0, -25%)' }))]),
23531
+ trigger('fadeMove', [
23532
+ transition('* => fadeDown', [
23533
+ style({ opacity: 0, transform: 'translate(0, -25%)' }),
23534
+ animate('0.2s ease-in-out'),
23535
+ ]),
23536
+ transition('fadeDown => *', [
23537
+ animate('0.2s ease-in-out', style({ opacity: 0, transform: 'translate(0, -25%)' })),
23538
+ ]),
23539
+ transition('* => fadeLeft', [style({ opacity: 0, transform: 'translate(25%, 0)' }), animate('0.2s ease-in-out')]),
23540
+ transition('fadeLeft => *', [animate('0.2s ease-in-out', style({ opacity: 0, transform: 'translate(25%, 0)' }))]),
22721
23541
  ]),
22722
23542
  trigger('fade', [
22723
23543
  transition('void => *', [style({ opacity: 0 }), animate('0.2s ease-in-out', style({ opacity: 0.85 }))]),
22724
23544
  transition('* => void', [animate('0.2s ease-in-out', style({ opacity: 0 }))]),
22725
23545
  ]),
22726
- ], template: "<!--\n ~ Copyright (c) 2016-2024 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 [@fadeDown]=\"skipAnimation\"\n (@fadeDown.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\"\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 <div class=\"modal-title-wrapper\" 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 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\n <div [@fade] class=\"modal-backdrop\" aria-hidden=\"true\" (click)=\"staticBackdrop || close()\"></div>\n</div>\n", styles: [":host{display:none}:host.open{display:inline}\n"] }]
22727
- }], ctorParameters: function () { return [{ type: ScrollingService }, { type: ClrCommonStringsService }, { type: ModalStackService }]; }, propDecorators: { _open: [{
23546
+ ], template: "<!--\n ~ Copyright (c) 2016-2024 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 <div class=\"modal-title-wrapper\" 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 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\n <div [@fade] *ngIf=\"backdrop\" class=\"modal-backdrop\" aria-hidden=\"true\" (click)=\"staticBackdrop || close()\"></div>\n</div>\n", styles: [":host{display:none}:host.open{display:inline}\n"] }]
23547
+ }], ctorParameters: function () { return [{ type: ScrollingService }, { type: ClrCommonStringsService }, { type: ModalStackService }, { type: ClrModalConfigurationService }]; }, propDecorators: { _open: [{
22728
23548
  type: Input,
22729
23549
  args: ['clrModalOpen']
22730
23550
  }, {
@@ -22757,6 +23577,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
22757
23577
  }], labelledBy: [{
22758
23578
  type: Input,
22759
23579
  args: ['clrModalLabelledById']
23580
+ }], bypassScrollService: [{
23581
+ type: Input,
23582
+ args: ['clrModalOverrideScrollService']
22760
23583
  }] } });
22761
23584
 
22762
23585
  /*
@@ -22836,16 +23659,122 @@ class ClrModalModule {
22836
23659
  }
22837
23660
  ClrModalModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModalModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
22838
23661
  ClrModalModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.2", ngImport: i0, type: ClrModalModule, declarations: [ClrModal, ClrModalBody], imports: [CommonModule, CdkTrapFocusModule, ClrIconModule], exports: [ClrModal, ClrModalBody, ClrIconModule] });
22839
- ClrModalModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModalModule, imports: [CommonModule, CdkTrapFocusModule, ClrIconModule, ClrIconModule] });
23662
+ ClrModalModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModalModule, providers: [ClrModalConfigurationService], imports: [CommonModule, CdkTrapFocusModule, ClrIconModule, ClrIconModule] });
22840
23663
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModalModule, decorators: [{
22841
23664
  type: NgModule,
22842
23665
  args: [{
22843
23666
  imports: [CommonModule, CdkTrapFocusModule, ClrIconModule],
22844
23667
  declarations: [CLR_MODAL_DIRECTIVES],
22845
23668
  exports: [CLR_MODAL_DIRECTIVES, ClrIconModule],
23669
+ providers: [ClrModalConfigurationService],
22846
23670
  }]
22847
23671
  }], ctorParameters: function () { return []; } });
22848
23672
 
23673
+ /*
23674
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
23675
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
23676
+ * This software is released under MIT license.
23677
+ * The full license information can be found in LICENSE in the root directory of this project.
23678
+ */
23679
+ class ClrSidePanel {
23680
+ constructor(element, configuration) {
23681
+ this.element = element;
23682
+ this.configuration = configuration;
23683
+ this._open = false;
23684
+ this.openChange = new EventEmitter(false);
23685
+ this.skipAnimation = 'false';
23686
+ this.staticBackdrop = false;
23687
+ this.preventClose = false;
23688
+ this.altClose = new EventEmitter(false);
23689
+ }
23690
+ get clrSidePanelBackdrop() {
23691
+ return this.configuration.backdrop;
23692
+ }
23693
+ set clrSidePanelBackdrop(backdrop) {
23694
+ if (backdrop !== undefined) {
23695
+ this.configuration.backdrop = backdrop;
23696
+ }
23697
+ }
23698
+ ngOnInit() {
23699
+ this.configuration.fadeMove = 'fadeLeft';
23700
+ }
23701
+ open() {
23702
+ this.modal.open();
23703
+ }
23704
+ close() {
23705
+ this.modal.close();
23706
+ }
23707
+ documentClick(event) {
23708
+ if (!this.element.nativeElement.contains(event.target) && this.modal._open && !this.configuration.backdrop) {
23709
+ this.modal.close();
23710
+ }
23711
+ }
23712
+ }
23713
+ ClrSidePanel.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrSidePanel, deps: [{ token: i0.ElementRef }, { token: ClrModalConfigurationService }], target: i0.ɵɵFactoryTarget.Component });
23714
+ 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"], size: ["clrSidePanelSize", "size"], skipAnimation: ["clrSidePanelSkipAnimation", "skipAnimation"], labelledById: ["clrSidePanelLabelledById", "labelledById"], staticBackdrop: ["clrSidePanelStaticBackdrop", "staticBackdrop"], preventClose: ["clrSidePanelPreventClose", "preventClose"], clrSidePanelBackdrop: "clrSidePanelBackdrop" }, 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 }], 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>\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: "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" }] });
23715
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrSidePanel, decorators: [{
23716
+ type: Component,
23717
+ args: [{ selector: 'clr-side-panel', host: {
23718
+ '[class.side-panel]': 'true',
23719
+ }, 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>\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" }]
23720
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: ClrModalConfigurationService }]; }, propDecorators: { _open: [{
23721
+ type: Input,
23722
+ args: ['clrSidePanelOpen']
23723
+ }], openChange: [{
23724
+ type: Output,
23725
+ args: ['clrSidePanelOpenChange']
23726
+ }], closeButtonAriaLabel: [{
23727
+ type: Input,
23728
+ args: ['clrSidePanelCloseButtonAriaLabel']
23729
+ }], size: [{
23730
+ type: Input,
23731
+ args: ['clrSidePanelSize']
23732
+ }], skipAnimation: [{
23733
+ type: Input,
23734
+ args: ['clrSidePanelSkipAnimation']
23735
+ }], labelledById: [{
23736
+ type: Input,
23737
+ args: ['clrSidePanelLabelledById']
23738
+ }], staticBackdrop: [{
23739
+ type: Input,
23740
+ args: ['clrSidePanelStaticBackdrop']
23741
+ }], preventClose: [{
23742
+ type: Input,
23743
+ args: ['clrSidePanelPreventClose']
23744
+ }], altClose: [{
23745
+ type: Output,
23746
+ args: ['clrSidePanelAlternateClose']
23747
+ }], modal: [{
23748
+ type: ViewChild,
23749
+ args: [ClrModal]
23750
+ }], clrSidePanelBackdrop: [{
23751
+ type: Input
23752
+ }], documentClick: [{
23753
+ type: HostListener,
23754
+ args: ['document:pointerup', ['$event']]
23755
+ }] } });
23756
+
23757
+ /*
23758
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
23759
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
23760
+ * This software is released under MIT license.
23761
+ * The full license information can be found in LICENSE in the root directory of this project.
23762
+ */
23763
+ const CLR_SIDEPANEL_DIRECTIVES = [ClrSidePanel];
23764
+ class ClrSidePanelModule {
23765
+ }
23766
+ ClrSidePanelModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrSidePanelModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
23767
+ ClrSidePanelModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.2", ngImport: i0, type: ClrSidePanelModule, declarations: [ClrSidePanel], imports: [CommonModule, CdkTrapFocusModule, ClrIconModule, ClrModalModule], exports: [ClrSidePanel, ClrIconModule] });
23768
+ ClrSidePanelModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrSidePanelModule, imports: [CommonModule, CdkTrapFocusModule, ClrIconModule, ClrModalModule, ClrIconModule] });
23769
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrSidePanelModule, decorators: [{
23770
+ type: NgModule,
23771
+ args: [{
23772
+ imports: [CommonModule, CdkTrapFocusModule, ClrIconModule, ClrModalModule],
23773
+ declarations: [CLR_SIDEPANEL_DIRECTIVES],
23774
+ exports: [CLR_SIDEPANEL_DIRECTIVES, ClrIconModule],
23775
+ }]
23776
+ }] });
23777
+
22849
23778
  /*
22850
23779
  * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
22851
23780
  * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
@@ -23663,13 +24592,13 @@ class ClrTimeline {
23663
24592
  }
23664
24593
  }
23665
24594
  ClrTimeline.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrTimeline, deps: [], target: i0.ɵɵFactoryTarget.Component });
23666
- ClrTimeline.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrTimeline, selector: "clr-timeline", inputs: { layout: ["clrLayout", "layout"] }, host: { properties: { "class.clr-timeline": "true", "class.clr-timeline-vertical": "this.isVertical" } }, providers: [TimelineIconAttributeService], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true });
24595
+ ClrTimeline.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrTimeline, selector: "clr-timeline", inputs: { layout: ["clrLayout", "layout"] }, host: { properties: { "class.clr-timeline": "true", "attr.role": "\"list\"", "class.clr-timeline-vertical": "this.isVertical" } }, providers: [TimelineIconAttributeService], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true });
23667
24596
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrTimeline, decorators: [{
23668
24597
  type: Component,
23669
24598
  args: [{
23670
24599
  selector: 'clr-timeline',
23671
24600
  template: `<ng-content></ng-content>`,
23672
- host: { '[class.clr-timeline]': 'true' },
24601
+ host: { '[class.clr-timeline]': 'true', '[attr.role]': '"list"' },
23673
24602
  providers: [TimelineIconAttributeService],
23674
24603
  }]
23675
24604
  }], propDecorators: { layout: [{
@@ -23740,7 +24669,7 @@ class ClrTimelineStep {
23740
24669
  }
23741
24670
  }
23742
24671
  ClrTimelineStep.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrTimelineStep, deps: [{ token: TimelineIconAttributeService }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Component });
23743
- ClrTimelineStep.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrTimelineStep, selector: "clr-timeline-step", inputs: { state: ["clrState", "state"] }, host: { properties: { "class.clr-timeline-step": "true" } }, queries: [{ propertyName: "stepTitle", first: true, predicate: ClrTimelineStepTitle, descendants: true, read: ElementRef }], ngImport: i0, template: `
24672
+ ClrTimelineStep.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrTimelineStep, selector: "clr-timeline-step", inputs: { state: ["clrState", "state"] }, host: { properties: { "class.clr-timeline-step": "true", "attr.role": "\"listitem\"" } }, queries: [{ propertyName: "stepTitle", first: true, predicate: ClrTimelineStepTitle, descendants: true, read: ElementRef }], ngImport: i0, template: `
23744
24673
  <ng-content select="clr-timeline-step-header"></ng-content>
23745
24674
  <span class="clr-sr-only">{{ stepTitleText }}</span>
23746
24675
  <ng-container *ngIf="!isProcessing; else processing">
@@ -23784,7 +24713,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
23784
24713
  <clr-spinner clrMedium [attr.aria-label]="iconAriaLabel"></clr-spinner>
23785
24714
  </ng-template>
23786
24715
  `,
23787
- host: { '[class.clr-timeline-step]': 'true' },
24716
+ host: { '[class.clr-timeline-step]': 'true', '[attr.role]': '"listitem"' },
23788
24717
  }]
23789
24718
  }], ctorParameters: function () { return [{ type: TimelineIconAttributeService }, { type: undefined, decorators: [{
23790
24719
  type: Inject,
@@ -25888,13 +26817,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
25888
26817
  * The full license information can be found in LICENSE in the root directory of this project.
25889
26818
  */
25890
26819
  class ClrWizard {
25891
- constructor(platformId, commonStrings, navService, pageCollection, buttonService, headerActionService, differs) {
26820
+ constructor(platformId, commonStrings, navService, pageCollection, buttonService, headerActionService, elementRef, differs) {
25892
26821
  this.platformId = platformId;
25893
26822
  this.commonStrings = commonStrings;
25894
26823
  this.navService = navService;
25895
26824
  this.pageCollection = pageCollection;
25896
26825
  this.buttonService = buttonService;
25897
26826
  this.headerActionService = headerActionService;
26827
+ this.elementRef = elementRef;
25898
26828
  /**
25899
26829
  * Set the aria-label for the stepnav section of the wizard. Set using `[clrWizardStepnavAriaLabel]` input.
25900
26830
  */
@@ -25908,6 +26838,12 @@ class ClrWizard {
25908
26838
  * in the top right corner. Set using `[clrWizardClosable]` input.
25909
26839
  */
25910
26840
  this.closable = true;
26841
+ /**
26842
+ * Used to communicate to the underlying modal that animations are not
26843
+ * wanted. Primary use is for the display of static/inline wizards.
26844
+ * Set using `[clrWizardPreventModalAnimation]` input.
26845
+ */
26846
+ this._stopModalAnimations = false;
25911
26847
  /**
25912
26848
  * Emits when the wizard is opened or closed.
25913
26849
  * Listen via `(clrWizardOpenChange)` event.
@@ -26046,9 +26982,16 @@ class ClrWizard {
26046
26982
  get isFirst() {
26047
26983
  return this.navService.currentPageIsFirst;
26048
26984
  }
26985
+ get isInline() {
26986
+ return this.elementRef.nativeElement.classList.contains('clr-wizard--inline');
26987
+ }
26988
+ get stopModalAnimations() {
26989
+ return this._stopModalAnimations ? 'true' : 'false';
26990
+ }
26049
26991
  ngAfterContentInit() {
26050
26992
  this.pageCollection.pages = this.pages;
26051
26993
  this.headerActionService.wizardHeaderActions = this.headerActions;
26994
+ this.initializeButtons();
26052
26995
  }
26053
26996
  ngDoCheck() {
26054
26997
  this.updateNavOnPageChanges();
@@ -26250,6 +27193,12 @@ class ClrWizard {
26250
27193
  changes.forEachRemovedItem(() => this.navService.updateNavigation());
26251
27194
  }
26252
27195
  }
27196
+ initializeButtons() {
27197
+ // Only trigger buttons ready if default is open (inlined)
27198
+ if (this._open) {
27199
+ this.buttonService.buttonsReady = true;
27200
+ }
27201
+ }
26253
27202
  emitWizardFinished() {
26254
27203
  if (!this.stopNext) {
26255
27204
  this.forceFinish();
@@ -26257,8 +27206,8 @@ class ClrWizard {
26257
27206
  this.wizardFinished.emit();
26258
27207
  }
26259
27208
  }
26260
- 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.IterableDiffers }], target: i0.ɵɵFactoryTarget.Component });
26261
- 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"], 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 }], ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2024 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 [clrModalPreventClose]=\"true\"\n (clrModalAlternateClose)=\"modalCancel()\"\n [clrModalLabelledById]=\"wizardId\"\n>\n <div class=\"modal-nav clr-wizard-stepnav-wrapper\" role=\"region\" [attr.aria-label]=\"stepnavAriaLabel\">\n <div class=\"clr-wizard-title\" id=\"{{wizardId}}\" role=\"heading\" [attr.aria-level]=\"wizardTitle.headingLevel || 1\">\n <ng-content select=\"clr-wizard-title\"></ng-content>\n </div>\n <clr-wizard-stepnav></clr-wizard-stepnav>\n </div>\n\n <div class=\"modal-title\" role=\"heading\" [attr.aria-level]=\"navService.currentPage.pageTitle.headingLevel || 2\">\n <span tabindex=\"-1\" #pageTitle class=\"modal-title-text\">\n <ng-template [ngTemplateOutlet]=\"navService.currentPageTitle\"></ng-template>\n </span>\n\n <div class=\"modal-header-actions-wrapper\" *ngIf=\"headerActionService.displayHeaderActionsWrapper\">\n <div *ngIf=\"headerActionService.showWizardHeaderActions\">\n <ng-content select=\"clr-wizard-header-action\"></ng-content>\n </div>\n <div *ngIf=\"headerActionService.currentPageHasHeaderActions\">\n <ng-template [ngTemplateOutlet]=\"navService.currentPage.headerActions\"></ng-template>\n </div>\n </div>\n </div>\n\n <div class=\"modal-body\">\n <main clr-wizard-pages-wrapper class=\"clr-wizard-content\">\n <ng-content></ng-content>\n </main>\n </div>\n <div class=\"modal-footer clr-wizard-footer\">\n <div class=\"clr-wizard-footer-buttons\">\n <div\n *ngIf=\"navService.currentPage && !navService.currentPage.hasButtons\"\n class=\"clr-wizard-footer-buttons-wrapper\"\n >\n <ng-content select=\"clr-wizard-button\"></ng-content>\n </div>\n <div\n *ngIf=\"navService.currentPage && navService.currentPage.hasButtons\"\n class=\"clr-wizard-footer-buttons-wrapper\"\n >\n <ng-template [ngTemplateOutlet]=\"navService.currentPage.buttons\"></ng-template>\n </div>\n </div>\n </div>\n</clr-modal>\n", dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ClrModal, selector: "clr-modal", inputs: ["clrModalOpen", "clrModalClosable", "clrModalCloseButtonAriaLabel", "clrModalSize", "clrModalStaticBackdrop", "clrModalSkipAnimation", "clrModalPreventClose", "clrModalLabelledById"], outputs: ["clrModalOpenChange", "clrModalAlternateClose"] }, { kind: "directive", type: ClrModalBody, selector: ".modal-body" }, { kind: "component", type: ClrWizardStepnav, selector: "clr-wizard-stepnav" }] });
27209
+ 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 });
27210
+ 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 }], ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2024 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<clr-modal\n [clrModalOpen]=\"_open\"\n [clrModalSize]=\"size\"\n [clrModalClosable]=\"closable\"\n [clrModalStaticBackdrop]=\"true\"\n [clrModalSkipAnimation]=\"stopModalAnimations\"\n [clrModalOverrideScrollService]=\"isInline\"\n [clrModalPreventClose]=\"true\"\n (clrModalAlternateClose)=\"modalCancel()\"\n [clrModalLabelledById]=\"wizardId\"\n>\n <div class=\"modal-nav clr-wizard-stepnav-wrapper\" role=\"region\" [attr.aria-label]=\"stepnavAriaLabel\">\n <div class=\"clr-wizard-title\" id=\"{{wizardId}}\" role=\"heading\" [attr.aria-level]=\"wizardTitle.headingLevel || 1\">\n <ng-content select=\"clr-wizard-title\"></ng-content>\n </div>\n <clr-wizard-stepnav></clr-wizard-stepnav>\n </div>\n\n <div class=\"modal-title\" role=\"heading\" [attr.aria-level]=\"navService.currentPage.pageTitle.headingLevel || 2\">\n <span tabindex=\"-1\" #pageTitle class=\"modal-title-text\">\n <ng-template [ngTemplateOutlet]=\"navService.currentPageTitle\"></ng-template>\n </span>\n\n <div class=\"modal-header-actions-wrapper\" *ngIf=\"headerActionService.displayHeaderActionsWrapper\">\n <div *ngIf=\"headerActionService.showWizardHeaderActions\">\n <ng-content select=\"clr-wizard-header-action\"></ng-content>\n </div>\n <div *ngIf=\"headerActionService.currentPageHasHeaderActions\">\n <ng-template [ngTemplateOutlet]=\"navService.currentPage.headerActions\"></ng-template>\n </div>\n </div>\n </div>\n\n <div class=\"modal-body\">\n <main clr-wizard-pages-wrapper class=\"clr-wizard-content\">\n <ng-content></ng-content>\n </main>\n </div>\n <div class=\"modal-footer clr-wizard-footer\">\n <div class=\"clr-wizard-footer-buttons\">\n <div\n *ngIf=\"navService.currentPage && !navService.currentPage.hasButtons\"\n class=\"clr-wizard-footer-buttons-wrapper\"\n >\n <ng-content select=\"clr-wizard-button\"></ng-content>\n </div>\n <div\n *ngIf=\"navService.currentPage && navService.currentPage.hasButtons\"\n class=\"clr-wizard-footer-buttons-wrapper\"\n >\n <ng-template [ngTemplateOutlet]=\"navService.currentPage.buttons\"></ng-template>\n </div>\n </div>\n </div>\n</clr-modal>\n", dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ClrModal, selector: "clr-modal", inputs: ["clrModalOpen", "clrModalClosable", "clrModalCloseButtonAriaLabel", "clrModalSize", "clrModalStaticBackdrop", "clrModalSkipAnimation", "clrModalPreventClose", "clrModalLabelledById", "clrModalOverrideScrollService"], outputs: ["clrModalOpenChange", "clrModalAlternateClose"] }, { kind: "directive", type: ClrModalBody, selector: ".modal-body" }, { kind: "component", type: ClrWizardStepnav, selector: "clr-wizard-stepnav" }] });
26262
27211
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrWizard, decorators: [{
26263
27212
  type: Component,
26264
27213
  args: [{ selector: 'clr-wizard', providers: [WizardNavigationService, PageCollectionService, ButtonHubService, HeaderActionService], host: {
@@ -26267,11 +27216,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
26267
27216
  '[class.wizard-lg]': "size == 'lg'",
26268
27217
  '[class.wizard-xl]': "size == 'xl'",
26269
27218
  '[class.lastPage]': 'navService.currentPageIsLast',
26270
- }, template: "<!--\n ~ Copyright (c) 2016-2024 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 [clrModalPreventClose]=\"true\"\n (clrModalAlternateClose)=\"modalCancel()\"\n [clrModalLabelledById]=\"wizardId\"\n>\n <div class=\"modal-nav clr-wizard-stepnav-wrapper\" role=\"region\" [attr.aria-label]=\"stepnavAriaLabel\">\n <div class=\"clr-wizard-title\" id=\"{{wizardId}}\" role=\"heading\" [attr.aria-level]=\"wizardTitle.headingLevel || 1\">\n <ng-content select=\"clr-wizard-title\"></ng-content>\n </div>\n <clr-wizard-stepnav></clr-wizard-stepnav>\n </div>\n\n <div class=\"modal-title\" role=\"heading\" [attr.aria-level]=\"navService.currentPage.pageTitle.headingLevel || 2\">\n <span tabindex=\"-1\" #pageTitle class=\"modal-title-text\">\n <ng-template [ngTemplateOutlet]=\"navService.currentPageTitle\"></ng-template>\n </span>\n\n <div class=\"modal-header-actions-wrapper\" *ngIf=\"headerActionService.displayHeaderActionsWrapper\">\n <div *ngIf=\"headerActionService.showWizardHeaderActions\">\n <ng-content select=\"clr-wizard-header-action\"></ng-content>\n </div>\n <div *ngIf=\"headerActionService.currentPageHasHeaderActions\">\n <ng-template [ngTemplateOutlet]=\"navService.currentPage.headerActions\"></ng-template>\n </div>\n </div>\n </div>\n\n <div class=\"modal-body\">\n <main clr-wizard-pages-wrapper class=\"clr-wizard-content\">\n <ng-content></ng-content>\n </main>\n </div>\n <div class=\"modal-footer clr-wizard-footer\">\n <div class=\"clr-wizard-footer-buttons\">\n <div\n *ngIf=\"navService.currentPage && !navService.currentPage.hasButtons\"\n class=\"clr-wizard-footer-buttons-wrapper\"\n >\n <ng-content select=\"clr-wizard-button\"></ng-content>\n </div>\n <div\n *ngIf=\"navService.currentPage && navService.currentPage.hasButtons\"\n class=\"clr-wizard-footer-buttons-wrapper\"\n >\n <ng-template [ngTemplateOutlet]=\"navService.currentPage.buttons\"></ng-template>\n </div>\n </div>\n </div>\n</clr-modal>\n" }]
27219
+ }, template: "<!--\n ~ Copyright (c) 2016-2024 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<clr-modal\n [clrModalOpen]=\"_open\"\n [clrModalSize]=\"size\"\n [clrModalClosable]=\"closable\"\n [clrModalStaticBackdrop]=\"true\"\n [clrModalSkipAnimation]=\"stopModalAnimations\"\n [clrModalOverrideScrollService]=\"isInline\"\n [clrModalPreventClose]=\"true\"\n (clrModalAlternateClose)=\"modalCancel()\"\n [clrModalLabelledById]=\"wizardId\"\n>\n <div class=\"modal-nav clr-wizard-stepnav-wrapper\" role=\"region\" [attr.aria-label]=\"stepnavAriaLabel\">\n <div class=\"clr-wizard-title\" id=\"{{wizardId}}\" role=\"heading\" [attr.aria-level]=\"wizardTitle.headingLevel || 1\">\n <ng-content select=\"clr-wizard-title\"></ng-content>\n </div>\n <clr-wizard-stepnav></clr-wizard-stepnav>\n </div>\n\n <div class=\"modal-title\" role=\"heading\" [attr.aria-level]=\"navService.currentPage.pageTitle.headingLevel || 2\">\n <span tabindex=\"-1\" #pageTitle class=\"modal-title-text\">\n <ng-template [ngTemplateOutlet]=\"navService.currentPageTitle\"></ng-template>\n </span>\n\n <div class=\"modal-header-actions-wrapper\" *ngIf=\"headerActionService.displayHeaderActionsWrapper\">\n <div *ngIf=\"headerActionService.showWizardHeaderActions\">\n <ng-content select=\"clr-wizard-header-action\"></ng-content>\n </div>\n <div *ngIf=\"headerActionService.currentPageHasHeaderActions\">\n <ng-template [ngTemplateOutlet]=\"navService.currentPage.headerActions\"></ng-template>\n </div>\n </div>\n </div>\n\n <div class=\"modal-body\">\n <main clr-wizard-pages-wrapper class=\"clr-wizard-content\">\n <ng-content></ng-content>\n </main>\n </div>\n <div class=\"modal-footer clr-wizard-footer\">\n <div class=\"clr-wizard-footer-buttons\">\n <div\n *ngIf=\"navService.currentPage && !navService.currentPage.hasButtons\"\n class=\"clr-wizard-footer-buttons-wrapper\"\n >\n <ng-content select=\"clr-wizard-button\"></ng-content>\n </div>\n <div\n *ngIf=\"navService.currentPage && navService.currentPage.hasButtons\"\n class=\"clr-wizard-footer-buttons-wrapper\"\n >\n <ng-template [ngTemplateOutlet]=\"navService.currentPage.buttons\"></ng-template>\n </div>\n </div>\n </div>\n</clr-modal>\n" }]
26271
27220
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
26272
27221
  type: Inject,
26273
27222
  args: [PLATFORM_ID]
26274
- }] }, { type: ClrCommonStringsService }, { type: WizardNavigationService }, { type: PageCollectionService }, { type: ButtonHubService }, { type: HeaderActionService }, { type: i0.IterableDiffers }]; }, propDecorators: { stepnavAriaLabel: [{
27223
+ }] }, { type: ClrCommonStringsService }, { type: WizardNavigationService }, { type: PageCollectionService }, { type: ButtonHubService }, { type: HeaderActionService }, { type: i0.ElementRef }, { type: i0.IterableDiffers }]; }, propDecorators: { stepnavAriaLabel: [{
26275
27224
  type: Input,
26276
27225
  args: ['clrWizardStepnavAriaLabel']
26277
27226
  }], size: [{
@@ -26280,6 +27229,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
26280
27229
  }], closable: [{
26281
27230
  type: Input,
26282
27231
  args: ['clrWizardClosable']
27232
+ }], _stopModalAnimations: [{
27233
+ type: Input,
27234
+ args: ['clrWizardPreventModalAnimation']
26283
27235
  }], _openChanged: [{
26284
27236
  type: Output,
26285
27237
  args: ['clrWizardOpenChange']
@@ -26594,6 +27546,7 @@ ClarityModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version:
26594
27546
  ClrLayoutModule,
26595
27547
  ClrPopoverModule,
26596
27548
  ClrWizardModule,
27549
+ ClrSidePanelModule,
26597
27550
  ClrStepperModule,
26598
27551
  ClrSpinnerModule,
26599
27552
  ClrProgressBarModule,
@@ -26611,6 +27564,7 @@ ClarityModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version:
26611
27564
  ClrLayoutModule,
26612
27565
  ClrPopoverModule,
26613
27566
  ClrWizardModule,
27567
+ ClrSidePanelModule,
26614
27568
  ClrStepperModule,
26615
27569
  ClrSpinnerModule,
26616
27570
  ClrProgressBarModule,
@@ -26632,6 +27586,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
26632
27586
  ClrLayoutModule,
26633
27587
  ClrPopoverModule,
26634
27588
  ClrWizardModule,
27589
+ ClrSidePanelModule,
26635
27590
  ClrStepperModule,
26636
27591
  ClrSpinnerModule,
26637
27592
  ClrProgressBarModule,
@@ -26970,5 +27925,5 @@ const CLR_MENU_POSITIONS = [
26970
27925
  * Generated bundle index. Do not edit.
26971
27926
  */
26972
27927
 
26973
- export { CHANGE_KEYS, CLR_ALERT_DIRECTIVES, CLR_BUTTON_GROUP_DIRECTIVES, CLR_DATAGRID_DIRECTIVES, CLR_DATEPICKER_DIRECTIVES, CLR_DROPDOWN_DIRECTIVES, 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_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, 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, ClrDateInputValidator, ClrDatepickerModule, ClrDatepickerViewManager, ClrDay, ClrDaypicker, ClrDestroyService, ClrDropdown, ClrDropdownItem, ClrDropdownMenu, ClrDropdownModule, ClrDropdownTrigger, ClrEmphasisModule, ClrExpandableAnimation, 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, ClrModalModule, ClrMonthpicker, ClrNavLevel, ClrNavigationModule, 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, ClrSignpost, ClrSignpostContent, ClrSignpostModule, ClrSignpostTrigger, ClrSpinner, ClrSpinnerModule, ClrStackBlock, ClrStackContentInput, ClrStackHeader, ClrStackView, ClrStackViewCustomTags, ClrStackViewLabel, ClrStackViewModule, ClrStandaloneCdkTrapFocus, ClrStepButton, ClrStepButtonType, ClrStepper, ClrStepperModule, ClrStepperPanel, ClrStopEscapePropagationDirective, ClrTab, ClrTabContent, ClrTabLink, ClrTabOverflowContent, ClrTabs, 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, DatagridWillyWonka as ÇlrDatagridWillyWonka, ExpandableOompaLoompa as ÇlrExpandableOompaLoompa, StepperOompaLoompa as ÇlrStepperOompaLoompa, StepperWillyWonka as ÇlrStepperWillyWonka, TabsWillyWonka as ÇlrTabsWillyWonka, WrappedCell as ÇlrWrappedCell, WrappedColumn as ÇlrWrappedColumn, WrappedRow as ÇlrWrappedRow };
27928
+ export { CHANGE_KEYS, CLR_ALERT_DIRECTIVES, CLR_BUTTON_GROUP_DIRECTIVES, CLR_DATAGRID_DIRECTIVES, CLR_DATEPICKER_DIRECTIVES, CLR_DROPDOWN_DIRECTIVES, 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, 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, ClrDateInputValidator, ClrDatepickerModule, ClrDatepickerViewManager, ClrDay, ClrDaypicker, ClrDestroyService, ClrDropdown, ClrDropdownItem, ClrDropdownMenu, ClrDropdownModule, ClrDropdownTrigger, ClrEmphasisModule, ClrExpandableAnimation, ClrFileInput, ClrFileInputContainer, ClrFileInputModule, ClrFileInputValidator, ClrFileInputValueAccessor, 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, ClrModalModule, ClrMonthpicker, ClrNavLevel, ClrNavigationModule, 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, ClrSignpostTrigger, ClrSpinner, ClrSpinnerModule, ClrStackBlock, ClrStackContentInput, ClrStackHeader, ClrStackView, ClrStackViewCustomTags, ClrStackViewLabel, ClrStackViewModule, ClrStandaloneCdkTrapFocus, ClrStepButton, ClrStepButtonType, ClrStepper, ClrStepperModule, ClrStepperPanel, ClrStopEscapePropagationDirective, ClrTab, ClrTabContent, ClrTabLink, ClrTabOverflowContent, ClrTabs, 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 };
26974
27929
  //# sourceMappingURL=clr-angular.mjs.map