@clr/angular 17.1.0 → 17.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/clarity.api.md +377 -141
  2. package/clr-angular.module.d.ts +7 -6
  3. package/data/datagrid/datagrid-virtual-scroll.directive.d.ts +59 -0
  4. package/data/datagrid/datagrid.d.ts +7 -4
  5. package/data/datagrid/datagrid.module.d.ts +31 -30
  6. package/data/datagrid/index.d.ts +1 -0
  7. package/data/datagrid/interfaces/column-state.interface.d.ts +1 -0
  8. package/data/datagrid/providers/detail.service.d.ts +1 -0
  9. package/data/datagrid/render/cell-renderer.d.ts +3 -6
  10. package/data/datagrid/render/header-renderer.d.ts +2 -3
  11. package/data/datagrid/render/main-renderer.d.ts +5 -1
  12. package/data/datagrid/render/row-renderer.d.ts +4 -3
  13. package/data/datagrid/utils/key-navigation-grid.controller.d.ts +4 -1
  14. package/esm2020/accordion/accordion-panel.mjs +3 -3
  15. package/esm2020/accordion/stepper/stepper-panel.mjs +8 -4
  16. package/esm2020/clr-angular.module.mjs +5 -1
  17. package/esm2020/data/datagrid/datagrid-row.mjs +3 -3
  18. package/esm2020/data/datagrid/datagrid-selection-cell.directive.mjs +2 -2
  19. package/esm2020/data/datagrid/datagrid-virtual-scroll.directive.mjs +225 -0
  20. package/esm2020/data/datagrid/datagrid.mjs +32 -10
  21. package/esm2020/data/datagrid/datagrid.module.mjs +5 -1
  22. package/esm2020/data/datagrid/index.mjs +2 -1
  23. package/esm2020/data/datagrid/interfaces/column-state.interface.mjs +1 -1
  24. package/esm2020/data/datagrid/providers/detail.service.mjs +6 -1
  25. package/esm2020/data/datagrid/render/cell-renderer.mjs +10 -33
  26. package/esm2020/data/datagrid/render/header-renderer.mjs +25 -43
  27. package/esm2020/data/datagrid/render/main-renderer.mjs +54 -9
  28. package/esm2020/data/datagrid/render/render-organizer.mjs +2 -2
  29. package/esm2020/data/datagrid/render/row-renderer.mjs +5 -5
  30. package/esm2020/data/datagrid/utils/key-navigation-grid.controller.mjs +17 -4
  31. package/esm2020/forms/combobox/combobox.mjs +3 -3
  32. package/esm2020/forms/datalist/datalist-container.mjs +1 -4
  33. package/esm2020/forms/datepicker/datepicker-view-manager.mjs +3 -3
  34. package/esm2020/forms/file-input/file-input-container.mjs +157 -0
  35. package/esm2020/forms/file-input/file-input-validator.mjs +72 -0
  36. package/esm2020/forms/file-input/file-input-value-accessor.mjs +53 -0
  37. package/esm2020/forms/file-input/file-input.helpers.mjs +22 -0
  38. package/esm2020/forms/file-input/file-input.mjs +68 -0
  39. package/esm2020/forms/file-input/file-input.module.mjs +43 -0
  40. package/esm2020/forms/file-input/index.mjs +12 -0
  41. package/esm2020/forms/forms.module.mjs +5 -1
  42. package/esm2020/forms/index.mjs +2 -1
  43. package/esm2020/modal/index.mjs +3 -1
  44. package/esm2020/modal/modal-configuration.service.mjs +20 -0
  45. package/esm2020/modal/modal.mjs +47 -18
  46. package/esm2020/modal/modal.module.mjs +4 -2
  47. package/esm2020/modal/side-panel.mjs +90 -0
  48. package/esm2020/modal/side-panel.module.mjs +28 -0
  49. package/esm2020/utils/animations/expandable-animation/expandable-animation.mjs +17 -12
  50. package/esm2020/utils/dom-adapter/dom-adapter.mjs +13 -4
  51. package/esm2020/utils/i18n/common-strings.default.mjs +6 -1
  52. package/esm2020/utils/i18n/common-strings.interface.mjs +1 -1
  53. package/esm2020/wizard/wizard.mjs +29 -6
  54. package/fesm2015/clr-angular.mjs +1123 -264
  55. package/fesm2015/clr-angular.mjs.map +1 -1
  56. package/fesm2020/clr-angular.mjs +1114 -266
  57. package/fesm2020/clr-angular.mjs.map +1 -1
  58. package/forms/file-input/file-input-container.d.ts +16 -0
  59. package/forms/file-input/file-input-validator.d.ts +12 -0
  60. package/forms/file-input/file-input-value-accessor.d.ts +15 -0
  61. package/forms/file-input/file-input.d.ts +21 -0
  62. package/forms/file-input/file-input.helpers.d.ts +3 -0
  63. package/forms/file-input/file-input.module.d.ts +14 -0
  64. package/forms/file-input/index.d.ts +5 -0
  65. package/forms/forms.module.d.ts +9 -8
  66. package/forms/index.d.ts +1 -0
  67. package/modal/index.d.ts +2 -0
  68. package/modal/modal-configuration.service.d.ts +7 -0
  69. package/modal/modal.d.ts +8 -2
  70. package/modal/side-panel.d.ts +26 -0
  71. package/modal/side-panel.module.d.ts +13 -0
  72. package/package.json +2 -2
  73. package/utils/animations/expandable-animation/expandable-animation.d.ts +5 -4
  74. package/utils/i18n/common-strings.interface.d.ts +4 -0
  75. 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';
@@ -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
  /*
@@ -7255,7 +7282,7 @@ ClrCombobox.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
7255
7282
  IF_ACTIVE_ID_PROVIDER,
7256
7283
  FOCUS_SERVICE_PROVIDER,
7257
7284
  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"] }] });
7285
+ ], 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
7286
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrCombobox, decorators: [{
7260
7287
  type: Component,
7261
7288
  args: [{ selector: 'clr-combobox', providers: [
@@ -7268,7 +7295,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
7268
7295
  '[class.aria-required]': 'true',
7269
7296
  '[class.clr-combobox]': 'true',
7270
7297
  '[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" }]
7298
+ }, 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
7299
  }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.Injector }, { type: i1.NgControl, decorators: [{
7273
7300
  type: Self
7274
7301
  }, {
@@ -7717,7 +7744,6 @@ class ClrDatalistContainer extends ClrAbstractContainer {
7717
7744
  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
7745
  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
7746
  ControlClassService,
7720
- LayoutService,
7721
7747
  ControlIdService,
7722
7748
  FocusService,
7723
7749
  NgControlService,
@@ -7794,7 +7820,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
7794
7820
  },
7795
7821
  providers: [
7796
7822
  ControlClassService,
7797
- LayoutService,
7798
7823
  ControlIdService,
7799
7824
  FocusService,
7800
7825
  NgControlService,
@@ -9593,7 +9618,7 @@ class ClrDatepickerViewManager {
9593
9618
  }
9594
9619
  }
9595
9620
  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" }] });
9621
+ 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
9622
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatepickerViewManager, decorators: [{
9598
9623
  type: Component,
9599
9624
  args: [{ selector: 'clr-datepicker-view-manager', providers: [DatepickerFocusService], host: {
@@ -9601,7 +9626,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
9601
9626
  '[attr.aria-modal]': 'true',
9602
9627
  '[attr.aria-label]': 'commonStrings.keys.datepickerDialogLabel',
9603
9628
  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" }]
9629
+ }, 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
9630
  }], ctorParameters: function () { return [{ type: ClrCommonStringsService }, { type: ViewManagerService }]; } });
9606
9631
 
9607
9632
  /*
@@ -10223,6 +10248,393 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
10223
10248
  }]
10224
10249
  }], ctorParameters: function () { return []; } });
10225
10250
 
10251
+ /*
10252
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
10253
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
10254
+ * This software is released under MIT license.
10255
+ * The full license information can be found in LICENSE in the root directory of this project.
10256
+ */
10257
+ class ClrFileInputContainer extends ClrAbstractContainer {
10258
+ constructor() {
10259
+ super(...arguments);
10260
+ this.commonStrings = inject(ClrCommonStringsService);
10261
+ }
10262
+ get disabled() {
10263
+ return this.fileInput.elementRef.nativeElement.disabled;
10264
+ }
10265
+ get browseButtonDescribedBy() {
10266
+ return this.fileInput.elementRef.nativeElement.getAttribute('aria-describedby');
10267
+ }
10268
+ browse() {
10269
+ this.fileInput.elementRef.nativeElement.click();
10270
+ }
10271
+ clearSelectedFiles() {
10272
+ this.fileInput.elementRef.nativeElement.value = '';
10273
+ this.fileInput.elementRef.nativeElement.dispatchEvent(new Event('change', { bubbles: true, cancelable: true }));
10274
+ this.browseButtonElementRef.nativeElement.focus();
10275
+ }
10276
+ }
10277
+ ClrFileInputContainer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInputContainer, deps: null, target: i0.ɵɵFactoryTarget.Component });
10278
+ 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: `
10279
+ <ng-content select="label"></ng-content>
10280
+ <label *ngIf="!label && addGrid()"></label>
10281
+ <div class="clr-control-container" [ngClass]="controlClass()">
10282
+ <div class="clr-file-input-wrapper">
10283
+ <ng-content select="[clrFileInput]"></ng-content>
10284
+ <button
10285
+ #browseButton
10286
+ type="button"
10287
+ class="btn btn-sm clr-file-input-browse-button"
10288
+ [attr.aria-describedby]="browseButtonDescribedBy"
10289
+ [disabled]="disabled"
10290
+ (click)="browse()"
10291
+ >
10292
+ <cds-icon shape="folder-open"></cds-icon>
10293
+ <span class="clr-file-input-browse-button-text">
10294
+ {{ fileInput?.selection?.buttonLabel || customButtonLabel || commonStrings.keys.browse }}
10295
+ </span>
10296
+ </button>
10297
+ <button
10298
+ *ngIf="fileInput?.selection?.fileCount"
10299
+ type="button"
10300
+ class="btn btn-sm clr-file-input-clear-button"
10301
+ [attr.aria-label]="fileInput?.selection?.clearFilesButtonLabel"
10302
+ (click)="clearSelectedFiles()"
10303
+ >
10304
+ <cds-icon shape="times" status="neutral" size="md"></cds-icon>
10305
+ </button>
10306
+ <cds-icon
10307
+ *ngIf="showInvalid"
10308
+ class="clr-validate-icon"
10309
+ shape="exclamation-circle"
10310
+ status="danger"
10311
+ aria-hidden="true"
10312
+ ></cds-icon>
10313
+ <cds-icon
10314
+ *ngIf="showValid"
10315
+ class="clr-validate-icon"
10316
+ shape="check-circle"
10317
+ status="success"
10318
+ aria-hidden="true"
10319
+ ></cds-icon>
10320
+ </div>
10321
+ <ng-content select="clr-control-helper" *ngIf="showHelper"></ng-content>
10322
+ <ng-content select="clr-control-error" *ngIf="showInvalid"></ng-content>
10323
+ <ng-content select="clr-control-success" *ngIf="showValid"></ng-content>
10324
+ </div>
10325
+ `, 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"] }] });
10326
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInputContainer, decorators: [{
10327
+ type: Component,
10328
+ args: [{
10329
+ selector: 'clr-file-input-container',
10330
+ template: `
10331
+ <ng-content select="label"></ng-content>
10332
+ <label *ngIf="!label && addGrid()"></label>
10333
+ <div class="clr-control-container" [ngClass]="controlClass()">
10334
+ <div class="clr-file-input-wrapper">
10335
+ <ng-content select="[clrFileInput]"></ng-content>
10336
+ <button
10337
+ #browseButton
10338
+ type="button"
10339
+ class="btn btn-sm clr-file-input-browse-button"
10340
+ [attr.aria-describedby]="browseButtonDescribedBy"
10341
+ [disabled]="disabled"
10342
+ (click)="browse()"
10343
+ >
10344
+ <cds-icon shape="folder-open"></cds-icon>
10345
+ <span class="clr-file-input-browse-button-text">
10346
+ {{ fileInput?.selection?.buttonLabel || customButtonLabel || commonStrings.keys.browse }}
10347
+ </span>
10348
+ </button>
10349
+ <button
10350
+ *ngIf="fileInput?.selection?.fileCount"
10351
+ type="button"
10352
+ class="btn btn-sm clr-file-input-clear-button"
10353
+ [attr.aria-label]="fileInput?.selection?.clearFilesButtonLabel"
10354
+ (click)="clearSelectedFiles()"
10355
+ >
10356
+ <cds-icon shape="times" status="neutral" size="md"></cds-icon>
10357
+ </button>
10358
+ <cds-icon
10359
+ *ngIf="showInvalid"
10360
+ class="clr-validate-icon"
10361
+ shape="exclamation-circle"
10362
+ status="danger"
10363
+ aria-hidden="true"
10364
+ ></cds-icon>
10365
+ <cds-icon
10366
+ *ngIf="showValid"
10367
+ class="clr-validate-icon"
10368
+ shape="check-circle"
10369
+ status="success"
10370
+ aria-hidden="true"
10371
+ ></cds-icon>
10372
+ </div>
10373
+ <ng-content select="clr-control-helper" *ngIf="showHelper"></ng-content>
10374
+ <ng-content select="clr-control-error" *ngIf="showInvalid"></ng-content>
10375
+ <ng-content select="clr-control-success" *ngIf="showValid"></ng-content>
10376
+ </div>
10377
+ `,
10378
+ host: {
10379
+ '[class.clr-form-control]': 'true',
10380
+ '[class.clr-form-control-disabled]': 'disabled',
10381
+ '[class.clr-row]': 'addGrid()',
10382
+ },
10383
+ providers: [IfControlStateService, NgControlService, ControlIdService, ControlClassService],
10384
+ }]
10385
+ }], propDecorators: { customButtonLabel: [{
10386
+ type: Input,
10387
+ args: ['clrButtonLabel']
10388
+ }], fileInput: [{
10389
+ type: ContentChild,
10390
+ args: [forwardRef(() => ClrFileInput)]
10391
+ }], browseButtonElementRef: [{
10392
+ type: ViewChild,
10393
+ args: ['browseButton']
10394
+ }] } });
10395
+
10396
+ /*
10397
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
10398
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
10399
+ * This software is released under MIT license.
10400
+ * The full license information can be found in LICENSE in the root directory of this project.
10401
+ */
10402
+ class ClrFileInput extends WrappedFormControl {
10403
+ constructor(injector, renderer, viewContainerRef, elementRef, control, commonStrings) {
10404
+ super(viewContainerRef, ClrFileInputContainer, injector, control, renderer, elementRef);
10405
+ this.elementRef = elementRef;
10406
+ this.commonStrings = commonStrings;
10407
+ this.selection = undefined;
10408
+ }
10409
+ handleChange() {
10410
+ this.updateSelection();
10411
+ }
10412
+ updateSelection() {
10413
+ const files = this.elementRef.nativeElement.files;
10414
+ let selectionButtonLabel;
10415
+ let clearFilesButtonLabel;
10416
+ if (files?.length === 1) {
10417
+ const filename = files[0].name;
10418
+ selectionButtonLabel = filename;
10419
+ clearFilesButtonLabel = this.commonStrings.parse(this.commonStrings.keys.clearFile, {
10420
+ FILE: filename,
10421
+ });
10422
+ }
10423
+ else if (files?.length > 1) {
10424
+ const fileCount = files.length.toString();
10425
+ selectionButtonLabel = this.commonStrings.parse(this.commonStrings.keys.fileCount, {
10426
+ COUNT: fileCount,
10427
+ });
10428
+ clearFilesButtonLabel = this.commonStrings.parse(this.commonStrings.keys.clearFiles, {
10429
+ COUNT: fileCount,
10430
+ });
10431
+ }
10432
+ this.selection = {
10433
+ fileCount: files.length,
10434
+ buttonLabel: selectionButtonLabel,
10435
+ clearFilesButtonLabel,
10436
+ };
10437
+ }
10438
+ }
10439
+ 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 });
10440
+ 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 });
10441
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInput, decorators: [{
10442
+ type: Directive,
10443
+ args: [{
10444
+ selector: 'input[type="file"][clrFileInput]',
10445
+ host: {
10446
+ '[class.clr-file-input]': 'true',
10447
+ },
10448
+ }]
10449
+ }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i0.Renderer2 }, { type: i0.ViewContainerRef }, { type: i0.ElementRef }, { type: i1.NgControl, decorators: [{
10450
+ type: Self
10451
+ }, {
10452
+ type: Optional
10453
+ }] }, { type: ClrCommonStringsService }]; }, propDecorators: { handleChange: [{
10454
+ type: HostListener,
10455
+ args: ['change']
10456
+ }] } });
10457
+
10458
+ /*
10459
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
10460
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
10461
+ * This software is released under MIT license.
10462
+ * The full license information can be found in LICENSE in the root directory of this project.
10463
+ */
10464
+ class ClrFileInputValidator {
10465
+ constructor(elementRef) {
10466
+ this.elementRef = elementRef;
10467
+ }
10468
+ validate(control) {
10469
+ const files = control.value;
10470
+ const fileInputElement = this.elementRef.nativeElement;
10471
+ const errors = {};
10472
+ // required validation (native attribute)
10473
+ if (fileInputElement.required && files?.length === 0) {
10474
+ errors.required = true;
10475
+ }
10476
+ // accept validation (native attribute)
10477
+ if (fileInputElement.accept && files?.length > 0) {
10478
+ const accept = fileInputElement.accept.split(',').map(type => type.trim());
10479
+ for (let i = 0; i < files.length; i++) {
10480
+ const file = files.item(i);
10481
+ const [fileExtension] = file.name.match(/\..+$/);
10482
+ if (!accept.includes(file.type) && !accept.includes(fileExtension)) {
10483
+ errors.accept = errors.accept || [];
10484
+ errors.accept.push({ name: file.name, accept, type: file.type, extension: fileExtension });
10485
+ }
10486
+ }
10487
+ }
10488
+ // min file validation (custom input)
10489
+ if (this.minFileSize && files?.length > 0) {
10490
+ for (let i = 0; i < files.length; i++) {
10491
+ const file = files.item(i);
10492
+ if (file.size < this.minFileSize) {
10493
+ errors.minFileSize = errors.minFileSize || [];
10494
+ errors.minFileSize.push({ name: file.name, minFileSize: this.minFileSize, actualFileSize: file.size });
10495
+ }
10496
+ }
10497
+ }
10498
+ // max file validation (custom input)
10499
+ if (this.maxFileSize && files?.length > 0) {
10500
+ for (let i = 0; i < files.length; i++) {
10501
+ const file = files.item(i);
10502
+ if (file.size > this.maxFileSize) {
10503
+ errors.maxFileSize = errors.maxFileSize || [];
10504
+ errors.maxFileSize.push({ name: file.name, maxFileSize: this.maxFileSize, actualFileSize: file.size });
10505
+ }
10506
+ }
10507
+ }
10508
+ return Object.keys(errors).length ? errors : null;
10509
+ }
10510
+ }
10511
+ ClrFileInputValidator.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInputValidator, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
10512
+ 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 });
10513
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInputValidator, decorators: [{
10514
+ type: Directive,
10515
+ args: [{
10516
+ selector: 'input[type="file"][clrFileInput]',
10517
+ providers: [{ provide: NG_VALIDATORS, useExisting: ClrFileInputValidator, multi: true }],
10518
+ }]
10519
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { minFileSize: [{
10520
+ type: Input,
10521
+ args: ['clrMinFileSize']
10522
+ }], maxFileSize: [{
10523
+ type: Input,
10524
+ args: ['clrMaxFileSize']
10525
+ }] } });
10526
+
10527
+ /*
10528
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
10529
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
10530
+ * This software is released under MIT license.
10531
+ * The full license information can be found in LICENSE in the root directory of this project.
10532
+ */
10533
+ function buildFileList(files) {
10534
+ const dataTransfer = new DataTransfer();
10535
+ for (const file of files) {
10536
+ dataTransfer.items.add(file);
10537
+ }
10538
+ return dataTransfer.files;
10539
+ }
10540
+ function selectFiles(fileInputElement, files) {
10541
+ fileInputElement.files = files instanceof FileList ? files : buildFileList(files);
10542
+ fileInputElement.dispatchEvent(new Event('change', { bubbles: true, cancelable: true }));
10543
+ }
10544
+ function clearFiles(fileInputElement) {
10545
+ fileInputElement.value = '';
10546
+ fileInputElement.dispatchEvent(new Event('change', { bubbles: true, cancelable: true }));
10547
+ }
10548
+
10549
+ /*
10550
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
10551
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
10552
+ * This software is released under MIT license.
10553
+ * The full license information can be found in LICENSE in the root directory of this project.
10554
+ */
10555
+ class ClrFileInputValueAccessor {
10556
+ constructor(elementRef) {
10557
+ this.elementRef = elementRef;
10558
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
10559
+ this.onChange = (_value) => { };
10560
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
10561
+ this.onTouched = () => { };
10562
+ }
10563
+ writeValue(value) {
10564
+ if (value !== undefined && value !== null && !(value instanceof FileList)) {
10565
+ throw new Error('The value of a file input control must be a FileList.');
10566
+ }
10567
+ if (value) {
10568
+ selectFiles(this.elementRef.nativeElement, value);
10569
+ }
10570
+ else if (this.elementRef.nativeElement.files.length) {
10571
+ clearFiles(this.elementRef.nativeElement);
10572
+ }
10573
+ }
10574
+ registerOnChange(fn) {
10575
+ this.onChange = fn;
10576
+ }
10577
+ registerOnTouched(fn) {
10578
+ this.onTouched = fn;
10579
+ }
10580
+ handleChange() {
10581
+ this.onTouched();
10582
+ this.onChange(this.elementRef.nativeElement.files);
10583
+ }
10584
+ }
10585
+ ClrFileInputValueAccessor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInputValueAccessor, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
10586
+ 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 });
10587
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInputValueAccessor, decorators: [{
10588
+ type: Directive,
10589
+ args: [{
10590
+ selector: 'input[type="file"][clrFileInput]',
10591
+ providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: ClrFileInputValueAccessor, multi: true }],
10592
+ }]
10593
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { handleChange: [{
10594
+ type: HostListener,
10595
+ args: ['change']
10596
+ }] } });
10597
+
10598
+ /*
10599
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
10600
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
10601
+ * This software is released under MIT license.
10602
+ * The full license information can be found in LICENSE in the root directory of this project.
10603
+ */
10604
+ class ClrFileInputModule {
10605
+ constructor() {
10606
+ ClarityIcons.addIcons(folderOpenIcon);
10607
+ }
10608
+ }
10609
+ ClrFileInputModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInputModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
10610
+ 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,
10611
+ ClrFileInput,
10612
+ ClrFileInputContainer,
10613
+ ClrFileInputValidator,
10614
+ ClrFileInputValueAccessor] });
10615
+ ClrFileInputModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInputModule, imports: [CommonModule, ClrIconModule, ClrCommonFormsModule, ClrCommonFormsModule] });
10616
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFileInputModule, decorators: [{
10617
+ type: NgModule,
10618
+ args: [{
10619
+ imports: [CommonModule, ClrIconModule, ClrCommonFormsModule],
10620
+ declarations: [ClrFileInput, ClrFileInputContainer, ClrFileInputValidator, ClrFileInputValueAccessor],
10621
+ exports: [
10622
+ ClrCommonFormsModule,
10623
+ ClrFileInput,
10624
+ ClrFileInputContainer,
10625
+ ClrFileInputValidator,
10626
+ ClrFileInputValueAccessor,
10627
+ ],
10628
+ }]
10629
+ }], ctorParameters: function () { return []; } });
10630
+
10631
+ /*
10632
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
10633
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
10634
+ * This software is released under MIT license.
10635
+ * The full license information can be found in LICENSE in the root directory of this project.
10636
+ */
10637
+
10226
10638
  /*
10227
10639
  * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
10228
10640
  * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
@@ -11146,6 +11558,7 @@ ClrFormsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version:
11146
11558
  ClrCheckboxModule,
11147
11559
  ClrComboboxModule,
11148
11560
  ClrDatepickerModule,
11561
+ ClrFileInputModule,
11149
11562
  ClrInputModule,
11150
11563
  ClrPasswordModule,
11151
11564
  ClrRadioModule,
@@ -11157,6 +11570,7 @@ ClrFormsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version:
11157
11570
  ClrCheckboxModule,
11158
11571
  ClrComboboxModule,
11159
11572
  ClrDatepickerModule,
11573
+ ClrFileInputModule,
11160
11574
  ClrInputModule,
11161
11575
  ClrPasswordModule,
11162
11576
  ClrRadioModule,
@@ -11173,6 +11587,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
11173
11587
  ClrCheckboxModule,
11174
11588
  ClrComboboxModule,
11175
11589
  ClrDatepickerModule,
11590
+ ClrFileInputModule,
11176
11591
  ClrInputModule,
11177
11592
  ClrPasswordModule,
11178
11593
  ClrRadioModule,
@@ -12630,6 +13045,11 @@ class DetailService {
12630
13045
  this.toggleState = false;
12631
13046
  this._state.next(this.toggleState);
12632
13047
  this.modalStackService.trackModalClose(this);
13048
+ // In the case of browser zoom greater than 250%, the detail pane toggle button is not visible on the page.
13049
+ // Wait for the detail pane to close, and return focus to the detail toggle button.
13050
+ setTimeout(() => this.returnFocus(), 0);
13051
+ }
13052
+ returnFocus() {
12633
13053
  if (this.button) {
12634
13054
  this.button.focus();
12635
13055
  this.button = null;
@@ -12937,7 +13357,7 @@ class DatagridRenderOrganizer {
12937
13357
  this._renderStep.next(DatagridRenderStep.CLEAR_WIDTHS);
12938
13358
  }
12939
13359
  this._renderStep.next(DatagridRenderStep.COMPUTE_COLUMN_WIDTHS);
12940
- this._renderStep.next(DatagridRenderStep.ALIGN_COLUMNS);
13360
+ this._renderStep.next(DatagridRenderStep.ALIGN_COLUMNS); // NOT USED
12941
13361
  this.alreadySized = true;
12942
13362
  this._renderStep.next(DatagridRenderStep.CALCULATE_MODE_OFF);
12943
13363
  }
@@ -14653,7 +15073,7 @@ class ClrDatagridSelectionCellDirective {
14653
15073
  }
14654
15074
  // If click was outside the label/input, forward the click to the input.
14655
15075
  if (event.target.tagName !== 'LABEL' && event.target.tagName !== 'INPUT') {
14656
- event.target.querySelector('input').click();
15076
+ event.target.querySelector('input')?.click();
14657
15077
  }
14658
15078
  }
14659
15079
  }
@@ -14923,7 +15343,7 @@ ClrDatagridRow.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version
14923
15343
  DatagridIfExpandService,
14924
15344
  { provide: IfExpandService, useExisting: DatagridIfExpandService },
14925
15345
  { 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" }] });
15346
+ ], 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\n *ngIf=\"detailService.enabled\"\n class=\"datagrid-detail-caret datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\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.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
15347
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridRow, decorators: [{
14928
15348
  type: Component,
14929
15349
  args: [{ selector: 'clr-dg-row', host: {
@@ -14935,7 +15355,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
14935
15355
  DatagridIfExpandService,
14936
15356
  { provide: IfExpandService, useExisting: DatagridIfExpandService },
14937
15357
  { 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" }]
15358
+ ], 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\n *ngIf=\"detailService.enabled\"\n class=\"datagrid-detail-caret datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\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.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
15359
  }], 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
15360
  type: Inject,
14941
15361
  args: [DOCUMENT]
@@ -15144,6 +15564,7 @@ class KeyNavigationGridController {
15144
15564
  this.zone = zone;
15145
15565
  this.listenersAdded = false;
15146
15566
  this.destroy$ = new Subject();
15567
+ this._activeCell = null;
15147
15568
  this.config = {
15148
15569
  keyGridRows: '[role=row]:not(.datagrid-placeholder)',
15149
15570
  keyGridCells: '[role=gridcell]:not(.datagrid-hidden-column):not(.datagrid-placeholder-content), [role=columnheader]:not(.datagrid-hidden-column):not(.datagrid-placeholder-content), .datagrid-detail-caret',
@@ -15181,6 +15602,11 @@ class KeyNavigationGridController {
15181
15602
  }
15182
15603
  }
15183
15604
  });
15605
+ fromEvent(this.grid, 'wheel')
15606
+ .pipe(takeUntil(this.destroy$))
15607
+ .subscribe(() => {
15608
+ this.removeActiveCell();
15609
+ });
15184
15610
  fromEvent(this.grid, 'keydown')
15185
15611
  .pipe(takeUntil(this.destroy$))
15186
15612
  .subscribe((e) => {
@@ -15220,6 +15646,12 @@ class KeyNavigationGridController {
15220
15646
  const firstCell = this.cells ? this.cells[0] : null;
15221
15647
  firstCell?.setAttribute('tabindex', '0');
15222
15648
  }
15649
+ removeActiveCell() {
15650
+ this._activeCell = null;
15651
+ }
15652
+ getActiveCell() {
15653
+ return this._activeCell;
15654
+ }
15223
15655
  setActiveCell(activeCell) {
15224
15656
  const prior = this.cells ? Array.from(this.cells).find(c => c.getAttribute('tabindex') === '0') : null;
15225
15657
  if (prior) {
@@ -15229,6 +15661,7 @@ class KeyNavigationGridController {
15229
15661
  const items = getTabableItems(activeCell);
15230
15662
  const item = activeCell.getAttribute('role') !== 'columnheader' && items[0] ? items[0] : activeCell;
15231
15663
  item.focus();
15664
+ this._activeCell = item;
15232
15665
  }
15233
15666
  getNextItemCoordinate(e) {
15234
15667
  let currentCell = this.cells ? Array.from(this.cells).find(i => i.getAttribute('tabindex') === '0') : null;
@@ -15237,7 +15670,7 @@ class KeyNavigationGridController {
15237
15670
  }
15238
15671
  const currentRow = this.rows && currentCell ? Array.from(this.rows).find(r => r.contains(currentCell)) : null;
15239
15672
  const numOfRows = this.rows ? this.rows.length - 1 : 0;
15240
- const numOfColumns = this.cells ? this.cells.length / this.rows.length - 1 : 0;
15673
+ const numOfColumns = this.cells ? Math.floor(this.cells.length / this.rows.length - 1) : 0;
15241
15674
  let x = currentRow && currentCell
15242
15675
  ? Array.from(currentRow.querySelectorAll(this.config.keyGridCells)).indexOf(currentCell)
15243
15676
  : 0;
@@ -15245,7 +15678,7 @@ class KeyNavigationGridController {
15245
15678
  const dir = this.host.dir;
15246
15679
  const inlineStart = dir === 'rtl' ? 'ArrowRight' : 'ArrowLeft';
15247
15680
  const inlineEnd = dir === 'rtl' ? 'ArrowLeft' : 'ArrowRight';
15248
- const itemsPerPage = this.rows.length || 0;
15681
+ const itemsPerPage = Math.floor(this.host?.querySelector('.datagrid').clientHeight / this.rows[0].clientHeight) - 1 || 0;
15249
15682
  if (e.code === 'ArrowUp' && y !== 0) {
15250
15683
  y = y - 1;
15251
15684
  }
@@ -15271,7 +15704,7 @@ class KeyNavigationGridController {
15271
15704
  }
15272
15705
  }
15273
15706
  else if (e.code === 'PageUp') {
15274
- y = y - itemsPerPage > 0 ? y - itemsPerPage : 0;
15707
+ y = y - itemsPerPage > 0 ? y - itemsPerPage + 1 : 1;
15275
15708
  }
15276
15709
  else if (e.code === 'PageDown') {
15277
15710
  y = y + itemsPerPage < numOfRows ? y + itemsPerPage : numOfRows;
@@ -15291,31 +15724,156 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
15291
15724
  * This software is released under MIT license.
15292
15725
  * The full license information can be found in LICENSE in the root directory of this project.
15293
15726
  */
15294
- class ClrDatagrid {
15295
- constructor(organizer, items, expandableRows, selection, rowActionService, stateProvider, displayMode, renderer, detailService, document, el, page, commonStrings, columnsService, keyNavigation, zone) {
15296
- this.organizer = organizer;
15297
- this.items = items;
15298
- this.expandableRows = expandableRows;
15299
- this.selection = selection;
15300
- this.rowActionService = rowActionService;
15301
- this.stateProvider = stateProvider;
15302
- this.displayMode = displayMode;
15303
- this.renderer = renderer;
15304
- this.detailService = detailService;
15305
- this.document = document;
15727
+ // @TODO The top two are not used now, which is probably a performance drag that was broken along the way.
15728
+ // There was a previous pattern to hide everything to do computation then display, for Firefox, needs revisiting.
15729
+ const NO_LAYOUT_CLASS = 'datagrid-no-layout';
15730
+ const COMPUTE_WIDTH_CLASS = 'datagrid-computing-columns-width';
15731
+ const STRICT_WIDTH_CLASS = 'datagrid-fixed-width';
15732
+ const HIDDEN_COLUMN_CLASS = 'datagrid-hidden-column';
15733
+
15734
+ /*
15735
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
15736
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
15737
+ * This software is released under MIT license.
15738
+ * The full license information can be found in LICENSE in the root directory of this project.
15739
+ */
15740
+ class DatagridCellRenderer {
15741
+ constructor(el, renderer, organizer) {
15306
15742
  this.el = el;
15307
- this.page = page;
15308
- this.commonStrings = commonStrings;
15309
- this.columnsService = columnsService;
15310
- this.keyNavigation = keyNavigation;
15311
- this.zone = zone;
15312
- this.clrDgSingleSelectionAriaLabel = this.commonStrings.keys.singleSelectionAriaLabel;
15313
- this.clrDgSingleActionableAriaLabel = this.commonStrings.keys.singleActionableAriaLabel;
15314
- this.clrDetailExpandableAriaLabel = this.commonStrings.keys.detailExpandableAriaLabel;
15315
- // Allows disabling of the auto focus on page/state changes (excludes focus management inside of popups)
15316
- this.clrDgDisablePageFocus = false;
15317
- this.selectedChanged = new EventEmitter(false);
15318
- this.singleSelectedChanged = new EventEmitter(false);
15743
+ this.renderer = renderer;
15744
+ this.subscriptions = [];
15745
+ this.subscriptions.push(organizer.filterRenderSteps(DatagridRenderStep.CLEAR_WIDTHS).subscribe(() => this.clearWidth()));
15746
+ }
15747
+ ngOnDestroy() {
15748
+ this.subscriptions.forEach(sub => sub.unsubscribe());
15749
+ if (this.stateSubscription) {
15750
+ this.stateSubscription.unsubscribe();
15751
+ }
15752
+ }
15753
+ resetState(state) {
15754
+ state.changes = ALL_COLUMN_CHANGES;
15755
+ this.setWidth(state);
15756
+ this.setHidden(state);
15757
+ }
15758
+ setWidth(state) {
15759
+ if (state.strictWidth) {
15760
+ this.renderer.addClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
15761
+ }
15762
+ else {
15763
+ this.renderer.removeClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
15764
+ }
15765
+ this.renderer.setStyle(this.el.nativeElement, 'width', state.width + 'px');
15766
+ }
15767
+ setHidden(state) {
15768
+ if (state.hidden) {
15769
+ this.renderer.addClass(this.el.nativeElement, HIDDEN_COLUMN_CLASS);
15770
+ }
15771
+ else {
15772
+ this.renderer.removeClass(this.el.nativeElement, HIDDEN_COLUMN_CLASS);
15773
+ }
15774
+ }
15775
+ clearWidth() {
15776
+ this.renderer.removeClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
15777
+ this.renderer.setStyle(this.el.nativeElement, 'width', null);
15778
+ }
15779
+ }
15780
+ 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 });
15781
+ DatagridCellRenderer.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: DatagridCellRenderer, selector: "clr-dg-cell", ngImport: i0 });
15782
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: DatagridCellRenderer, decorators: [{
15783
+ type: Directive,
15784
+ args: [{
15785
+ selector: 'clr-dg-cell',
15786
+ }]
15787
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: DatagridRenderOrganizer }]; } });
15788
+
15789
+ /*
15790
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
15791
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
15792
+ * This software is released under MIT license.
15793
+ * The full license information can be found in LICENSE in the root directory of this project.
15794
+ */
15795
+ class DatagridRowRenderer {
15796
+ constructor(columnsService) {
15797
+ this.columnsService = columnsService;
15798
+ this.subscriptions = [];
15799
+ }
15800
+ ngAfterContentInit() {
15801
+ this.setCellsState(); // case #3 and #4
15802
+ this.subscriptions.push(this.cells.changes.subscribe(() => {
15803
+ this.setCellsState(); // case #2
15804
+ // Note on case #2: In the case of dynamic columns, when one column (header/cell together) gets deleted,
15805
+ // this.cells.changes emits before this.columnsService.columns gets updated in MainRenderer
15806
+ // when this.headers.changes emits as well. So that means there will be n+1 column state providers
15807
+ // when this.cells.changes emits. Hence, we should quit earlier there. But this method will be called
15808
+ // right after again when this.headers.changes emits. By then, there will be the same number of column state
15809
+ // providers as column headers.
15810
+ }));
15811
+ }
15812
+ ngOnDestroy() {
15813
+ this.subscriptions.forEach(sub => sub.unsubscribe());
15814
+ }
15815
+ setCellsState() {
15816
+ // This method runs in four cases:
15817
+ // 1. When the initial rows appear on the first page.
15818
+ // In this case, the method will be called in DatagridMainRenderer.
15819
+ // 2. When columns (corresponding header/cells) get added and deleted.
15820
+ // In this case, the method will be called in DatagridMainRenderer. (Read the note on this case above).
15821
+ // 3. When rows load asynchronously.
15822
+ // In this case, the method will be called in this class.
15823
+ // 4. When rows load after switching pages.
15824
+ // In this case, the method will be called in this class (Basically, same as the case 3).
15825
+ if (this.cells.length === this.columnsService.columns.length) {
15826
+ this.cells.forEach((cell, index) => {
15827
+ if (this.columnsService.columns[index]) {
15828
+ cell.resetState(this.columnsService.columns[index].value);
15829
+ }
15830
+ });
15831
+ }
15832
+ }
15833
+ }
15834
+ DatagridRowRenderer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: DatagridRowRenderer, deps: [{ token: ColumnsService }], target: i0.ɵɵFactoryTarget.Directive });
15835
+ 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 });
15836
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: DatagridRowRenderer, decorators: [{
15837
+ type: Directive,
15838
+ args: [{
15839
+ selector: 'clr-dg-row, clr-dg-row-detail',
15840
+ }]
15841
+ }], ctorParameters: function () { return [{ type: ColumnsService }]; }, propDecorators: { cells: [{
15842
+ type: ContentChildren,
15843
+ args: [DatagridCellRenderer]
15844
+ }] } });
15845
+
15846
+ /*
15847
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
15848
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
15849
+ * This software is released under MIT license.
15850
+ * The full license information can be found in LICENSE in the root directory of this project.
15851
+ */
15852
+ class ClrDatagrid {
15853
+ constructor(organizer, items, expandableRows, selection, rowActionService, stateProvider, displayMode, renderer, detailService, document, el, page, commonStrings, columnsService, keyNavigation, zone) {
15854
+ this.organizer = organizer;
15855
+ this.items = items;
15856
+ this.expandableRows = expandableRows;
15857
+ this.selection = selection;
15858
+ this.rowActionService = rowActionService;
15859
+ this.stateProvider = stateProvider;
15860
+ this.displayMode = displayMode;
15861
+ this.renderer = renderer;
15862
+ this.detailService = detailService;
15863
+ this.document = document;
15864
+ this.el = el;
15865
+ this.page = page;
15866
+ this.commonStrings = commonStrings;
15867
+ this.columnsService = columnsService;
15868
+ this.keyNavigation = keyNavigation;
15869
+ this.zone = zone;
15870
+ this.clrDgSingleSelectionAriaLabel = this.commonStrings.keys.singleSelectionAriaLabel;
15871
+ this.clrDgSingleActionableAriaLabel = this.commonStrings.keys.singleActionableAriaLabel;
15872
+ this.clrDetailExpandableAriaLabel = this.commonStrings.keys.detailExpandableAriaLabel;
15873
+ // Allows disabling of the auto focus on page/state changes (excludes focus management inside of popups)
15874
+ this.clrDgDisablePageFocus = false;
15875
+ this.selectedChanged = new EventEmitter(false);
15876
+ this.singleSelectedChanged = new EventEmitter(false);
15319
15877
  /**
15320
15878
  * Output emitted whenever the data needs to be refreshed, based on user action or external ones
15321
15879
  */
@@ -15424,7 +15982,19 @@ class ClrDatagrid {
15424
15982
  /**
15425
15983
  * Reopen updated row or close it
15426
15984
  */
15427
- row ? this.detailService.open(row.item, row.detailButton.nativeElement) : this.detailService.close();
15985
+ if (row) {
15986
+ this.detailService.open(row.item, row.detailButton.nativeElement);
15987
+ }
15988
+ else if (!this.hasVirtualScroller || !row) {
15989
+ this.detailService.close();
15990
+ }
15991
+ }
15992
+ // retain active cell when navigating with PageUp and PageDown buttons in virtual scroller
15993
+ const active = this.keyNavigation.getActiveCell();
15994
+ if (active) {
15995
+ this.zone.runOutsideAngular(() => {
15996
+ setTimeout(() => this.keyNavigation.setActiveCell(active));
15997
+ });
15428
15998
  }
15429
15999
  }));
15430
16000
  }
@@ -15450,8 +16020,6 @@ class ClrDatagrid {
15450
16020
  this.datagridTable.nativeElement.focus();
15451
16021
  }
15452
16022
  }),
15453
- // Reinitialize arrow key navigation on hide/unhide columns
15454
- combineLatest(this.columnsService.columns).subscribe(() => this.keyNavigation?.resetKeyGrid()),
15455
16023
  // A subscription that listens for displayMode changes on the datagrid
15456
16024
  this.displayMode.view.subscribe(viewChange => {
15457
16025
  // Remove any projected columns from the projectedDisplayColumns container
@@ -15519,7 +16087,7 @@ class ClrDatagrid {
15519
16087
  }
15520
16088
  }
15521
16089
  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: [
16090
+ 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
16091
  Selection,
15524
16092
  Sort,
15525
16093
  FiltersProvider,
@@ -15535,7 +16103,7 @@ ClrDatagrid.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
15535
16103
  ColumnsService,
15536
16104
  DisplayModeService,
15537
16105
  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" }] });
16106
+ ], 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)=\"allSelected = !allSelected; $event.preventDefault()\"\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-loading-more-items-row\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell class=\"datagrid-loading-more-items-cell\">\n <clr-spinner [clrMedium]=\"true\"></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-loading-more-items-row\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell class=\"datagrid-loading-more-items-cell\">\n <clr-spinner [clrMedium]=\"true\"></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
16107
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagrid, decorators: [{
15540
16108
  type: Component,
15541
16109
  args: [{ selector: 'clr-datagrid', providers: [
@@ -15557,11 +16125,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
15557
16125
  ], host: {
15558
16126
  '[class.datagrid-host]': 'true',
15559
16127
  '[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" }]
16128
+ }, 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 *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-loading-more-items-row\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell class=\"datagrid-loading-more-items-cell\">\n <clr-spinner [clrMedium]=\"true\"></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-loading-more-items-row\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell class=\"datagrid-loading-more-items-cell\">\n <clr-spinner [clrMedium]=\"true\"></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
16129
  }], 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
16130
  type: Inject,
15563
16131
  args: [DOCUMENT]
15564
- }] }, { type: i0.ElementRef }, { type: Page }, { type: ClrCommonStringsService }, { type: ColumnsService }, { type: KeyNavigationGridController }, { type: i0.NgZone }]; }, propDecorators: { clrDgSingleSelectionAriaLabel: [{
16132
+ }] }, { type: i0.ElementRef }, { type: Page }, { type: ClrCommonStringsService }, { type: ColumnsService }, { type: KeyNavigationGridController }, { type: i0.NgZone }]; }, propDecorators: { loadingMoreItems: [{
16133
+ type: Input,
16134
+ args: ['clrLoadingMoreItems']
16135
+ }], clrDgSingleSelectionAriaLabel: [{
15565
16136
  type: Input
15566
16137
  }], clrDgSingleActionableAriaLabel: [{
15567
16138
  type: Input
@@ -15590,6 +16161,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
15590
16161
  }], rows: [{
15591
16162
  type: ContentChildren,
15592
16163
  args: [ClrDatagridRow]
16164
+ }], datagrid: [{
16165
+ type: ViewChild,
16166
+ args: ['datagrid', { read: ElementRef }]
15593
16167
  }], datagridTable: [{
15594
16168
  type: ViewChild,
15595
16169
  args: ['datagridTable', { read: ElementRef }]
@@ -16991,96 +17565,220 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
16991
17565
  args: ['clrDgReplace']
16992
17566
  }] } });
16993
17567
 
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;
17568
+ const defaultCdkFixedSizeVirtualScrollInputs = {
17569
+ itemSize: 32,
17570
+ minBufferPx: 200,
17571
+ maxBufferPx: 400,
17572
+ };
17573
+ class ClrDatagridVirtualScrollDirective {
17574
+ constructor(changeDetectorRef, iterableDiffers, items, ngZone, templateRef, viewContainerRef, directionality, scrollDispatcher, viewportRuler, datagrid, injector) {
17575
+ this.changeDetectorRef = changeDetectorRef;
17576
+ this.iterableDiffers = iterableDiffers;
17577
+ this.items = items;
17578
+ this.ngZone = ngZone;
17579
+ this.templateRef = templateRef;
17580
+ this.viewContainerRef = viewContainerRef;
17581
+ this.directionality = directionality;
17582
+ this.scrollDispatcher = scrollDispatcher;
17583
+ this.viewportRuler = viewportRuler;
17584
+ this.datagrid = datagrid;
17585
+ this.injector = injector;
17586
+ this.renderedRangeChange = new EventEmitter();
17587
+ this._cdkFixedSizeVirtualScrollInputs = { ...defaultCdkFixedSizeVirtualScrollInputs };
17017
17588
  this.subscriptions = [];
17018
- this.subscriptions.push(organizer.filterRenderSteps(DatagridRenderStep.CLEAR_WIDTHS).subscribe(() => this.clearWidth()));
17589
+ this.mutationChanges = new MutationObserver((mutations) => {
17590
+ mutations.forEach((mutation) => {
17591
+ // it is possible this to be called twice because the old class is removed and the new added
17592
+ if (mutation.target.classList.contains('datagrid-compact') && this.itemSize > 24) {
17593
+ this.itemSize = 24;
17594
+ }
17595
+ });
17596
+ });
17597
+ this.cdkVirtualForInputs = {
17598
+ cdkVirtualForTrackBy: index => index,
17599
+ };
17600
+ this.items.smartenUp();
17601
+ this.datagrid.hasVirtualScroller = true;
17602
+ this.datagridElementRef = this.datagrid.el;
17603
+ this.mutationChanges.observe(this.datagridElementRef.nativeElement, {
17604
+ attributeFilter: ['class'],
17605
+ attributeOldValue: true,
17606
+ });
17607
+ this.virtualScrollStrategy = new FixedSizeVirtualScrollStrategy(this._cdkFixedSizeVirtualScrollInputs.itemSize, this._cdkFixedSizeVirtualScrollInputs.minBufferPx, this._cdkFixedSizeVirtualScrollInputs.maxBufferPx);
17019
17608
  }
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));
17609
+ get cdkVirtualForOf() {
17610
+ return this.cdkVirtualForInputs.cdkVirtualForOf;
17611
+ }
17612
+ set cdkVirtualForOf(value) {
17613
+ this.cdkVirtualForInputs.cdkVirtualForOf = value;
17614
+ this.items.all = value;
17615
+ this.updateCdkVirtualForInputs();
17616
+ }
17617
+ get cdkVirtualForTrackBy() {
17618
+ return this.cdkVirtualForInputs.cdkVirtualForTrackBy;
17619
+ }
17620
+ set cdkVirtualForTrackBy(value) {
17621
+ this.cdkVirtualForInputs.cdkVirtualForTrackBy = value;
17622
+ this.updateCdkVirtualForInputs();
17623
+ }
17624
+ get cdkVirtualForTemplate() {
17625
+ return this?.cdkVirtualForInputs?.cdkVirtualForTemplate;
17626
+ }
17627
+ set cdkVirtualForTemplate(value) {
17628
+ this.cdkVirtualForInputs.cdkVirtualForTemplate = value;
17629
+ this.updateCdkVirtualForInputs();
17630
+ }
17631
+ get cdkVirtualForTemplateCacheSize() {
17632
+ return this.cdkVirtualForInputs.cdkVirtualForTemplateCacheSize;
17633
+ }
17634
+ set cdkVirtualForTemplateCacheSize(value) {
17635
+ this.cdkVirtualForInputs.cdkVirtualForTemplateCacheSize = coerceNumberProperty(value);
17636
+ this.updateCdkVirtualForInputs();
17637
+ }
17638
+ get itemSize() {
17639
+ return this._cdkFixedSizeVirtualScrollInputs.itemSize;
17640
+ }
17641
+ set itemSize(value) {
17642
+ this._cdkFixedSizeVirtualScrollInputs.itemSize = coerceNumberProperty(value);
17643
+ this.updateFixedSizeVirtualScrollInputs();
17644
+ }
17645
+ get minBufferPx() {
17646
+ return this._cdkFixedSizeVirtualScrollInputs.minBufferPx;
17647
+ }
17648
+ set minBufferPx(value) {
17649
+ this._cdkFixedSizeVirtualScrollInputs.minBufferPx = coerceNumberProperty(value);
17650
+ this.updateFixedSizeVirtualScrollInputs();
17651
+ }
17652
+ get maxBufferPx() {
17653
+ return this._cdkFixedSizeVirtualScrollInputs.maxBufferPx;
17654
+ }
17655
+ set maxBufferPx(value) {
17656
+ this._cdkFixedSizeVirtualScrollInputs.maxBufferPx = coerceNumberProperty(value);
17657
+ this.updateFixedSizeVirtualScrollInputs();
17658
+ }
17659
+ ngAfterViewInit() {
17660
+ this.injector.runInContext(() => {
17661
+ this.virtualScrollViewport = this.createVirtualScrollViewportForDatagrid(this.changeDetectorRef, this.ngZone, this.directionality, this.scrollDispatcher, this.viewportRuler, this.datagridElementRef, this.virtualScrollStrategy);
17662
+ this.cdkVirtualFor = new CdkVirtualForOf(this.viewContainerRef, this.templateRef, this.iterableDiffers, new _RecycleViewRepeaterStrategy(), this.virtualScrollViewport, this.ngZone);
17663
+ this.virtualScrollViewport.ngOnInit();
17664
+ });
17665
+ this.gridRoleElement = this.datagridElementRef.nativeElement.querySelector('[role="grid"]');
17666
+ this.updateCdkVirtualForInputs();
17667
+ this.subscriptions.push(this.items.change.subscribe(newItems => {
17668
+ this.cdkVirtualFor.cdkVirtualForOf = newItems;
17669
+ }), this.cdkVirtualFor.dataStream.subscribe(data => {
17670
+ this.updateAriaRowCount(data.length);
17671
+ }), this.virtualScrollViewport.renderedRangeStream.subscribe(renderedRange => {
17672
+ this.renderedRangeChange.emit(renderedRange);
17673
+ }), this.datagrid.refresh.subscribe(datagridState => {
17674
+ if (datagridState.filters) {
17675
+ this.virtualScrollViewport.scrollToIndex(0);
17676
+ }
17677
+ }));
17678
+ }
17679
+ ngDoCheck() {
17680
+ this.cdkVirtualFor?.ngDoCheck();
17681
+ this.updateAriaRowIndexes();
17027
17682
  }
17028
17683
  ngOnDestroy() {
17029
- this.subscriptions.forEach(sub => sub.unsubscribe());
17030
- if (this.stateSubscription) {
17031
- this.stateSubscription.unsubscribe();
17032
- }
17684
+ this.cdkVirtualFor?.ngOnDestroy();
17685
+ this.virtualScrollViewport?.ngOnDestroy();
17686
+ this.mutationChanges?.disconnect();
17687
+ this.subscriptions.forEach(subscription => {
17688
+ subscription.unsubscribe();
17689
+ });
17033
17690
  }
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;
17691
+ updateCdkVirtualForInputs() {
17692
+ if (this.cdkVirtualFor) {
17693
+ for (const cdkVirtualForInputKey of Object.keys(this.cdkVirtualForInputs)) {
17694
+ if (this.cdkVirtualFor[cdkVirtualForInputKey] !== this.cdkVirtualForInputs[cdkVirtualForInputKey]) {
17695
+ this.cdkVirtualFor[cdkVirtualForInputKey] = this.cdkVirtualForInputs[cdkVirtualForInputKey];
17050
17696
  }
17051
- });
17697
+ }
17052
17698
  }
17053
17699
  }
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);
17700
+ updateFixedSizeVirtualScrollInputs() {
17701
+ if (this.virtualScrollStrategy) {
17702
+ this.virtualScrollStrategy.updateItemAndBufferSize(this._cdkFixedSizeVirtualScrollInputs.itemSize, this._cdkFixedSizeVirtualScrollInputs.minBufferPx, this._cdkFixedSizeVirtualScrollInputs.maxBufferPx);
17064
17703
  }
17065
- this.renderer.setStyle(this.el.nativeElement, 'width', state.width + 'px');
17066
17704
  }
17067
- setHidden(state) {
17068
- if (state.hidden) {
17069
- this.renderer.addClass(this.el.nativeElement, HIDDEN_COLUMN_CLASS);
17705
+ updateAriaRowCount(rowCount) {
17706
+ this.gridRoleElement?.setAttribute('aria-rowcount', rowCount.toString());
17707
+ }
17708
+ updateAriaRowIndexes() {
17709
+ for (let i = 0; i < this.viewContainerRef.length; i++) {
17710
+ const viewRef = this.viewContainerRef.get(i);
17711
+ const rootElements = viewRef.rootNodes;
17712
+ const datagridRowElement = rootElements.find(rowElement => rowElement.tagName === 'CLR-DG-ROW');
17713
+ const rowRoleElement = datagridRowElement?.querySelector('[role="row"]');
17714
+ // aria-rowindex should start with one, not zero, so we have to add one to the zero-based index
17715
+ rowRoleElement?.setAttribute('aria-rowindex', (viewRef.context.index + 1).toString());
17070
17716
  }
17071
- else {
17072
- this.renderer.removeClass(this.el.nativeElement, HIDDEN_COLUMN_CLASS);
17717
+ }
17718
+ createVirtualScrollViewportForDatagrid(changeDetectorRef, ngZone, directionality, scrollDispatcher, viewportRuler, datagridElementRef, virtualScrollStrategy) {
17719
+ const datagridDivElement = datagridElementRef.nativeElement.querySelector('.datagrid');
17720
+ const datagridTableElement = datagridElementRef.nativeElement.querySelector('.datagrid-table');
17721
+ const datagridRowsElement = datagridElementRef.nativeElement.querySelector('.datagrid-rows');
17722
+ const datagridDivElementRef = { nativeElement: datagridDivElement };
17723
+ let topOffset = 0;
17724
+ let totalContentSize = 0;
17725
+ function updateDatagridElementStyles() {
17726
+ datagridRowsElement.style.transform = `translateY(${topOffset}px)`;
17727
+ datagridRowsElement.style.height = `${totalContentSize - topOffset}px`;
17073
17728
  }
17729
+ const virtualScrollViewport = new CdkVirtualScrollViewport(datagridDivElementRef, changeDetectorRef, ngZone, virtualScrollStrategy, directionality, scrollDispatcher, viewportRuler, null);
17730
+ virtualScrollViewport._contentWrapper = {
17731
+ nativeElement: {
17732
+ style: {
17733
+ set transform(value) {
17734
+ topOffset = value === undefined ? 0 : +/translateY\(([0-9]+)px\)/.exec(value)?.[1];
17735
+ updateDatagridElementStyles();
17736
+ },
17737
+ },
17738
+ },
17739
+ };
17740
+ virtualScrollViewport.setTotalContentSize = (value) => {
17741
+ totalContentSize = value;
17742
+ datagridTableElement.style.height = `${totalContentSize}px`;
17743
+ updateDatagridElementStyles();
17744
+ };
17745
+ return virtualScrollViewport;
17074
17746
  }
17075
17747
  }
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: [{
17748
+ 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: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Directive });
17749
+ 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 });
17750
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridVirtualScrollDirective, decorators: [{
17079
17751
  type: Directive,
17080
17752
  args: [{
17081
- selector: 'clr-dg-cell',
17753
+ selector: '[ClrVirtualScroll]',
17754
+ providers: [Items],
17082
17755
  }]
17083
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: DatagridRenderOrganizer }]; } });
17756
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.IterableDiffers }, { type: Items, decorators: [{
17757
+ type: SkipSelf
17758
+ }] }, { type: i0.NgZone }, { type: i0.TemplateRef }, { type: i0.ViewContainerRef }, { type: i1$2.Directionality }, { type: i3$1.ScrollDispatcher }, { type: i3$1.ViewportRuler }, { type: ClrDatagrid }, { type: i0.EnvironmentInjector }]; }, propDecorators: { renderedRangeChange: [{
17759
+ type: Output
17760
+ }], cdkVirtualForOf: [{
17761
+ type: Input,
17762
+ args: ['clrVirtualRowsOf']
17763
+ }], cdkVirtualForTrackBy: [{
17764
+ type: Input,
17765
+ args: ['clrVirtualRowsTrackBy']
17766
+ }], cdkVirtualForTemplate: [{
17767
+ type: Input,
17768
+ args: ['clrVirtualRowsTemplate']
17769
+ }], cdkVirtualForTemplateCacheSize: [{
17770
+ type: Input,
17771
+ args: ['clrVirtualRowsTemplateCacheSize']
17772
+ }], itemSize: [{
17773
+ type: Input,
17774
+ args: ['clrVirtualRowsItemSize']
17775
+ }], minBufferPx: [{
17776
+ type: Input,
17777
+ args: ['clrVirtualRowsMinBufferPx']
17778
+ }], maxBufferPx: [{
17779
+ type: Input,
17780
+ args: ['clrVirtualRowsMaxBufferPx']
17781
+ }] } });
17084
17782
 
17085
17783
  /*
17086
17784
  * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
@@ -17105,7 +17803,6 @@ class DatagridHeaderRenderer {
17105
17803
  this.autoSet = false;
17106
17804
  this.subscriptions = [];
17107
17805
  this.subscriptions.push(this.organizer.filterRenderSteps(DatagridRenderStep.CLEAR_WIDTHS).subscribe(() => this.clearWidth()));
17108
- this.subscriptions.push(columnState.subscribe(state => this.stateChanges(state)));
17109
17806
  }
17110
17807
  ngOnDestroy() {
17111
17808
  this.subscriptions.forEach(sub => sub.unsubscribe());
@@ -17120,20 +17817,30 @@ class DatagridHeaderRenderer {
17120
17817
  setColumnState(index) {
17121
17818
  this.columnsService.columns[index] = this.columnState;
17122
17819
  }
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
- });
17820
+ setWidth(state) {
17821
+ if (state.strictWidth) {
17822
+ if (this.columnResizerService.resizedBy) {
17823
+ this.resizeEmitter.emit(state.width);
17824
+ this.renderer.setStyle(this.el.nativeElement, 'width', state.width + 'px');
17825
+ this.widthSet = false;
17826
+ }
17827
+ // Don't set width if there is a user-defined one. Just add the strict width class.
17828
+ this.renderer.addClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
17829
+ this.autoSet = false;
17830
+ }
17831
+ else {
17832
+ this.renderer.removeClass(this.el.nativeElement, STRICT_WIDTH_CLASS);
17833
+ this.renderer.setStyle(this.el.nativeElement, 'width', state.width + 'px');
17834
+ this.widthSet = true;
17835
+ this.autoSet = true;
17836
+ }
17837
+ }
17838
+ setHidden(state) {
17839
+ if (state.hidden) {
17840
+ this.renderer.addClass(this.el.nativeElement, HIDDEN_COLUMN_CLASS);
17841
+ }
17842
+ else {
17843
+ this.renderer.removeClass(this.el.nativeElement, HIDDEN_COLUMN_CLASS);
17137
17844
  }
17138
17845
  }
17139
17846
  clearWidth() {
@@ -17163,32 +17870,6 @@ class DatagridHeaderRenderer {
17163
17870
  }
17164
17871
  return width;
17165
17872
  }
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
17873
  }
17193
17874
  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
17875
  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 +17929,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
17248
17929
  type: Injectable
17249
17930
  }] });
17250
17931
 
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
17932
  /*
17309
17933
  * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
17310
17934
  * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
@@ -17324,7 +17948,7 @@ const domAdapterFactory = (platformId) => {
17324
17948
  // Fixes build error
17325
17949
  // @dynamic (https://github.com/angular/angular/issues/19698#issuecomment-338340211)
17326
17950
  class DatagridMainRenderer {
17327
- constructor(organizer, items, page, domAdapter, el, renderer, detailService, tableSizeService, columnsService, ngZone) {
17951
+ constructor(organizer, items, page, domAdapter, el, renderer, detailService, tableSizeService, columnsService, ngZone, keyNavigation) {
17328
17952
  this.organizer = organizer;
17329
17953
  this.items = items;
17330
17954
  this.page = page;
@@ -17335,6 +17959,7 @@ class DatagridMainRenderer {
17335
17959
  this.tableSizeService = tableSizeService;
17336
17960
  this.columnsService = columnsService;
17337
17961
  this.ngZone = ngZone;
17962
+ this.keyNavigation = keyNavigation;
17338
17963
  this._heightSet = false;
17339
17964
  this.shouldStabilizeColumns = true;
17340
17965
  this.subscriptions = [];
@@ -17364,6 +17989,7 @@ class DatagridMainRenderer {
17364
17989
  this.columnsSizesStable = false;
17365
17990
  this.stabilizeColumns();
17366
17991
  }));
17992
+ this.listenForColumnChanges();
17367
17993
  }
17368
17994
  // Initialize and set Table width for horizontal scrolling here.
17369
17995
  ngAfterViewInit() {
@@ -17405,7 +18031,7 @@ class DatagridMainRenderer {
17405
18031
  setupColumns() {
17406
18032
  this.headers.forEach((header, index) => header.setColumnState(index));
17407
18033
  this.columnsService.columns.splice(this.headers.length); // Trim any old columns
17408
- this.rows.forEach(row => row.setColumnState());
18034
+ this.rows.forEach(row => row.setCellsState());
17409
18035
  }
17410
18036
  shouldComputeHeight() {
17411
18037
  if (!this._heightSet && this.page.size > 0) {
@@ -17426,9 +18052,8 @@ class DatagridMainRenderer {
17426
18052
  * Refer: http://stackoverflow.com/questions/24396205/flex-grow-not-working-in-internet-explorer-11-0
17427
18053
  */
17428
18054
  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');
18055
+ const height = window.getComputedStyle(this.el.nativeElement).height;
18056
+ this.renderer.setStyle(this.el.nativeElement, 'height', height);
17432
18057
  this._heightSet = true;
17433
18058
  }
17434
18059
  resetDatagridHeight() {
@@ -17440,6 +18065,9 @@ class DatagridMainRenderer {
17440
18065
  */
17441
18066
  computeHeadersWidth() {
17442
18067
  const nbColumns = this.headers.length;
18068
+ const headerWidths = this.headers.map(header => {
18069
+ return header.getColumnWidthState();
18070
+ });
17443
18071
  let allStrict = true;
17444
18072
  this.headers.forEach((header, index) => {
17445
18073
  // On the last header column check whether all columns have strict widths.
@@ -17448,7 +18076,7 @@ class DatagridMainRenderer {
17448
18076
  // gap in the Datagrid.
17449
18077
  const state = {
17450
18078
  changes: [DatagridColumnChanges.WIDTH],
17451
- ...header.getColumnWidthState(),
18079
+ ...headerWidths[index],
17452
18080
  };
17453
18081
  if (!state.strictWidth) {
17454
18082
  allStrict = false;
@@ -17459,6 +18087,45 @@ class DatagridMainRenderer {
17459
18087
  this.columnsService.emitStateChangeAt(index, state);
17460
18088
  });
17461
18089
  }
18090
+ columnStateChanged(state) {
18091
+ const columnIndex = state.columnIndex;
18092
+ if (state.changes && state.changes.length) {
18093
+ state.changes.forEach(change => {
18094
+ switch (change) {
18095
+ case DatagridColumnChanges.WIDTH:
18096
+ this.headers.get(columnIndex).setWidth(state);
18097
+ this.rows.forEach(row => {
18098
+ if (row.cells && row.cells.length) {
18099
+ row.cells.get(columnIndex).setWidth(state);
18100
+ }
18101
+ });
18102
+ break;
18103
+ case DatagridColumnChanges.HIDDEN:
18104
+ this.headers.get(columnIndex).setHidden(state);
18105
+ this.rows.forEach(row => {
18106
+ if (row.cells && row.cells.length) {
18107
+ row.cells.get(columnIndex).setHidden(state);
18108
+ }
18109
+ });
18110
+ this.keyNavigation.resetKeyGrid();
18111
+ break;
18112
+ default:
18113
+ break;
18114
+ }
18115
+ });
18116
+ }
18117
+ }
18118
+ listenForColumnChanges() {
18119
+ this.columnsService.columns.forEach((column, index) => {
18120
+ this.columnsService.emitStateChange(column, { changes: [], columnIndex: index });
18121
+ });
18122
+ /*
18123
+ Merges all column subject so we can track them at once
18124
+ and receive only the changed column as result
18125
+ */
18126
+ const columnChanges = merge(...this.columnsService.columns);
18127
+ this.subscriptions.push(columnChanges.subscribe(change => this.columnStateChanged(change)));
18128
+ }
17462
18129
  /**
17463
18130
  * Triggers a whole re-rendring cycle to set column sizes, if needed.
17464
18131
  */
@@ -17475,7 +18142,7 @@ class DatagridMainRenderer {
17475
18142
  }
17476
18143
  }
17477
18144
  }
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 });
18145
+ 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
18146
  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
18147
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: DatagridMainRenderer, decorators: [{
17481
18148
  type: Directive,
@@ -17483,7 +18150,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
17483
18150
  selector: 'clr-datagrid',
17484
18151
  providers: [{ provide: DomAdapter, useFactory: domAdapterFactory, deps: [PLATFORM_ID] }],
17485
18152
  }]
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: [{
18153
+ }], 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
18154
  type: ContentChildren,
17488
18155
  args: [DatagridHeaderRenderer]
17489
18156
  }], rows: [{
@@ -17518,6 +18185,7 @@ const CLR_DATAGRID_DIRECTIVES = [
17518
18185
  ClrDatagridRow,
17519
18186
  ClrDatagridRowDetail,
17520
18187
  ClrDatagridSelectionCellDirective,
18188
+ ClrDatagridVirtualScrollDirective,
17521
18189
  ClrIfDetail,
17522
18190
  DatagridDetailRegisterer,
17523
18191
  WrappedCell,
@@ -17564,6 +18232,7 @@ ClrDatagridModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", versi
17564
18232
  ClrDatagridRow,
17565
18233
  ClrDatagridRowDetail,
17566
18234
  ClrDatagridSelectionCellDirective,
18235
+ ClrDatagridVirtualScrollDirective,
17567
18236
  ClrIfDetail,
17568
18237
  DatagridDetailRegisterer,
17569
18238
  WrappedCell,
@@ -17613,6 +18282,7 @@ ClrDatagridModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", versi
17613
18282
  ClrDatagridRow,
17614
18283
  ClrDatagridRowDetail,
17615
18284
  ClrDatagridSelectionCellDirective,
18285
+ ClrDatagridVirtualScrollDirective,
17616
18286
  ClrIfDetail,
17617
18287
  DatagridDetailRegisterer,
17618
18288
  WrappedCell,
@@ -22638,6 +23308,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
22638
23308
  args: [DOCUMENT]
22639
23309
  }] }]; } });
22640
23310
 
23311
+ /*
23312
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
23313
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
23314
+ * This software is released under MIT license.
23315
+ * The full license information can be found in LICENSE in the root directory of this project.
23316
+ */
23317
+ class ClrModalConfigurationService {
23318
+ constructor() {
23319
+ this.fadeMove = 'fadeDown';
23320
+ this.backdrop = true;
23321
+ }
23322
+ }
23323
+ ClrModalConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModalConfigurationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
23324
+ ClrModalConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModalConfigurationService });
23325
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModalConfigurationService, decorators: [{
23326
+ type: Injectable
23327
+ }] });
23328
+
22641
23329
  /*
22642
23330
  * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
22643
23331
  * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
@@ -22645,10 +23333,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
22645
23333
  * The full license information can be found in LICENSE in the root directory of this project.
22646
23334
  */
22647
23335
  class ClrModal {
22648
- constructor(_scrollingService, commonStrings, modalStackService) {
23336
+ constructor(_scrollingService, commonStrings, modalStackService, configuration) {
22649
23337
  this._scrollingService = _scrollingService;
22650
23338
  this.commonStrings = commonStrings;
22651
23339
  this.modalStackService = modalStackService;
23340
+ this.configuration = configuration;
22652
23341
  this.modalId = uniqueIdFactory();
22653
23342
  this._open = false;
22654
23343
  this._openChanged = new EventEmitter(false);
@@ -22658,13 +23347,23 @@ class ClrModal {
22658
23347
  this.skipAnimation = 'false';
22659
23348
  this.stopClose = false;
22660
23349
  this.altClose = new EventEmitter(false);
22661
- this.labelledBy = this.modalId;
23350
+ // presently this is only used by inline wizards
23351
+ this.bypassScrollService = false;
23352
+ }
23353
+ get fadeMove() {
23354
+ return this.skipAnimation ? '' : this.configuration.fadeMove;
23355
+ }
23356
+ set fadeMove(move) {
23357
+ this.configuration.fadeMove = move;
23358
+ }
23359
+ get backdrop() {
23360
+ return this.configuration.backdrop;
22662
23361
  }
22663
23362
  // Detect when _open is set to true and set no-scrolling to true
22664
23363
  ngOnChanges(changes) {
22665
- if (changes && Object.prototype.hasOwnProperty.call(changes, '_open')) {
23364
+ if (!this.bypassScrollService && changes && Object.prototype.hasOwnProperty.call(changes, '_open')) {
22666
23365
  if (changes._open.currentValue) {
22667
- this._scrollingService.stopScrolling();
23366
+ this.backdrop && this._scrollingService.stopScrolling();
22668
23367
  this.modalStackService.trackModalOpen(this);
22669
23368
  }
22670
23369
  else {
@@ -22701,11 +23400,18 @@ class ClrModal {
22701
23400
  }
22702
23401
  }
22703
23402
  }
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%)' }))]),
23403
+ 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 });
23404
+ 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: [
23405
+ trigger('fadeMove', [
23406
+ transition('* => fadeDown', [
23407
+ style({ opacity: 0, transform: 'translate(0, -25%)' }),
23408
+ animate('0.2s ease-in-out'),
23409
+ ]),
23410
+ transition('fadeDown => *', [
23411
+ animate('0.2s ease-in-out', style({ opacity: 0, transform: 'translate(0, -25%)' })),
23412
+ ]),
23413
+ transition('* => fadeLeft', [style({ opacity: 0, transform: 'translate(25%, 0)' }), animate('0.2s ease-in-out')]),
23414
+ transition('fadeLeft => *', [animate('0.2s ease-in-out', style({ opacity: 0, transform: 'translate(25%, 0)' }))]),
22709
23415
  ]),
22710
23416
  trigger('fade', [
22711
23417
  transition('void => *', [style({ opacity: 0 }), animate('0.2s ease-in-out', style({ opacity: 0.85 }))]),
@@ -22715,16 +23421,23 @@ ClrModal.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.
22715
23421
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModal, decorators: [{
22716
23422
  type: Component,
22717
23423
  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%)' }))]),
23424
+ trigger('fadeMove', [
23425
+ transition('* => fadeDown', [
23426
+ style({ opacity: 0, transform: 'translate(0, -25%)' }),
23427
+ animate('0.2s ease-in-out'),
23428
+ ]),
23429
+ transition('fadeDown => *', [
23430
+ animate('0.2s ease-in-out', style({ opacity: 0, transform: 'translate(0, -25%)' })),
23431
+ ]),
23432
+ transition('* => fadeLeft', [style({ opacity: 0, transform: 'translate(25%, 0)' }), animate('0.2s ease-in-out')]),
23433
+ transition('fadeLeft => *', [animate('0.2s ease-in-out', style({ opacity: 0, transform: 'translate(25%, 0)' }))]),
22721
23434
  ]),
22722
23435
  trigger('fade', [
22723
23436
  transition('void => *', [style({ opacity: 0 }), animate('0.2s ease-in-out', style({ opacity: 0.85 }))]),
22724
23437
  transition('* => void', [animate('0.2s ease-in-out', style({ opacity: 0 }))]),
22725
23438
  ]),
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: [{
23439
+ ], 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"] }]
23440
+ }], ctorParameters: function () { return [{ type: ScrollingService }, { type: ClrCommonStringsService }, { type: ModalStackService }, { type: ClrModalConfigurationService }]; }, propDecorators: { _open: [{
22728
23441
  type: Input,
22729
23442
  args: ['clrModalOpen']
22730
23443
  }, {
@@ -22757,6 +23470,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
22757
23470
  }], labelledBy: [{
22758
23471
  type: Input,
22759
23472
  args: ['clrModalLabelledById']
23473
+ }], bypassScrollService: [{
23474
+ type: Input,
23475
+ args: ['clrModalOverrideScrollService']
22760
23476
  }] } });
22761
23477
 
22762
23478
  /*
@@ -22836,16 +23552,122 @@ class ClrModalModule {
22836
23552
  }
22837
23553
  ClrModalModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModalModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
22838
23554
  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] });
23555
+ ClrModalModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModalModule, providers: [ClrModalConfigurationService], imports: [CommonModule, CdkTrapFocusModule, ClrIconModule, ClrIconModule] });
22840
23556
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrModalModule, decorators: [{
22841
23557
  type: NgModule,
22842
23558
  args: [{
22843
23559
  imports: [CommonModule, CdkTrapFocusModule, ClrIconModule],
22844
23560
  declarations: [CLR_MODAL_DIRECTIVES],
22845
23561
  exports: [CLR_MODAL_DIRECTIVES, ClrIconModule],
23562
+ providers: [ClrModalConfigurationService],
22846
23563
  }]
22847
23564
  }], ctorParameters: function () { return []; } });
22848
23565
 
23566
+ /*
23567
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
23568
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
23569
+ * This software is released under MIT license.
23570
+ * The full license information can be found in LICENSE in the root directory of this project.
23571
+ */
23572
+ class ClrSidePanel {
23573
+ constructor(element, configuration) {
23574
+ this.element = element;
23575
+ this.configuration = configuration;
23576
+ this._open = false;
23577
+ this.openChange = new EventEmitter(false);
23578
+ this.skipAnimation = 'false';
23579
+ this.staticBackdrop = false;
23580
+ this.preventClose = false;
23581
+ this.altClose = new EventEmitter(false);
23582
+ }
23583
+ get clrSidePanelBackdrop() {
23584
+ return this.configuration.backdrop;
23585
+ }
23586
+ set clrSidePanelBackdrop(backdrop) {
23587
+ if (backdrop !== undefined) {
23588
+ this.configuration.backdrop = backdrop;
23589
+ }
23590
+ }
23591
+ ngOnInit() {
23592
+ this.configuration.fadeMove = 'fadeLeft';
23593
+ }
23594
+ open() {
23595
+ this.modal.open();
23596
+ }
23597
+ close() {
23598
+ this.modal.close();
23599
+ }
23600
+ documentClick(event) {
23601
+ if (!this.element.nativeElement.contains(event.target) && this.modal._open && !this.configuration.backdrop) {
23602
+ this.modal.close();
23603
+ }
23604
+ }
23605
+ }
23606
+ 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 });
23607
+ 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" }] });
23608
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrSidePanel, decorators: [{
23609
+ type: Component,
23610
+ args: [{ selector: 'clr-side-panel', host: {
23611
+ '[class.side-panel]': 'true',
23612
+ }, 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" }]
23613
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: ClrModalConfigurationService }]; }, propDecorators: { _open: [{
23614
+ type: Input,
23615
+ args: ['clrSidePanelOpen']
23616
+ }], openChange: [{
23617
+ type: Output,
23618
+ args: ['clrSidePanelOpenChange']
23619
+ }], closeButtonAriaLabel: [{
23620
+ type: Input,
23621
+ args: ['clrSidePanelCloseButtonAriaLabel']
23622
+ }], size: [{
23623
+ type: Input,
23624
+ args: ['clrSidePanelSize']
23625
+ }], skipAnimation: [{
23626
+ type: Input,
23627
+ args: ['clrSidePanelSkipAnimation']
23628
+ }], labelledById: [{
23629
+ type: Input,
23630
+ args: ['clrSidePanelLabelledById']
23631
+ }], staticBackdrop: [{
23632
+ type: Input,
23633
+ args: ['clrSidePanelStaticBackdrop']
23634
+ }], preventClose: [{
23635
+ type: Input,
23636
+ args: ['clrSidePanelPreventClose']
23637
+ }], altClose: [{
23638
+ type: Output,
23639
+ args: ['clrSidePanelAlternateClose']
23640
+ }], modal: [{
23641
+ type: ViewChild,
23642
+ args: [ClrModal]
23643
+ }], clrSidePanelBackdrop: [{
23644
+ type: Input
23645
+ }], documentClick: [{
23646
+ type: HostListener,
23647
+ args: ['document:pointerup', ['$event']]
23648
+ }] } });
23649
+
23650
+ /*
23651
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
23652
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
23653
+ * This software is released under MIT license.
23654
+ * The full license information can be found in LICENSE in the root directory of this project.
23655
+ */
23656
+ const CLR_SIDEPANEL_DIRECTIVES = [ClrSidePanel];
23657
+ class ClrSidePanelModule {
23658
+ }
23659
+ ClrSidePanelModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrSidePanelModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
23660
+ 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] });
23661
+ ClrSidePanelModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrSidePanelModule, imports: [CommonModule, CdkTrapFocusModule, ClrIconModule, ClrModalModule, ClrIconModule] });
23662
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrSidePanelModule, decorators: [{
23663
+ type: NgModule,
23664
+ args: [{
23665
+ imports: [CommonModule, CdkTrapFocusModule, ClrIconModule, ClrModalModule],
23666
+ declarations: [CLR_SIDEPANEL_DIRECTIVES],
23667
+ exports: [CLR_SIDEPANEL_DIRECTIVES, ClrIconModule],
23668
+ }]
23669
+ }] });
23670
+
22849
23671
  /*
22850
23672
  * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
22851
23673
  * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
@@ -25888,13 +26710,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
25888
26710
  * The full license information can be found in LICENSE in the root directory of this project.
25889
26711
  */
25890
26712
  class ClrWizard {
25891
- constructor(platformId, commonStrings, navService, pageCollection, buttonService, headerActionService, differs) {
26713
+ constructor(platformId, commonStrings, navService, pageCollection, buttonService, headerActionService, elementRef, differs) {
25892
26714
  this.platformId = platformId;
25893
26715
  this.commonStrings = commonStrings;
25894
26716
  this.navService = navService;
25895
26717
  this.pageCollection = pageCollection;
25896
26718
  this.buttonService = buttonService;
25897
26719
  this.headerActionService = headerActionService;
26720
+ this.elementRef = elementRef;
25898
26721
  /**
25899
26722
  * Set the aria-label for the stepnav section of the wizard. Set using `[clrWizardStepnavAriaLabel]` input.
25900
26723
  */
@@ -25908,6 +26731,12 @@ class ClrWizard {
25908
26731
  * in the top right corner. Set using `[clrWizardClosable]` input.
25909
26732
  */
25910
26733
  this.closable = true;
26734
+ /**
26735
+ * Used to communicate to the underlying modal that animations are not
26736
+ * wanted. Primary use is for the display of static/inline wizards.
26737
+ * Set using `[clrWizardPreventModalAnimation]` input.
26738
+ */
26739
+ this._stopModalAnimations = false;
25911
26740
  /**
25912
26741
  * Emits when the wizard is opened or closed.
25913
26742
  * Listen via `(clrWizardOpenChange)` event.
@@ -26046,9 +26875,16 @@ class ClrWizard {
26046
26875
  get isFirst() {
26047
26876
  return this.navService.currentPageIsFirst;
26048
26877
  }
26878
+ get isInline() {
26879
+ return this.elementRef.nativeElement.classList.contains('clr-wizard--inline');
26880
+ }
26881
+ get stopModalAnimations() {
26882
+ return this._stopModalAnimations ? 'true' : 'false';
26883
+ }
26049
26884
  ngAfterContentInit() {
26050
26885
  this.pageCollection.pages = this.pages;
26051
26886
  this.headerActionService.wizardHeaderActions = this.headerActions;
26887
+ this.initializeButtons();
26052
26888
  }
26053
26889
  ngDoCheck() {
26054
26890
  this.updateNavOnPageChanges();
@@ -26250,6 +27086,12 @@ class ClrWizard {
26250
27086
  changes.forEachRemovedItem(() => this.navService.updateNavigation());
26251
27087
  }
26252
27088
  }
27089
+ initializeButtons() {
27090
+ // Only trigger buttons ready if default is open (inlined)
27091
+ if (this._open) {
27092
+ this.buttonService.buttonsReady = true;
27093
+ }
27094
+ }
26253
27095
  emitWizardFinished() {
26254
27096
  if (!this.stopNext) {
26255
27097
  this.forceFinish();
@@ -26257,8 +27099,8 @@ class ClrWizard {
26257
27099
  this.wizardFinished.emit();
26258
27100
  }
26259
27101
  }
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" }] });
27102
+ 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 });
27103
+ 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
27104
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrWizard, decorators: [{
26263
27105
  type: Component,
26264
27106
  args: [{ selector: 'clr-wizard', providers: [WizardNavigationService, PageCollectionService, ButtonHubService, HeaderActionService], host: {
@@ -26267,11 +27109,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
26267
27109
  '[class.wizard-lg]': "size == 'lg'",
26268
27110
  '[class.wizard-xl]': "size == 'xl'",
26269
27111
  '[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" }]
27112
+ }, 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
27113
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
26272
27114
  type: Inject,
26273
27115
  args: [PLATFORM_ID]
26274
- }] }, { type: ClrCommonStringsService }, { type: WizardNavigationService }, { type: PageCollectionService }, { type: ButtonHubService }, { type: HeaderActionService }, { type: i0.IterableDiffers }]; }, propDecorators: { stepnavAriaLabel: [{
27116
+ }] }, { type: ClrCommonStringsService }, { type: WizardNavigationService }, { type: PageCollectionService }, { type: ButtonHubService }, { type: HeaderActionService }, { type: i0.ElementRef }, { type: i0.IterableDiffers }]; }, propDecorators: { stepnavAriaLabel: [{
26275
27117
  type: Input,
26276
27118
  args: ['clrWizardStepnavAriaLabel']
26277
27119
  }], size: [{
@@ -26280,6 +27122,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
26280
27122
  }], closable: [{
26281
27123
  type: Input,
26282
27124
  args: ['clrWizardClosable']
27125
+ }], _stopModalAnimations: [{
27126
+ type: Input,
27127
+ args: ['clrWizardPreventModalAnimation']
26283
27128
  }], _openChanged: [{
26284
27129
  type: Output,
26285
27130
  args: ['clrWizardOpenChange']
@@ -26594,6 +27439,7 @@ ClarityModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version:
26594
27439
  ClrLayoutModule,
26595
27440
  ClrPopoverModule,
26596
27441
  ClrWizardModule,
27442
+ ClrSidePanelModule,
26597
27443
  ClrStepperModule,
26598
27444
  ClrSpinnerModule,
26599
27445
  ClrProgressBarModule,
@@ -26611,6 +27457,7 @@ ClarityModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version:
26611
27457
  ClrLayoutModule,
26612
27458
  ClrPopoverModule,
26613
27459
  ClrWizardModule,
27460
+ ClrSidePanelModule,
26614
27461
  ClrStepperModule,
26615
27462
  ClrSpinnerModule,
26616
27463
  ClrProgressBarModule,
@@ -26632,6 +27479,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
26632
27479
  ClrLayoutModule,
26633
27480
  ClrPopoverModule,
26634
27481
  ClrWizardModule,
27482
+ ClrSidePanelModule,
26635
27483
  ClrStepperModule,
26636
27484
  ClrSpinnerModule,
26637
27485
  ClrProgressBarModule,
@@ -26970,5 +27818,5 @@ const CLR_MENU_POSITIONS = [
26970
27818
  * Generated bundle index. Do not edit.
26971
27819
  */
26972
27820
 
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 };
27821
+ 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
27822
  //# sourceMappingURL=clr-angular.mjs.map