diff --git a/packages/textfield/src/Textfield.ts b/packages/textfield/src/Textfield.ts index e64fa7c187..edb8a0172d 100644 --- a/packages/textfield/src/Textfield.ts +++ b/packages/textfield/src/Textfield.ts @@ -249,6 +249,7 @@ export class TextfieldBase extends ManageHelpText( minlength=${ifDefined( this.minlength > -1 ? this.minlength : undefined )} + title=${this.invalid ? '' : nothing} pattern=${ifDefined(this.pattern)} placeholder=${this.placeholder} .value=${this.displayValue} @@ -276,6 +277,7 @@ export class TextfieldBase extends ManageHelpText( this.placeholder} aria-invalid=${ifDefined(this.invalid || undefined)} class="input" + title=${this.invalid ? '' : nothing} maxlength=${ifDefined( this.maxlength > -1 ? this.maxlength : undefined )} diff --git a/packages/textfield/test/textfield.test.ts b/packages/textfield/test/textfield.test.ts index 022965f53b..fb6a0b7f0d 100644 --- a/packages/textfield/test/textfield.test.ts +++ b/packages/textfield/test/textfield.test.ts @@ -168,7 +168,9 @@ describe('Textfield', () => { const boundsDefaultElement = defaultTextarea?.getBoundingClientRect(); const boundsOneRowElement = oneRowTextarea?.getBoundingClientRect(); - expect(boundsDefaultElement?.height).to.be.greaterThan(boundsOneRowElement?.height ?? 0); + expect(boundsDefaultElement?.height).to.be.greaterThan( + boundsOneRowElement?.height ?? 0 + ); }); it('multiline with rows does not resize', async () => { const el = await litFixture( @@ -429,6 +431,41 @@ describe('Textfield', () => { : null; expect(input).to.not.be.null; }); + it('valid - boundary-type assertions and title', async () => { + const el = await litFixture( + html` + + ` + ); + await elementUpdated(el); + + expect(el).to.not.equal(undefined); + const input = el.shadowRoot.querySelector('#valid'); + expect(input).to.not.be.null; + expect(el.focusElement).to.not.have.attribute('title'); + }); + it('valid - multiline - boundary-type assertions and title', async () => { + const el = await litFixture( + html` + + ` + ); + await elementUpdated(el); + + expect(el).to.not.equal(undefined); + const input = el.shadowRoot.querySelector('#valid'); + expect(input).to.not.be.null; + expect(el.focusElement).to.not.have.attribute('title'); + }); it('valid - unicode', async () => { const el = await litFixture( html` @@ -602,6 +639,43 @@ describe('Textfield', () => { : null; expect(input).to.not.be.null; }); + it('invalid - boundary-type assertions and title', async () => { + const el = await litFixture( + html` + + ` + ); + await elementUpdated(el); + + expect(el).to.not.equal(undefined); + const input = el.shadowRoot.querySelector('#invalid'); + expect(input).to.not.be.null; + expect(el.focusElement).to.have.attribute('title'); + }); + it('invalid - multiline - boundary-type assertions and title', async () => { + const el = await litFixture( + html` + + ` + ); + await elementUpdated(el); + + expect(el).to.not.equal(undefined); + const input = el.shadowRoot.querySelector('#invalid'); + expect(input).to.not.be.null; + expect(el.focusElement).to.have.attribute('title'); + }); it('invalid - multiline - boundary-type assertions', async () => { const el = await litFixture( html`