@clr/angular 15.14.2 → 15.14.5

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.
@@ -3,7 +3,7 @@ import { Directive, NgModule, Optional, Input, Injectable, Component, ChangeDete
3
3
  import * as i5 from '@angular/common';
4
4
  import { CommonModule, isPlatformBrowser, DOCUMENT, NgForOf, getLocaleDayNames, FormStyle, TranslationWidth, getLocaleMonthNames, getLocaleFirstDayOfWeek, getLocaleDateFormat, FormatWidth } from '@angular/common';
5
5
  import { ClarityIcons, angleIcon, exclamationCircleIcon, checkCircleIcon, ellipsisHorizontalIcon, windowCloseIcon, eventIcon, calendarIcon, eyeHideIcon, eyeIcon, ellipsisVerticalIcon, viewColumnsIcon, arrowIcon, timesIcon, stepForward2Icon, angleDoubleIcon, filterGridCircleIcon, filterGridIcon, infoCircleIcon, exclamationTriangleIcon, circleIcon, dotCircleIcon, errorStandardIcon, successStandardIcon } from '@cds/core/icon';
6
- import { map, tap, startWith, distinctUntilChanged, pairwise, filter, debounceTime, takeUntil, take, first, switchMap } from 'rxjs/operators';
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';
@@ -361,8 +361,8 @@ const commonStringsDefault = {
361
361
  * Password Input
362
362
  * Screen-reader text for the hide/show password field button
363
363
  */
364
- passwordHide: 'Hide password',
365
- passwordShow: 'Show password',
364
+ passwordHide: 'Hide password for {LABEL}',
365
+ passwordShow: 'Show password for {LABEL}',
366
366
  /**
367
367
  * Datagrid footer; sr-only text after the number of selected rows.
368
368
  */
@@ -941,6 +941,12 @@ class StepperModel extends AccordionModel {
941
941
  }
942
942
  });
943
943
  }
944
+ setPanelValid(panelId) {
945
+ this._panels[panelId].status = AccordionStatus.Complete;
946
+ }
947
+ setPanelInvalid(panelId) {
948
+ this._panels[panelId].status = AccordionStatus.Error;
949
+ }
944
950
  setPanelsWithErrors(ids) {
945
951
  ids.forEach(id => this.setPanelError(id));
946
952
  }
@@ -1021,6 +1027,14 @@ class StepperService extends AccordionService {
1021
1027
  this.accordion.resetPanels();
1022
1028
  this.emitUpdatedPanels();
1023
1029
  }
1030
+ setPanelValid(panelId) {
1031
+ this.accordion.setPanelValid(panelId);
1032
+ this.emitUpdatedPanels();
1033
+ }
1034
+ setPanelInvalid(panelId) {
1035
+ this.accordion.setPanelInvalid(panelId);
1036
+ this.emitUpdatedPanels();
1037
+ }
1024
1038
  setPanelsWithErrors(ids) {
1025
1039
  this.accordion.setPanelsWithErrors(ids);
1026
1040
  this.emitUpdatedPanels();
@@ -1083,11 +1097,16 @@ class ClrStepperPanel extends ClrAccordionPanel {
1083
1097
  this.panel = this.panel.pipe(tap(panel => this.triggerAllFormControlValidationIfError(panel)));
1084
1098
  this.stepperService.disablePanel(this.id, true);
1085
1099
  this.listenToFocusChanges();
1100
+ // not all stepper panels are guaranteed to have a form (i.e. empty template-driven)
1086
1101
  if (this.formGroup) {
1087
- // not all stepper panels are guaranteed to have a form (i.e. empty template-driven)
1088
- this.subscriptions.push(this.formGroup.statusChanges.pipe(pairwise()).subscribe(([prevStatus, newStatus]) => {
1089
- if ('VALID' === prevStatus && 'INVALID' === newStatus) {
1090
- this.stepperService.navigateToNextPanel(this.id, this.formGroup.valid);
1102
+ // set panel status on form status change only after the form becomes invalid
1103
+ const invalidStatusTrigger = this.formGroup.statusChanges.pipe(filter(status => status === 'INVALID'));
1104
+ this.subscriptions.push(this.formGroup.statusChanges.pipe(skipUntil(invalidStatusTrigger), distinctUntilChanged()).subscribe(status => {
1105
+ if (status === 'VALID') {
1106
+ this.stepperService.setPanelValid(this.id);
1107
+ }
1108
+ else if (status === 'INVALID') {
1109
+ this.stepperService.setPanelInvalid(this.id);
1091
1110
  }
1092
1111
  }));
1093
1112
  }
@@ -1933,12 +1952,12 @@ class ClrPopoverPositionService {
1933
1952
  *
1934
1953
  * Note, more than 3 viewport violations and there isn't anything we can do to help. Also when there are two
1935
1954
  * violations, we can't help if the violations are TOP+BOTTOM || LEFT+RIGHT => There is no transformation we
1936
- * can make to the postion that will help.
1955
+ * can make to the position that will help.
1937
1956
  *
1938
1957
  * Some examples:
1939
1958
  * There is only one error and Primary axis is VERTICAL
1940
1959
  * - this.handleVerticalAxisOneViolation has a switch that will use the error sum to apply the correct
1941
- * transform to the postion based on the reduction of visibilityViolations.
1960
+ * transform to the position based on the reduction of visibilityViolations.
1942
1961
  *
1943
1962
  * There are two errors and Primary axis is HORIZONTAL
1944
1963
  * - handleHorizontalAxisTwoViolations has a switch that uses the error sum to apply both transforms needed to
@@ -1970,6 +1989,14 @@ class ClrPopoverPositionService {
1970
1989
  if (this.currentContentCoords.top < 0) {
1971
1990
  this.contentOffsets.yOffset += Math.abs(this.currentContentCoords.top);
1972
1991
  }
1992
+ /**
1993
+ * This detects the condition where the popover is flipped because it would violate the bottom of the viewport, but flipping it results in the
1994
+ * popover rendering above the top of the body (y coordinate outside the body). In that event, it should be rendered within the body
1995
+ * as much as possible, so this logic sets the top of popover to render touching the top of the body.
1996
+ */
1997
+ if (this.contentOffsets.yOffset + this.currentAnchorCoords.y < 0) {
1998
+ this.contentOffsets.yOffset = 0 - this.currentContentCoords.top;
1999
+ }
1973
2000
  return this.contentOffsets;
1974
2001
  }
1975
2002
  handleVerticalAxisOneViolation(errorSum) {
@@ -3901,7 +3928,7 @@ class ClrLoadingButton {
3901
3928
  }
3902
3929
  ClrLoadingButton.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrLoadingButton, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
3903
3930
  ClrLoadingButton.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrLoadingButton, selector: "button[clrLoading]", inputs: { disabled: "disabled" }, outputs: { clrLoadingChange: "clrLoadingChange" }, host: { properties: { "attr.disabled": "disabled? '' : null" } }, providers: [{ provide: LoadingListener, useExisting: ClrLoadingButton }], ngImport: i0, template: `
3904
- <div @parent [ngSwitch]="state">
3931
+ <span @parent [ngSwitch]="state">
3905
3932
  <span *ngSwitchCase="buttonState.LOADING">
3906
3933
  <span @spinner class="spinner spinner-inline"></span>
3907
3934
  </span>
@@ -3915,7 +3942,7 @@ ClrLoadingButton.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", versi
3915
3942
  <span *ngSwitchCase="buttonState.DEFAULT" @defaultButton>
3916
3943
  <ng-content></ng-content>
3917
3944
  </span>
3918
- </div>
3945
+ </span>
3919
3946
  `, isInline: true, dependencies: [{ kind: "directive", type: i5.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i5.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }], animations: [
3920
3947
  trigger('parent', [
3921
3948
  // Skip :enter animation on first render.
@@ -3949,7 +3976,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
3949
3976
  args: [{
3950
3977
  selector: 'button[clrLoading]',
3951
3978
  template: `
3952
- <div @parent [ngSwitch]="state">
3979
+ <span @parent [ngSwitch]="state">
3953
3980
  <span *ngSwitchCase="buttonState.LOADING">
3954
3981
  <span @spinner class="spinner spinner-inline"></span>
3955
3982
  </span>
@@ -3963,7 +3990,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
3963
3990
  <span *ngSwitchCase="buttonState.DEFAULT" @defaultButton>
3964
3991
  <ng-content></ng-content>
3965
3992
  </span>
3966
- </div>
3993
+ </span>
3967
3994
  `,
3968
3995
  providers: [{ provide: LoadingListener, useExisting: ClrLoadingButton }],
3969
3996
  animations: [
@@ -7134,25 +7161,24 @@ class ClrOptionItems {
7134
7161
  if (!this._rawItems || this.filter === undefined || this.filter === null) {
7135
7162
  return;
7136
7163
  }
7164
+ const normalizedFilterValue = normalizeValue(this.filter);
7137
7165
  if (this.optionService.showAllOptions) {
7138
7166
  this.filteredItems = this._rawItems;
7139
7167
  }
7140
7168
  else if (this._filterField) {
7141
7169
  this.filteredItems = this._rawItems.filter(item => {
7142
7170
  const objValue = item[this._filterField];
7143
- return objValue ? objValue.toString().toLowerCase().indexOf(this.filter.toLowerCase().toString()) > -1 : false;
7171
+ return objValue ? normalizeValue(objValue).includes(normalizedFilterValue) : false;
7144
7172
  });
7145
7173
  }
7146
7174
  else {
7147
7175
  // Filter by all item object values
7148
7176
  this.filteredItems = this._rawItems.filter(item => {
7149
7177
  if (typeof item !== 'object') {
7150
- return item.toString().toLowerCase().indexOf(this.filter.toString().toLowerCase()) > -1;
7178
+ return normalizeValue(item).includes(normalizedFilterValue);
7151
7179
  }
7152
7180
  const objValues = Object.values(item).filter(value => {
7153
- return value !== null && value !== undefined
7154
- ? value.toString().toLowerCase().indexOf(this.filter.toString().toLowerCase()) > -1
7155
- : false;
7181
+ return value !== null && value !== undefined ? normalizeValue(value).includes(normalizedFilterValue) : false;
7156
7182
  });
7157
7183
  return objValues.length > 0;
7158
7184
  });
@@ -7177,6 +7203,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
7177
7203
  type: Input,
7178
7204
  args: ['clrOptionItemsField']
7179
7205
  }] } });
7206
+ function normalizeValue(value) {
7207
+ return value
7208
+ .toString()
7209
+ .normalize('NFD')
7210
+ .replace(/\p{Diacritic}/gu, '')
7211
+ .toLowerCase();
7212
+ }
7180
7213
 
7181
7214
  /*
7182
7215
  * Copyright (c) 2016-2023 VMware, Inc. All Rights Reserved.
@@ -8381,7 +8414,7 @@ class DateIOService {
8381
8414
  return '';
8382
8415
  }
8383
8416
  getDateValueFromDateString(date) {
8384
- if (!date) {
8417
+ if (!date || typeof date !== 'string') {
8385
8418
  return null;
8386
8419
  }
8387
8420
  const dateParts = date.match(USER_INPUT_REGEX);
@@ -9968,6 +10001,12 @@ class ClrPasswordContainer extends ClrAbstractContainer {
9968
10001
  this.show = !this.show;
9969
10002
  this.toggleService.next(this.show);
9970
10003
  }
10004
+ showPasswordText(label) {
10005
+ return this.commonStrings.parse(this.commonStrings.keys.passwordShow, { LABEL: label });
10006
+ }
10007
+ hidePasswordText(label) {
10008
+ return this.commonStrings.parse(this.commonStrings.keys.passwordHide, { LABEL: label });
10009
+ }
9971
10010
  }
9972
10011
  ClrPasswordContainer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrPasswordContainer, deps: [{ token: IfControlStateService }, { token: LayoutService, optional: true }, { token: ControlClassService }, { token: NgControlService }, { token: FocusService }, { token: TOGGLE_SERVICE }, { token: ClrCommonStringsService }], target: i0.ɵɵFactoryTarget.Component });
9973
10012
  ClrPasswordContainer.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrPasswordContainer, selector: "clr-password-container", inputs: { clrToggle: "clrToggle" }, host: { properties: { "class.clr-form-control": "true", "class.clr-form-control-disabled": "control?.disabled", "class.clr-row": "addGrid()" } }, providers: [
@@ -9993,7 +10032,7 @@ ClrPasswordContainer.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", v
9993
10032
  >
9994
10033
  <cds-icon status="info" class="clr-password-eye-icon" [attr.shape]="show ? 'eye-hide' : 'eye'"></cds-icon>
9995
10034
  <span class="clr-sr-only">
9996
- {{ show ? commonStrings.keys.passwordHide : commonStrings.keys.passwordShow }}
10035
+ {{ show ? hidePasswordText(label?.labelText) : showPasswordText(label?.labelText) }}
9997
10036
  </span>
9998
10037
  </button>
9999
10038
  </div>
@@ -10037,7 +10076,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
10037
10076
  >
10038
10077
  <cds-icon status="info" class="clr-password-eye-icon" [attr.shape]="show ? 'eye-hide' : 'eye'"></cds-icon>
10039
10078
  <span class="clr-sr-only">
10040
- {{ show ? commonStrings.keys.passwordHide : commonStrings.keys.passwordShow }}
10079
+ {{ show ? hidePasswordText(label?.labelText) : showPasswordText(label?.labelText) }}
10041
10080
  </span>
10042
10081
  </button>
10043
10082
  </div>
@@ -13541,6 +13580,7 @@ class ClrSignpostTrigger {
13541
13580
  this.signpostIdService = signpostIdService;
13542
13581
  this.signpostFocusManager = signpostFocusManager;
13543
13582
  this.platformId = platformId;
13583
+ this.ariaExpanded = false;
13544
13584
  this.subscriptions = [];
13545
13585
  this.document = document;
13546
13586
  }
@@ -22437,7 +22477,7 @@ ClrSignpostContent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", ver
22437
22477
  <cds-icon shape="window-close" [attr.title]="commonStrings.keys.close"></cds-icon>
22438
22478
  </button>
22439
22479
  </div>
22440
- <div class="signpost-content-body">
22480
+ <div class="signpost-content-body" tabindex="0">
22441
22481
  <ng-content></ng-content>
22442
22482
  </div>
22443
22483
  </div>
@@ -22460,7 +22500,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
22460
22500
  <cds-icon shape="window-close" [attr.title]="commonStrings.keys.close"></cds-icon>
22461
22501
  </button>
22462
22502
  </div>
22463
- <div class="signpost-content-body">
22503
+ <div class="signpost-content-body" tabindex="0">
22464
22504
  <ng-content></ng-content>
22465
22505
  </div>
22466
22506
  </div>