• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

IgniteUI / igniteui-webcomponents / 25305468193

04 May 2026 06:58AM UTC coverage: 98.375% (+0.002%) from 98.373%
25305468193

Pull #2213

github

web-flow
Merge b940d381c into 4933be93d
Pull Request #2213: feat: Add support for submitting forms with the Enter key

5723 of 6018 branches covered (95.1%)

Branch coverage included in aggregate %.

60 of 60 new or added lines in 13 files covered. (100.0%)

9 existing lines in 3 files now uncovered.

40471 of 40939 relevant lines covered (98.86%)

1580.56 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.96
/src/components/input/input.ts
1
import { html } from 'lit';
14✔
2
import { property } from 'lit/decorators.js';
14✔
3
import { ifDefined } from 'lit/directives/if-defined.js';
14✔
4
import { live } from 'lit/directives/live.js';
14✔
5
import { addThemingController } from '../../theming/theming-controller.js';
14✔
6
import { addSlotController, setSlots } from '../common/controllers/slot.js';
14✔
7
import { registerComponent } from '../common/definitions/register.js';
14✔
8
import { createFormValueState } from '../common/mixins/forms/form-value.js';
14✔
9
import { partMap } from '../common/part-map.js';
14✔
10
import { addSafeEventListener, bindIf } from '../common/util.js';
14✔
11
import type {
14✔
12
  InputType,
14✔
13
  RangeTextSelectMode,
14✔
14
  SelectionRangeDirection,
14✔
15
} from '../types.js';
14✔
16
import IgcValidationContainerComponent from '../validation-container/validation-container.js';
14✔
17
import { IgcInputBaseComponent } from './input-base.js';
14✔
18
import { styles } from './themes/input.base.css.js';
14✔
19
import { styles as shared } from './themes/shared/input.common.css.js';
14✔
20
import { all } from './themes/themes.js';
14✔
21
import { numberValidators, stringValidators } from './validators.js';
14✔
22

14✔
23
const Slots = setSlots(
14✔
24
  'prefix',
14✔
25
  'suffix',
14✔
26
  'helper-text',
14✔
27
  'value-missing',
14✔
28
  'type-mismatch',
14✔
29
  'pattern-mismatch',
14✔
30
  'too-long',
14✔
31
  'too-short',
14✔
32
  'range-overflow',
14✔
33
  'range-underflow',
14✔
34
  'step-mismatch',
14✔
35
  'custom-error',
14✔
36
  'invalid'
14✔
37
);
14✔
38

14✔
39
/**
14✔
40
 * @element igc-input
14✔
41
 *
14✔
42
 * @slot prefix - Renders content before the input.
14✔
43
 * @slot suffix - Renders content after input.
14✔
44
 * @slot helper-text - Renders content below the input.
14✔
45
 * @slot value-missing - Renders content when the required validation fails.
14✔
46
 * @slot type-mismatch - Renders content when the a type url/email input pattern validation fails.
14✔
47
 * @slot pattern-mismatch - Renders content when the pattern validation fails.
14✔
48
 * @slot too-long - Renders content when the maxlength validation fails.
14✔
49
 * @slot too-short - Renders content when the minlength validation fails.
14✔
50
 * @slot range-overflow - Renders content when the max validation fails.
14✔
51
 * @slot range-underflow - Renders content when the min validation fails.
14✔
52
 * @slot step-mismatch - Renders content when the step validation fails.
14✔
53
 * @slot custom-error - Renders content when setCustomValidity(message) is set.
14✔
54
 * @slot invalid - Renders content when the component is in invalid state (validity.valid = false).
14✔
55
 *
14✔
56
 * @fires igcInput - Emitted when the control input receives user input.
14✔
57
 * @fires igcChange - Emitted when the control's checked state changes.
14✔
58
 *
14✔
59
 * @csspart container - The main wrapper that holds all main input elements.
14✔
60
 * @csspart input - The native input element.
14✔
61
 * @csspart label - The native label element.
14✔
62
 * @csspart prefix - The prefix wrapper.
14✔
63
 * @csspart suffix - The suffix wrapper.
14✔
64
 * @csspart helper-text - The helper text wrapper.
14✔
65
 */
14✔
66
export default class IgcInputComponent extends IgcInputBaseComponent {
14✔
67
  public static readonly tagName = 'igc-input';
14✔
68
  public static styles = [styles, shared];
14✔
69

14✔
70
  /* blazorSuppress */
14✔
71
  public static register(): void {
14✔
72
    registerComponent(IgcInputComponent, IgcValidationContainerComponent);
7✔
73
  }
7✔
74

14✔
75
  protected override readonly _themes = addThemingController(this, all);
14✔
76

14✔
77
  protected override readonly _slots = addSlotController(this, {
14✔
78
    slots: Slots,
14✔
79
  });
14✔
80

14✔
81
  protected override readonly _formValue = createFormValueState(this, {
14✔
82
    initialValue: '',
14✔
83
  });
14✔
84

14✔
85
  protected override get __validators() {
14✔
86
    return this.type !== 'number' ? stringValidators : numberValidators;
1,165✔
87
  }
1,165✔
88

14✔
89
  private _min?: number;
14✔
90
  private _max?: number;
14✔
91
  private _minLength?: number;
14✔
92
  private _maxLength?: number;
14✔
93
  private _pattern?: string;
14✔
94
  private _step?: number;
14✔
95

14✔
96
  /* @tsTwoWayProperty(true, "igcChange", "detail", false) */
14✔
97
  /**
14✔
98
   * The value of the control.
14✔
99
   * @attr
14✔
100
   */
14✔
101
  @property()
14✔
102
  public set value(value: string) {
14✔
103
    this._formValue.setValueAndFormState(value);
438✔
104
  }
438✔
105

14✔
106
  public get value(): string {
14✔
107
    return this._formValue.value;
8,439✔
108
  }
8,439✔
109

14✔
110
  /* alternateName: displayType */
14✔
111
  /**
14✔
112
   * The type attribute of the control.
14✔
113
   * @attr
14✔
114
   */
14✔
115
  @property({ reflect: true })
14✔
116
  public type: InputType = 'text';
14✔
117

14✔
118
  /**
14✔
119
   * Makes the control a readonly field.
14✔
120
   *
14✔
121
   * @attr readonly
14✔
122
   * @default false
14✔
123
   */
14✔
124
  @property({ type: Boolean, reflect: true })
14✔
125
  public readOnly = false;
14✔
126

14✔
127
  /**
14✔
128
   * The input mode attribute of the control.
14✔
129
   * See [relevant MDN article](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inputmode)
14✔
130
   * @attr inputmode
14✔
131
   */
14✔
132
  @property({ attribute: 'inputmode' })
14✔
133
  public override inputMode!: string;
14✔
134

14✔
135
  /**
14✔
136
   * The pattern attribute of the control.
14✔
137
   * @attr
14✔
138
   */
14✔
139
  @property()
14✔
140
  public set pattern(value: string | undefined) {
14✔
141
    this._pattern = value;
6✔
142
    this._validate();
6✔
143
  }
6✔
144

14✔
145
  public get pattern(): string | undefined {
14✔
146
    return this._pattern;
2,321✔
147
  }
2,321✔
148

14✔
149
  /**
14✔
150
   * The minimum string length required by the control.
14✔
151
   * @attr minlength
14✔
152
   */
14✔
153
  @property({ type: Number, attribute: 'minlength' })
14✔
154
  public set minLength(value: number | undefined) {
14✔
155
    this._minLength = value;
7✔
156
    this._validate();
7✔
157
  }
7✔
158

14✔
159
  public get minLength(): number | undefined {
14✔
160
    return this._minLength;
2,330✔
161
  }
2,330✔
162

14✔
163
  /**
14✔
164
   * The maximum string length of the control.
14✔
165
   * @attr maxlength
14✔
166
   */
14✔
167
  @property({ type: Number, attribute: 'maxlength' })
14✔
168
  public set maxLength(value: number | undefined) {
14✔
169
    this._maxLength = value;
6✔
170
    this._validate();
6✔
171
  }
6✔
172

14✔
173
  public get maxLength(): number | undefined {
14✔
174
    return this._maxLength;
2,325✔
175
  }
2,325✔
176

14✔
177
  /**
14✔
178
   * The min attribute of the control.
14✔
179
   * @attr
14✔
180
   */
14✔
181
  @property({ type: Number })
14✔
182
  public set min(value: number | undefined) {
14✔
183
    this._min = value;
6✔
184
    this._validate();
6✔
185
  }
6✔
186

14✔
187
  public get min(): number | undefined {
14✔
188
    return this._min;
1,325✔
189
  }
1,325✔
190

14✔
191
  /**
14✔
192
   * The max attribute of the control.
14✔
193
   * @attr
14✔
194
   */
14✔
195
  @property({ type: Number })
14✔
196
  public set max(value: number | undefined) {
14✔
197
    this._max = value;
6✔
198
    this._validate();
6✔
199
  }
6✔
200

14✔
201
  public get max(): number | undefined {
14✔
202
    return this._max;
1,271✔
203
  }
1,271✔
204

14✔
205
  /**
14✔
206
   * The step attribute of the control.
14✔
207
   * @attr
14✔
208
   */
14✔
209
  @property({ type: Number })
14✔
210
  public set step(value: number | undefined) {
14✔
211
    this._step = value;
7✔
212
    this._validate();
7✔
213
  }
7✔
214

14✔
215
  public get step(): number | undefined {
14✔
216
    return this._step;
1,265✔
217
  }
1,265✔
218

14✔
219
  /**
14✔
220
   * The autofocus attribute of the control.
14✔
221
   * @attr
14✔
222
   */
14✔
223
  @property({ type: Boolean })
14✔
224
  public override autofocus!: boolean;
14✔
225

14✔
226
  /**
14✔
227
   * The autocomplete attribute of the control.
14✔
228
   * @attr
14✔
229
   */
14✔
230
  @property()
14✔
231
  public autocomplete!: string;
14✔
232

14✔
233
  /**
14✔
234
   * Enables validation rules to be evaluated without restricting user input. This applies to the `maxLength` property for
14✔
235
   * string-type inputs or allows spin buttons to exceed the predefined `min/max` limits for number-type inputs.
14✔
236
   *
14✔
237
   * @attr validate-only
14✔
238
   * @default false
14✔
239
   */
14✔
240
  @property({ type: Boolean, reflect: true, attribute: 'validate-only' })
14✔
241
  public validateOnly = false;
14✔
242

14✔
243
  constructor() {
14✔
244
    super();
377✔
245
    addSafeEventListener(this, 'keydown', this._handleEnterKeydown);
377✔
246
  }
377✔
247

14✔
248
  /* blazorSuppress */
14✔
249
  /** Replaces the selected text in the input. */
14✔
250
  public setRangeText(
14✔
251
    replacement: string,
1✔
252
    start?: number,
1✔
253
    end?: number,
1✔
254
    selectMode: RangeTextSelectMode = 'preserve'
1✔
255
  ): void {
1✔
256
    this._input?.setRangeText(replacement, start!, end!, selectMode);
1✔
257
    this.value = this._input?.value ?? '';
1!
258
  }
1✔
259

14✔
260
  /* blazorSuppress */
14✔
261
  /** Sets the text selection range of the control */
14✔
262
  public setSelectionRange(
14✔
263
    start?: number,
×
UNCOV
264
    end?: number,
×
UNCOV
265
    direction: SelectionRangeDirection = 'none'
×
UNCOV
266
  ): void {
×
UNCOV
267
    this._input?.setSelectionRange(start ?? null, end ?? null, direction);
×
UNCOV
268
  }
×
269

14✔
270
  /** Increments the numeric value of the input by one or more steps. */
14✔
271
  public stepUp(n?: number): void {
14✔
272
    this._input?.stepUp(n);
2✔
273
    this.value = this._input?.value ?? '';
2!
274
  }
2✔
275

14✔
276
  /** Decrements the numeric value of the input by one or more steps. */
14✔
277
  public stepDown(n?: number): void {
14✔
278
    this._input?.stepDown(n);
2✔
279
    this.value = this._input?.value ?? '';
2!
280
  }
2✔
281

14✔
282
  private _handleInput(): void {
14✔
283
    this._setTouchedState();
6✔
284
    this.value = this._input?.value ?? '';
6!
285
    this.emitEvent('igcInput', { detail: this.value });
6✔
286
  }
6✔
287

14✔
288
  private _handleChange(): void {
14✔
289
    this._setTouchedState();
1✔
290
    this.value = this._input?.value ?? '';
1!
291
    this.emitEvent('igcChange', { detail: this.value });
1✔
292
  }
1✔
293

14✔
294
  protected _renderInput() {
14✔
295
    const hasNegativeTabIndex = this.getAttribute('tabindex') === '-1';
819✔
296
    const hasHelperText = this._slots.hasAssignedElements('helper-text');
819✔
297

819✔
298
    return html`
819✔
299
      <input
819✔
300
        id=${this._inputId}
819✔
301
        part=${partMap(this._resolvePartNames('input'))}
819✔
302
        name=${ifDefined(this.name)}
819✔
303
        type=${ifDefined(this.type)}
819✔
304
        pattern=${ifDefined(this.pattern)}
819✔
305
        placeholder=${ifDefined(this.placeholder)}
819✔
306
        .value=${live(this.value)}
819✔
307
        ?readonly=${this.readOnly}
819✔
308
        ?disabled=${this.disabled}
819✔
309
        ?required=${this.required}
819✔
310
        ?autofocus=${this.autofocus}
819✔
311
        tabindex=${bindIf(hasNegativeTabIndex, -1)}
819✔
312
        autocomplete=${ifDefined(this.autocomplete as any)}
819✔
313
        inputmode=${ifDefined(this.inputMode)}
819✔
314
        min=${bindIf(!this.validateOnly, this.min)}
819✔
315
        max=${bindIf(!this.validateOnly, this.max)}
819✔
316
        minlength=${ifDefined(this.minLength)}
819✔
317
        maxlength=${bindIf(!this.validateOnly, this.maxLength)}
819✔
318
        step=${ifDefined(this.step)}
819✔
319
        aria-describedby=${bindIf(hasHelperText, 'helper-text')}
819✔
320
        @change=${this._handleChange}
819✔
321
        @input=${this._handleInput}
819✔
322
        @blur=${this._handleBlur}
819✔
323
      />
819✔
324
    `;
819✔
325
  }
819✔
326
}
14✔
327

14✔
328
declare global {
14✔
329
  interface HTMLElementTagNameMap {
14✔
330
    'igc-input': IgcInputComponent;
14✔
331
  }
14✔
332
}
14✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc