mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
feat(input, textarea): ionInput and ionChange pass event and value (#26176)
BREAKING CHANGE: The `detail` payload for the `ionInput` event on `ion-input` and `ion-textarea` now contains an object with the current `value` as well as the native event that triggered `ionInput`.
This commit is contained in:
@@ -1,12 +1,16 @@
|
||||
export interface InputChangeEventDetail {
|
||||
value: string | undefined | null;
|
||||
value?: string | number | null;
|
||||
event?: Event;
|
||||
}
|
||||
|
||||
// We recognize that InputInput is not an ideal naming pattern for this type.
|
||||
// TODO (FW-2199): Explore renaming this type to something more appropriate.
|
||||
export type InputInputEventDetail = InputEvent | Event;
|
||||
export interface InputInputEventDetail {
|
||||
value?: string | number | null;
|
||||
event?: Event;
|
||||
}
|
||||
|
||||
export interface InputCustomEvent extends CustomEvent {
|
||||
detail: InputChangeEventDetail;
|
||||
export interface InputCustomEvent<T = InputChangeEventDetail> extends CustomEvent {
|
||||
detail: T;
|
||||
target: HTMLIonInputElement;
|
||||
}
|
||||
|
||||
@@ -342,13 +342,21 @@ export class Input implements ComponentInterface {
|
||||
* This API should be called for user committed changes.
|
||||
* This API should not be used for external value changes.
|
||||
*/
|
||||
private emitValueChange() {
|
||||
private emitValueChange(event?: Event) {
|
||||
const { value } = this;
|
||||
// Checks for both null and undefined values
|
||||
const newValue = value == null ? value : value.toString();
|
||||
// Emitting a value change should update the internal state for tracking the focused value
|
||||
this.focusedValue = newValue;
|
||||
this.ionChange.emit({ value: newValue });
|
||||
this.ionChange.emit({ value: newValue, event });
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits an `ionInput` event.
|
||||
*/
|
||||
private emitInputChange(event?: Event) {
|
||||
const { value } = this;
|
||||
this.ionInput.emit({ value, event });
|
||||
}
|
||||
|
||||
private shouldClearOnEdit() {
|
||||
@@ -376,11 +384,11 @@ export class Input implements ComponentInterface {
|
||||
if (input) {
|
||||
this.value = input.value || '';
|
||||
}
|
||||
this.ionInput.emit(ev as InputEvent);
|
||||
this.emitInputChange(ev);
|
||||
};
|
||||
|
||||
private onChange = () => {
|
||||
this.emitValueChange();
|
||||
private onChange = (ev: Event) => {
|
||||
this.emitValueChange(ev);
|
||||
};
|
||||
|
||||
private onBlur = (ev: FocusEvent) => {
|
||||
@@ -392,7 +400,7 @@ export class Input implements ComponentInterface {
|
||||
* Emits the `ionChange` event when the input value
|
||||
* is different than the value when the input was focused.
|
||||
*/
|
||||
this.emitValueChange();
|
||||
this.emitValueChange(ev);
|
||||
}
|
||||
|
||||
this.didInputClearOnEdit = false;
|
||||
@@ -422,7 +430,7 @@ export class Input implements ComponentInterface {
|
||||
*/
|
||||
if (!this.didInputClearOnEdit && this.hasValue() && ev.key !== 'Enter') {
|
||||
this.value = '';
|
||||
this.ionInput.emit();
|
||||
this.emitInputChange(ev);
|
||||
}
|
||||
this.didInputClearOnEdit = true;
|
||||
}
|
||||
@@ -443,7 +451,7 @@ export class Input implements ComponentInterface {
|
||||
this.setFocus();
|
||||
}
|
||||
this.value = '';
|
||||
this.ionInput.emit(ev);
|
||||
this.emitInputChange(ev);
|
||||
};
|
||||
|
||||
private hasValue(): boolean {
|
||||
|
||||
@@ -20,7 +20,7 @@ test.describe('input: events: ionChange', () => {
|
||||
|
||||
await ionChangeSpy.next();
|
||||
|
||||
expect(ionChangeSpy).toHaveReceivedEventDetail({ value: 'new value' });
|
||||
expect(ionChangeSpy).toHaveReceivedEventDetail({ value: 'new value', event: { isTrusted: true } });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -71,7 +71,7 @@ test.describe('input: events: ionInput', () => {
|
||||
|
||||
await page.click('ion-input .input-clear-icon');
|
||||
|
||||
expect(ionInputSpy).toHaveReceivedEventDetail({ isTrusted: true });
|
||||
expect(ionInputSpy).toHaveReceivedEventDetail({ value: '', event: { isTrusted: true } });
|
||||
});
|
||||
|
||||
test('should emit when the input is cleared from the keyboard', async ({ page }) => {
|
||||
@@ -86,6 +86,6 @@ test.describe('input: events: ionInput', () => {
|
||||
expect(await input.evaluate((el: HTMLIonInputElement) => el.value)).toBe('');
|
||||
|
||||
expect(ionInputSpy).toHaveReceivedEventTimes(1);
|
||||
expect(ionInputSpy).toHaveReceivedEventDetail(null);
|
||||
expect(ionInputSpy).toHaveReceivedEventDetail({ value: '', event: { isTrusted: true } });
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user