@ionic/core 8.6.4 → 8.6.5-dev.11752243397.18475074

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -33,6 +33,7 @@ const InputOTP = /*@__PURE__*/ proxyCustomElement(class InputOTP extends HTMLEle
33
33
  this.isKeyboardNavigation = false;
34
34
  this.inputValues = [];
35
35
  this.hasFocus = false;
36
+ this.previousInputValues = [];
36
37
  /**
37
38
  * Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user.
38
39
  * Available options: `"off"`, `"none"`, `"on"`, `"sentences"`, `"words"`, `"characters"`.
@@ -133,19 +134,12 @@ const InputOTP = /*@__PURE__*/ proxyCustomElement(class InputOTP extends HTMLEle
133
134
  }
134
135
  };
135
136
  /**
136
- * Handles keyboard navigation and input for the OTP component.
137
+ * Handles keyboard navigation for the OTP component.
137
138
  *
138
139
  * Navigation:
139
140
  * - Backspace: Clears current input and moves to previous box if empty
140
141
  * - Arrow Left/Right: Moves focus between input boxes
141
142
  * - Tab: Allows normal tab navigation between components
142
- *
143
- * Input Behavior:
144
- * - Validates input against the allowed pattern
145
- * - When entering a key in a filled box:
146
- * - Shifts existing values right if there is room
147
- * - Updates the value of the input group
148
- * - Prevents default behavior to avoid automatic focus shift
149
143
  */
150
144
  this.onKeyDown = (index) => (event) => {
151
145
  const { length } = this;
@@ -200,69 +194,132 @@ const InputOTP = /*@__PURE__*/ proxyCustomElement(class InputOTP extends HTMLEle
200
194
  // Let all tab events proceed normally
201
195
  return;
202
196
  }
203
- // If the input box contains a value and the key being
204
- // entered is a valid key for the input box update the value
205
- // and shift the values to the right if there is room.
206
- if (this.inputValues[index] && this.validKeyPattern.test(event.key)) {
207
- if (!this.inputValues[length - 1]) {
208
- for (let i = length - 1; i > index; i--) {
209
- this.inputValues[i] = this.inputValues[i - 1];
210
- this.inputRefs[i].value = this.inputValues[i] || '';
211
- }
212
- }
213
- this.inputValues[index] = event.key;
214
- this.inputRefs[index].value = event.key;
215
- this.updateValue(event);
216
- // Prevent default to avoid the browser from
217
- // automatically moving the focus to the next input
218
- event.preventDefault();
219
- }
220
197
  };
198
+ /**
199
+ * Processes all input scenarios for each input box.
200
+ *
201
+ * This function manages:
202
+ * 1. Autofill handling
203
+ * 2. Input validation
204
+ * 3. Full selection replacement or typing in an empty box
205
+ * 4. Inserting in the middle with available space (shifting)
206
+ * 5. Single character replacement
207
+ */
221
208
  this.onInput = (index) => (event) => {
209
+ var _a, _b;
222
210
  const { length, validKeyPattern } = this;
223
- const value = event.target.value;
224
- // If the value is longer than 1 character (autofill), split it into
225
- // characters and filter out invalid ones
226
- if (value.length > 1) {
211
+ const input = event.target;
212
+ const value = input.value;
213
+ const previousValue = this.previousInputValues[index] || '';
214
+ // 1. Autofill handling
215
+ // If the length of the value increases by more than 1 from the previous
216
+ // value, treat this as autofill. This is to prevent the case where the
217
+ // user is typing a single character into an input box containing a value
218
+ // as that will trigger this function with a value length of 2 characters.
219
+ const isAutofill = value.length - previousValue.length > 1;
220
+ if (isAutofill) {
221
+ // Distribute valid characters across input boxes
227
222
  const validChars = value
228
223
  .split('')
229
224
  .filter((char) => validKeyPattern.test(char))
230
225
  .slice(0, length);
231
- // If there are no valid characters coming from the
232
- // autofill, all input refs have to be cleared after the
233
- // browser has finished the autofill behavior
234
- if (validChars.length === 0) {
235
- requestAnimationFrame(() => {
236
- this.inputRefs.forEach((input) => {
237
- input.value = '';
238
- });
239
- });
226
+ for (let i = 0; i < length; i++) {
227
+ this.inputValues[i] = validChars[i] || '';
228
+ if (this.inputRefs[i] != null) {
229
+ this.inputRefs[i].value = validChars[i] || '';
230
+ }
240
231
  }
241
- // Update the value of the input group and emit the input change event
242
- this.value = validChars.join('');
243
232
  this.updateValue(event);
244
- // Focus the first empty input box or the last input box if all boxes
245
- // are filled after a small delay to ensure the input boxes have been
246
- // updated before moving the focus
233
+ // Focus the next empty input or the last one
247
234
  setTimeout(() => {
248
- var _a;
249
235
  const nextIndex = validChars.length < length ? validChars.length : length - 1;
250
- (_a = this.inputRefs[nextIndex]) === null || _a === void 0 ? void 0 : _a.focus();
236
+ if (this.inputRefs[nextIndex] != null) {
237
+ this.inputRefs[nextIndex].focus();
238
+ }
251
239
  }, 20);
240
+ this.previousInputValues = [...this.inputValues];
252
241
  return;
253
242
  }
254
- // Only allow input if it matches the pattern
255
- if (value.length > 0 && !validKeyPattern.test(value)) {
256
- this.inputRefs[index].value = '';
257
- this.inputValues[index] = '';
243
+ // 2. Input validation
244
+ // If the character entered is invalid (does not match the pattern),
245
+ // restore the previous value and exit
246
+ if (value.length > 0 && !validKeyPattern.test(value[value.length - 1])) {
247
+ input.value = this.inputValues[index] || '';
248
+ this.previousInputValues[index] = this.inputValues[index] || '';
249
+ this.previousInputValues = [...this.inputValues];
258
250
  return;
259
251
  }
260
- // For single character input, fill the current box
261
- this.inputValues[index] = value;
262
- this.updateValue(event);
263
- if (value.length > 0) {
252
+ // 3. Full selection replacement or typing in an empty box
253
+ // If the user selects all text in the input box and types, or if the
254
+ // input box is empty, replace only this input box. If the box is empty,
255
+ // move to the next box, otherwise stay focused on this box.
256
+ const isAllSelected = input.selectionStart === 0 && input.selectionEnd === value.length;
257
+ const isEmpty = !this.inputValues[index];
258
+ if (isAllSelected || isEmpty) {
259
+ this.inputValues[index] = value;
260
+ input.value = value;
261
+ this.previousInputValues[index] = value;
262
+ this.updateValue(event);
264
263
  this.focusNext(index);
264
+ this.previousInputValues = [...this.inputValues];
265
+ return;
265
266
  }
267
+ // 4. Inserting in the middle with available space (shifting)
268
+ // If typing in a filled input box and there are empty boxes at the end,
269
+ // shift all values starting at the current box to the right, and insert
270
+ // the new character at the current box.
271
+ const hasAvailableBoxAtEnd = this.inputValues[this.inputValues.length - 1] === '';
272
+ if (this.inputValues[index] && hasAvailableBoxAtEnd && value.length === 2) {
273
+ // Get the inserted character (from event or by diffing value/previousValue)
274
+ let newChar = event.data;
275
+ if (!newChar) {
276
+ newChar = value.split('').find((c, i) => c !== previousValue[i]) || value[value.length - 1];
277
+ }
278
+ // Validate the new character before shifting
279
+ if (!validKeyPattern.test(newChar)) {
280
+ input.value = this.inputValues[index] || '';
281
+ this.previousInputValues[index] = this.inputValues[index] || '';
282
+ this.previousInputValues = [...this.inputValues];
283
+ return;
284
+ }
285
+ // Shift values right from the end to the insertion point
286
+ for (let i = this.inputValues.length - 1; i > index; i--) {
287
+ this.inputValues[i] = this.inputValues[i - 1];
288
+ if (this.inputRefs[i] != null) {
289
+ this.inputRefs[i].value = this.inputValues[i] || '';
290
+ }
291
+ }
292
+ this.inputValues[index] = newChar;
293
+ if (this.inputRefs[index] != null) {
294
+ this.inputRefs[index].value = newChar;
295
+ }
296
+ this.previousInputValues[index] = newChar;
297
+ this.updateValue(event);
298
+ this.previousInputValues = [...this.inputValues];
299
+ return;
300
+ }
301
+ // 5. Single character replacement
302
+ // Handles replacing a single character in a box containing a value based
303
+ // on the cursor position. We need the cursor position to determine which
304
+ // character was the last character typed. For example, if the user types "2"
305
+ // in an input box with the cursor at the beginning of the value of "6",
306
+ // the value will be "26", but we want to grab the "2" as the last character
307
+ // typed.
308
+ const cursorPos = (_a = input.selectionStart) !== null && _a !== void 0 ? _a : value.length;
309
+ const newCharIndex = cursorPos - 1;
310
+ const newChar = (_b = value[newCharIndex]) !== null && _b !== void 0 ? _b : value[0];
311
+ // Check if the new character is valid before updating the value
312
+ if (!validKeyPattern.test(newChar)) {
313
+ input.value = this.inputValues[index] || '';
314
+ this.previousInputValues[index] = this.inputValues[index] || '';
315
+ this.previousInputValues = [...this.inputValues];
316
+ return;
317
+ }
318
+ input.value = newChar;
319
+ this.inputValues[index] = newChar;
320
+ this.previousInputValues[index] = newChar;
321
+ this.updateValue(event);
322
+ this.previousInputValues = [...this.inputValues];
266
323
  };
267
324
  /**
268
325
  * Handles pasting text into the input OTP component.
@@ -272,7 +329,7 @@ const InputOTP = /*@__PURE__*/ proxyCustomElement(class InputOTP extends HTMLEle
272
329
  * the next empty input after pasting.
273
330
  */
274
331
  this.onPaste = (event) => {
275
- var _a, _b, _c;
332
+ var _a, _b;
276
333
  const { inputRefs, length, validKeyPattern } = this;
277
334
  event.preventDefault();
278
335
  const pastedText = (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text');
@@ -299,13 +356,8 @@ const InputOTP = /*@__PURE__*/ proxyCustomElement(class InputOTP extends HTMLEle
299
356
  this.updateValue(event);
300
357
  // Focus the next empty input after pasting
301
358
  // If all boxes are filled, focus the last input
302
- const nextEmptyIndex = validChars.length;
303
- if (nextEmptyIndex < length) {
304
- (_b = inputRefs[nextEmptyIndex]) === null || _b === void 0 ? void 0 : _b.focus();
305
- }
306
- else {
307
- (_c = inputRefs[length - 1]) === null || _c === void 0 ? void 0 : _c.focus();
308
- }
359
+ const nextEmptyIndex = validChars.length < length ? validChars.length : length - 1;
360
+ (_b = inputRefs[nextEmptyIndex]) === null || _b === void 0 ? void 0 : _b.focus();
309
361
  };
310
362
  }
311
363
  /**
@@ -444,6 +496,7 @@ const InputOTP = /*@__PURE__*/ proxyCustomElement(class InputOTP extends HTMLEle
444
496
  });
445
497
  // Update the value without emitting events
446
498
  this.value = this.inputValues.join('');
499
+ this.previousInputValues = [...this.inputValues];
447
500
  }
448
501
  /**
449
502
  * Updates the value of the input group.
@@ -565,7 +618,7 @@ const InputOTP = /*@__PURE__*/ proxyCustomElement(class InputOTP extends HTMLEle
565
618
  const tabbableIndex = this.getTabbableIndex();
566
619
  const pattern = this.getPattern();
567
620
  const hasDescription = ((_b = (_a = el.querySelector('.input-otp-description')) === null || _a === void 0 ? void 0 : _a.textContent) === null || _b === void 0 ? void 0 : _b.trim()) !== '';
568
- return (h(Host, { key: 'df8fca036cedea0812185a02e3b655d7d76285e0', class: createColorClasses(color, {
621
+ return (h(Host, { key: '084b4f7d148a55aef6b4b51c11483ee51d70d3bd', class: createColorClasses(color, {
569
622
  [mode]: true,
570
623
  'has-focus': hasFocus,
571
624
  [`input-otp-size-${size}`]: true,
@@ -573,10 +626,10 @@ const InputOTP = /*@__PURE__*/ proxyCustomElement(class InputOTP extends HTMLEle
573
626
  [`input-otp-fill-${fill}`]: true,
574
627
  'input-otp-disabled': disabled,
575
628
  'input-otp-readonly': readonly,
576
- }) }, h("div", Object.assign({ key: '831be3f939cf037f0eb8d7e37e0afd4ef9a3c2c5', role: "group", "aria-label": "One-time password input", class: "input-otp-group" }, inheritedAttributes), Array.from({ length }).map((_, index) => (h(Fragment, null, h("div", { class: "native-wrapper" }, h("input", { class: "native-input", id: `${inputId}-${index}`, "aria-label": `Input ${index + 1} of ${length}`, type: "text", autoCapitalize: autocapitalize, inputmode: inputmode, pattern: pattern, disabled: disabled, readOnly: readonly, tabIndex: index === tabbableIndex ? 0 : -1, value: inputValues[index] || '', autocomplete: "one-time-code", ref: (el) => (inputRefs[index] = el), onInput: this.onInput(index), onBlur: this.onBlur, onFocus: this.onFocus(index), onKeyDown: this.onKeyDown(index), onPaste: this.onPaste })), this.showSeparator(index) && h("div", { class: "input-otp-separator" }))))), h("div", { key: '5311fedc34f7af3efd5f69e5a3d768055119c4f1', class: {
629
+ }) }, h("div", Object.assign({ key: '9d797deb7170bf6e4cc1acf70cca0b5d4ef51610', role: "group", "aria-label": "One-time password input", class: "input-otp-group" }, inheritedAttributes), Array.from({ length }).map((_, index) => (h(Fragment, null, h("div", { class: "native-wrapper" }, h("input", { class: "native-input", id: `${inputId}-${index}`, "aria-label": `Input ${index + 1} of ${length}`, type: "text", autoCapitalize: autocapitalize, inputmode: inputmode, pattern: pattern, disabled: disabled, readOnly: readonly, tabIndex: index === tabbableIndex ? 0 : -1, value: inputValues[index] || '', autocomplete: "one-time-code", ref: (el) => (inputRefs[index] = el), onInput: this.onInput(index), onBlur: this.onBlur, onFocus: this.onFocus(index), onKeyDown: this.onKeyDown(index), onPaste: this.onPaste })), this.showSeparator(index) && h("div", { class: "input-otp-separator" }))))), h("div", { key: 'a0463205729699430560032a68ade2e2ffa49b61', class: {
577
630
  'input-otp-description': true,
578
631
  'input-otp-description-hidden': !hasDescription,
579
- } }, h("slot", { key: '9e8afa2f7fa76c3092582dc27770fdf565a1b9ba' }))));
632
+ } }, h("slot", { key: '287fdaf0375cda3dcfafa2762d7daebf6f2bfe68' }))));
580
633
  }
581
634
  get el() { return this; }
582
635
  static get watchers() { return {
@@ -604,6 +657,7 @@ const InputOTP = /*@__PURE__*/ proxyCustomElement(class InputOTP extends HTMLEle
604
657
  "value": [1032],
605
658
  "inputValues": [32],
606
659
  "hasFocus": [32],
660
+ "previousInputValues": [32],
607
661
  "setFocus": [64]
608
662
  }, undefined, {
609
663
  "value": ["valueChanged"],
@@ -32,6 +32,7 @@ const InputOTP = class {
32
32
  this.isKeyboardNavigation = false;
33
33
  this.inputValues = [];
34
34
  this.hasFocus = false;
35
+ this.previousInputValues = [];
35
36
  /**
36
37
  * Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user.
37
38
  * Available options: `"off"`, `"none"`, `"on"`, `"sentences"`, `"words"`, `"characters"`.
@@ -132,19 +133,12 @@ const InputOTP = class {
132
133
  }
133
134
  };
134
135
  /**
135
- * Handles keyboard navigation and input for the OTP component.
136
+ * Handles keyboard navigation for the OTP component.
136
137
  *
137
138
  * Navigation:
138
139
  * - Backspace: Clears current input and moves to previous box if empty
139
140
  * - Arrow Left/Right: Moves focus between input boxes
140
141
  * - Tab: Allows normal tab navigation between components
141
- *
142
- * Input Behavior:
143
- * - Validates input against the allowed pattern
144
- * - When entering a key in a filled box:
145
- * - Shifts existing values right if there is room
146
- * - Updates the value of the input group
147
- * - Prevents default behavior to avoid automatic focus shift
148
142
  */
149
143
  this.onKeyDown = (index) => (event) => {
150
144
  const { length } = this;
@@ -199,69 +193,132 @@ const InputOTP = class {
199
193
  // Let all tab events proceed normally
200
194
  return;
201
195
  }
202
- // If the input box contains a value and the key being
203
- // entered is a valid key for the input box update the value
204
- // and shift the values to the right if there is room.
205
- if (this.inputValues[index] && this.validKeyPattern.test(event.key)) {
206
- if (!this.inputValues[length - 1]) {
207
- for (let i = length - 1; i > index; i--) {
208
- this.inputValues[i] = this.inputValues[i - 1];
209
- this.inputRefs[i].value = this.inputValues[i] || '';
210
- }
211
- }
212
- this.inputValues[index] = event.key;
213
- this.inputRefs[index].value = event.key;
214
- this.updateValue(event);
215
- // Prevent default to avoid the browser from
216
- // automatically moving the focus to the next input
217
- event.preventDefault();
218
- }
219
196
  };
197
+ /**
198
+ * Processes all input scenarios for each input box.
199
+ *
200
+ * This function manages:
201
+ * 1. Autofill handling
202
+ * 2. Input validation
203
+ * 3. Full selection replacement or typing in an empty box
204
+ * 4. Inserting in the middle with available space (shifting)
205
+ * 5. Single character replacement
206
+ */
220
207
  this.onInput = (index) => (event) => {
208
+ var _a, _b;
221
209
  const { length, validKeyPattern } = this;
222
- const value = event.target.value;
223
- // If the value is longer than 1 character (autofill), split it into
224
- // characters and filter out invalid ones
225
- if (value.length > 1) {
210
+ const input = event.target;
211
+ const value = input.value;
212
+ const previousValue = this.previousInputValues[index] || '';
213
+ // 1. Autofill handling
214
+ // If the length of the value increases by more than 1 from the previous
215
+ // value, treat this as autofill. This is to prevent the case where the
216
+ // user is typing a single character into an input box containing a value
217
+ // as that will trigger this function with a value length of 2 characters.
218
+ const isAutofill = value.length - previousValue.length > 1;
219
+ if (isAutofill) {
220
+ // Distribute valid characters across input boxes
226
221
  const validChars = value
227
222
  .split('')
228
223
  .filter((char) => validKeyPattern.test(char))
229
224
  .slice(0, length);
230
- // If there are no valid characters coming from the
231
- // autofill, all input refs have to be cleared after the
232
- // browser has finished the autofill behavior
233
- if (validChars.length === 0) {
234
- requestAnimationFrame(() => {
235
- this.inputRefs.forEach((input) => {
236
- input.value = '';
237
- });
238
- });
225
+ for (let i = 0; i < length; i++) {
226
+ this.inputValues[i] = validChars[i] || '';
227
+ if (this.inputRefs[i] != null) {
228
+ this.inputRefs[i].value = validChars[i] || '';
229
+ }
239
230
  }
240
- // Update the value of the input group and emit the input change event
241
- this.value = validChars.join('');
242
231
  this.updateValue(event);
243
- // Focus the first empty input box or the last input box if all boxes
244
- // are filled after a small delay to ensure the input boxes have been
245
- // updated before moving the focus
232
+ // Focus the next empty input or the last one
246
233
  setTimeout(() => {
247
- var _a;
248
234
  const nextIndex = validChars.length < length ? validChars.length : length - 1;
249
- (_a = this.inputRefs[nextIndex]) === null || _a === void 0 ? void 0 : _a.focus();
235
+ if (this.inputRefs[nextIndex] != null) {
236
+ this.inputRefs[nextIndex].focus();
237
+ }
250
238
  }, 20);
239
+ this.previousInputValues = [...this.inputValues];
251
240
  return;
252
241
  }
253
- // Only allow input if it matches the pattern
254
- if (value.length > 0 && !validKeyPattern.test(value)) {
255
- this.inputRefs[index].value = '';
256
- this.inputValues[index] = '';
242
+ // 2. Input validation
243
+ // If the character entered is invalid (does not match the pattern),
244
+ // restore the previous value and exit
245
+ if (value.length > 0 && !validKeyPattern.test(value[value.length - 1])) {
246
+ input.value = this.inputValues[index] || '';
247
+ this.previousInputValues[index] = this.inputValues[index] || '';
248
+ this.previousInputValues = [...this.inputValues];
257
249
  return;
258
250
  }
259
- // For single character input, fill the current box
260
- this.inputValues[index] = value;
261
- this.updateValue(event);
262
- if (value.length > 0) {
251
+ // 3. Full selection replacement or typing in an empty box
252
+ // If the user selects all text in the input box and types, or if the
253
+ // input box is empty, replace only this input box. If the box is empty,
254
+ // move to the next box, otherwise stay focused on this box.
255
+ const isAllSelected = input.selectionStart === 0 && input.selectionEnd === value.length;
256
+ const isEmpty = !this.inputValues[index];
257
+ if (isAllSelected || isEmpty) {
258
+ this.inputValues[index] = value;
259
+ input.value = value;
260
+ this.previousInputValues[index] = value;
261
+ this.updateValue(event);
263
262
  this.focusNext(index);
263
+ this.previousInputValues = [...this.inputValues];
264
+ return;
264
265
  }
266
+ // 4. Inserting in the middle with available space (shifting)
267
+ // If typing in a filled input box and there are empty boxes at the end,
268
+ // shift all values starting at the current box to the right, and insert
269
+ // the new character at the current box.
270
+ const hasAvailableBoxAtEnd = this.inputValues[this.inputValues.length - 1] === '';
271
+ if (this.inputValues[index] && hasAvailableBoxAtEnd && value.length === 2) {
272
+ // Get the inserted character (from event or by diffing value/previousValue)
273
+ let newChar = event.data;
274
+ if (!newChar) {
275
+ newChar = value.split('').find((c, i) => c !== previousValue[i]) || value[value.length - 1];
276
+ }
277
+ // Validate the new character before shifting
278
+ if (!validKeyPattern.test(newChar)) {
279
+ input.value = this.inputValues[index] || '';
280
+ this.previousInputValues[index] = this.inputValues[index] || '';
281
+ this.previousInputValues = [...this.inputValues];
282
+ return;
283
+ }
284
+ // Shift values right from the end to the insertion point
285
+ for (let i = this.inputValues.length - 1; i > index; i--) {
286
+ this.inputValues[i] = this.inputValues[i - 1];
287
+ if (this.inputRefs[i] != null) {
288
+ this.inputRefs[i].value = this.inputValues[i] || '';
289
+ }
290
+ }
291
+ this.inputValues[index] = newChar;
292
+ if (this.inputRefs[index] != null) {
293
+ this.inputRefs[index].value = newChar;
294
+ }
295
+ this.previousInputValues[index] = newChar;
296
+ this.updateValue(event);
297
+ this.previousInputValues = [...this.inputValues];
298
+ return;
299
+ }
300
+ // 5. Single character replacement
301
+ // Handles replacing a single character in a box containing a value based
302
+ // on the cursor position. We need the cursor position to determine which
303
+ // character was the last character typed. For example, if the user types "2"
304
+ // in an input box with the cursor at the beginning of the value of "6",
305
+ // the value will be "26", but we want to grab the "2" as the last character
306
+ // typed.
307
+ const cursorPos = (_a = input.selectionStart) !== null && _a !== void 0 ? _a : value.length;
308
+ const newCharIndex = cursorPos - 1;
309
+ const newChar = (_b = value[newCharIndex]) !== null && _b !== void 0 ? _b : value[0];
310
+ // Check if the new character is valid before updating the value
311
+ if (!validKeyPattern.test(newChar)) {
312
+ input.value = this.inputValues[index] || '';
313
+ this.previousInputValues[index] = this.inputValues[index] || '';
314
+ this.previousInputValues = [...this.inputValues];
315
+ return;
316
+ }
317
+ input.value = newChar;
318
+ this.inputValues[index] = newChar;
319
+ this.previousInputValues[index] = newChar;
320
+ this.updateValue(event);
321
+ this.previousInputValues = [...this.inputValues];
265
322
  };
266
323
  /**
267
324
  * Handles pasting text into the input OTP component.
@@ -271,7 +328,7 @@ const InputOTP = class {
271
328
  * the next empty input after pasting.
272
329
  */
273
330
  this.onPaste = (event) => {
274
- var _a, _b, _c;
331
+ var _a, _b;
275
332
  const { inputRefs, length, validKeyPattern } = this;
276
333
  event.preventDefault();
277
334
  const pastedText = (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text');
@@ -298,13 +355,8 @@ const InputOTP = class {
298
355
  this.updateValue(event);
299
356
  // Focus the next empty input after pasting
300
357
  // If all boxes are filled, focus the last input
301
- const nextEmptyIndex = validChars.length;
302
- if (nextEmptyIndex < length) {
303
- (_b = inputRefs[nextEmptyIndex]) === null || _b === void 0 ? void 0 : _b.focus();
304
- }
305
- else {
306
- (_c = inputRefs[length - 1]) === null || _c === void 0 ? void 0 : _c.focus();
307
- }
358
+ const nextEmptyIndex = validChars.length < length ? validChars.length : length - 1;
359
+ (_b = inputRefs[nextEmptyIndex]) === null || _b === void 0 ? void 0 : _b.focus();
308
360
  };
309
361
  }
310
362
  /**
@@ -443,6 +495,7 @@ const InputOTP = class {
443
495
  });
444
496
  // Update the value without emitting events
445
497
  this.value = this.inputValues.join('');
498
+ this.previousInputValues = [...this.inputValues];
446
499
  }
447
500
  /**
448
501
  * Updates the value of the input group.
@@ -564,7 +617,7 @@ const InputOTP = class {
564
617
  const tabbableIndex = this.getTabbableIndex();
565
618
  const pattern = this.getPattern();
566
619
  const hasDescription = ((_b = (_a = el.querySelector('.input-otp-description')) === null || _a === void 0 ? void 0 : _a.textContent) === null || _b === void 0 ? void 0 : _b.trim()) !== '';
567
- return (index.h(index.Host, { key: 'df8fca036cedea0812185a02e3b655d7d76285e0', class: theme.createColorClasses(color, {
620
+ return (index.h(index.Host, { key: '084b4f7d148a55aef6b4b51c11483ee51d70d3bd', class: theme.createColorClasses(color, {
568
621
  [mode]: true,
569
622
  'has-focus': hasFocus,
570
623
  [`input-otp-size-${size}`]: true,
@@ -572,10 +625,10 @@ const InputOTP = class {
572
625
  [`input-otp-fill-${fill}`]: true,
573
626
  'input-otp-disabled': disabled,
574
627
  'input-otp-readonly': readonly,
575
- }) }, index.h("div", Object.assign({ key: '831be3f939cf037f0eb8d7e37e0afd4ef9a3c2c5', role: "group", "aria-label": "One-time password input", class: "input-otp-group" }, inheritedAttributes), Array.from({ length }).map((_, index$1) => (index.h(index.Fragment, null, index.h("div", { class: "native-wrapper" }, index.h("input", { class: "native-input", id: `${inputId}-${index$1}`, "aria-label": `Input ${index$1 + 1} of ${length}`, type: "text", autoCapitalize: autocapitalize, inputmode: inputmode, pattern: pattern, disabled: disabled, readOnly: readonly, tabIndex: index$1 === tabbableIndex ? 0 : -1, value: inputValues[index$1] || '', autocomplete: "one-time-code", ref: (el) => (inputRefs[index$1] = el), onInput: this.onInput(index$1), onBlur: this.onBlur, onFocus: this.onFocus(index$1), onKeyDown: this.onKeyDown(index$1), onPaste: this.onPaste })), this.showSeparator(index$1) && index.h("div", { class: "input-otp-separator" }))))), index.h("div", { key: '5311fedc34f7af3efd5f69e5a3d768055119c4f1', class: {
628
+ }) }, index.h("div", Object.assign({ key: '9d797deb7170bf6e4cc1acf70cca0b5d4ef51610', role: "group", "aria-label": "One-time password input", class: "input-otp-group" }, inheritedAttributes), Array.from({ length }).map((_, index$1) => (index.h(index.Fragment, null, index.h("div", { class: "native-wrapper" }, index.h("input", { class: "native-input", id: `${inputId}-${index$1}`, "aria-label": `Input ${index$1 + 1} of ${length}`, type: "text", autoCapitalize: autocapitalize, inputmode: inputmode, pattern: pattern, disabled: disabled, readOnly: readonly, tabIndex: index$1 === tabbableIndex ? 0 : -1, value: inputValues[index$1] || '', autocomplete: "one-time-code", ref: (el) => (inputRefs[index$1] = el), onInput: this.onInput(index$1), onBlur: this.onBlur, onFocus: this.onFocus(index$1), onKeyDown: this.onKeyDown(index$1), onPaste: this.onPaste })), this.showSeparator(index$1) && index.h("div", { class: "input-otp-separator" }))))), index.h("div", { key: 'a0463205729699430560032a68ade2e2ffa49b61', class: {
576
629
  'input-otp-description': true,
577
630
  'input-otp-description-hidden': !hasDescription,
578
- } }, index.h("slot", { key: '9e8afa2f7fa76c3092582dc27770fdf565a1b9ba' }))));
631
+ } }, index.h("slot", { key: '287fdaf0375cda3dcfafa2762d7daebf6f2bfe68' }))));
579
632
  }
580
633
  get el() { return index.getElement(this); }
581
634
  static get watchers() { return {