mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-09 16:16:41 +08:00
fix(input, searchbar, textarea): ensure nativeInput is always available (#28362)
Issue number: resolves #28283 --------- <!-- Please do not submit updates to dependencies unless it fixes an issue. --> <!-- Please try to limit your pull request to one type (bugfix, feature, etc). Submit multiple pull requests if needed. --> ## What is the current behavior? <!-- Please describe the current behavior that you are modifying. --> `getInputElement()` is used to access the native input. If the component has yet to render, then the function will return `undefined`. This happens mostly when using `ref` on React. ```tsx <IonInput ref={async input => { const nativeInput = await input.getInputElement(); // nativeInput is undefined }} /> ``` ## What is the new behavior? <!-- Please describe the behavior or changes that are being added by this PR. --> - `getInputElement()` will wait to return once the component is ready. ## Does this introduce a breaking change? - [ ] Yes - [x] No <!-- If this introduces a breaking change, please describe the impact and migration path for existing applications below. --> ## Other information <!-- Any other information that is important to this PR such as screenshots of how the component looks before and after the change. --> Dev build: `7.5.1-dev.11697488622.175c9183`
This commit is contained in:
@ -3,7 +3,13 @@ import { Build, Component, Element, Event, Host, Method, Prop, State, Watch, for
|
|||||||
import type { LegacyFormController, NotchController } from '@utils/forms';
|
import type { LegacyFormController, NotchController } from '@utils/forms';
|
||||||
import { createLegacyFormController, createNotchController } from '@utils/forms';
|
import { createLegacyFormController, createNotchController } from '@utils/forms';
|
||||||
import type { Attributes } from '@utils/helpers';
|
import type { Attributes } from '@utils/helpers';
|
||||||
import { inheritAriaAttributes, debounceEvent, findItemLabel, inheritAttributes } from '@utils/helpers';
|
import {
|
||||||
|
inheritAriaAttributes,
|
||||||
|
debounceEvent,
|
||||||
|
findItemLabel,
|
||||||
|
inheritAttributes,
|
||||||
|
componentOnReady,
|
||||||
|
} from '@utils/helpers';
|
||||||
import { printIonWarning } from '@utils/logging';
|
import { printIonWarning } from '@utils/logging';
|
||||||
import { createSlotMutationController } from '@utils/slot-mutation-controller';
|
import { createSlotMutationController } from '@utils/slot-mutation-controller';
|
||||||
import type { SlotMutationController } from '@utils/slot-mutation-controller';
|
import type { SlotMutationController } from '@utils/slot-mutation-controller';
|
||||||
@ -430,7 +436,14 @@ export class Input implements ComponentInterface {
|
|||||||
* Returns the native `<input>` element used under the hood.
|
* Returns the native `<input>` element used under the hood.
|
||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
getInputElement(): Promise<HTMLInputElement> {
|
async getInputElement(): Promise<HTMLInputElement> {
|
||||||
|
/**
|
||||||
|
* If this gets called in certain early lifecycle hooks (ex: Vue onMounted),
|
||||||
|
* nativeInput won't be defined yet with the custom elements build, so wait for it to load in.
|
||||||
|
*/
|
||||||
|
if (!this.nativeInput) {
|
||||||
|
await new Promise((resolve) => componentOnReady(this.el, resolve));
|
||||||
|
}
|
||||||
return Promise.resolve(this.nativeInput!);
|
return Promise.resolve(this.nativeInput!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import type { ComponentInterface, EventEmitter } from '@stencil/core';
|
import type { ComponentInterface, EventEmitter } from '@stencil/core';
|
||||||
import { Component, Element, Event, Host, Method, Prop, State, Watch, forceUpdate, h } from '@stencil/core';
|
import { Component, Element, Event, Host, Method, Prop, State, Watch, forceUpdate, h } from '@stencil/core';
|
||||||
import { debounceEvent, raf } from '@utils/helpers';
|
import { debounceEvent, raf, componentOnReady } from '@utils/helpers';
|
||||||
import { isRTL } from '@utils/rtl';
|
import { isRTL } from '@utils/rtl';
|
||||||
import { createColorClasses } from '@utils/theme';
|
import { createColorClasses } from '@utils/theme';
|
||||||
import { arrowBackSharp, closeCircle, closeSharp, searchOutline, searchSharp } from 'ionicons/icons';
|
import { arrowBackSharp, closeCircle, closeSharp, searchOutline, searchSharp } from 'ionicons/icons';
|
||||||
@ -269,7 +269,14 @@ export class Searchbar implements ComponentInterface {
|
|||||||
* Returns the native `<input>` element used under the hood.
|
* Returns the native `<input>` element used under the hood.
|
||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
getInputElement(): Promise<HTMLInputElement> {
|
async getInputElement(): Promise<HTMLInputElement> {
|
||||||
|
/**
|
||||||
|
* If this gets called in certain early lifecycle hooks (ex: Vue onMounted),
|
||||||
|
* nativeInput won't be defined yet with the custom elements build, so wait for it to load in.
|
||||||
|
*/
|
||||||
|
if (!this.nativeInput) {
|
||||||
|
await new Promise((resolve) => componentOnReady(this.el, resolve));
|
||||||
|
}
|
||||||
return Promise.resolve(this.nativeInput!);
|
return Promise.resolve(this.nativeInput!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,13 @@ import {
|
|||||||
import type { LegacyFormController, NotchController } from '@utils/forms';
|
import type { LegacyFormController, NotchController } from '@utils/forms';
|
||||||
import { createLegacyFormController, createNotchController } from '@utils/forms';
|
import { createLegacyFormController, createNotchController } from '@utils/forms';
|
||||||
import type { Attributes } from '@utils/helpers';
|
import type { Attributes } from '@utils/helpers';
|
||||||
import { inheritAriaAttributes, debounceEvent, findItemLabel, inheritAttributes } from '@utils/helpers';
|
import {
|
||||||
|
inheritAriaAttributes,
|
||||||
|
debounceEvent,
|
||||||
|
findItemLabel,
|
||||||
|
inheritAttributes,
|
||||||
|
componentOnReady,
|
||||||
|
} from '@utils/helpers';
|
||||||
import { printIonWarning } from '@utils/logging';
|
import { printIonWarning } from '@utils/logging';
|
||||||
import { createSlotMutationController } from '@utils/slot-mutation-controller';
|
import { createSlotMutationController } from '@utils/slot-mutation-controller';
|
||||||
import type { SlotMutationController } from '@utils/slot-mutation-controller';
|
import type { SlotMutationController } from '@utils/slot-mutation-controller';
|
||||||
@ -378,7 +384,14 @@ export class Textarea implements ComponentInterface {
|
|||||||
* Returns the native `<textarea>` element used under the hood.
|
* Returns the native `<textarea>` element used under the hood.
|
||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
getInputElement(): Promise<HTMLTextAreaElement> {
|
async getInputElement(): Promise<HTMLTextAreaElement> {
|
||||||
|
/**
|
||||||
|
* If this gets called in certain early lifecycle hooks (ex: Vue onMounted),
|
||||||
|
* nativeInput won't be defined yet with the custom elements build, so wait for it to load in.
|
||||||
|
*/
|
||||||
|
if (!this.nativeInput) {
|
||||||
|
await new Promise((resolve) => componentOnReady(this.el, resolve));
|
||||||
|
}
|
||||||
return Promise.resolve(this.nativeInput!);
|
return Promise.resolve(this.nativeInput!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user