@@ -6,8 +6,11 @@ import {
66 HostBinding ,
77 TemplateRef ,
88 ViewChild ,
9- ChangeDetectorRef
9+ ChangeDetectorRef ,
10+ ContentChild
1011} from "@angular/core" ;
12+ import { PasswordInput } from "./password.directive" ;
13+ import { BaseIconButton } from "../button" ;
1114
1215/**
1316 * Get started with importing the module:
@@ -19,8 +22,7 @@ import {
1922 * ```html
2023 * <cds-password-label>
2124 * Label
22- * <input cdsPassword type="text">
23- * <input cdsPassword type="password">
25+ * <input cdsPassword>
2426 * </cds-password-label>
2527 * ```
2628 *
@@ -29,142 +31,113 @@ import {
2931@Component ( {
3032 selector : "cds-password-label, ibm-password-label" ,
3133 template : `
32- <label
33- [for]="labelInputID"
34- [attr.aria-label]="ariaLabel"
35- class="cds--label"
36- [ngClass]="{
37- 'cds--label--disabled': disabled,
38- 'cds--skeleton': skeleton
39- }"
40- >
41- <ng-template *ngIf="labelTemplate; else labelContent" [ngTemplateOutlet]="labelTemplate"></ng-template>
42- <ng-template #labelContent>
43- <ng-content></ng-content>
44- </ng-template>
45- </label>
46-
47- <div
48- class="cds--text-input__field-wrapper"
49- [ngClass]="{
50- 'cds--text-input__field-wrapper--warning': warn
51- }"
52- [attr.data-invalid]="invalid ? true : null"
53- #wrapper
54- >
55- <svg *ngIf="!warn && invalid" cdsIcon="warning--filled" size="16" class="cds--text-input__invalid-icon"></svg>
56- <svg
57- *ngIf="!invalid && warn"
58- cdsIcon="warning--alt--filled"
59- size="16"
60- class="cds--text-input__invalid-icon cds--text-input__invalid-icon--warning"
61- ></svg>
62-
63- <ng-template *ngIf="passwordInputTemplate; else contentTemplate" [ngTemplateOutlet]="passwordInputTemplate"></ng-template>
64-
65- <ng-template #passwordContent>
66- <ng-content select="input[type=password]"></ng-content>
67- </ng-template>
68-
69- <ng-template #textContent>
70- <ng-content select="input[type=text]"></ng-content>
71- </ng-template>
72-
73- <ng-template #contentTemplate>
74- <ng-container
75- *ngIf="inputType === 'password'; else textContent"
76- >
77- <ng-container
78- *ngTemplateOutlet="passwordContent"
79- ></ng-container>
80- </ng-container>
81- </ng-template>
82-
83- <button
84- *ngIf="!skeleton"
85- type="button"
86- [ngClass]="passwordVisibilityToggleClasses"
87- [disabled]="disabled"
88- (click)="handleTogglePasswordVisibility()"
89- >
90- <ng-container *ngIf="!disabled">
91- <span class="cds--assistive-text">
92- {{
93- passwordIsVisible
94- ? hidePasswordLabel
95- : showPasswordLabel
96- }}
97- </span>
98- </ng-container>
99- <svg *ngIf="passwordIsVisible" cdsIcon="view--off" size="16"></svg>
100- <svg *ngIf="!passwordIsVisible" cdsIcon="view" size="16"></svg>
101- </button>
102- </div>
103-
104- <div
105- *ngIf="!skeleton && helperText && !invalid && !warn"
106- class="cds--form__helper-text"
107- [ngClass]="{ 'cds--form__helper-text--disabled': disabled }"
108- >
109- <ng-container *ngIf="!isTemplate(helperText)">{{ helperText }}</ng-container>
110- <ng-template *ngIf="isTemplate(helperText)" [ngTemplateOutlet]="helperText"></ng-template>
111- </div>
112-
113- <div *ngIf="!warn && invalid" class="cds--form-requirement">
114- <ng-container *ngIf="!isTemplate(invalidText)">{{ invalidText }}</ng-container>
115- <ng-template *ngIf="isTemplate(invalidText)" [ngTemplateOutlet]="invalidText"></ng-template>
116- </div>
117-
118- <div *ngIf="!invalid && warn" class="cds--form-requirement">
119- <ng-container *ngIf="!isTemplate(warnText)">{{ warnText }}</ng-container>
120- <ng-template *ngIf="isTemplate(warnText)" [ngTemplateOutlet]="warnText"></ng-template>
121- </div>
34+ <label
35+ [for]="labelInputID"
36+ [attr.aria-label]="ariaLabel"
37+ class="cds--label"
38+ [ngClass]="{
39+ 'cds--label--disabled': disabled,
40+ 'cds--skeleton': skeleton
41+ }"
42+ >
43+ <ng-template *ngIf="labelTemplate; else labelContent" [ngTemplateOutlet]="labelTemplate"></ng-template>
44+ <ng-template #labelContent>
45+ <ng-content></ng-content>
46+ </ng-template>
47+ </label>
48+
49+ <div class="cds--text-input__field-outer-wrapper">
50+ <div
51+ class="cds--text-input__field-wrapper"
52+ [ngClass]="{
53+ 'cds--text-input__field-wrapper--warning': warn
54+ }"
55+ [attr.data-invalid]="invalid ? true : null"
56+ #wrapper>
57+ <svg
58+ *ngIf="!warn && invalid"
59+ cdsIcon="warning--filled"
60+ size="16"
61+ class="cds--text-input__invalid-icon">
62+ </svg>
63+ <svg
64+ *ngIf="!invalid && warn"
65+ cdsIcon="warning--alt--filled"
66+ size="16"
67+ class="cds--text-input__invalid-icon cds--text-input__invalid-icon--warning">
68+ </svg>
69+ <ng-content select="[cdsPassword], [ibmPassword]"></ng-content>
70+ <cds-tooltip
71+ *ngIf="!skeleton"
72+ [description]="passwordIsVisible ? hidePasswordLabel : showPasswordLabel"
73+ [disabled]="disabled"
74+ [caret]="caret"
75+ [dropShadow]="dropShadow"
76+ [highContrast]="highContrast"
77+ [isOpen]="isOpen"
78+ [align]="align"
79+ [autoAlign]="autoAlign"
80+ [enterDelayMs]="enterDelayMs"
81+ [leaveDelayMs]="leaveDelayMs"
82+ class="cds--toggle-password-tooltip">
83+ <div class="cds--tooltip-trigger__wrapper">
84+ <button
85+ class="cds--text-input--password__visibility__toggle cds--btn cds--tooltip__trigger cds--tooltip--a11y"
86+ [disabled]="disabled"
87+ type="button"
88+ (click)="handleTogglePasswordVisibility($event)">
89+ <svg *ngIf="passwordIsVisible" cdsIcon="view--off" class="cds--icon-visibility-off" size="16"></svg>
90+ <svg *ngIf="!passwordIsVisible" cdsIcon="view" class="cds--icon-visibility-on" size="16"></svg>
91+ </button>
92+ </div>
93+ </cds-tooltip>
94+ </div>
95+ <div
96+ *ngIf="!skeleton && helperText && !invalid && !warn"
97+ class="cds--form__helper-text"
98+ [ngClass]="{ 'cds--form__helper-text--disabled': disabled }">
99+ <ng-container *ngIf="!isTemplate(helperText)">{{ helperText }}</ng-container>
100+ <ng-template *ngIf="isTemplate(helperText)" [ngTemplateOutlet]="helperText"></ng-template>
101+ </div>
102+
103+ <div *ngIf="!warn && invalid" class="cds--form-requirement">
104+ <ng-container *ngIf="!isTemplate(invalidText)">{{ invalidText }}</ng-container>
105+ <ng-template *ngIf="isTemplate(invalidText)" [ngTemplateOutlet]="invalidText"></ng-template>
106+ </div>
107+
108+ <div *ngIf="!invalid && warn" class="cds--form-requirement">
109+ <ng-container *ngIf="!isTemplate(warnText)">{{ warnText }}</ng-container>
110+ <ng-template *ngIf="isTemplate(warnText)" [ngTemplateOutlet]="warnText"></ng-template>
111+ </div>
112+ </div>
122113 `
123114} )
124115/**
125116 * Represents the Password Input Label Component.
126117 */
127- export class PasswordInputLabelComponent implements AfterViewInit {
118+ export class PasswordInputLabelComponent extends BaseIconButton implements AfterViewInit {
128119
129120 /**
130- * Getter for generating classes for password visibility toggle .
121+ * Counter for generating unique labelInputID .
131122 */
132- get passwordVisibilityToggleClasses ( ) : string {
133- return [
134- "cds--text-input--password__visibility__toggle" ,
135- "cds--btn" ,
136- "cds--btn--icon-only" ,
137- "cds--tooltip__trigger" ,
138- "cds--tooltip--a11y" ,
139- this . disabled ? "cds--btn--disabled" : "" ,
140- this . tooltipPosition ? `cds--tooltip--${ this . tooltipPosition } ` : "" ,
141- this . tooltipAlignment
142- ? `cds--tooltip--align-${ this . tooltipAlignment } `
143- : ""
144- ] . join ( " " ) ;
145- }
123+ static labelCounter = 0 ;
146124
147- /**
148- * Getter for checking if password is visible.
149- */
150- get passwordIsVisible ( ) {
151- return this . inputType === "text" ;
152- }
125+ @ContentChild ( PasswordInput ) textInput : PasswordInput ;
153126
154127 /**
155- * Counter for generating unique labelInputID .
128+ * ID for the input item associated with the label .
156129 */
157- static labelCounter = 0 ;
130+ @Input ( ) labelInputID = "cds-password-input-" + PasswordInputLabelComponent . labelCounter ++ ;
131+
158132 /**
159133 * Type for input field, either password or text.
160134 */
161135 inputType : "password" | "text" = "password" ;
162136
163137 /**
164- * ID for the input item associated with the label.
165- */
166- @Input ( ) labelInputID =
167- "ibm-password-input-" + PasswordInputLabelComponent . labelCounter ++ ;
138+ * Flag for checking if password is visible.
139+ */
140+ passwordIsVisible = false ;
168141
169142 /**
170143 * Flag for disabled label.
@@ -226,36 +199,28 @@ export class PasswordInputLabelComponent implements AfterViewInit {
226199 */
227200 @Input ( ) showPasswordLabel = "Show password" ;
228201
229- /**
230- * Alignment of the tooltip to the icon-only button.
231- */
232- @Input ( ) tooltipPosition : "top" | "right" | "bottom" | "left" = "bottom" ;
233-
234- /**
235- * Direction of the tooltip for icon-only buttons.
236- */
237- @Input ( ) tooltipAlignment : "start" | "center" | "end" = "center" ;
238-
239202 /**
240203 * Reference to the wrapper element.
241- * @ts -ignore
242204 */
243- @ViewChild ( "wrapper" , { static : false } )
244- wrapper : ElementRef < HTMLDivElement > ;
205+ @ViewChild ( "wrapper" ) wrapper : ElementRef < HTMLDivElement > ;
245206
246207 /**
247208 * Binding for applying class to host element.
248209 */
249210 @HostBinding ( "class.cds--form-item" ) labelClass = true ;
211+ @HostBinding ( "class.cds--password-input-wrapper" ) passwordInputWrapper = true ;
212+ @HostBinding ( "class.cds--text-input-wrapper" ) textInputWrapper = true ;
250213
251214 /**
252215 * Constructor for PasswordInputLabelComponent.
253216 * @param changeDetectorRef - Reference to ChangeDetectorRef.
254217 */
255- constructor ( protected changeDetectorRef : ChangeDetectorRef ) { }
218+ constructor ( protected changeDetectorRef : ChangeDetectorRef ) {
219+ super ( ) ;
220+ }
256221
257222 /**
258- * Lifecycle hook called after the view has been initialized.
223+ * Lifecycle hook called after the view has been initialized to set the ID of the input element
259224 */
260225 ngAfterViewInit ( ) {
261226 if ( this . wrapper ) {
@@ -269,15 +234,6 @@ export class PasswordInputLabelComponent implements AfterViewInit {
269234 inputElement . setAttribute ( "id" , this . labelInputID ) ;
270235 return ;
271236 }
272-
273- const divElement = this . wrapper . nativeElement . querySelector ( "div" ) ;
274- if ( divElement ) {
275- if ( divElement . id ) {
276- this . labelInputID = divElement . id ;
277- this . changeDetectorRef . detectChanges ( ) ;
278- }
279- divElement . setAttribute ( "id" , this . labelInputID ) ;
280- }
281237 }
282238 }
283239
@@ -295,5 +251,7 @@ export class PasswordInputLabelComponent implements AfterViewInit {
295251 */
296252 public handleTogglePasswordVisibility ( ) {
297253 this . inputType = this . inputType === "password" ? "text" : "password" ;
254+ this . textInput . type = this . inputType ;
255+ this . passwordIsVisible = this . inputType === "text" ;
298256 }
299257}
0 commit comments