Skip to content

Commit

Permalink
fix(textarea): clearOnEdit clears textarea when user initially types (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
sean-perkins committed Oct 10, 2022
1 parent bf5e118 commit f7176bb
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 22 deletions.
7 changes: 5 additions & 2 deletions angular/src/directives/proxies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1832,8 +1832,11 @@ has been modified.
*/
ionChange: EventEmitter<CustomEvent<ITextareaTextareaChangeEventDetail>>;
/**
* Ths `ionInput` event fires when the `value` of an `<ion-textarea>` element
has been changed.
* The `ionInput` event fires when the `value` of an `<ion-textarea>` element
has been changed.
When `clearOnEdit` is enabled, the `ionInput` event will be fired when
the user clears the textarea by performing a keydown event.
*/
ionInput: EventEmitter<CustomEvent<InputEvent | null>>;
/**
Expand Down
4 changes: 2 additions & 2 deletions core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6564,9 +6564,9 @@ declare namespace LocalJSX {
*/
"onIonFocus"?: (event: IonTextareaCustomEvent<FocusEvent>) => void;
/**
* Ths `ionInput` event fires when the `value` of an `<ion-textarea>` element has been changed.
* The `ionInput` event fires when the `value` of an `<ion-textarea>` element has been changed. When `clearOnEdit` is enabled, the `ionInput` event will be fired when the user clears the textarea by performing a keydown event.
*/
"onIonInput"?: (event: IonTextareaCustomEvent<InputEvent | null>) => void;
"onIonInput"?: (event: IonTextareaCustomEvent<InputEvent>) => void;
/**
* Emitted when the styles change.
*/
Expand Down
35 changes: 35 additions & 0 deletions core/src/components/textarea/test/clearOnEdit/textarea.e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';

test.describe('textarea: clearOnEdit', () => {
test.beforeEach(async ({ skip }) => {
skip.rtl();
skip.mode('md');
});

test('should clear the textarea on first keystroke of textarea being focused', async ({ page }) => {
await page.setContent(`<ion-textarea value="some value" clear-on-edit="true"></ion-textarea>`);

const textarea = page.locator('ion-textarea');

await textarea.click();
await textarea.type('h');

expect(await textarea.evaluate((el: HTMLIonTextareaElement) => el.value)).toBe('h');

await textarea.type('ello world');

expect(await textarea.evaluate((el: HTMLIonTextareaElement) => el.value)).toBe('hello world');
});

test('should not clear the textarea if it does not have an initial value when typing', async ({ page }) => {
await page.setContent(`<ion-textarea value="" clear-on-edit="true"></ion-textarea>`);

const textarea = page.locator('ion-textarea');

await textarea.click();
await textarea.type('hello world');

expect(await textarea.evaluate((el: HTMLIonTextareaElement) => el.value)).toBe('hello world');
});
});
39 changes: 21 additions & 18 deletions core/src/components/textarea/textarea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,17 @@ import { createColorClasses } from '../../utils/theme';
export class Textarea implements ComponentInterface {
private nativeInput?: HTMLTextAreaElement;
private inputId = `ion-textarea-${textareaIds++}`;
private didBlurAfterEdit = this.hasValue();
/**
* `true` if the textarea was cleared as a result of the user typing
* with `clearOnEdit` enabled.
*
* Resets when the textarea loses focus.
*/
private didTextareaClearOnEdit = false;
private textareaWrapper?: HTMLElement;
private inheritedAttributes: Attributes = {};
/**
* The value of the input when the textarea is focused.
* The value of the textarea when the textarea is focused.
*/
private focusedValue?: string | null;

Expand Down Expand Up @@ -176,10 +182,13 @@ export class Textarea implements ComponentInterface {
@Event() ionChange!: EventEmitter<TextareaChangeEventDetail>;

/**
* Ths `ionInput` event fires when the `value` of an `<ion-textarea>` element
* The `ionInput` event fires when the `value` of an `<ion-textarea>` element
* has been changed.
*
* When `clearOnEdit` is enabled, the `ionInput` event will be fired when
* the user clears the textarea by performing a keydown event.
*/
@Event() ionInput!: EventEmitter<InputEvent | null>;
@Event() ionInput!: EventEmitter<InputEvent>;

/**
* Emitted when the styles change.
Expand Down Expand Up @@ -295,24 +304,18 @@ export class Textarea implements ComponentInterface {
if (!this.clearOnEdit) {
return;
}

// Did the input value change after it was blurred and edited?
if (this.didBlurAfterEdit && this.hasValue()) {
// Clear the input
/**
* Clear the textarea if the control has not been previously cleared
* during focus.
*/
if (!this.didTextareaClearOnEdit && this.hasValue()) {
this.value = '';
this.ionInput.emit();
}

this.ionInput.emit(null);

// Reset the flag
this.didBlurAfterEdit = false;
this.didTextareaClearOnEdit = true;
}

private focusChange() {
// If clearOnEdit is enabled and the input blurred but has a value, set a flag
if (this.clearOnEdit && !this.hasFocus && this.hasValue()) {
this.didBlurAfterEdit = true;
}
this.emitStyle();
}

Expand Down Expand Up @@ -360,7 +363,7 @@ export class Textarea implements ComponentInterface {
*/
this.emitValueChange();
}

this.didTextareaClearOnEdit = false;
this.ionBlur.emit(ev);
};

Expand Down

0 comments on commit f7176bb

Please sign in to comment.