igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
1,088 lines (1,080 loc) • 55.6 kB
JavaScript
import * as i0 from '@angular/core';
import { Input, HostBinding, Directive, inject, ElementRef, ChangeDetectorRef, Renderer2, booleanAttribute, HostListener, InjectionToken, DOCUMENT, DestroyRef, ContentChild, ContentChildren, Component, input, effect, NgModule } from '@angular/core';
import { NgModel, NgControl, TouchedChangeEvent } from '@angular/forms';
import { filter } from 'rxjs';
import { NgTemplateOutlet } from '@angular/common';
import { PlatformUtil, THEME_TOKEN, getCurrentResourceStrings, InputResourceStringsEN, getComponentTheme } from 'igniteui-angular/core';
import { IgxButtonDirective } from 'igniteui-angular/directives';
import { IgxIconComponent } from 'igniteui-angular/icon';
var IgxHintPosition;
(function (IgxHintPosition) {
IgxHintPosition[IgxHintPosition["START"] = 0] = "START";
IgxHintPosition[IgxHintPosition["END"] = 1] = "END";
})(IgxHintPosition || (IgxHintPosition = {}));
class IgxHintDirective {
constructor() {
/**
* Sets/gets whether the hint position is at the start.
* Default value is `false`.
* ```typescript
* @ViewChild('hint', {read: IgxHintDirective})
* public igxHint: IgxHintDirective;
* this.igxHint.isPositionStart = true;
* ```
* ```typescript
* let isHintPositionStart = this.igxHint.isPositionStart;
* ```
*
* @memberof IgxHintDirective
*/
this.isPositionStart = false;
/**
* Sets/gets whether the hint position is at the end.
* Default value is `false`.
* ```typescript
* @ViewChild('hint', {read: IgxHintDirective})
* public igxHint: IgxHintDirective;
* this.igxHint.isPositionEnd = true;
* ```
* ```typescript
* let isHintPositionEnd = this.igxHint.isPositionEnd;
* ```
*
* @memberof IgxHintDirective
*/
this.isPositionEnd = false;
this._position = IgxHintPosition.START;
}
/**
* Sets the position of the hint.
* ```html
* <igx-input-group>
* <input igxInput type="text"/>
* <igx-hint #hint [position]="'start'">IgxHint displayed at the start</igx-hint>
* </igx-input-group>
* ```
*
* @memberof IgxHintDirective
*/
set position(value) {
const position = IgxHintPosition[value.toUpperCase()];
if (position !== undefined) {
this._position = position;
this._applyPosition(this._position);
}
}
/**
* Gets the position of the hint.
* ```typescript
* @ViewChild('hint', {read: IgxHintDirective})
* public igxHint: IgxHintDirective;
* let hintPosition = this.igxHint.position;
* ```
*
* @memberof IgxHintDirective
*/
get position() {
return this._position.toString();
}
/**
* @hidden
*/
ngOnInit() {
this._applyPosition(this._position);
}
_applyPosition(position) {
this.isPositionStart = this.isPositionEnd = false;
switch (position) {
case IgxHintPosition.START:
this.isPositionStart = true;
break;
case IgxHintPosition.END:
this.isPositionEnd = true;
break;
default: break;
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxHintDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.2", type: IgxHintDirective, isStandalone: true, selector: "igx-hint,[igxHint]", inputs: { position: "position" }, host: { properties: { "class.igx-input-group__hint-item--start": "this.isPositionStart", "class.igx-input-group__hint-item--end": "this.isPositionEnd" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxHintDirective, decorators: [{
type: Directive,
args: [{
selector: 'igx-hint,[igxHint]',
standalone: true
}]
}], propDecorators: { isPositionStart: [{
type: HostBinding,
args: ['class.igx-input-group__hint-item--start']
}], isPositionEnd: [{
type: HostBinding,
args: ['class.igx-input-group__hint-item--end']
}], position: [{
type: Input
}] } });
/** @hidden */
class IgxInputGroupBase {
}
const nativeValidationAttributes = [
'required',
'pattern',
'minlength',
'maxlength',
'min',
'max',
'step',
];
var IgxInputState;
(function (IgxInputState) {
IgxInputState[IgxInputState["INITIAL"] = 0] = "INITIAL";
IgxInputState[IgxInputState["VALID"] = 1] = "VALID";
IgxInputState[IgxInputState["INVALID"] = 2] = "INVALID";
})(IgxInputState || (IgxInputState = {}));
/**
* The `igxInput` directive creates single- or multiline text elements, covering common scenarios when dealing with form inputs.
*
* @igxModule IgxInputGroupModule
*
* @igxParent Data Entry & Display
*
* @igxTheme igx-input-group-theme
*
* @igxKeywords input, input group, form, field, validation
*
* @igxGroup presentation
*
* @example
* ```html
* <input-group>
* <label for="address">Address</label>
* <input igxInput name="address" type="text" [(ngModel)]="customer.address">
* </input-group>
* ```
*/
class IgxInputDirective {
constructor() {
this.inputGroup = inject(IgxInputGroupBase);
this.ngModel = inject(NgModel, { optional: true, self: true });
this.formControl = inject(NgControl, { optional: true, self: true });
this.element = inject(ElementRef);
this.cdr = inject(ChangeDetectorRef);
this.renderer = inject(Renderer2);
/**
* Sets/gets whether the `"igx-input-group__input"` class is added to the host element.
* Default value is `false`.
*
* @example
* ```typescript
* this.igxInput.isInput = true;
* ```
*
* @example
* ```typescript
* let isCLassAdded = this.igxInput.isInput;
* ```
*/
this.isInput = false;
/**
* Sets/gets whether the `"class.igx-input-group__textarea"` class is added to the host element.
* Default value is `false`.
*
* @example
* ```typescript
* this.igxInput.isTextArea = true;
* ```
*
* @example
* ```typescript
* let isCLassAdded = this.igxInput.isTextArea;
* ```
*/
this.isTextArea = false;
this._valid = IgxInputState.INITIAL;
this._disabled = false;
}
get ngControl() {
return this.ngModel ? this.ngModel : this.formControl;
}
/**
* Sets the `value` property.
*
* @example
* ```html
* <input-group>
* <input igxInput #igxInput [value]="'IgxInput Value'">
* </input-group>
* ```
*/
set value(value) {
this.nativeElement.value = value ?? '';
this.updateValidityState();
}
/**
* Gets the `value` property.
*
* @example
* ```typescript
* @ViewChild('igxInput', {read: IgxInputDirective})
* public igxInput: IgxInputDirective;
* let inputValue = this.igxInput.value;
* ```
*/
get value() {
return this.nativeElement.value;
}
/**
* Sets the `disabled` property.
*
* @example
* ```html
* <input-group>
* <input igxInput #igxInput [disabled]="true">
* </input-group>
* ```
*/
set disabled(value) {
this._disabled = this.inputGroup.disabled = value;
if (this.focused && this._disabled) {
// Browser focus may not fire in good time and mess with change detection, adjust here in advance:
this.inputGroup.isFocused = false;
}
}
/**
* Gets the `disabled` property
*
* @example
* ```typescript
* @ViewChild('igxInput', {read: IgxInputDirective})
* public igxInput: IgxInputDirective;
* let isDisabled = this.igxInput.disabled;
* ```
*/
get disabled() {
return this._disabled;
}
/**
* Sets the `required` property.
*
* @example
* ```html
* <input-group>
* <input igxInput #igxInput required>
* </input-group>
* ```
*/
set required(value) {
this.nativeElement.required = this.inputGroup.isRequired = value;
}
/**
* Gets whether the igxInput is required.
*
* @example
* ```typescript
* let isRequired = this.igxInput.required;
* ```
*/
get required() {
let validation;
if (this.ngControl && (this.ngControl.control.validator || this.ngControl.control.asyncValidator)) {
validation = this.ngControl.control.validator({});
}
return validation && validation.required || this.nativeElement.hasAttribute('required');
}
/**
* @hidden
* @internal
*/
onFocus() {
this.inputGroup.isFocused = true;
}
/**
* @param event The event to invoke the handler
*
* @hidden
* @internal
*/
onBlur() {
this.inputGroup.isFocused = false;
if (this.ngControl?.control) {
this.ngControl.control.markAsTouched();
}
this.updateValidityState();
}
/** @hidden @internal */
onInput() {
this.checkNativeValidity();
}
/** @hidden @internal */
change(event) {
if (this.type === 'file') {
const fileList = event.target
.files;
const fileArray = [];
if (fileList) {
for (const file of Array.from(fileList)) {
fileArray.push(file);
}
}
this._fileNames = (fileArray || []).map((f) => f.name).join(', ');
if (this.required && fileList?.length > 0) {
this._valid = IgxInputState.INITIAL;
}
}
}
/** @hidden @internal */
get fileNames() {
return this._fileNames;
}
/** @hidden @internal */
clear() {
this.ngControl?.control?.setValue('');
this.nativeElement.value = null;
this._fileNames = '';
}
/** @hidden @internal */
ngAfterViewInit() {
this.inputGroup.hasPlaceholder = this.nativeElement.hasAttribute('placeholder');
if (this.ngControl && this.ngControl.disabled !== null) {
this.disabled = this.ngControl.disabled;
}
this.inputGroup.disabled =
this.inputGroup.disabled ||
this.nativeElement.hasAttribute('disabled');
this.inputGroup.isRequired = this.nativeElement.hasAttribute('required');
// Make sure we do not invalidate the input on init
if (!this.ngControl) {
this._valid = IgxInputState.INITIAL;
}
// Also check the control's validators for required
if (this.required && !this.inputGroup.isRequired) {
this.inputGroup.isRequired = this.required;
}
this.renderer.setAttribute(this.nativeElement, 'aria-required', this.required.toString());
const elTag = this.nativeElement.tagName.toLowerCase();
if (elTag === 'textarea') {
this.isTextArea = true;
if (this.nativeElement.getAttribute('rows') === null) {
this.renderer.setAttribute(this.nativeElement, 'rows', '3');
}
}
else {
this.isInput = true;
}
if (this.ngControl) {
this._statusChanges$ = this.ngControl.statusChanges.subscribe(this.onStatusChanged.bind(this));
this._valueChanges$ = this.ngControl.valueChanges.subscribe(this.onValueChanged.bind(this));
if (this.ngControl.control) {
this._touchedChanges$ = this.ngControl.control.events
.pipe(filter(e => e instanceof TouchedChangeEvent))
.subscribe(this.updateValidityState.bind(this));
}
}
this.cdr.detectChanges();
}
/** @hidden @internal */
ngOnDestroy() {
if (this._statusChanges$) {
this._statusChanges$.unsubscribe();
}
if (this._valueChanges$) {
this._valueChanges$.unsubscribe();
}
if (this._touchedChanges$) {
this._touchedChanges$.unsubscribe();
}
}
/**
* Sets a focus on the igxInput.
*
* @example
* ```typescript
* this.igxInput.focus();
* ```
*/
focus() {
this.nativeElement.focus();
}
/**
* Gets the `nativeElement` of the igxInput.
*
* @example
* ```typescript
* let igxInputNativeElement = this.igxInput.nativeElement;
* ```
*/
get nativeElement() {
return this.element.nativeElement;
}
/** @hidden @internal */
onStatusChanged() {
// Enable/Disable control based on ngControl #7086
if (this.disabled !== this.ngControl.disabled) {
this.disabled = this.ngControl.disabled;
}
this.updateValidityState();
}
/** @hidden @internal */
onValueChanged() {
if (this._fileNames && !this.value) {
this._fileNames = '';
}
}
/**
* @hidden
* @internal
*/
updateValidityState() {
if (this.ngControl) {
if (!this.disabled && this.isTouchedOrDirty) {
if (this.hasValidators) {
// Run the validation with empty object to check if required is enabled.
const error = this.ngControl.control.validator({});
this.inputGroup.isRequired = error && error.required;
if (this.focused) {
this._valid = this.ngControl.valid ? IgxInputState.VALID : IgxInputState.INVALID;
}
else {
this._valid = this.ngControl.valid ? IgxInputState.INITIAL : IgxInputState.INVALID;
}
}
else {
// If validator is dynamically cleared, reset label's required class(asterisk) and IgxInputState #10010
this.inputGroup.isRequired = false;
this._valid = this.ngControl.valid ? IgxInputState.INITIAL : IgxInputState.INVALID;
}
}
else {
this._valid = IgxInputState.INITIAL;
}
this.renderer.setAttribute(this.nativeElement, 'aria-required', this.required.toString());
const ariaInvalid = this.valid === IgxInputState.INVALID;
this.renderer.setAttribute(this.nativeElement, 'aria-invalid', ariaInvalid.toString());
}
else {
this.checkNativeValidity();
}
}
get isTouchedOrDirty() {
return (this.ngControl.control.touched || this.ngControl.control.dirty);
}
get hasValidators() {
return (!!this.ngControl.control.validator || !!this.ngControl.control.asyncValidator);
}
/**
* Gets whether the igxInput has a placeholder.
*
* @example
* ```typescript
* let hasPlaceholder = this.igxInput.hasPlaceholder;
* ```
*/
get hasPlaceholder() {
return this.nativeElement.hasAttribute('placeholder');
}
/**
* Gets the placeholder element of the igxInput.
*
* @example
* ```typescript
* let igxInputPlaceholder = this.igxInput.placeholder;
* ```
*/
get placeholder() {
return this.nativeElement.placeholder;
}
/**
* @returns An indicator of whether the input has validator attributes or not
*
* @hidden
* @internal
*/
_hasValidators() {
for (const nativeValidationAttribute of nativeValidationAttributes) {
if (this.nativeElement.hasAttribute(nativeValidationAttribute)) {
return true;
}
}
return false;
}
/**
* Gets whether the igxInput is focused.
*
* @example
* ```typescript
* let isFocused = this.igxInput.focused;
* ```
*/
get focused() {
return this.inputGroup.isFocused;
}
/**
* Gets the state of the igxInput.
*
* @example
* ```typescript
* let igxInputState = this.igxInput.valid;
* ```
*/
get valid() {
return this._valid;
}
/**
* Sets the state of the igxInput.
*
* @example
* ```typescript
* this.igxInput.valid = IgxInputState.INVALID;
* ```
*/
set valid(value) {
this._valid = value;
}
/**
* Gets whether the igxInput is valid.
*
* @example
* ```typescript
* let valid = this.igxInput.isValid;
* ```
*/
get isValid() {
return this.valid !== IgxInputState.INVALID;
}
/**
* A function to assign a native validity property of an input.
* This should be used when there's no ngControl
*
* @hidden
* @internal
*/
checkNativeValidity() {
if (!this.disabled && this._hasValidators()) {
this._valid = this.nativeElement.checkValidity() ?
this.focused ? IgxInputState.VALID : IgxInputState.INITIAL :
IgxInputState.INVALID;
}
}
/**
* Returns the input type.
*
* @hidden
* @internal
*/
get type() {
return this.nativeElement.type;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxInputDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "21.0.2", type: IgxInputDirective, isStandalone: true, selector: "[igxInput]", inputs: { value: "value", disabled: ["disabled", "disabled", booleanAttribute], required: ["required", "required", booleanAttribute] }, host: { listeners: { "focus": "onFocus()", "blur": "onBlur()", "input": "onInput()", "change": "change($event)" }, properties: { "class.igx-input-group__input": "this.isInput", "class.igx-input-group__textarea": "this.isTextArea", "disabled": "this.disabled" } }, exportAs: ["igxInput"], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxInputDirective, decorators: [{
type: Directive,
args: [{
selector: '[igxInput]',
exportAs: 'igxInput',
standalone: true
}]
}], propDecorators: { isInput: [{
type: HostBinding,
args: ['class.igx-input-group__input']
}], isTextArea: [{
type: HostBinding,
args: ['class.igx-input-group__textarea']
}], value: [{
type: Input
}], disabled: [{
type: Input,
args: [{ transform: booleanAttribute }]
}, {
type: HostBinding,
args: ['disabled']
}], required: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], onFocus: [{
type: HostListener,
args: ['focus']
}], onBlur: [{
type: HostListener,
args: ['blur']
}], onInput: [{
type: HostListener,
args: ['input']
}], change: [{
type: HostListener,
args: ['change', ['$event']]
}] } });
let NEXT_ID = 0;
class IgxLabelDirective {
constructor() {
this.defaultClass = true;
/**
* @hidden
*/
this.id = `igx-label-${NEXT_ID++}`;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxLabelDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.2", type: IgxLabelDirective, isStandalone: true, selector: "[igxLabel]", inputs: { id: "id" }, host: { properties: { "class.igx-input-group__label": "this.defaultClass", "attr.id": "this.id" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxLabelDirective, decorators: [{
type: Directive,
args: [{
selector: '[igxLabel]',
standalone: true
}]
}], propDecorators: { defaultClass: [{
type: HostBinding,
args: ['class.igx-input-group__label']
}], id: [{
type: HostBinding,
args: ['attr.id']
}, {
type: Input
}] } });
/**
* @hidden
*/
class IgxPrefixDirective {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxPrefixDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.2", type: IgxPrefixDirective, isStandalone: true, selector: "igx-prefix,[igxPrefix],[igxStart]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxPrefixDirective, decorators: [{
type: Directive,
args: [{
selector: 'igx-prefix,[igxPrefix],[igxStart]',
standalone: true
}]
}] });
/**
* @hidden
*/
class IgxSuffixDirective {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxSuffixDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.2", type: IgxSuffixDirective, isStandalone: true, selector: "igx-suffix,[igxSuffix],[igxEnd]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxSuffixDirective, decorators: [{
type: Directive,
args: [{
selector: 'igx-suffix,[igxSuffix],[igxEnd]',
standalone: true
}]
}] });
const IgxInputGroupEnum = {
Line: 'line',
Box: 'box',
Border: 'border',
Search: 'search'
};
/**
* Defines the InputGroupType DI token.
*/
// Should this go trough Interface https://angular.io/api/core/InjectionToken
const IGX_INPUT_GROUP_TYPE = /*@__PURE__*/ new InjectionToken('InputGroupType');
class IgxInputGroupComponent {
/**
* Sets the resource strings.
* By default it uses EN resources.
*/
set resourceStrings(value) {
this._resourceStrings = Object.assign({}, this._resourceStrings, value);
}
/**
* Returns the resource strings.
*/
get resourceStrings() {
return this._resourceStrings;
}
/** @hidden @internal */
get readOnly() {
return this._readOnly ?? (this.input?.nativeElement.readOnly || false);
}
/** @hidden @internal */
set readOnly(value) {
this._readOnly = value;
}
/** @hidden */
get validClass() {
return this.input.valid === IgxInputState.VALID;
}
/** @hidden */
get invalidClass() {
return this.input.valid === IgxInputState.INVALID;
}
/** @hidden */
get isFilled() {
return this._filled || (this.input && this.input.value);
}
/** @hidden */
get textAreaClass() {
return this.input.isTextArea;
}
/**
* Sets how the input will be styled.
* Allowed values of type IgxInputGroupType.
* ```html
* <igx-input-group [type]="'search'">
* ```
*/
set type(value) {
this._type = value;
}
/**
* Returns the type of the `IgxInputGroupComponent`. How the input is styled.
* The default is `line`.
* ```typescript
* @ViewChild("MyInputGroup")
* public inputGroup: IgxInputGroupComponent;
* ngAfterViewInit(){
* let inputType = this.inputGroup.type;
* }
* ```
*/
get type() {
return this._type || this._inputGroupType || 'line';
}
/**
* Sets the theme of the input.
* Allowed values of type IgxInputGroupTheme.
* ```typescript
* @ViewChild("MyInputGroup")
* public inputGroup: IgxInputGroupComponent;
* ngAfterViewInit() {
* let inputTheme = 'fluent';
* }
*/
set theme(value) {
this._theme = value;
}
/**
* Returns the theme of the input.
* The returned value is of type IgxInputGroupType.
* ```typescript
* @ViewChild("MyInputGroup")
* public inputGroup: IgxInputGroupComponent;
* ngAfterViewInit() {
* let inputTheme = this.inputGroup.theme;
* }
*/
get theme() {
return this._theme;
}
constructor() {
this.element = inject(ElementRef);
this._inputGroupType = inject(IGX_INPUT_GROUP_TYPE, { optional: true });
this.document = inject(DOCUMENT);
this.platform = inject(PlatformUtil);
this.cdr = inject(ChangeDetectorRef);
this.themeToken = inject(THEME_TOKEN);
/**
* Property that enables/disables the auto-generated class of the `IgxInputGroupComponent`.
* By default applied the class is applied.
* ```typescript
* @ViewChild("MyInputGroup")
* public inputGroup: IgxInputGroupComponent;
* ngAfterViewInit(){
* this.inputGroup.defaultClass = false;
* ```
* }
*/
this.defaultClass = true;
/** @hidden */
this.hasPlaceholder = false;
/** @hidden */
this.isRequired = false;
/** @hidden */
this.isFocused = false;
/**
* @hidden @internal
* When truthy, disables the `IgxInputGroupComponent`.
* Controlled by the underlying `IgxInputDirective`.
* ```html
* <igx-input-group [disabled]="true"></igx-input-group>
* ```
*/
this.disabled = false;
/**
* Prevents automatically focusing the input when clicking on other elements in the input group (e.g. prefix or suffix).
*
* @remarks Automatic focus causes software keyboard to show on mobile devices.
*
* @example
* ```html
* <igx-input-group [suppressInputAutofocus]="true"></igx-input-group>
* ```
*/
this.suppressInputAutofocus = false;
/** @hidden */
this.hasWarning = false;
this._destroyRef = inject(DestroyRef);
this._type = null;
this._filled = false;
this._resourceStrings = getCurrentResourceStrings(InputResourceStringsEN);
this._theme = this.themeToken.theme;
const themeChange = this.themeToken.onChange((theme) => {
if (this._theme !== theme) {
this._theme = theme;
this.cdr.detectChanges();
}
});
this._destroyRef.onDestroy(() => themeChange.unsubscribe());
}
/** @hidden */
onClick(event) {
if (!this.isFocused &&
event.target !== this.input.nativeElement &&
!this.suppressInputAutofocus) {
this.input.focus();
}
}
/** @hidden */
onPointerDown(event) {
if (this.isFocused && event.target !== this.input.nativeElement) {
event.preventDefault();
}
}
/** @hidden @internal */
hintClickHandler(event) {
event.stopPropagation();
}
/**
* Returns whether the `IgxInputGroupComponent` has hints.
* ```typescript
* @ViewChild("MyInputGroup")
* public inputGroup: IgxInputGroupComponent;
* ngAfterViewInit(){
* let inputHints = this.inputGroup.hasHints;
* }
* ```
*/
get hasHints() {
return this.hints.length > 0;
}
/** @hidden @internal */
get hasPrefixes() {
return this._prefixes.length > 0;
}
/** @hidden @internal */
set prefixes(items) {
this._prefixes = items;
}
/** @hidden @internal */
get hasSuffixes() {
return this._suffixes.length > 0 || this.isFileType && this.isFilled;
}
/** @hidden @internal */
set suffixes(items) {
this._suffixes = items;
}
/**
* Returns whether the `IgxInputGroupComponent` has border.
* ```typescript
* @ViewChild("MyInputGroup")
* public inputGroup: IgxInputGroupComponent;
* ngAfterViewInit(){
* let inputBorder = this.inputGroup.hasBorder;
* }
* ```
*/
get hasBorder() {
return ((this.type === 'line' || this.type === 'box') &&
this._theme === 'material');
}
/**
* Returns whether the `IgxInputGroupComponent` type is line.
* ```typescript
* @ViewChild("MyInputGroup1")
* public inputGroup: IgxInputGroupComponent;
* ngAfterViewInit(){
* let isTypeLine = this.inputGroup.isTypeLine;
* }
* ```
*/
get isTypeLine() {
return this.type === 'line' && this._theme === 'material';
}
/**
* Returns whether the `IgxInputGroupComponent` type is box.
* ```typescript
* @ViewChild("MyInputGroup1")
* public inputGroup: IgxInputGroupComponent;
* ngAfterViewInit(){
* let isTypeBox = this.inputGroup.isTypeBox;
* }
* ```
*/
get isTypeBox() {
return this.type === 'box' && this._theme === 'material';
}
/** @hidden @internal */
clearValueHandler() {
this.input.clear();
}
/** @hidden @internal */
get isFileType() {
return this.input.type === 'file';
}
/** @hidden @internal */
get isFileInput() {
return this.input.type === 'file';
}
/** @hidden @internal */
get isFileInputFilled() {
return this.isFileType && this.isFilled;
}
/** @hidden @internal */
get isFileInputFocused() {
return this.isFileType && this.isFocused;
}
/** @hidden @internal */
get isFileInputDisabled() {
return this.isFileType && this.disabled;
}
/** @hidden @internal */
get fileNames() {
return this.input.fileNames || this._resourceStrings.igx_input_file_placeholder;
}
/**
* Returns whether the `IgxInputGroupComponent` type is border.
* ```typescript
* @ViewChild("MyInputGroup1")
* public inputGroup: IgxInputGroupComponent;
* ngAfterViewInit(){
* let isTypeBorder = this.inputGroup.isTypeBorder;
* }
* ```
*/
get isTypeBorder() {
return this.type === 'border' && this._theme === 'material';
}
/**
* Returns true if the `IgxInputGroupComponent` theme is Fluent.
* ```typescript
* @ViewChild("MyInputGroup1")
* public inputGroup: IgxInputGroupComponent;
* ngAfterViewInit(){
* let isTypeFluent = this.inputGroup.isTypeFluent;
* }
* ```
*/
get isTypeFluent() {
return this._theme === 'fluent';
}
/**
* Returns true if the `IgxInputGroupComponent` theme is Bootstrap.
* ```typescript
* @ViewChild("MyInputGroup1")
* public inputGroup: IgxInputGroupComponent;
* ngAfterViewInit(){
* let isTypeBootstrap = this.inputGroup.isTypeBootstrap;
* }
* ```
*/
get isTypeBootstrap() {
return this._theme === 'bootstrap';
}
/**
* Returns true if the `IgxInputGroupComponent` theme is Indigo.
* ```typescript
* @ViewChild("MyInputGroup1")
* public inputGroup: IgxInputGroupComponent;
* ngAfterViewInit(){
* let isTypeIndigo = this.inputGroup.isTypeIndigo;
* }
* ```
*/
get isTypeIndigo() {
return this._theme === 'indigo';
}
/**
* Returns whether the `IgxInputGroupComponent` type is search.
* ```typescript
* @ViewChild("MyInputGroup1")
* public inputGroup: IgxInputGroupComponent;
* ngAfterViewInit(){
* let isTypeSearch = this.inputGroup.isTypeSearch;
* }
* ```
*/
get isTypeSearch() {
if (!this.isFileType && !this.input.isTextArea) {
return this.type === 'search';
}
}
/** @hidden */
get filled() {
return this._filled;
}
/** @hidden */
set filled(val) {
this._filled = val;
}
setComponentTheme() {
if (!this.themeToken.preferToken) {
const theme = getComponentTheme(this.element.nativeElement);
if (theme && theme !== this._theme) {
this.theme = theme;
this.cdr.markForCheck();
}
}
}
/** @hidden @internal */
ngAfterContentChecked() {
this.setComponentTheme();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxInputGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.2", type: IgxInputGroupComponent, isStandalone: true, selector: "igx-input-group", inputs: { resourceStrings: "resourceStrings", suppressInputAutofocus: ["suppressInputAutofocus", "suppressInputAutofocus", booleanAttribute], type: "type", theme: "theme" }, host: { listeners: { "click": "onClick($event)", "pointerdown": "onPointerDown($event)" }, properties: { "class.igx-input-group": "this.defaultClass", "class.igx-input-group--placeholder": "this.hasPlaceholder", "class.igx-input-group--required": "this.isRequired", "class.igx-input-group--focused": "this.isFocused", "class.igx-input-group--disabled": "this.disabled", "class.igx-input-group--warning": "this.hasWarning", "class.igx-input-group--readonly": "this.readOnly", "class.igx-input-group--valid": "this.validClass", "class.igx-input-group--invalid": "this.invalidClass", "class.igx-input-group--filled": "this.isFilled", "class.igx-input-group--textarea-group": "this.textAreaClass", "class.igx-input-group--prefixed": "this.hasPrefixes", "class.igx-input-group--suffixed": "this.hasSuffixes", "class.igx-input-group--box": "this.isTypeBox", "class.igx-input-group--file": "this.isFileType", "class.igx-file-input": "this.isFileInput", "class.igx-file-input--filled": "this.isFileInputFilled", "class.igx-file-input--focused": "this.isFileInputFocused", "class.igx-file-input--disabled": "this.isFileInputDisabled", "class.igx-input-group--border": "this.isTypeBorder", "class.igx-input-group--fluent": "this.isTypeFluent", "class.igx-input-group--bootstrap": "this.isTypeBootstrap", "class.igx-input-group--indigo": "this.isTypeIndigo", "class.igx-input-group--search": "this.isTypeSearch" } }, providers: [{ provide: IgxInputGroupBase, useExisting: IgxInputGroupComponent }], queries: [{ propertyName: "input", first: true, predicate: IgxInputDirective, descendants: true, read: IgxInputDirective, static: true }, { propertyName: "hints", predicate: IgxHintDirective, read: IgxHintDirective }, { propertyName: "_prefixes", predicate: IgxPrefixDirective, descendants: true, read: IgxPrefixDirective }, { propertyName: "_suffixes", predicate: IgxSuffixDirective, descendants: true, read: IgxSuffixDirective }], ngImport: i0, template: "@if (isTypeBox) {\n <div class=\"igx-input-group__wrapper\">\n <ng-container *ngTemplateOutlet=\"bundle\"></ng-container>\n </div>\n} @else {\n <ng-container *ngTemplateOutlet=\"bundle\"></ng-container>\n}\n\n<div class=\"igx-input-group__hint\" (click)=\"hintClickHandler($event)\">\n <ng-content select=\"igx-hint, [igxHint]\"></ng-content>\n</div>\n\n<ng-template #label>\n <ng-content select=\"[igxLabel]\"></ng-content>\n</ng-template>\n\n<ng-template #input>\n <ng-content select=\"[igxInput]\"></ng-content>\n</ng-template>\n\n<ng-template #prefix>\n <ng-content select=\"igx-prefix, [igxPrefix]\"></ng-content>\n</ng-template>\n\n<!-- Dummy usage to satisfy Angular compiler -->\n<ng-template #dummy><span igxPrefix hidden></span></ng-template>\n\n<ng-template #uploadButton>\n @if (isFileType) {\n <div class=\"igx-input-group__upload-button igx-file-input__upload-button-wrapper\">\n <button\n igxButton=\"flat\"\n type=\"button\"\n tabindex=\"-1\"\n [disabled]=\"disabled\"\n class=\"igx-file-input__upload-button\"\n >\n {{ resourceStrings.igx_input_upload_button }}\n </button>\n </div>\n }\n</ng-template>\n\n<ng-template #files>\n @if (isFileType) {\n <div\n class=\"igx-input-group__file-input igx-file-input__file-names\"\n [title]=\"fileNames\"\n >\n <span>{{ fileNames }}</span>\n </div>\n }\n</ng-template>\n\n<ng-template #clear>\n @if (isFileType && isFilled) {\n <igx-suffix\n class=\"igx-input-group__clear-icon igx-file-input__clear-icon\"\n (click)=\"clearValueHandler()\"\n (keydown.Enter)=\"clearValueHandler()\"\n title=\"clear files\"\n tabindex=\"0\"\n >\n <igx-icon family=\"default\" name=\"input_clear\"></igx-icon>\n </igx-suffix>\n }\n</ng-template>\n\n<ng-template #suffix>\n <ng-content select=\"igx-suffix, [igxSuffix]\"></ng-content>\n</ng-template>\n\n<ng-template #materialBundle>\n <div class=\"igx-input-group__bundle\">\n <div class=\"igx-input-group__bundle-start\">\n <ng-container *ngTemplateOutlet=\"prefix\"></ng-container>\n </div>\n\n <ng-container>\n <div class=\"igx-input-group__notch\">\n <ng-container *ngTemplateOutlet=\"label\"></ng-container>\n </div>\n </ng-container>\n\n <div class=\"igx-input-group__bundle-main\">\n <ng-container *ngTemplateOutlet=\"input\"></ng-container>\n <ng-container *ngTemplateOutlet=\"uploadButton\"></ng-container>\n <ng-container *ngTemplateOutlet=\"files\"></ng-container>\n </div>\n\n <div class=\"igx-input-group__filler\"></div>\n\n <div class=\"igx-input-group__bundle-end\">\n <ng-container *ngTemplateOutlet=\"clear\"></ng-container>\n <ng-container *ngTemplateOutlet=\"suffix\"></ng-container>\n </div>\n\n @if (hasBorder) {\n <div class=\"igx-input-group__line\"></div>\n }\n </div>\n</ng-template>\n\n<ng-template #fluentBundle>\n <ng-container *ngTemplateOutlet=\"label\"></ng-container>\n\n <div class=\"igx-input-group__bundle\">\n <div class=\"igx-input-group__bundle-start\">\n <ng-container *ngTemplateOutlet=\"prefix\"></ng-container>\n </div>\n\n\n <div class=\"igx-input-group__bundle-main\">\n <ng-container *ngTemplateOutlet=\"input\"></ng-container>\n <ng-container *ngTemplateOutlet=\"uploadButton\"></ng-container>\n <ng-container *ngTemplateOutlet=\"files\"></ng-container>\n </div>\n\n <div class=\"igx-input-group__bundle-end\">\n <ng-container *ngTemplateOutlet=\"clear\"></ng-container>\n <ng-container *ngTemplateOutlet=\"suffix\"></ng-container>\n </div>\n\n @if (hasBorder) {\n <div class=\"igx-input-group__line\"></div>\n }\n </div>\n</ng-template>\n\n<ng-template #bootstrapBundle>\n <ng-container *ngTemplateOutlet=\"label\"></ng-container>\n\n <div class=\"igx-input-group__bundle\">\n <div class=\"igx-input-group__bundle-start\">\n <ng-container *ngTemplateOutlet=\"prefix\"></ng-container>\n </div>\n\n <ng-container *ngTemplateOutlet=\"input\"></ng-container>\n <ng-container *ngTemplateOutlet=\"uploadButton\"></ng-container>\n <ng-container *ngTemplateOutlet=\"files\"></ng-container>\n\n <div class=\"igx-input-group__bundle-end\">\n <ng-container *ngTemplateOutlet=\"clear\"></ng-container>\n <ng-container *ngTemplateOutlet=\"suffix\"></ng-container>\n </div>\n </div>\n</ng-template>\n\n<ng-template #bundle>\n @switch (theme) {\n @case ('bootstrap') {\n <ng-container *ngTemplateOutlet=\"bootstrapBundle\"></ng-container>\n }\n @case ('fluent') {\n <ng-container *ngTemplateOutlet=\"fluentBundle\"></ng-container>\n }\n @case ('indigo') {\n <ng-container *ngTemplateOutlet=\"fluentBundle\"></ng-container>\n }\n @default {\n <ng-container *ngTemplateOutlet=\"materialBundle\"></ng-container>\n }\n }\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: IgxPrefixDirective, selector: "igx-prefix,[igxPrefix],[igxStart]" }, { kind: "directive", type: IgxButtonDirective, selector: "[igxButton]", inputs: ["selected", "igxButton", "igxLabel"], outputs: ["buttonSelected"] }, { kind: "directive", type: IgxSuffixDirective, selector: "igx-suffix,[igxSuffix],[igxEnd]" }, { kind: "component", type: IgxIconComponent, selector: "igx-icon", inputs: ["ariaHidden", "family", "name", "active"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxInputGroupComponent, decorators: [{
type: Component,
args: [{ selector: 'igx-input-group', providers: [{ provide: IgxInputGroupBase, useExisting: IgxInputGroupComponent }], imports: [NgTemplateOutlet, IgxPrefixDirective, IgxButtonDirective, IgxSuffixDirective, IgxIconComponent], template: "@if (isTypeBox) {\n <div class=\"igx-input-group__wrapper\">\n <ng-container *ngTemplateOutlet=\"bundle\"></ng-container>\n </div>\n} @else {\n <ng-container *ngTemplateOutlet=\"bundle\"></ng-container>\n}\n\n<div class=\"igx-input-group__hint\" (click)=\"hintClickHandler($event)\">\n <ng-content select=\"igx-hint, [igxHint]\"></ng-content>\n</div>\n\n<ng-template #label>\n <ng-content select=\"[igxLabel]\"></ng-content>\n</ng-template>\n\n<ng-template #input>\n <ng-content select=\"[igxInput]\"></ng-content>\n</ng-template>\n\n<ng-template #prefix>\n <ng-content select=\"igx-prefix, [igxPrefix]\"></ng-content>\n</ng-template>\n\n<!-- Dummy usage to satisfy Angular compiler -->\n<ng-template #dummy><span igxPrefix hidden></span></ng-template>\n\n<ng-template #uploadButton>\n @if (isFileType) {\n <div class=\"igx-input-group__upload-button igx-file-input__upload-button-wrapper\">\n <button\n igxButton=\"flat\"\n type=\"button\"\n tabindex=\"-1\"\n [disabled]=\"disabled\"\n class=\"igx-file-input__upload-button\"\n >\n {{ resourceStrings.igx_input_upload_button }}\n </button>\n </div>\n }\n</ng-template>\n\n<ng-template #files>\n @if (isFileType) {\n <div\n class=\"igx-input-group__file-input igx-file-input__file-names\"\n [title]=\"fileNames\"\n >\n <span>{{ fileNames }}</span>\n </div>\n }\n</ng-template>\n\n<ng-template #clear>\n @if (isFileType && isFilled) {\n <igx-suffix\n class=\"igx-input-group__clear-icon igx-file-input__clear-icon\"\n (click)=\"clearValueHandler()\"\n (keydown.Enter)=\"clearValueHandler()\"\n title=\"clear files\"\n tabindex=\"0\"\n >\n <igx-icon family=\"default\" name=\"input_clear\"></igx-icon>\n </igx-suffix>\n }\n</ng-template>\n\n<ng-template #suffix>\n <ng-content select=\"igx-suffix, [igxSuffix]\"></ng-content>\n</ng-template>\n\n<ng-template #materialBundle>\n <div class=\"igx-input-group__bundle\">\n <div class=\"igx-input-group__bundle-start\">\n <ng-container *ngTemplateOutlet=\"prefix\"></ng-container>\n </div>\n\n <ng-container>\n <div class=\"igx-input-group__notch\">\n <ng-container *ngTemplateOutlet=\"label\"></ng-container>\n </div>\n </ng-container>\n\n <div class=\"igx-input-group__bundle-main\">\n <ng-container *ngTemplateOutlet=\"input\"></ng-container>\n <ng-container *ngTemplateOutlet=\"uploadButton\"></ng-container>\n <ng-container *ngTemplateOutlet=\"files\"></ng-container>\n </div>\n\n <div class=\"igx-input-group__filler\"></div>\n\n <div class=\"igx-input-group__bundle-end\">\n <ng-container *ngTemplateOutlet=\"clear\"></ng-container>\n <ng-container *ngTemplateOutlet=\"suffix\"></ng-container>\n </div>\n\n @if (hasBorder) {\n <div class=\"igx-input-group__line\"></div>\n }\n </div>\n</ng-template>\n\n<ng-template #fluentBundle>\n <ng-container *ngTemplateOutlet=\"label\"></ng-container>\n\n <div class=\"igx-input-group__bundle\">\n <div class=\"igx-input-group__bundle-start\">\n <ng-container *ngTemplateOutlet=\"prefix\"></ng-container>\n </div>\n\n\n <div class=\"igx-input-group__bundle-main\">\n <ng-container *ngTemplateOutlet=\"input\"></ng-container>\n <ng-container *ngTemplateOutlet=\"uploadButton\"></ng-container>\n <ng-container *ngTemplateOutlet=\"files\"></ng-container>\n </div>\n\n <div class=\"igx-input-group__bundle-end\">\n <ng-container *ngTemplateOutlet=\"clear\"></ng-container>\n <ng-container *ngTemplateOutlet=\"suffix\"></ng-container>\n </div>\n\n @if (hasBorder) {\n <div class=\"igx-input-group__line\"></div>\n }\n </div>\n</ng-template>\n\n<ng-template #bootstrapBundle>\n <ng-container *ngTemplateOutlet=\"label\"></ng-container>\n\n <div class=\"igx-input-group__bundle\">\n <div class=\"igx-input-group__bundle-start\">\n <ng-container *ngTemplateOutlet=\"prefix\"></ng-container>\n </div>\n\n <ng-container *ngTemplateOutlet=\"input\"></ng-container>\n <ng-container *ngTemplateOutlet=\"uploadButton\"></ng-container>\n <ng-container *ngTemplateOutlet=\"files\"></ng-container>\n\n <div class=\"igx-input-group__bundle-end\">\n <ng-container *ngTemplateOutlet=\"clear\"></ng-container>\n <ng-container *ngTemplateOutlet=\"suffix\"></ng-container>\n </div>\n </div>\n</ng-template>\n\n<ng-template #bundle>\n @switch (theme) {\n @case ('bootstrap') {\n <ng-container *ngTemplateOutlet=\"bootstrapBundle\"></ng-container>\n }\n @case ('fluent') {\n <ng-container *ngTemplateOutlet=\"fluentBundle\"></ng-container>\n }\n @case ('indigo') {\n <ng-container *ngTemplateOutlet=\"fluentBundle\"></ng-container>\n }\n @default {\n <ng-container *ngTemplateOutlet=\"materialBundle\"></ng-container>\n }\n }\n</ng-template>\n" }]
}], ctorParameters: () => [], propDecorators: { resourceStrings: [{
type: Input
}], defaultClass: [{
type: HostBinding,
args: ['class.igx-input-group']
}], hasPlaceholder: [{
type: HostBinding,
args: ['class.igx-input-group--placeholder']
}], isRequired: [{
type: HostBinding,
args: ['class.igx-input-group--required']
}], isFocused: [{
type: HostBinding,
args: ['class.igx-input-group--focused']
}], disabled: [{
type: HostBinding,
args: ['class.igx-input-group--disabled']
}], suppressInputAutofocus: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], hasWarning: [{
type: HostBinding,
args: ['class.igx-input-group--warning']
}], hints: [{
type: ContentChildren,
args: [IgxHintDirective, { read: IgxHintDirective }]
}], _prefixes: [{
type: ContentChildren,
args: [IgxPrefixDirective, { read: IgxPrefixDirective, descendants: true }]
}], _suffixes: [{
type: ContentChildren,
args: [IgxSuffixDirective, { read: IgxSuffixDirective, descendants: true }]
}], input: [{
type: ContentChild,
args: [IgxInputDirective, { read: IgxInputDirective, static: true }]
}], readOnly: [{
type: HostBinding,
args: ['class.igx-input-group--readonly']
}], validClass: [{
type: HostBinding,
args: ['class.igx-input-group--valid']
}], invalidClass: [{
type: HostBinding,
args: ['class.igx-input-group--invalid']
}], isFilled: [{
type: HostBinding,
args: ['class.igx-input-group--filled']
}], textAreaClass: [{
type: HostBinding,
args: ['class.igx-input-group--textarea-group']
}], type: [{
type: