src/components/sq-input/sq-input.component.ts
Represents the SqInputComponent, a customizable input component.
Look the link about the component in original framework and the appearance
See https://css.squidit.com.br/forms/input
<sq-input
[name]="'name-exemple'"
[id]="'id-exemple'"
[label]="'Example Input'"
[placeholder]="'Enter text'"
[(value)]="inputValue"
[required]="true"
(valueChange)="onInputChange($event)"
></sq-input>| selector | sq-input |
| standalone | true |
| imports |
NgClass
NgStyle
NgTemplateOutlet
FormsModule
SqTooltipComponent
UniversalSafePipe
|
| styleUrls | ./sq-input.component.scss |
| templateUrl | ./sq-input.component.html |
Properties |
Methods |
Inputs |
Outputs |
Accessors |
constructor(validatorHelper: ValidatorHelper, element: ElementRef, translate: TranslateService)
|
||||||||||||||||
|
Constructor for the SqInputComponent class.
Parameters :
|
| backgroundColor | |
Type : string
|
|
Default value : ''
|
|
|
Background color of the input element. |
|
| borderColor | |
Type : string
|
|
Default value : ''
|
|
|
Border color of the input element. |
|
| customClass | |
Type : string
|
|
Default value : ''
|
|
|
Custom CSS class for the input element. |
|
| disabled | |
Type : boolean
|
|
Default value : false
|
|
|
Flag to disable the input element. |
|
| errorSpan | |
Type : boolean
|
|
Default value : true
|
|
|
Flag to display an error span. |
|
| externalError | |
Type : string
|
|
Default value : ''
|
|
|
External error message to display. |
|
| externalIcon | |
Type : string
|
|
Default value : ''
|
|
|
External icon to display. |
|
| id | |
Type : string
|
|
|
The id attribute for the input element. |
|
| inputMode | |
Type : string
|
|
Default value : ''
|
|
|
Input mode for mobile devices. |
|
| label | |
Type : string
|
|
|
An optional label for the input. |
|
| labelColor | |
Type : string
|
|
Default value : ''
|
|
|
Color of the input label. |
|
| maxLength | |
Type : number | null
|
|
Default value : null
|
|
|
Maximum length for the input element. |
|
| name | |
Type : string
|
|
Default value : `random-name-${(1 + Date.now() + Math.random()).toString().replace('.', '')}`
|
|
|
The name attribute for the input element. |
|
| pattern | |
Type : string
|
|
Default value : ''
|
|
|
Regular expression pattern for input validation. |
|
| placeholder | |
Type : string
|
|
Default value : ''
|
|
|
Placeholder text for the input element. |
|
| readonly | |
Type : boolean
|
|
Default value : false
|
|
|
Flag to make the input element readonly. |
|
| required | |
Type : boolean
|
|
Default value : false
|
|
|
Flag to mark the input as required. |
|
| timeToChange | |
Type : number
|
|
Default value : 0
|
|
|
Time in milliseconds before triggering input timeout. |
|
| tooltipColor | |
Type : string
|
|
Default value : 'inherit'
|
|
|
Color of the tooltip. |
|
| tooltipIcon | |
Type : string
|
|
Default value : ''
|
|
|
Icon for the tooltip. |
|
| tooltipMessage | |
Type : string
|
|
Default value : ''
|
|
|
Tooltip message to display. |
|
| tooltipPlacement | |
Type : "center top" | "center bottom" | "left center" | "right center"
|
|
Default value : 'right center'
|
|
|
Placement of the tooltip. |
|
| type | |
Type : "text" | "email" | "email-multiple" | "hidden" | "password" | "tel" | "url" | "file"
|
|
Default value : 'text'
|
|
|
Type of the input element (e.g., text, email, password). |
|
| useFormErrors | |
Type : boolean
|
|
Default value : true
|
|
|
Flag to use form errors for validation messages. |
|
| value | |
Type : any
|
|
|
The value of the input element. |
|
| emitFocus | |
Type : EventEmitter<Event>
|
|
|
Event emitter for focus input changes. |
|
| inFocus | |
Type : EventEmitter<boolean>
|
|
|
Event emitter for input focus events. |
|
| keyPressDown | |
Type : EventEmitter<KeyboardEvent>
|
|
|
Event emitter for keydown events. |
|
| keyPressUp | |
Type : EventEmitter<KeyboardEvent>
|
|
|
Event emitter for keyup events. |
|
| valid | |
Type : EventEmitter<boolean>
|
|
|
Event emitter for validation status. |
|
| valueChange | |
Type : EventEmitter<any>
|
|
|
Event emitter for input value changes. |
|
| Async change | ||||||||
change(event: any)
|
||||||||
|
Handle input value changes.
Parameters :
Returns :
any
|
| keyDown | ||||||||
keyDown(event: KeyboardEvent)
|
||||||||
|
Handle keydown events.
Parameters :
Returns :
void
|
| keyUp | ||||||||
keyUp(event: KeyboardEvent)
|
||||||||
|
Handle keyup events.
Parameters :
Returns :
void
|
| Async setError | |||||||||||||||
setError(key: string, interpolateParams: Object)
|
|||||||||||||||
|
Sets an error message.
Parameters :
Returns :
any
|
| Async validate | ||||||||
validate(isBlur)
|
||||||||
|
Asynchronously validate the input value.
Parameters :
Returns :
any
|
| _value |
Type : any
|
Default value : ''
|
|
The internal value of the input element. |
| error |
Type : boolean | string
|
Default value : false
|
|
Error message to display. |
| labelTemplate |
Type : TemplateRef<HTMLElement> | null
|
Default value : null
|
Decorators :
@ContentChild('labelTemplate')
|
|
Reference to a label template. |
| leftLabel |
Type : TemplateRef<HTMLElement> | null
|
Default value : null
|
Decorators :
@ContentChild('leftLabel')
|
|
Reference to a left-aligned label template. |
| nativeElement |
Type : ElementRef
|
|
Reference to the native element. |
| rightLabel |
Type : TemplateRef<HTMLElement> | null
|
Default value : null
|
Decorators :
@ContentChild('rightLabel')
|
|
Reference to a right-aligned label template. |
| timeoutInput |
Type : ReturnType<>
|
|
Timeout for input changes. |
| Public translate |
Type : TranslateService
|
Decorators :
@Optional()
|
|
- The TranslateService for internationalization (optional).
|
| Public validatorHelper |
Type : ValidatorHelper
|
|
- The ValidatorHelper service for input validation.
|
| value | ||||||
getvalue()
|
||||||
setvalue(value: any)
|
||||||
|
The value of the input element.
Parameters :
Returns :
void
|
import { Component, ContentChild, ElementRef, EventEmitter, Input, Optional, Output, TemplateRef } from '@angular/core';
import { NgClass, NgStyle, NgTemplateOutlet } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { TranslateService } from '@ngx-translate/core';
import { ValidatorHelper } from '../../helpers/validator.helper';
import { SqTooltipComponent } from '../sq-tooltip/sq-tooltip.component';
import { UniversalSafePipe } from '../../pipes/universal-safe/universal-safe.pipe';
/**
* Represents the SqInputComponent, a customizable input component.
*
* Look the link about the component in original framework and the appearance
*
* @see {@link https://css.squidit.com.br/forms/input}
*
* <br>
* <label for='id-exemple'>
* Example Input
* </label>
* <input
* class='input mb-3'
* name="name-exemple"
* id="id-exemple"
* placeholder="Enter text"
* ></input>
*
* @example
* <sq-input
* [name]="'name-exemple'"
* [id]="'id-exemple'"
* [label]="'Example Input'"
* [placeholder]="'Enter text'"
* [(value)]="inputValue"
* [required]="true"
* (valueChange)="onInputChange($event)"
* ></sq-input>
*/
@Component({
selector: 'sq-input',
templateUrl: './sq-input.component.html',
styleUrls: ['./sq-input.component.scss'],
standalone: true,
imports: [NgClass, NgStyle, NgTemplateOutlet, FormsModule, SqTooltipComponent, UniversalSafePipe],
})
export class SqInputComponent {
/**
* The name attribute for the input element.
*
* @default 'random-name-[hash-random-code]'
*/
@Input() name = `random-name-${(1 + Date.now() + Math.random()).toString().replace('.', '')}`;
/**
* The id attribute for the input element.
*/
@Input() id?: string;
/**
* An optional label for the input.
*/
@Input() label?: string;
/**
* Custom CSS class for the input element.
*/
@Input() customClass = '';
/**
* Placeholder text for the input element.
*/
@Input() placeholder = '';
/**
* External error message to display.
*/
@Input() externalError = '';
/**
* External icon to display.
*/
@Input() externalIcon = '';
/**
* The value of the input element.
*/
@Input()
public set value(value: any) {
this._value = value;
}
public get value(): any {
return this._value;
}
/**
* Time in milliseconds before triggering input timeout.
*/
@Input() timeToChange = 0;
/**
* Flag to display an error span.
*/
@Input() errorSpan = true;
/**
* Flag to disable the input element.
*/
@Input() disabled = false;
/**
* Flag to make the input element readonly.
*/
@Input() readonly = false;
/**
* Flag to mark the input as required.
*/
@Input() required = false;
/**
* Flag to use form errors for validation messages.
*/
@Input() useFormErrors = true;
/**
* Tooltip message to display.
*/
@Input() tooltipMessage = '';
/**
* Placement of the tooltip.
*/
@Input() tooltipPlacement: 'center top' | 'center bottom' | 'left center' | 'right center' = 'right center';
/**
* Color of the tooltip.
*/
@Input() tooltipColor = 'inherit';
/**
* Icon for the tooltip.
*/
@Input() tooltipIcon = '';
/**
* Background color of the input element.
*/
@Input() backgroundColor = '';
/**
* Border color of the input element.
*/
@Input() borderColor = '';
/**
* Color of the input label.
*/
@Input() labelColor = '';
/**
* Type of the input element (e.g., text, email, password).
*/
@Input() type: 'text' | 'email' | 'email-multiple' | 'hidden' | 'password' | 'tel' | 'url' | 'file' = 'text';
/**
* Maximum length for the input element.
*/
@Input() maxLength: number | null = null;
/**
* Regular expression pattern for input validation.
*/
@Input() pattern = '';
/**
* Input mode for mobile devices.
*/
@Input() inputMode = '';
/**
* Event emitter for keydown events.
*/
@Output() keyPressDown: EventEmitter<KeyboardEvent> = new EventEmitter();
/**
* Event emitter for keyup events.
*/
@Output() keyPressUp: EventEmitter<KeyboardEvent> = new EventEmitter();
/**
* Event emitter for input focus events.
*/
@Output() inFocus: EventEmitter<boolean> = new EventEmitter();
/**
* Event emitter for validation status.
*/
@Output() valid: EventEmitter<boolean> = new EventEmitter();
/**
* Event emitter for input value changes.
*/
@Output() valueChange: EventEmitter<any> = new EventEmitter();
/**
* Event emitter for focus input changes.
*/
@Output() emitFocus: EventEmitter<Event> = new EventEmitter<Event>();
/**
* Reference to a left-aligned label template.
*/
@ContentChild('leftLabel')
leftLabel: TemplateRef<HTMLElement> | null = null;
/**
* Reference to a right-aligned label template.
*/
@ContentChild('rightLabel')
rightLabel: TemplateRef<HTMLElement> | null = null;
/**
* Reference to a label template.
*/
@ContentChild('labelTemplate')
labelTemplate: TemplateRef<HTMLElement> | null = null;
/**
* The internal value of the input element.
*/
_value: any = '';
/**
* Error message to display.
*/
error: boolean | string = false;
/**
* Reference to the native element.
*/
nativeElement: ElementRef;
/**
* Timeout for input changes.
*/
timeoutInput!: ReturnType<typeof setTimeout>;
/**
* Constructor for the SqInputComponent class.
* @param validatorHelper - The ValidatorHelper service for input validation.
* @param element - The ElementRef representing the input element.
* @param translate - The TranslateService for internationalization (optional).
*/
constructor(
public validatorHelper: ValidatorHelper,
element: ElementRef,
@Optional() public translate: TranslateService
) {
this.nativeElement = element.nativeElement;
}
/**
* Asynchronously validate the input value.
* @param isBlur - Indicates if the input has lost focus.
*/
async validate(isBlur = false) {
if (this.externalError) {
this.error = false;
} else if (!!this.required && !this.value) {
this.valid.emit(false);
this.setError('forms.required');
} else if (this.type === 'email' && !this.validatorHelper.email(this.value)) {
this.valid.emit(false);
this.setError('forms.email');
} else if (this.type === 'email-multiple') {
const emails = this.value.split(',');
const invalidEmails = emails.filter((email: string) => !this.validatorHelper.email(email));
if (
(emails.length === 1 && invalidEmails.length && invalidEmails[0] !== '') ||
(emails.length > 1 && invalidEmails.length)
) {
this.valid.emit(false);
this.setError('forms.emailMultiple', {
emails: invalidEmails.join(', '),
});
} else {
this.valid.emit(true);
this.error = '';
}
} else if (this.type === 'tel' && !this.validatorHelper.phone(this.value)) {
this.valid.emit(false);
this.setError('forms.phone');
} else if (this.type === 'url' && this.value && this.value.length && !this.validatorHelper.url(this.value)) {
this.valid.emit(false);
this.setError('forms.url');
} else {
this.valid.emit(true);
this.error = '';
}
if (isBlur) {
this.inFocus.emit(false);
}
}
/**
* Handle input value changes.
* @param event - The input change event.
*/
async change(event: any) {
this.inFocus.emit(true);
this.value = event;
clearTimeout(this.timeoutInput);
this.timeoutInput = setTimeout(() => {
this.valueChange.emit(event);
this.validate();
}, this.timeToChange);
}
/**
* Sets an error message.
*
* @param {string} key - The translation key for the error message.
* @param interpolateParams - Value to interpolate with translation.
*/
async setError(key: string, interpolateParams: Object = {}) {
if (this.useFormErrors && this.translate) {
this.error = await this.translate.instant(key, interpolateParams);
}
}
/**
* Handle keydown events.
* @param event - The keydown event.
*/
keyDown(event: KeyboardEvent) {
this.keyPressDown.emit(event);
}
/**
* Handle keyup events.
* @param event - The keyup event.
*/
keyUp(event: KeyboardEvent) {
this.keyPressUp.emit(event);
}
}
<div class="wrapper-all-inside-input {{ customClass }}">
@if (label?.length || tooltipMessage || labelTemplate) {
<label
class="display-flex"
[ngClass]="{
readonly: readonly,
}"
[for]="id"
>
@if (label && !labelTemplate) {
<div [ngStyle]="{ color: labelColor }" [innerHtml]="label | universalSafe"></div>
}
@if (labelTemplate) {
<div>
<ng-container *ngTemplateOutlet="labelTemplate"></ng-container>
</div>
}
@if (tooltipMessage) {
<sq-tooltip
class="ml-1"
[message]="tooltipMessage"
[placement]="tooltipPlacement"
[color]="tooltipColor"
[icon]="tooltipIcon"
></sq-tooltip>
}
</label>
}
<div
class="p-0 wrapper-input wrapper-input-squid text-ellipsisarea"
[ngClass]="{
error: (externalError && externalError !== '') || (error && error !== ''),
readonly: readonly,
}"
>
@if (leftLabel) {
<span class="input-group-text m-0">
<ng-container *ngTemplateOutlet="leftLabel"></ng-container>
</span>
}
<input
class="col input"
[ngClass]="{
'has-icon': error || externalError,
disabled: disabled,
readonly: readonly,
}"
[ngStyle]="{
'background-color': backgroundColor,
'border-color': borderColor,
}"
[id]="id"
[type]="type || 'text'"
[name]="name"
[placeholder]="placeholder || ''"
[required]="required"
[disabled]="disabled"
[readonly]="readonly"
(blur)="validate(true)"
[ngModel]="_value"
[maxlength]="maxLength"
(ngModelChange)="change($event)"
(keydown)="keyDown($event)"
(keyup)="keyUp($event)"
[pattern]="pattern"
[attr.inputmode]="inputMode"
(focus)="emitFocus.emit()"
ngDefaultControl
/>
@if (rightLabel) {
<span class="input-group-text m-0">
<ng-container *ngTemplateOutlet="rightLabel"></ng-container>
</span>
}
</div>
@if (externalIcon) {
<span
class="icon icon-external textarea-icon"
[ngClass]="{
'no-label': !label?.length,
}"
[innerHtml]="externalIcon || '' | universalSafe"
></span>
}
@if (errorSpan) {
<div
class="box-validation box-invalid show"
[ngClass]="{
'has-max-length': maxLength,
}"
>
<i
[ngClass]="{
'visibility-hidden-force': !error && !externalError,
}"
class="fa-solid fa-triangle-exclamation"
></i>
{{ externalError ? externalError : '' }}
{{ error && !externalError ? error : '' }}
@if (maxLength) {
<span
class="max-length-name"
[ngClass]="{
'visibility-hidden-force': disabled || readonly,
}"
>
{{ maxLength - (value?.length || 0) }}
</span>
}
</div>
}
</div>
./sq-input.component.scss
.wrapper-all-inside-input {
position: relative;
.icon {
margin: 0;
font-size: 1rem;
font-weight: 700;
position: absolute;
right: 24px;
top: 40px;
&.no-label {
top: 12px;
}
}
.icon-external {
color: inherit !important;
}
.max-length-name {
font-size: inherit;
float: right;
}
}