@clr/angular 17.0.0-beta.2 → 17.0.0-beta.4

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 (33) hide show
  1. package/README.md +4 -0
  2. package/accordion/stepper/models/stepper.model.d.ts +2 -0
  3. package/accordion/stepper/providers/stepper.service.d.ts +2 -0
  4. package/clarity.api.md +4 -0
  5. package/data/datagrid/datagrid-if-expanded.service.d.ts +1 -1
  6. package/esm2020/accordion/stepper/models/stepper.model.mjs +7 -1
  7. package/esm2020/accordion/stepper/providers/stepper.service.mjs +9 -1
  8. package/esm2020/accordion/stepper/stepper-panel.mjs +11 -6
  9. package/esm2020/button/button-loading/loading-button.mjs +5 -5
  10. package/esm2020/data/datagrid/datagrid-if-expanded.service.mjs +1 -1
  11. package/esm2020/emphasis/alert/alert.mjs +2 -6
  12. package/esm2020/emphasis/alert/alert.module.mjs +3 -3
  13. package/esm2020/emphasis/alert/providers/icon-and-types.service.mjs +6 -6
  14. package/esm2020/forms/combobox/option-items.directive.mjs +12 -6
  15. package/esm2020/forms/datepicker/providers/date-io.service.mjs +2 -2
  16. package/esm2020/forms/password/password-container.mjs +9 -3
  17. package/esm2020/popover/signpost/signpost-trigger.mjs +2 -1
  18. package/esm2020/utils/chocolate/willy-wonka.mjs +1 -1
  19. package/esm2020/utils/focus/key-focus/key-focus.mjs +2 -2
  20. package/esm2020/utils/i18n/common-strings.default.mjs +3 -3
  21. package/esm2020/utils/popover/providers/popover-position.service.mjs +11 -3
  22. package/esm2020/wizard/providers/button-hub.service.mjs +1 -1
  23. package/esm2020/wizard/providers/wizard-navigation.service.mjs +1 -1
  24. package/esm2020/wizard/wizard.mjs +2 -2
  25. package/fesm2015/clr-angular.mjs +71 -35
  26. package/fesm2015/clr-angular.mjs.map +1 -1
  27. package/fesm2020/clr-angular.mjs +71 -35
  28. package/fesm2020/clr-angular.mjs.map +1 -1
  29. package/forms/password/password-container.d.ts +2 -0
  30. package/package.json +3 -3
  31. package/utils/chocolate/willy-wonka.d.ts +1 -1
  32. package/wizard/providers/button-hub.service.d.ts +6 -6
  33. package/wizard/providers/wizard-navigation.service.d.ts +1 -1
@@ -2,8 +2,8 @@ import * as i0 from '@angular/core';
2
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';
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, 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';
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';
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';
@@ -365,8 +365,8 @@ const commonStringsDefault = {
365
365
  * Password Input
366
366
  * Screen-reader text for the hide/show password field button
367
367
  */
368
- passwordHide: 'Hide password',
369
- passwordShow: 'Show password',
368
+ passwordHide: 'Hide password for {LABEL}',
369
+ passwordShow: 'Show password for {LABEL}',
370
370
  /**
371
371
  * Datagrid footer; sr-only text after the number of selected rows.
372
372
  */
@@ -951,6 +951,12 @@ class StepperModel extends AccordionModel {
951
951
  }
952
952
  });
953
953
  }
954
+ setPanelValid(panelId) {
955
+ this._panels[panelId].status = AccordionStatus.Complete;
956
+ }
957
+ setPanelInvalid(panelId) {
958
+ this._panels[panelId].status = AccordionStatus.Error;
959
+ }
954
960
  setPanelsWithErrors(ids) {
955
961
  ids.forEach(id => this.setPanelError(id));
956
962
  }
@@ -1034,6 +1040,14 @@ class StepperService extends AccordionService {
1034
1040
  this.accordion.resetPanels();
1035
1041
  this.emitUpdatedPanels();
1036
1042
  }
1043
+ setPanelValid(panelId) {
1044
+ this.accordion.setPanelValid(panelId);
1045
+ this.emitUpdatedPanels();
1046
+ }
1047
+ setPanelInvalid(panelId) {
1048
+ this.accordion.setPanelInvalid(panelId);
1049
+ this.emitUpdatedPanels();
1050
+ }
1037
1051
  setPanelsWithErrors(ids) {
1038
1052
  this.accordion.setPanelsWithErrors(ids);
1039
1053
  this.emitUpdatedPanels();
@@ -1096,11 +1110,16 @@ class ClrStepperPanel extends ClrAccordionPanel {
1096
1110
  this.panel = this.panel.pipe(tap(panel => this.triggerAllFormControlValidationIfError(panel)));
1097
1111
  this.stepperService.disablePanel(this.id, true);
1098
1112
  this.listenToFocusChanges();
1113
+ // not all stepper panels are guaranteed to have a form (i.e. empty template-driven)
1099
1114
  if (this.formGroup) {
1100
- // not all stepper panels are guaranteed to have a form (i.e. empty template-driven)
1101
- this.subscriptions.push(this.formGroup.statusChanges.pipe(pairwise()).subscribe(([prevStatus, newStatus]) => {
1102
- if ('VALID' === prevStatus && 'INVALID' === newStatus) {
1103
- this.stepperService.navigateToNextPanel(this.id, this.formGroup.valid);
1115
+ // set panel status on form status change only after the form becomes invalid
1116
+ const invalidStatusTrigger = this.formGroup.statusChanges.pipe(filter(status => status === 'INVALID'));
1117
+ this.subscriptions.push(this.formGroup.statusChanges.pipe(skipUntil(invalidStatusTrigger), distinctUntilChanged()).subscribe(status => {
1118
+ if (status === 'VALID') {
1119
+ this.stepperService.setPanelValid(this.id);
1120
+ }
1121
+ else if (status === 'INVALID') {
1122
+ this.stepperService.setPanelInvalid(this.id);
1104
1123
  }
1105
1124
  }));
1106
1125
  }
@@ -1945,12 +1964,12 @@ class ClrPopoverPositionService {
1945
1964
  *
1946
1965
  * Note, more than 3 viewport violations and there isn't anything we can do to help. Also when there are two
1947
1966
  * violations, we can't help if the violations are TOP+BOTTOM || LEFT+RIGHT => There is no transformation we
1948
- * can make to the postion that will help.
1967
+ * can make to the position that will help.
1949
1968
  *
1950
1969
  * Some examples:
1951
1970
  * There is only one error and Primary axis is VERTICAL
1952
1971
  * - this.handleVerticalAxisOneViolation has a switch that will use the error sum to apply the correct
1953
- * transform to the postion based on the reduction of visibilityViolations.
1972
+ * transform to the position based on the reduction of visibilityViolations.
1954
1973
  *
1955
1974
  * There are two errors and Primary axis is HORIZONTAL
1956
1975
  * - handleHorizontalAxisTwoViolations has a switch that uses the error sum to apply both transforms needed to
@@ -1982,6 +2001,14 @@ class ClrPopoverPositionService {
1982
2001
  if (this.currentContentCoords.top < 0) {
1983
2002
  this.contentOffsets.yOffset += Math.abs(this.currentContentCoords.top);
1984
2003
  }
2004
+ /**
2005
+ * This detects the condition where the popover is flipped because it would violate the bottom of the viewport, but flipping it results in the
2006
+ * popover rendering above the top of the body (y coordinate outside the body). In that event, it should be rendered within the body
2007
+ * as much as possible, so this logic sets the top of popover to render touching the top of the body.
2008
+ */
2009
+ if (this.contentOffsets.yOffset + this.currentAnchorCoords.y < 0) {
2010
+ this.contentOffsets.yOffset = 0 - this.currentContentCoords.top;
2011
+ }
1985
2012
  return this.contentOffsets;
1986
2013
  }
1987
2014
  handleVerticalAxisOneViolation(errorSum) {
@@ -3914,7 +3941,7 @@ class ClrLoadingButton {
3914
3941
  }
3915
3942
  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 });
3916
3943
  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: `
3917
- <div @parent [ngSwitch]="state">
3944
+ <span @parent [ngSwitch]="state">
3918
3945
  <span *ngSwitchCase="buttonState.LOADING">
3919
3946
  <span @spinner class="spinner spinner-inline"></span>
3920
3947
  </span>
@@ -3928,7 +3955,7 @@ ClrLoadingButton.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", versi
3928
3955
  <span *ngSwitchCase="buttonState.DEFAULT" @defaultButton>
3929
3956
  <ng-content></ng-content>
3930
3957
  </span>
3931
- </div>
3958
+ </span>
3932
3959
  `, isInline: true, dependencies: [{ kind: "directive", type: i5.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i5.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }], animations: [
3933
3960
  trigger('parent', [
3934
3961
  // Skip :enter animation on first render.
@@ -3962,7 +3989,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
3962
3989
  args: [{
3963
3990
  selector: 'button[clrLoading]',
3964
3991
  template: `
3965
- <div @parent [ngSwitch]="state">
3992
+ <span @parent [ngSwitch]="state">
3966
3993
  <span *ngSwitchCase="buttonState.LOADING">
3967
3994
  <span @spinner class="spinner spinner-inline"></span>
3968
3995
  </span>
@@ -3976,7 +4003,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
3976
4003
  <span *ngSwitchCase="buttonState.DEFAULT" @defaultButton>
3977
4004
  <ng-content></ng-content>
3978
4005
  </span>
3979
- </div>
4006
+ </span>
3980
4007
  `,
3981
4008
  providers: [{ provide: LoadingListener, useExisting: ClrLoadingButton }],
3982
4009
  animations: [
@@ -5808,7 +5835,7 @@ class ClrKeyFocus {
5808
5835
  }
5809
5836
  if (this.focusOnLoad) {
5810
5837
  this.currentItem.focus();
5811
- this.focusChange.next();
5838
+ this.focusChange.emit();
5812
5839
  }
5813
5840
  }
5814
5841
  }
@@ -7194,25 +7221,24 @@ class ClrOptionItems {
7194
7221
  if (!this._rawItems || this.filter === undefined || this.filter === null) {
7195
7222
  return;
7196
7223
  }
7224
+ const normalizedFilterValue = normalizeValue(this.filter);
7197
7225
  if (this.optionService.showAllOptions) {
7198
7226
  this.filteredItems = this._rawItems;
7199
7227
  }
7200
7228
  else if (this._filterField) {
7201
7229
  this.filteredItems = this._rawItems.filter(item => {
7202
7230
  const objValue = item[this._filterField];
7203
- return objValue ? objValue.toString().toLowerCase().indexOf(this.filter.toLowerCase().toString()) > -1 : false;
7231
+ return objValue ? normalizeValue(objValue).includes(normalizedFilterValue) : false;
7204
7232
  });
7205
7233
  }
7206
7234
  else {
7207
7235
  // Filter by all item object values
7208
7236
  this.filteredItems = this._rawItems.filter(item => {
7209
7237
  if (typeof item !== 'object') {
7210
- return item.toString().toLowerCase().indexOf(this.filter.toString().toLowerCase()) > -1;
7238
+ return normalizeValue(item).includes(normalizedFilterValue);
7211
7239
  }
7212
7240
  const objValues = Object.values(item).filter(value => {
7213
- return value !== null && value !== undefined
7214
- ? value.toString().toLowerCase().indexOf(this.filter.toString().toLowerCase()) > -1
7215
- : false;
7241
+ return value !== null && value !== undefined ? normalizeValue(value).includes(normalizedFilterValue) : false;
7216
7242
  });
7217
7243
  return objValues.length > 0;
7218
7244
  });
@@ -7237,6 +7263,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
7237
7263
  type: Input,
7238
7264
  args: ['clrOptionItemsField']
7239
7265
  }] } });
7266
+ function normalizeValue(value) {
7267
+ return value
7268
+ .toString()
7269
+ .normalize('NFD')
7270
+ .replace(/\p{Diacritic}/gu, '')
7271
+ .toLowerCase();
7272
+ }
7240
7273
 
7241
7274
  /*
7242
7275
  * Copyright (c) 2016-2023 VMware, Inc. All Rights Reserved.
@@ -8458,7 +8491,7 @@ class DateIOService {
8458
8491
  return '';
8459
8492
  }
8460
8493
  getDateValueFromDateString(date) {
8461
- if (!date) {
8494
+ if (!date || typeof date !== 'string') {
8462
8495
  return null;
8463
8496
  }
8464
8497
  const dateParts = date.match(USER_INPUT_REGEX);
@@ -10054,6 +10087,12 @@ class ClrPasswordContainer extends ClrAbstractContainer {
10054
10087
  this.show = !this.show;
10055
10088
  this.toggleService.next(this.show);
10056
10089
  }
10090
+ showPasswordText(label) {
10091
+ return this.commonStrings.parse(this.commonStrings.keys.passwordShow, { LABEL: label });
10092
+ }
10093
+ hidePasswordText(label) {
10094
+ return this.commonStrings.parse(this.commonStrings.keys.passwordHide, { LABEL: label });
10095
+ }
10057
10096
  }
10058
10097
  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 });
10059
10098
  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: [
@@ -10079,7 +10118,7 @@ ClrPasswordContainer.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", v
10079
10118
  >
10080
10119
  <cds-icon class="clr-password-eye-icon" [attr.shape]="show ? 'eye-hide' : 'eye'"></cds-icon>
10081
10120
  <span class="clr-sr-only">
10082
- {{ show ? commonStrings.keys.passwordHide : commonStrings.keys.passwordShow }}
10121
+ {{ show ? hidePasswordText(label?.labelText) : showPasswordText(label?.labelText) }}
10083
10122
  </span>
10084
10123
  </button>
10085
10124
  </div>
@@ -10123,7 +10162,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
10123
10162
  >
10124
10163
  <cds-icon class="clr-password-eye-icon" [attr.shape]="show ? 'eye-hide' : 'eye'"></cds-icon>
10125
10164
  <span class="clr-sr-only">
10126
- {{ show ? commonStrings.keys.passwordHide : commonStrings.keys.passwordShow }}
10165
+ {{ show ? hidePasswordText(label?.labelText) : showPasswordText(label?.labelText) }}
10127
10166
  </span>
10128
10167
  </button>
10129
10168
  </div>
@@ -13638,6 +13677,7 @@ class ClrSignpostTrigger {
13638
13677
  this.signpostIdService = signpostIdService;
13639
13678
  this.signpostFocusManager = signpostFocusManager;
13640
13679
  this.platformId = platformId;
13680
+ this.ariaExpanded = false;
13641
13681
  this.subscriptions = [];
13642
13682
  this.document = document;
13643
13683
  }
@@ -19794,7 +19834,7 @@ const ALERT_TYPES = ['info', 'warning', 'danger', 'success', 'neutral', 'unknown
19794
19834
  class AlertIconAndTypesService {
19795
19835
  constructor(commonStrings) {
19796
19836
  this.commonStrings = commonStrings;
19797
- this.defaultIconShape = 'info-circle';
19837
+ this.defaultIconShape = 'info-standard';
19798
19838
  this._alertIconShape = '';
19799
19839
  this._alertType = 'info';
19800
19840
  }
@@ -19827,22 +19867,22 @@ class AlertIconAndTypesService {
19827
19867
  const returnObj = { shape: '', cssClass: '', title: '' };
19828
19868
  switch (type) {
19829
19869
  case 'warning':
19830
- returnObj.shape = 'exclamation-triangle';
19870
+ returnObj.shape = 'warning-standard';
19831
19871
  returnObj.cssClass = 'alert-warning';
19832
19872
  returnObj.title = this.commonStrings.keys.warning;
19833
19873
  break;
19834
19874
  case 'danger':
19835
- returnObj.shape = 'exclamation-circle';
19875
+ returnObj.shape = 'error-standard';
19836
19876
  returnObj.cssClass = 'alert-danger';
19837
19877
  returnObj.title = this.commonStrings.keys.danger;
19838
19878
  break;
19839
19879
  case 'success':
19840
- returnObj.shape = 'check-circle';
19880
+ returnObj.shape = 'success-standard';
19841
19881
  returnObj.cssClass = 'alert-success';
19842
19882
  returnObj.title = this.commonStrings.keys.success;
19843
19883
  break;
19844
19884
  case 'neutral':
19845
- returnObj.shape = 'note-edit';
19885
+ returnObj.shape = 'note';
19846
19886
  returnObj.cssClass = 'alert-neutral';
19847
19887
  returnObj.title = this.commonStrings.keys.neutral;
19848
19888
  break;
@@ -20041,11 +20081,7 @@ class ClrAlert {
20041
20081
  this.subscriptions.forEach(sub => sub.unsubscribe());
20042
20082
  }
20043
20083
  configAlertType(val) {
20044
- let innerVal = val;
20045
- if (!this._isLightweight && (innerVal === 'loading' || innerVal === 'unknown')) {
20046
- innerVal = 'info';
20047
- }
20048
- this.iconService.alertType = innerVal;
20084
+ this.iconService.alertType = val;
20049
20085
  }
20050
20086
  open() {
20051
20087
  this._closed = false;
@@ -20352,7 +20388,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
20352
20388
  const CLR_ALERT_DIRECTIVES = [ClrAlert, ClrAlertItem, ClrAlerts, ClrAlertsPager, ClrAlertText];
20353
20389
  class ClrAlertModule {
20354
20390
  constructor() {
20355
- ClarityIcons.addIcons(checkCircleIcon, infoCircleIcon, exclamationCircleIcon, exclamationTriangleIcon, windowCloseIcon);
20391
+ ClarityIcons.addIcons(errorStandardIcon, helpIcon, infoStandardIcon, noteIcon, successStandardIcon, warningStandardIcon, windowCloseIcon);
20356
20392
  }
20357
20393
  }
20358
20394
  ClrAlertModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrAlertModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
@@ -25797,7 +25833,7 @@ class ClrWizard {
25797
25833
  */
25798
25834
  reset() {
25799
25835
  this.pageCollection.reset();
25800
- this.onReset.next();
25836
+ this.onReset.emit();
25801
25837
  }
25802
25838
  listenForNextPageChanges() {
25803
25839
  return this.navService.movedToNextPage.pipe(filter(() => isPlatformBrowser(this.platformId))).subscribe(() => {