From c45d05476b34648b59dc8d407a8a1c9f8bd4f409 Mon Sep 17 00:00:00 2001 From: Amanda Johnston <90629384+amandaejohnston@users.noreply.github.com> Date: Wed, 9 Nov 2022 13:55:20 -0600 Subject: [PATCH] feat(input, textarea): change default debounce to undefined (#26073) Co-authored-by: Sean Perkins Co-authored-by: Liam DeBeasi --- BREAKING.md | 6 ++++++ core/api.txt | 4 ++-- core/src/components.d.ts | 4 ++-- core/src/components/input/input.tsx | 13 +++++++++++-- .../components/input/test/clearOnEdit/input.e2e.ts | 2 +- core/src/components/searchbar/searchbar.tsx | 4 ++-- core/src/components/textarea/textarea.tsx | 13 +++++++++++-- 7 files changed, 35 insertions(+), 11 deletions(-) diff --git a/BREAKING.md b/BREAKING.md index 9a07f10aa2..31141e8da1 100644 --- a/BREAKING.md +++ b/BREAKING.md @@ -97,6 +97,8 @@ This section details the desktop browser, JavaScript framework, and mobile platf - The `debounce` property has been updated to control the timing in milliseconds to delay the event emission of the `ionInput` event after each keystroke. Previously it would delay the event emission of `ionChange`. +- The `debounce` property's default value has changed from `0` to `undefined`. If `debounce` is undefined, the `ionInput` event will fire immediately. + - The `detail` payload for the `ionInput` event now contains an object with the current `value` as well as the native event that triggered `ionInput`.

Modal

@@ -175,6 +177,10 @@ Developers using these components will need to migrate to using Swiper.js direct - The `debounce` property has been updated to control the timing in milliseconds to delay the event emission of the `ionInput` event after each keystroke. Previously it would delay the event emission of `ionChange`. +- The `debounce` property's default value has changed from `0` to `undefined`. If `debounce` is undefined, the `ionInput` event will fire immediately. + +- `ionInput` dispatches an event detail of `null` when the textarea is cleared as a result of `clear-on-edit="true"`. + - The `detail` payload for the `ionInput` event now contains an object with the current `value` as well as the native event that triggered `ionInput`.

Toggle

diff --git a/core/api.txt b/core/api.txt index 3714b490a8..dc6419b9d5 100644 --- a/core/api.txt +++ b/core/api.txt @@ -533,7 +533,7 @@ ion-input,prop,autofocus,boolean,false,false,false ion-input,prop,clearInput,boolean,false,false,false ion-input,prop,clearOnEdit,boolean | undefined,undefined,false,false ion-input,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record | undefined,undefined,false,true -ion-input,prop,debounce,number,0,false,false +ion-input,prop,debounce,number | undefined,undefined,false,false ion-input,prop,disabled,boolean,false,false,false ion-input,prop,enterkeyhint,"done" | "enter" | "go" | "next" | "previous" | "search" | "send" | undefined,undefined,false,false ion-input,prop,inputmode,"decimal" | "email" | "none" | "numeric" | "search" | "tel" | "text" | "url" | undefined,undefined,false,false @@ -1301,7 +1301,7 @@ ion-textarea,prop,autofocus,boolean,false,false,false ion-textarea,prop,clearOnEdit,boolean,false,false,false ion-textarea,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record | undefined,undefined,false,true ion-textarea,prop,cols,number | undefined,undefined,false,false -ion-textarea,prop,debounce,number,0,false,false +ion-textarea,prop,debounce,number | undefined,undefined,false,false ion-textarea,prop,disabled,boolean,false,false,false ion-textarea,prop,enterkeyhint,"done" | "enter" | "go" | "next" | "previous" | "search" | "send" | undefined,undefined,false,false ion-textarea,prop,inputmode,"decimal" | "email" | "none" | "numeric" | "search" | "tel" | "text" | "url" | undefined,undefined,false,false diff --git a/core/src/components.d.ts b/core/src/components.d.ts index bbcd88d5cd..a2c2fdf2ab 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -1086,7 +1086,7 @@ export namespace Components { /** * Set the amount of time, in milliseconds, to wait to trigger the `ionInput` event after each keystroke. */ - "debounce": number; + "debounce"?: number; /** * If `true`, the user cannot interact with the input. */ @@ -2754,7 +2754,7 @@ export namespace Components { /** * Set the amount of time, in milliseconds, to wait to trigger the `ionInput` event after each keystroke. */ - "debounce": number; + "debounce"?: number; /** * If `true`, the user cannot interact with the textarea. */ diff --git a/core/src/components/input/input.tsx b/core/src/components/input/input.tsx index 045b955f6c..6fc366244e 100644 --- a/core/src/components/input/input.tsx +++ b/core/src/components/input/input.tsx @@ -30,6 +30,8 @@ export class Input implements ComponentInterface { private inputId = `ion-input-${inputIds++}`; private inheritedAttributes: Attributes = {}; private isComposing = false; + private originalIonInput?: EventEmitter; + /** * `true` if the input was cleared as a result of the user typing * with `clearOnEdit` enabled. @@ -93,11 +95,17 @@ export class Input implements ComponentInterface { /** * Set the amount of time, in milliseconds, to wait to trigger the `ionInput` event after each keystroke. */ - @Prop() debounce = 0; + @Prop() debounce?: number; @Watch('debounce') protected debounceChanged() { - this.ionInput = debounceEvent(this.ionInput, this.debounce); + const { ionInput, debounce, originalIonInput } = this; + + /** + * If debounce is undefined, we have to manually revert the ionInput emitter in case + * debounce used to be set to a number. Otherwise, the event would stay debounced. + */ + this.ionInput = debounce === undefined ? originalIonInput ?? ionInput : debounceEvent(ionInput, debounce); } /** @@ -293,6 +301,7 @@ export class Input implements ComponentInterface { } componentDidLoad() { + this.originalIonInput = this.ionInput; const nativeInput = this.nativeInput; if (nativeInput) { // TODO: FW-729 Update to JSX bindings when Stencil resolves bug with: diff --git a/core/src/components/input/test/clearOnEdit/input.e2e.ts b/core/src/components/input/test/clearOnEdit/input.e2e.ts index c301362588..0e5e74d1bc 100644 --- a/core/src/components/input/test/clearOnEdit/input.e2e.ts +++ b/core/src/components/input/test/clearOnEdit/input.e2e.ts @@ -67,7 +67,7 @@ test.describe('input: clearOnEdit', () => { await nativeInput.evaluate((el: HTMLInputElement) => el.blur()); - expect(ionInputSpy).toHaveReceivedEventTimes(4); + expect(ionInputSpy).toHaveReceivedEventTimes(5); expect(ionChangeSpy).toHaveReceivedEventTimes(2); }); }); diff --git a/core/src/components/searchbar/searchbar.tsx b/core/src/components/searchbar/searchbar.tsx index 4e2aaf2f57..c584ec43ca 100644 --- a/core/src/components/searchbar/searchbar.tsx +++ b/core/src/components/searchbar/searchbar.tsx @@ -24,7 +24,7 @@ export class Searchbar implements ComponentInterface { private nativeInput?: HTMLInputElement; private isCancelVisible = false; private shouldAlignLeft = true; - private originalIonInput!: EventEmitter; + private originalIonInput?: EventEmitter; /** * The value of the input when the textarea is focused. @@ -87,7 +87,7 @@ export class Searchbar implements ComponentInterface { * If debounce is undefined, we have to manually revert the ionInput emitter in case * debounce used to be set to a number. Otherwise, the event would stay debounced. */ - this.ionInput = debounce === undefined ? originalIonInput : debounceEvent(ionInput, debounce); + this.ionInput = debounce === undefined ? originalIonInput ?? ionInput : debounceEvent(ionInput, debounce); } /** diff --git a/core/src/components/textarea/textarea.tsx b/core/src/components/textarea/textarea.tsx index c4350b8da8..c3f6abf09f 100644 --- a/core/src/components/textarea/textarea.tsx +++ b/core/src/components/textarea/textarea.tsx @@ -30,6 +30,8 @@ export class Textarea implements ComponentInterface { private didTextareaClearOnEdit = false; private textareaWrapper?: HTMLElement; private inheritedAttributes: Attributes = {}; + private originalIonInput?: EventEmitter; + /** * The value of the textarea when the textarea is focused. */ @@ -65,11 +67,17 @@ export class Textarea implements ComponentInterface { /** * Set the amount of time, in milliseconds, to wait to trigger the `ionInput` event after each keystroke. */ - @Prop() debounce = 0; + @Prop() debounce?: number; @Watch('debounce') protected debounceChanged() { - this.ionInput = debounceEvent(this.ionInput, this.debounce); + const { ionInput, debounce, originalIonInput } = this; + + /** + * If debounce is undefined, we have to manually revert the ionInput emitter in case + * debounce used to be set to a number. Otherwise, the event would stay debounced. + */ + this.ionInput = debounce === undefined ? originalIonInput ?? ionInput : debounceEvent(ionInput, debounce); } /** @@ -236,6 +244,7 @@ export class Textarea implements ComponentInterface { } componentDidLoad() { + this.originalIonInput = this.ionInput; this.runAutoGrow(); }