@engie-group/fluid-design-system-angular
Version:
Fluid Design System Angular
307 lines (264 loc) • 6.23 kB
text/typescript
import {CommonModule} from '@angular/common';
import {
AfterContentInit,
ChangeDetectionStrategy,
Component,
ContentChild,
EventEmitter,
Input,
Output,
ViewEncapsulation,
} from '@angular/core';
import {FormFieldDirective} from '../form-field/form-field.directive';
import {IconButtonComponent} from '../icon-button/icon-button.component';
import {IconComponent} from '../icon/icon.component';
import {FormItemSize} from './form-item.model';
export class FormItemComponent implements AfterContentInit {
private readonly formItemClassName = 'nj-form-item';
/**
* @ignore
*/
private _hasError: boolean;
/**
* @ignore
*/
private _hasSuccess: boolean;
/**
* @ignore
*/
private _hasHint: boolean;
/**
* @ignore
*/
isPassword: boolean;
/**
* @ignore
*/
isVisible = false;
/**
* @ignore
*/
passwordNotice = '';
/**
* @ignore
*/
passwordButtonLabel = '';
/**
* @ignore
*/
isMultiline = false;
/**
* Input id and label for attribute, needed for focus to work properly
*/
inputId: string;
/**
* Form item size
*/
size: FormItemSize = 'medium';
/**
* Whether the form-item label is floating
*/
isFloatingLabel = true;
/**
* Whether form-item is disabled or not
*/
isDisabled: boolean;
/**
* Whether form-item is required or not
*/
isRequired: boolean;
/**
* Whether form-item is in success state
*/
set hasSuccess(value: boolean) {
this._hasSuccess = value;
this.setAriaAttributes();
}
get hasSuccess(): boolean {
return this._hasSuccess;
}
/**
* Whether form-item is in error state
*/
set hasError(value: boolean) {
this._hasError = value;
this.setAriaAttributes();
}
get hasError(): boolean {
return this._hasError;
}
/**
* Whether the form-item has a hint substring
*/
set hasHint(value: boolean) {
this._hasHint = value;
this.setAriaAttributes();
}
get hasHint(): boolean {
return this._hasHint;
}
/**
* Whether the form-item has a custom icon
*/
hasCustomIcon: boolean;
/**
* Whether the form-item's icon (or custom icon) is clickable
*/
isIconClickable = true;
/**
* Material icon name
*/
iconName: string;
/**
* Additional form-item css classes
*/
additionalClass: string = '';
/**
* Label for the button to toggle password visibility when password is hidden.
* @example "Show password"
*/
passwordButtonLabelShow?: string;
/**
* Label for the button to toggle password visibility when password is visible.
* @example "Hide password"
*/
passwordButtonLabelHide?: string;
/**
* Label to announce when password becomes visible.
* @example "Password is visible"
*/
passwordNoticeIsVisible?: string;
/**
* Label to announce when password becomes hidden.
* @example "Password is hidden"
*/
passwordNoticeIsHidden?: string;
/**
* Whether form-item is a select or not
*/
isSelect: boolean;
/**
* Outputs icon click
*/
iconClick: EventEmitter<MouseEvent> = new EventEmitter<
MouseEvent
>();
/**
* Outputs icon keydown
*/
iconKeydown: EventEmitter<KeyboardEvent> = new EventEmitter<
KeyboardEvent
>();
/**
* Outputs icon click
*/
wrapperClick: EventEmitter<MouseEvent> = new EventEmitter<
MouseEvent
>();
/**
* @ignore
*/
formField: FormFieldDirective;
ngAfterContentInit() {
const tagName = this.formField?.tagName?.toLowerCase();
this.isPassword = this.formField?.type === 'password';
this.isMultiline = tagName === 'textarea';
this.passwordButtonLabel = this.passwordButtonLabelShow;
this.setAriaAttributes();
if (this.isRequired) {
this.formField.element.setAttribute('required', 'required');
}
}
/**
* @ignore
*/
iconClickHandler(event: MouseEvent) {
if (!this.isIconClickable) {
return;
}
this.iconClick.emit(event);
}
/**
* @ignore
*/
iconKeydownHandler(event: KeyboardEvent) {
event?.preventDefault();
if (!this.isIconClickable) {
return;
}
this.iconKeydown.emit(event);
}
/**
* @ignore
*/
toggleVisibility() {
if (this.isVisible) {
this.formField.type = 'password';
this.passwordNotice = this.passwordNoticeIsHidden;
this.passwordButtonLabel = this.passwordButtonLabelShow;
} else {
this.formField.type = 'text';
this.passwordNotice = this.passwordNoticeIsVisible;
this.passwordButtonLabel = this.passwordButtonLabelHide;
}
this.isVisible = !this.isVisible;
}
/**
* @ignore
*/
getSubscriptId(): string {
return `${this.inputId}-subscript`;
}
/**
* @ignore
*/
setAriaAttributes() {
if (this.formField?.element) {
if (this.hasError) {
this.formField.element.setAttribute('aria-invalid', 'true');
}
if (this.hasError || this.hasSuccess || this.hasHint) {
this.formField.element.setAttribute('aria-describedby', this.getSubscriptId());
}
}
}
/**
* @ignore
*/
isCustomSelect(): boolean {
const type = this.formField?.type;
return this.isSelect && type === 'text';
}
/**
* @ignore
*/
getFormItemSizeClass(): string {
let sizeModifier: string;
switch (this.size) {
case 'small':
sizeModifier = 'sm';
break;
case 'large':
sizeModifier = 'lg';
break;
case 'xlarge':
sizeModifier = 'xl';
break;
default:
break;
}
return sizeModifier ? `${this.formItemClassName}--${sizeModifier}` : '';
}
}