@ionic/core 8.7.3-dev.11755195979.1ec83531 → 8.7.3-dev.11755285796.12743331
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.
- package/components/ion-input.js +7 -38
- package/components/ion-refresher.js +18 -1
- package/components/ion-textarea.js +6 -37
- package/dist/cjs/ion-input.cjs.entry.js +7 -37
- package/dist/cjs/ion-refresher_2.cjs.entry.js +18 -1
- package/dist/cjs/ion-textarea.cjs.entry.js +6 -36
- package/dist/cjs/ionic.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/components/input/input.js +8 -39
- package/dist/collection/components/refresher/refresher.js +18 -1
- package/dist/collection/components/textarea/textarea.js +7 -38
- package/dist/docs.json +1 -1
- package/dist/esm/ion-input.entry.js +7 -37
- package/dist/esm/ion-refresher_2.entry.js +18 -1
- package/dist/esm/ion-textarea.entry.js +6 -36
- package/dist/esm/ionic.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/p-1488b7cc.entry.js +4 -0
- package/dist/ionic/p-8cdb4ff5.entry.js +4 -0
- package/dist/ionic/p-c5210d3e.entry.js +4 -0
- package/dist/types/components/input/input.d.ts +0 -9
- package/dist/types/components/textarea/textarea.d.ts +0 -9
- package/hydrate/index.js +31 -46
- package/hydrate/index.mjs +31 -46
- package/package.json +1 -1
- package/dist/ionic/p-44415a3b.entry.js +0 -4
- package/dist/ionic/p-ac2be9d6.entry.js +0 -4
- package/dist/ionic/p-f80f7416.entry.js +0 -4
package/components/ion-input.js
CHANGED
|
@@ -43,10 +43,6 @@ const Input = /*@__PURE__*/ proxyCustomElement(class Input extends HTMLElement {
|
|
|
43
43
|
* is applied in both cases.
|
|
44
44
|
*/
|
|
45
45
|
this.hasFocus = false;
|
|
46
|
-
/**
|
|
47
|
-
* Track validation state for proper aria-live announcements
|
|
48
|
-
*/
|
|
49
|
-
this.isInvalid = false;
|
|
50
46
|
/**
|
|
51
47
|
* Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user.
|
|
52
48
|
* Available options: `"off"`, `"none"`, `"on"`, `"sentences"`, `"words"`, `"characters"`.
|
|
@@ -231,31 +227,10 @@ const Input = /*@__PURE__*/ proxyCustomElement(class Input extends HTMLElement {
|
|
|
231
227
|
componentWillLoad() {
|
|
232
228
|
this.inheritedAttributes = Object.assign(Object.assign({}, inheritAriaAttributes(this.el)), inheritAttributes(this.el, ['tabindex', 'title', 'data-form-type', 'dir']));
|
|
233
229
|
}
|
|
234
|
-
/**
|
|
235
|
-
* Checks if the input is in an invalid state based on validation classes
|
|
236
|
-
*/
|
|
237
|
-
checkValidationState() {
|
|
238
|
-
return this.el.classList.contains('ion-touched') && this.el.classList.contains('ion-invalid');
|
|
239
|
-
}
|
|
240
230
|
connectedCallback() {
|
|
241
231
|
const { el } = this;
|
|
242
232
|
this.slotMutationController = createSlotMutationController(el, ['label', 'start', 'end'], () => forceUpdate(this));
|
|
243
233
|
this.notchController = createNotchController(el, () => this.notchSpacerEl, () => this.labelSlot);
|
|
244
|
-
// Watch for class changes to update validation state
|
|
245
|
-
if (Build.isBrowser) {
|
|
246
|
-
this.validationObserver = new MutationObserver(() => {
|
|
247
|
-
const newIsInvalid = this.checkValidationState();
|
|
248
|
-
if (this.isInvalid !== newIsInvalid) {
|
|
249
|
-
this.isInvalid = newIsInvalid;
|
|
250
|
-
}
|
|
251
|
-
});
|
|
252
|
-
this.validationObserver.observe(el, {
|
|
253
|
-
attributes: true,
|
|
254
|
-
attributeFilter: ['class'],
|
|
255
|
-
});
|
|
256
|
-
// Set initial state
|
|
257
|
-
this.isInvalid = this.checkValidationState();
|
|
258
|
-
}
|
|
259
234
|
this.debounceChanged();
|
|
260
235
|
if (Build.isBrowser) {
|
|
261
236
|
document.dispatchEvent(new CustomEvent('ionInputDidLoad', {
|
|
@@ -292,11 +267,6 @@ const Input = /*@__PURE__*/ proxyCustomElement(class Input extends HTMLElement {
|
|
|
292
267
|
this.notchController.destroy();
|
|
293
268
|
this.notchController = undefined;
|
|
294
269
|
}
|
|
295
|
-
// Clean up validation observer to prevent memory leaks
|
|
296
|
-
if (this.validationObserver) {
|
|
297
|
-
this.validationObserver.disconnect();
|
|
298
|
-
this.validationObserver = undefined;
|
|
299
|
-
}
|
|
300
270
|
}
|
|
301
271
|
/**
|
|
302
272
|
* Sets focus on the native `input` in `ion-input`. Use this method instead of the global
|
|
@@ -398,15 +368,15 @@ const Input = /*@__PURE__*/ proxyCustomElement(class Input extends HTMLElement {
|
|
|
398
368
|
* Renders the helper text or error text values
|
|
399
369
|
*/
|
|
400
370
|
renderHintText() {
|
|
401
|
-
const { helperText, errorText, helperTextId, errorTextId
|
|
371
|
+
const { helperText, errorText, helperTextId, errorTextId } = this;
|
|
402
372
|
return [
|
|
403
373
|
h("div", { id: helperTextId, class: "helper-text" }, helperText),
|
|
404
|
-
h("div", { id: errorTextId, class: "error-text"
|
|
374
|
+
h("div", { id: errorTextId, class: "error-text" }, errorText),
|
|
405
375
|
];
|
|
406
376
|
}
|
|
407
377
|
getHintTextID() {
|
|
408
|
-
const {
|
|
409
|
-
if (
|
|
378
|
+
const { el, helperText, errorText, helperTextId, errorTextId } = this;
|
|
379
|
+
if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
|
|
410
380
|
return errorTextId;
|
|
411
381
|
}
|
|
412
382
|
if (helperText) {
|
|
@@ -519,7 +489,7 @@ const Input = /*@__PURE__*/ proxyCustomElement(class Input extends HTMLElement {
|
|
|
519
489
|
* TODO(FW-5592): Remove hasStartEndSlots condition
|
|
520
490
|
*/
|
|
521
491
|
const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
|
|
522
|
-
return (h(Host, { key: '
|
|
492
|
+
return (h(Host, { key: '41b2526627e7d2773a80f011b123284203a71ca0', class: createColorClasses(this.color, {
|
|
523
493
|
[mode]: true,
|
|
524
494
|
'has-value': hasValue,
|
|
525
495
|
'has-focus': hasFocus,
|
|
@@ -530,14 +500,14 @@ const Input = /*@__PURE__*/ proxyCustomElement(class Input extends HTMLElement {
|
|
|
530
500
|
'in-item': inItem,
|
|
531
501
|
'in-item-color': hostContext('ion-item.ion-color', this.el),
|
|
532
502
|
'input-disabled': disabled,
|
|
533
|
-
}) }, h("label", { key: '
|
|
503
|
+
}) }, h("label", { key: '9ab078363e32528102b441ad1791d83f86fdcbdc', class: "input-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), h("div", { key: 'e34b594980ec62e4c618e827fadf7669a39ad0d8', class: "native-wrapper", onClick: this.onLabelClick }, h("slot", { key: '12dc04ead5502e9e5736240e918bf9331bf7b5d9', name: "start" }), h("input", Object.assign({ key: 'df356eb4ced23109b2c0242f36dc043aba8782d6', class: "native-input", ref: (input) => (this.nativeInput = input), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, min: this.min, max: this.max, minLength: this.minlength, maxLength: this.maxlength, multiple: this.multiple, name: this.name, pattern: this.pattern, placeholder: this.placeholder || '', readOnly: readonly, required: this.required, spellcheck: this.spellcheck, step: this.step, type: this.type, value: value, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeydown, onCompositionstart: this.onCompositionStart, onCompositionend: this.onCompositionEnd, "aria-describedby": this.getHintTextID(), "aria-invalid": this.getHintTextID() === this.errorTextId }, this.inheritedAttributes)), this.clearInput && !readonly && !disabled && (h("button", { key: 'f79f68cabcd4ea99419331174a377827db0c0741', "aria-label": "reset", type: "button", class: "input-clear-icon", onPointerDown: (ev) => {
|
|
534
504
|
/**
|
|
535
505
|
* This prevents mobile browsers from
|
|
536
506
|
* blurring the input when the clear
|
|
537
507
|
* button is activated.
|
|
538
508
|
*/
|
|
539
509
|
ev.preventDefault();
|
|
540
|
-
}, onClick: this.clearTextInput }, h("ion-icon", { key: '
|
|
510
|
+
}, onClick: this.clearTextInput }, h("ion-icon", { key: '237ec07ec2e10f08818a332bb596578c2c49f770', "aria-hidden": "true", icon: clearIconData }))), h("slot", { key: '1f0a3624aa3e8dc3c307a6762230ab698768a5e5', name: "end" })), shouldRenderHighlight && h("div", { key: '8a8cbb82695a722a0010b53dd0b1f1f97534a20b', class: "input-highlight" })), this.renderBottomContent()));
|
|
541
511
|
}
|
|
542
512
|
get el() { return this; }
|
|
543
513
|
static get watchers() { return {
|
|
@@ -586,7 +556,6 @@ const Input = /*@__PURE__*/ proxyCustomElement(class Input extends HTMLElement {
|
|
|
586
556
|
"type": [1],
|
|
587
557
|
"value": [1032],
|
|
588
558
|
"hasFocus": [32],
|
|
589
|
-
"isInvalid": [32],
|
|
590
559
|
"setFocus": [64],
|
|
591
560
|
"getInputElement": [64]
|
|
592
561
|
}, [[2, "click", "onClickCapture"]], {
|
|
@@ -182,6 +182,14 @@ const Refresher = /*@__PURE__*/ proxyCustomElement(class Refresher extends HTMLE
|
|
|
182
182
|
this.beginRefresh();
|
|
183
183
|
this.didRefresh = true;
|
|
184
184
|
hapticImpact({ style: ImpactStyle.Light });
|
|
185
|
+
/**
|
|
186
|
+
* Clear focus from any active element to prevent scroll jumps
|
|
187
|
+
* when the refresh completes
|
|
188
|
+
*/
|
|
189
|
+
const activeElement = document.activeElement;
|
|
190
|
+
if ((activeElement === null || activeElement === void 0 ? void 0 : activeElement.blur) !== undefined) {
|
|
191
|
+
activeElement.blur();
|
|
192
|
+
}
|
|
185
193
|
/**
|
|
186
194
|
* Translate the content element otherwise when pointer is removed
|
|
187
195
|
* from screen the scroll content will bounce back over the refresher
|
|
@@ -597,6 +605,15 @@ const Refresher = /*@__PURE__*/ proxyCustomElement(class Refresher extends HTMLE
|
|
|
597
605
|
this.state = 8 /* RefresherState.Refreshing */;
|
|
598
606
|
// place the content in a hangout position while it thinks
|
|
599
607
|
this.setCss(this.pullMin, this.snapbackDuration, true, '');
|
|
608
|
+
/**
|
|
609
|
+
* Clear focus from any active element to prevent the browser
|
|
610
|
+
* from restoring focus and causing scroll jumps after refresh.
|
|
611
|
+
* This ensures the view stays at the top after refresh completes.
|
|
612
|
+
*/
|
|
613
|
+
const activeElement = document.activeElement;
|
|
614
|
+
if ((activeElement === null || activeElement === void 0 ? void 0 : activeElement.blur) !== undefined) {
|
|
615
|
+
activeElement.blur();
|
|
616
|
+
}
|
|
600
617
|
// emit "refresh" because it was pulled down far enough
|
|
601
618
|
// and they let go to begin refreshing
|
|
602
619
|
this.ionRefresh.emit({
|
|
@@ -679,7 +696,7 @@ const Refresher = /*@__PURE__*/ proxyCustomElement(class Refresher extends HTMLE
|
|
|
679
696
|
}
|
|
680
697
|
render() {
|
|
681
698
|
const mode = getIonMode(this);
|
|
682
|
-
return (h(Host, { key: '
|
|
699
|
+
return (h(Host, { key: '2d1bd880877b698604542ab2d602d38b9504d975', slot: "fixed", class: {
|
|
683
700
|
[mode]: true,
|
|
684
701
|
// Used internally for styling
|
|
685
702
|
[`refresher-${mode}`]: true,
|
|
@@ -40,10 +40,6 @@ const Textarea = /*@__PURE__*/ proxyCustomElement(class Textarea extends HTMLEle
|
|
|
40
40
|
* is applied in both cases.
|
|
41
41
|
*/
|
|
42
42
|
this.hasFocus = false;
|
|
43
|
-
/**
|
|
44
|
-
* Track validation state for proper aria-live announcements
|
|
45
|
-
*/
|
|
46
|
-
this.isInvalid = false;
|
|
47
43
|
/**
|
|
48
44
|
* Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user.
|
|
49
45
|
* Available options: `"off"`, `"none"`, `"on"`, `"sentences"`, `"words"`, `"characters"`.
|
|
@@ -190,31 +186,10 @@ const Textarea = /*@__PURE__*/ proxyCustomElement(class Textarea extends HTMLEle
|
|
|
190
186
|
this.el.click();
|
|
191
187
|
}
|
|
192
188
|
}
|
|
193
|
-
/**
|
|
194
|
-
* Checks if the textarea is in an invalid state based on validation classes
|
|
195
|
-
*/
|
|
196
|
-
checkValidationState() {
|
|
197
|
-
return this.el.classList.contains('ion-touched') && this.el.classList.contains('ion-invalid');
|
|
198
|
-
}
|
|
199
189
|
connectedCallback() {
|
|
200
190
|
const { el } = this;
|
|
201
191
|
this.slotMutationController = createSlotMutationController(el, ['label', 'start', 'end'], () => forceUpdate(this));
|
|
202
192
|
this.notchController = createNotchController(el, () => this.notchSpacerEl, () => this.labelSlot);
|
|
203
|
-
// Watch for class changes to update validation state
|
|
204
|
-
if (Build.isBrowser) {
|
|
205
|
-
this.validationObserver = new MutationObserver(() => {
|
|
206
|
-
const newIsInvalid = this.checkValidationState();
|
|
207
|
-
if (this.isInvalid !== newIsInvalid) {
|
|
208
|
-
this.isInvalid = newIsInvalid;
|
|
209
|
-
}
|
|
210
|
-
});
|
|
211
|
-
this.validationObserver.observe(el, {
|
|
212
|
-
attributes: true,
|
|
213
|
-
attributeFilter: ['class'],
|
|
214
|
-
});
|
|
215
|
-
// Set initial state
|
|
216
|
-
this.isInvalid = this.checkValidationState();
|
|
217
|
-
}
|
|
218
193
|
this.debounceChanged();
|
|
219
194
|
if (Build.isBrowser) {
|
|
220
195
|
document.dispatchEvent(new CustomEvent('ionInputDidLoad', {
|
|
@@ -236,11 +211,6 @@ const Textarea = /*@__PURE__*/ proxyCustomElement(class Textarea extends HTMLEle
|
|
|
236
211
|
this.notchController.destroy();
|
|
237
212
|
this.notchController = undefined;
|
|
238
213
|
}
|
|
239
|
-
// Clean up validation observer to prevent memory leaks
|
|
240
|
-
if (this.validationObserver) {
|
|
241
|
-
this.validationObserver.disconnect();
|
|
242
|
-
this.validationObserver = undefined;
|
|
243
|
-
}
|
|
244
214
|
}
|
|
245
215
|
componentWillLoad() {
|
|
246
216
|
this.inheritedAttributes = Object.assign(Object.assign({}, inheritAriaAttributes(this.el)), inheritAttributes(this.el, ['data-form-type', 'title', 'tabindex', 'dir']));
|
|
@@ -411,15 +381,15 @@ const Textarea = /*@__PURE__*/ proxyCustomElement(class Textarea extends HTMLEle
|
|
|
411
381
|
* Renders the helper text or error text values
|
|
412
382
|
*/
|
|
413
383
|
renderHintText() {
|
|
414
|
-
const { helperText, errorText, helperTextId, errorTextId
|
|
384
|
+
const { helperText, errorText, helperTextId, errorTextId } = this;
|
|
415
385
|
return [
|
|
416
386
|
h("div", { id: helperTextId, class: "helper-text" }, helperText),
|
|
417
|
-
h("div", { id: errorTextId, class: "error-text"
|
|
387
|
+
h("div", { id: errorTextId, class: "error-text" }, errorText),
|
|
418
388
|
];
|
|
419
389
|
}
|
|
420
390
|
getHintTextID() {
|
|
421
|
-
const {
|
|
422
|
-
if (
|
|
391
|
+
const { el, helperText, errorText, helperTextId, errorTextId } = this;
|
|
392
|
+
if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
|
|
423
393
|
return errorTextId;
|
|
424
394
|
}
|
|
425
395
|
if (helperText) {
|
|
@@ -478,7 +448,7 @@ const Textarea = /*@__PURE__*/ proxyCustomElement(class Textarea extends HTMLEle
|
|
|
478
448
|
* TODO(FW-5592): Remove hasStartEndSlots condition
|
|
479
449
|
*/
|
|
480
450
|
const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
|
|
481
|
-
return (h(Host, { key: '
|
|
451
|
+
return (h(Host, { key: 'd9f2ede0107987fc42c99e310cd2336bad5a5755', class: createColorClasses(this.color, {
|
|
482
452
|
[mode]: true,
|
|
483
453
|
'has-value': hasValue,
|
|
484
454
|
'has-focus': hasFocus,
|
|
@@ -487,7 +457,7 @@ const Textarea = /*@__PURE__*/ proxyCustomElement(class Textarea extends HTMLEle
|
|
|
487
457
|
[`textarea-shape-${shape}`]: shape !== undefined,
|
|
488
458
|
[`textarea-label-placement-${labelPlacement}`]: true,
|
|
489
459
|
'textarea-disabled': disabled,
|
|
490
|
-
}) }, h("label", { key: '
|
|
460
|
+
}) }, h("label", { key: '9de598b95237462bb3bccffaefe83afbb43554b8', class: "textarea-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), h("div", { key: 'e33c426c6541d723ccc246bb404c03687726ff83', class: "textarea-wrapper-inner" }, h("div", { key: '521e11af9d54d281b0a2b1c25bcfc6f742c18296', class: "start-slot-wrapper" }, h("slot", { key: '515523f6ca3ce0e5dd08f3275c21a190fb1ca177', name: "start" })), h("div", { key: '916e01e00de8400ae00ef06bc1fb62d8be2eee08', class: "native-wrapper", ref: (el) => (this.textareaWrapper = el) }, h("textarea", Object.assign({ key: '810271e6532d90e27dab1fcb26546113c1ce9cb0', class: "native-textarea", ref: (el) => (this.nativeInput = el), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, minLength: this.minlength, maxLength: this.maxlength, name: this.name, placeholder: this.placeholder || '', readOnly: this.readonly, required: this.required, spellcheck: this.spellcheck, cols: this.cols, rows: this.rows, wrap: this.wrap, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeyDown, "aria-describedby": this.getHintTextID(), "aria-invalid": this.getHintTextID() === this.errorTextId }, this.inheritedAttributes), value)), h("div", { key: '80aca9ea9546dca9d38efd291a6b0be384bb6978', class: "end-slot-wrapper" }, h("slot", { key: '407fab16c66a9f4a542369bfecc0d9afa0065977', name: "end" }))), shouldRenderHighlight && h("div", { key: 'f00523a6698fac8a1996e04303487bef01d10f25', class: "textarea-highlight" })), this.renderBottomContent()));
|
|
491
461
|
}
|
|
492
462
|
get el() { return this; }
|
|
493
463
|
static get watchers() { return {
|
|
@@ -529,7 +499,6 @@ const Textarea = /*@__PURE__*/ proxyCustomElement(class Textarea extends HTMLEle
|
|
|
529
499
|
"labelPlacement": [1, "label-placement"],
|
|
530
500
|
"shape": [1],
|
|
531
501
|
"hasFocus": [32],
|
|
532
|
-
"isInvalid": [32],
|
|
533
502
|
"setFocus": [64],
|
|
534
503
|
"getInputElement": [64]
|
|
535
504
|
}, [[2, "click", "onClickCapture"]], {
|
|
@@ -44,10 +44,6 @@ const Input = class {
|
|
|
44
44
|
* is applied in both cases.
|
|
45
45
|
*/
|
|
46
46
|
this.hasFocus = false;
|
|
47
|
-
/**
|
|
48
|
-
* Track validation state for proper aria-live announcements
|
|
49
|
-
*/
|
|
50
|
-
this.isInvalid = false;
|
|
51
47
|
/**
|
|
52
48
|
* Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user.
|
|
53
49
|
* Available options: `"off"`, `"none"`, `"on"`, `"sentences"`, `"words"`, `"characters"`.
|
|
@@ -232,31 +228,10 @@ const Input = class {
|
|
|
232
228
|
componentWillLoad() {
|
|
233
229
|
this.inheritedAttributes = Object.assign(Object.assign({}, helpers.inheritAriaAttributes(this.el)), helpers.inheritAttributes(this.el, ['tabindex', 'title', 'data-form-type', 'dir']));
|
|
234
230
|
}
|
|
235
|
-
/**
|
|
236
|
-
* Checks if the input is in an invalid state based on validation classes
|
|
237
|
-
*/
|
|
238
|
-
checkValidationState() {
|
|
239
|
-
return this.el.classList.contains('ion-touched') && this.el.classList.contains('ion-invalid');
|
|
240
|
-
}
|
|
241
231
|
connectedCallback() {
|
|
242
232
|
const { el } = this;
|
|
243
233
|
this.slotMutationController = input_utils.createSlotMutationController(el, ['label', 'start', 'end'], () => index.forceUpdate(this));
|
|
244
234
|
this.notchController = notchController.createNotchController(el, () => this.notchSpacerEl, () => this.labelSlot);
|
|
245
|
-
// Watch for class changes to update validation state
|
|
246
|
-
{
|
|
247
|
-
this.validationObserver = new MutationObserver(() => {
|
|
248
|
-
const newIsInvalid = this.checkValidationState();
|
|
249
|
-
if (this.isInvalid !== newIsInvalid) {
|
|
250
|
-
this.isInvalid = newIsInvalid;
|
|
251
|
-
}
|
|
252
|
-
});
|
|
253
|
-
this.validationObserver.observe(el, {
|
|
254
|
-
attributes: true,
|
|
255
|
-
attributeFilter: ['class'],
|
|
256
|
-
});
|
|
257
|
-
// Set initial state
|
|
258
|
-
this.isInvalid = this.checkValidationState();
|
|
259
|
-
}
|
|
260
235
|
this.debounceChanged();
|
|
261
236
|
{
|
|
262
237
|
document.dispatchEvent(new CustomEvent('ionInputDidLoad', {
|
|
@@ -293,11 +268,6 @@ const Input = class {
|
|
|
293
268
|
this.notchController.destroy();
|
|
294
269
|
this.notchController = undefined;
|
|
295
270
|
}
|
|
296
|
-
// Clean up validation observer to prevent memory leaks
|
|
297
|
-
if (this.validationObserver) {
|
|
298
|
-
this.validationObserver.disconnect();
|
|
299
|
-
this.validationObserver = undefined;
|
|
300
|
-
}
|
|
301
271
|
}
|
|
302
272
|
/**
|
|
303
273
|
* Sets focus on the native `input` in `ion-input`. Use this method instead of the global
|
|
@@ -399,15 +369,15 @@ const Input = class {
|
|
|
399
369
|
* Renders the helper text or error text values
|
|
400
370
|
*/
|
|
401
371
|
renderHintText() {
|
|
402
|
-
const { helperText, errorText, helperTextId, errorTextId
|
|
372
|
+
const { helperText, errorText, helperTextId, errorTextId } = this;
|
|
403
373
|
return [
|
|
404
374
|
index.h("div", { id: helperTextId, class: "helper-text" }, helperText),
|
|
405
|
-
index.h("div", { id: errorTextId, class: "error-text"
|
|
375
|
+
index.h("div", { id: errorTextId, class: "error-text" }, errorText),
|
|
406
376
|
];
|
|
407
377
|
}
|
|
408
378
|
getHintTextID() {
|
|
409
|
-
const {
|
|
410
|
-
if (
|
|
379
|
+
const { el, helperText, errorText, helperTextId, errorTextId } = this;
|
|
380
|
+
if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
|
|
411
381
|
return errorTextId;
|
|
412
382
|
}
|
|
413
383
|
if (helperText) {
|
|
@@ -520,7 +490,7 @@ const Input = class {
|
|
|
520
490
|
* TODO(FW-5592): Remove hasStartEndSlots condition
|
|
521
491
|
*/
|
|
522
492
|
const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
|
|
523
|
-
return (index.h(index.Host, { key: '
|
|
493
|
+
return (index.h(index.Host, { key: '41b2526627e7d2773a80f011b123284203a71ca0', class: theme.createColorClasses(this.color, {
|
|
524
494
|
[mode]: true,
|
|
525
495
|
'has-value': hasValue,
|
|
526
496
|
'has-focus': hasFocus,
|
|
@@ -531,14 +501,14 @@ const Input = class {
|
|
|
531
501
|
'in-item': inItem,
|
|
532
502
|
'in-item-color': theme.hostContext('ion-item.ion-color', this.el),
|
|
533
503
|
'input-disabled': disabled,
|
|
534
|
-
}) }, index.h("label", { key: '
|
|
504
|
+
}) }, index.h("label", { key: '9ab078363e32528102b441ad1791d83f86fdcbdc', class: "input-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), index.h("div", { key: 'e34b594980ec62e4c618e827fadf7669a39ad0d8', class: "native-wrapper", onClick: this.onLabelClick }, index.h("slot", { key: '12dc04ead5502e9e5736240e918bf9331bf7b5d9', name: "start" }), index.h("input", Object.assign({ key: 'df356eb4ced23109b2c0242f36dc043aba8782d6', class: "native-input", ref: (input) => (this.nativeInput = input), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, min: this.min, max: this.max, minLength: this.minlength, maxLength: this.maxlength, multiple: this.multiple, name: this.name, pattern: this.pattern, placeholder: this.placeholder || '', readOnly: readonly, required: this.required, spellcheck: this.spellcheck, step: this.step, type: this.type, value: value, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeydown, onCompositionstart: this.onCompositionStart, onCompositionend: this.onCompositionEnd, "aria-describedby": this.getHintTextID(), "aria-invalid": this.getHintTextID() === this.errorTextId }, this.inheritedAttributes)), this.clearInput && !readonly && !disabled && (index.h("button", { key: 'f79f68cabcd4ea99419331174a377827db0c0741', "aria-label": "reset", type: "button", class: "input-clear-icon", onPointerDown: (ev) => {
|
|
535
505
|
/**
|
|
536
506
|
* This prevents mobile browsers from
|
|
537
507
|
* blurring the input when the clear
|
|
538
508
|
* button is activated.
|
|
539
509
|
*/
|
|
540
510
|
ev.preventDefault();
|
|
541
|
-
}, onClick: this.clearTextInput }, index.h("ion-icon", { key: '
|
|
511
|
+
}, onClick: this.clearTextInput }, index.h("ion-icon", { key: '237ec07ec2e10f08818a332bb596578c2c49f770', "aria-hidden": "true", icon: clearIconData }))), index.h("slot", { key: '1f0a3624aa3e8dc3c307a6762230ab698768a5e5', name: "end" })), shouldRenderHighlight && index.h("div", { key: '8a8cbb82695a722a0010b53dd0b1f1f97534a20b', class: "input-highlight" })), this.renderBottomContent()));
|
|
542
512
|
}
|
|
543
513
|
get el() { return index.getElement(this); }
|
|
544
514
|
static get watchers() { return {
|
|
@@ -375,6 +375,14 @@ const Refresher = class {
|
|
|
375
375
|
this.beginRefresh();
|
|
376
376
|
this.didRefresh = true;
|
|
377
377
|
haptic.hapticImpact({ style: haptic.ImpactStyle.Light });
|
|
378
|
+
/**
|
|
379
|
+
* Clear focus from any active element to prevent scroll jumps
|
|
380
|
+
* when the refresh completes
|
|
381
|
+
*/
|
|
382
|
+
const activeElement = document.activeElement;
|
|
383
|
+
if ((activeElement === null || activeElement === void 0 ? void 0 : activeElement.blur) !== undefined) {
|
|
384
|
+
activeElement.blur();
|
|
385
|
+
}
|
|
378
386
|
/**
|
|
379
387
|
* Translate the content element otherwise when pointer is removed
|
|
380
388
|
* from screen the scroll content will bounce back over the refresher
|
|
@@ -790,6 +798,15 @@ const Refresher = class {
|
|
|
790
798
|
this.state = 8 /* RefresherState.Refreshing */;
|
|
791
799
|
// place the content in a hangout position while it thinks
|
|
792
800
|
this.setCss(this.pullMin, this.snapbackDuration, true, '');
|
|
801
|
+
/**
|
|
802
|
+
* Clear focus from any active element to prevent the browser
|
|
803
|
+
* from restoring focus and causing scroll jumps after refresh.
|
|
804
|
+
* This ensures the view stays at the top after refresh completes.
|
|
805
|
+
*/
|
|
806
|
+
const activeElement = document.activeElement;
|
|
807
|
+
if ((activeElement === null || activeElement === void 0 ? void 0 : activeElement.blur) !== undefined) {
|
|
808
|
+
activeElement.blur();
|
|
809
|
+
}
|
|
793
810
|
// emit "refresh" because it was pulled down far enough
|
|
794
811
|
// and they let go to begin refreshing
|
|
795
812
|
this.ionRefresh.emit({
|
|
@@ -872,7 +889,7 @@ const Refresher = class {
|
|
|
872
889
|
}
|
|
873
890
|
render() {
|
|
874
891
|
const mode = ionicGlobal.getIonMode(this);
|
|
875
|
-
return (index.h(index.Host, { key: '
|
|
892
|
+
return (index.h(index.Host, { key: '2d1bd880877b698604542ab2d602d38b9504d975', slot: "fixed", class: {
|
|
876
893
|
[mode]: true,
|
|
877
894
|
// Used internally for styling
|
|
878
895
|
[`refresher-${mode}`]: true,
|
|
@@ -42,10 +42,6 @@ const Textarea = class {
|
|
|
42
42
|
* is applied in both cases.
|
|
43
43
|
*/
|
|
44
44
|
this.hasFocus = false;
|
|
45
|
-
/**
|
|
46
|
-
* Track validation state for proper aria-live announcements
|
|
47
|
-
*/
|
|
48
|
-
this.isInvalid = false;
|
|
49
45
|
/**
|
|
50
46
|
* Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user.
|
|
51
47
|
* Available options: `"off"`, `"none"`, `"on"`, `"sentences"`, `"words"`, `"characters"`.
|
|
@@ -192,31 +188,10 @@ const Textarea = class {
|
|
|
192
188
|
this.el.click();
|
|
193
189
|
}
|
|
194
190
|
}
|
|
195
|
-
/**
|
|
196
|
-
* Checks if the textarea is in an invalid state based on validation classes
|
|
197
|
-
*/
|
|
198
|
-
checkValidationState() {
|
|
199
|
-
return this.el.classList.contains('ion-touched') && this.el.classList.contains('ion-invalid');
|
|
200
|
-
}
|
|
201
191
|
connectedCallback() {
|
|
202
192
|
const { el } = this;
|
|
203
193
|
this.slotMutationController = input_utils.createSlotMutationController(el, ['label', 'start', 'end'], () => index.forceUpdate(this));
|
|
204
194
|
this.notchController = notchController.createNotchController(el, () => this.notchSpacerEl, () => this.labelSlot);
|
|
205
|
-
// Watch for class changes to update validation state
|
|
206
|
-
{
|
|
207
|
-
this.validationObserver = new MutationObserver(() => {
|
|
208
|
-
const newIsInvalid = this.checkValidationState();
|
|
209
|
-
if (this.isInvalid !== newIsInvalid) {
|
|
210
|
-
this.isInvalid = newIsInvalid;
|
|
211
|
-
}
|
|
212
|
-
});
|
|
213
|
-
this.validationObserver.observe(el, {
|
|
214
|
-
attributes: true,
|
|
215
|
-
attributeFilter: ['class'],
|
|
216
|
-
});
|
|
217
|
-
// Set initial state
|
|
218
|
-
this.isInvalid = this.checkValidationState();
|
|
219
|
-
}
|
|
220
195
|
this.debounceChanged();
|
|
221
196
|
{
|
|
222
197
|
document.dispatchEvent(new CustomEvent('ionInputDidLoad', {
|
|
@@ -238,11 +213,6 @@ const Textarea = class {
|
|
|
238
213
|
this.notchController.destroy();
|
|
239
214
|
this.notchController = undefined;
|
|
240
215
|
}
|
|
241
|
-
// Clean up validation observer to prevent memory leaks
|
|
242
|
-
if (this.validationObserver) {
|
|
243
|
-
this.validationObserver.disconnect();
|
|
244
|
-
this.validationObserver = undefined;
|
|
245
|
-
}
|
|
246
216
|
}
|
|
247
217
|
componentWillLoad() {
|
|
248
218
|
this.inheritedAttributes = Object.assign(Object.assign({}, helpers.inheritAriaAttributes(this.el)), helpers.inheritAttributes(this.el, ['data-form-type', 'title', 'tabindex', 'dir']));
|
|
@@ -413,15 +383,15 @@ const Textarea = class {
|
|
|
413
383
|
* Renders the helper text or error text values
|
|
414
384
|
*/
|
|
415
385
|
renderHintText() {
|
|
416
|
-
const { helperText, errorText, helperTextId, errorTextId
|
|
386
|
+
const { helperText, errorText, helperTextId, errorTextId } = this;
|
|
417
387
|
return [
|
|
418
388
|
index.h("div", { id: helperTextId, class: "helper-text" }, helperText),
|
|
419
|
-
index.h("div", { id: errorTextId, class: "error-text"
|
|
389
|
+
index.h("div", { id: errorTextId, class: "error-text" }, errorText),
|
|
420
390
|
];
|
|
421
391
|
}
|
|
422
392
|
getHintTextID() {
|
|
423
|
-
const {
|
|
424
|
-
if (
|
|
393
|
+
const { el, helperText, errorText, helperTextId, errorTextId } = this;
|
|
394
|
+
if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
|
|
425
395
|
return errorTextId;
|
|
426
396
|
}
|
|
427
397
|
if (helperText) {
|
|
@@ -480,7 +450,7 @@ const Textarea = class {
|
|
|
480
450
|
* TODO(FW-5592): Remove hasStartEndSlots condition
|
|
481
451
|
*/
|
|
482
452
|
const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
|
|
483
|
-
return (index.h(index.Host, { key: '
|
|
453
|
+
return (index.h(index.Host, { key: 'd9f2ede0107987fc42c99e310cd2336bad5a5755', class: theme.createColorClasses(this.color, {
|
|
484
454
|
[mode]: true,
|
|
485
455
|
'has-value': hasValue,
|
|
486
456
|
'has-focus': hasFocus,
|
|
@@ -489,7 +459,7 @@ const Textarea = class {
|
|
|
489
459
|
[`textarea-shape-${shape}`]: shape !== undefined,
|
|
490
460
|
[`textarea-label-placement-${labelPlacement}`]: true,
|
|
491
461
|
'textarea-disabled': disabled,
|
|
492
|
-
}) }, index.h("label", { key: '
|
|
462
|
+
}) }, index.h("label", { key: '9de598b95237462bb3bccffaefe83afbb43554b8', class: "textarea-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), index.h("div", { key: 'e33c426c6541d723ccc246bb404c03687726ff83', class: "textarea-wrapper-inner" }, index.h("div", { key: '521e11af9d54d281b0a2b1c25bcfc6f742c18296', class: "start-slot-wrapper" }, index.h("slot", { key: '515523f6ca3ce0e5dd08f3275c21a190fb1ca177', name: "start" })), index.h("div", { key: '916e01e00de8400ae00ef06bc1fb62d8be2eee08', class: "native-wrapper", ref: (el) => (this.textareaWrapper = el) }, index.h("textarea", Object.assign({ key: '810271e6532d90e27dab1fcb26546113c1ce9cb0', class: "native-textarea", ref: (el) => (this.nativeInput = el), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, minLength: this.minlength, maxLength: this.maxlength, name: this.name, placeholder: this.placeholder || '', readOnly: this.readonly, required: this.required, spellcheck: this.spellcheck, cols: this.cols, rows: this.rows, wrap: this.wrap, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeyDown, "aria-describedby": this.getHintTextID(), "aria-invalid": this.getHintTextID() === this.errorTextId }, this.inheritedAttributes), value)), index.h("div", { key: '80aca9ea9546dca9d38efd291a6b0be384bb6978', class: "end-slot-wrapper" }, index.h("slot", { key: '407fab16c66a9f4a542369bfecc0d9afa0065977', name: "end" }))), shouldRenderHighlight && index.h("div", { key: 'f00523a6698fac8a1996e04303487bef01d10f25', class: "textarea-highlight" })), this.renderBottomContent()));
|
|
493
463
|
}
|
|
494
464
|
get el() { return index.getElement(this); }
|
|
495
465
|
static get watchers() { return {
|