UNPKG

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
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: