diff --git a/CHANGELOG.md b/CHANGELOG.md index 47d8c90f8..1faa5a8f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [Unreleased] +### Fixed +- Input, Textarea - passing `undefined` to **value** sets the underlying input value to undefined [#1206](https://github.com/IgniteUI/igniteui-webcomponents/issues/1206) + ## [4.9.0] - 2024-04-30 ### Added - Button group component now allows resetting the selection state via the `selectedItems` property [#1168](https://github.com/IgniteUI/igniteui-webcomponents/pull/1168) diff --git a/src/components/input/input.spec.ts b/src/components/input/input.spec.ts index b53442fa0..94c581991 100644 --- a/src/components/input/input.spec.ts +++ b/src/components/input/input.spec.ts @@ -22,7 +22,7 @@ describe('Input component', () => { it('is initialized with the proper default values', async () => { expect(el.size).to.equal('medium'); expect(el.type).to.equal('text'); - expect(el.value).to.equal(''); + expect(el.value).to.be.empty; expect(el.invalid).to.be.false; expect(el.required).to.be.false; expect(el.readonly).to.be.false; @@ -118,7 +118,7 @@ describe('Input component', () => { }); it('sets the pattern property successfully', async () => { - expect(input.pattern).to.equal(''); + expect(input.pattern).to.be.empty; el.pattern = '123'; await elementUpdated(el); @@ -246,6 +246,20 @@ describe('Input component', () => { expect(eventSpy).calledTwice; expect(eventSpy).calledWithExactly('igcBlur'); }); + + it('issue #1026 - passing undefined sets the underlying input value to undefined', async () => { + el.value = 'a'; + await elementUpdated(el); + + expect(el.value).to.equal('a'); + expect(input.value).to.equal('a'); + + el.value = undefined as any; + await elementUpdated(el); + + expect(el.value).to.be.empty; + expect(input.value).to.be.empty; + }); }); it('should reflect validation state when updating through attribute', async () => { @@ -290,7 +304,7 @@ describe('Input component', () => { spec.element.value = 'abc'; spec.reset(); - expect(spec.element.value).to.equal(''); + expect(spec.element.value).to.be.empty; }); it('reflects disabled ancestor state', async () => { diff --git a/src/components/input/input.ts b/src/components/input/input.ts index a2b5a263e..4bbff4f7c 100644 --- a/src/components/input/input.ts +++ b/src/components/input/input.ts @@ -115,7 +115,7 @@ export default class IgcInputComponent extends IgcInputBaseComponent { */ @property() public set value(value: string) { - this._value = value; + this._value = value ?? ''; this.setFormValue(value ? value : null); this.updateValidity(); this.setInvalidState(); diff --git a/src/components/select/select.spec.ts b/src/components/select/select.spec.ts index fc2a402e2..b123b7042 100644 --- a/src/components/select/select.spec.ts +++ b/src/components/select/select.spec.ts @@ -259,7 +259,7 @@ describe('Select', () => { select.value = '123151'; await elementUpdated(select); - expect(input.value).to.be.null; + expect(input.value).to.be.empty; }); }); diff --git a/src/components/textarea/textarea.spec.ts b/src/components/textarea/textarea.spec.ts index 814024632..171d552d8 100644 --- a/src/components/textarea/textarea.spec.ts +++ b/src/components/textarea/textarea.spec.ts @@ -48,6 +48,25 @@ describe('Textarea component', () => { expect(element.value).to.equal([value, ...additional].join('\r\n')); }); + + it('issue #1206 - passing undefined sets the underlying textarea value to undefined', async () => { + element = await fixture( + html`` + ); + textArea = element.renderRoot.querySelector('textarea')!; + + element.value = 'a'; + await elementUpdated(element); + + expect(element.value).to.equal('a'); + expect(textArea.value).to.equal('a'); + + element.value = undefined as any; + await elementUpdated(element); + + expect(element.value).to.be.empty; + expect(textArea.value).to.be.empty; + }); }); describe('Events', () => { @@ -193,7 +212,7 @@ describe('Textarea component', () => { await elementUpdated(spec.element); spec.reset(); - expect(spec.element.value).to.equal(''); + expect(spec.element.value).to.be.empty; }); it('reflects disabled ancestor state', async () => { diff --git a/src/components/textarea/textarea.ts b/src/components/textarea/textarea.ts index cd5d29ae7..31c20d526 100644 --- a/src/components/textarea/textarea.ts +++ b/src/components/textarea/textarea.ts @@ -85,6 +85,7 @@ export default class IgcTextareaComponent extends FormAssociatedRequiredMixin( delegatesFocus: true, }; + private _value = ''; private observer!: ResizeObserver; @queryAssignedNodes({ flatten: true }) @@ -226,7 +227,16 @@ export default class IgcTextareaComponent extends FormAssociatedRequiredMixin( * @attr */ @property() - public value = ''; + public set value(value: string) { + this._value = value ?? ''; + this.setFormValue(this._value ? this._value : null); + this.updateValidity(); + this.setInvalidState(); + } + + public get value(): string { + return this._value; + } /** * Controls whether the element may be checked for spelling errors. @@ -276,6 +286,7 @@ export default class IgcTextareaComponent extends FormAssociatedRequiredMixin( public override async connectedCallback() { super.connectedCallback(); + this.updateValidity(); await this.updateComplete; @@ -340,10 +351,6 @@ export default class IgcTextareaComponent extends FormAssociatedRequiredMixin( @watch('value') protected async valueChanged() { - this.value ? this.setFormValue(this.value) : this.setFormValue(null); - this.updateValidity(); - this.setInvalidState(); - await this.updateComplete; this.setAreaHeight(); } diff --git a/stories/textarea.stories.ts b/stories/textarea.stories.ts index 4b27ee70b..1b880fbc8 100644 --- a/stories/textarea.stories.ts +++ b/stories/textarea.stories.ts @@ -114,7 +114,6 @@ const metadata: Meta = { type: 'string', description: 'The value of the component', control: 'text', - table: { defaultValue: { summary: '' } }, }, spellcheck: { type: 'boolean', @@ -167,7 +166,6 @@ const metadata: Meta = { readOnly: false, resize: 'vertical', rows: 2, - value: '', spellcheck: true, wrap: 'soft', validateOnly: false,