From c2c5e7c299d99750db5bded1014d8e24f2f6d4c8 Mon Sep 17 00:00:00 2001 From: qa46hx Date: Mon, 3 Feb 2020 10:52:09 +0100 Subject: [PATCH 1/2] fix(field): allow html inside labels --- packages/field/src/FormControlMixin.js | 28 ++++++++++++ packages/field/src/LionField.js | 5 +-- packages/field/test/FormControlMixin.test.js | 46 +++++++++++++++----- 3 files changed, 64 insertions(+), 15 deletions(-) diff --git a/packages/field/src/FormControlMixin.js b/packages/field/src/FormControlMixin.js index c835e2922..1fd94e8ca 100644 --- a/packages/field/src/FormControlMixin.js +++ b/packages/field/src/FormControlMixin.js @@ -53,6 +53,34 @@ export const FormControlMixin = dedupeMixin( }; } + get label() { + return ( + (this.querySelector('[slot="label"]') && + this.querySelector('[slot="label"]').textContent) || + this.__label + ); + } + + set label(newValue) { + const oldValue = this.label; + this.__label = newValue; + this.requestUpdate('label', oldValue); + } + + get helpText() { + return ( + (this.querySelector('[slot="help-text"]') && + this.querySelector('[slot="help-text"]').textContent) || + this.__helpText + ); + } + + set helpText(newValue) { + const oldValue = this.helpText; + this.__helpText = newValue; + this.requestUpdate('helpText', oldValue); + } + get slots() { return { ...super.slots, diff --git a/packages/field/src/LionField.js b/packages/field/src/LionField.js index e2ccb2647..8e05f5863 100644 --- a/packages/field/src/LionField.js +++ b/packages/field/src/LionField.js @@ -230,9 +230,6 @@ export class LionField extends FormControlMixin( } get fieldName() { - const label = - this.label || - (this.querySelector('[slot=label]') && this.querySelector('[slot=label]').textContent); - return this.__fieldName || label || this.name; + return this.__fieldName || this.label || this.name; } } diff --git a/packages/field/test/FormControlMixin.test.js b/packages/field/test/FormControlMixin.test.js index df30e8ae9..115b66af3 100644 --- a/packages/field/test/FormControlMixin.test.js +++ b/packages/field/test/FormControlMixin.test.js @@ -23,22 +23,46 @@ describe('FormControlMixin', () => { tag = unsafeStatic(elem); }); - it('has the capability to override the help text', async () => { - const lionFieldAttr = await fixture(html` - <${tag} help-text="This email address is already taken">${inputSlot} + it('has a label', async () => { + const elAttr = await fixture(html` + <${tag} label="Email address">${inputSlot} `); - expect( - Array.from(lionFieldAttr.children).find(child => child.slot === 'help-text').textContent, - ).to.contain('This email address is already taken'); - const lionFieldProp = await fixture(html` + expect(elAttr.label).to.equal('Email address', 'as an attribute'); + + const elProp = await fixture(html` <${tag} - .helpText=${'This email address is already taken'} + .label=${'Email address'} >${inputSlot} `); + expect(elProp.label).to.equal('Email address', 'as a property'); - expect( - Array.from(lionFieldProp.children).find(child => child.slot === 'help-text').textContent, - ).to.contain('This email address is already taken'); + const elElem = await fixture(html` + <${tag}> + + ${inputSlot} + `); + expect(elElem.label).to.equal('Email address', 'as an element'); + }); + + it('can have a help-text', async () => { + const elAttr = await fixture(html` + <${tag} help-text="We will not send you any spam">${inputSlot} + `); + expect(elAttr.helpText).to.equal('We will not send you any spam', 'as an attribute'); + + const elProp = await fixture(html` + <${tag} + .helpText=${'We will not send you any spam'} + >${inputSlot} + `); + expect(elProp.helpText).to.equal('We will not send you any spam', 'as a property'); + + const elElem = await fixture(html` + <${tag}> + + ${inputSlot} + `); + expect(elElem.helpText).to.equal('We will not send you any spam', 'as an element'); }); it('does not duplicate aria-describedby and aria-labelledby ids', async () => { From 66b2a71550f1f2984a6829666c5b0113939553bd Mon Sep 17 00:00:00 2001 From: qa46hx Date: Mon, 3 Feb 2020 10:52:56 +0100 Subject: [PATCH 2/2] chore(input): show example html inside label --- packages/field/test/FormControlMixin.test.js | 22 ++++++- packages/input/stories/index.stories.mdx | 61 +++++++++++++++++++- 2 files changed, 78 insertions(+), 5 deletions(-) diff --git a/packages/field/test/FormControlMixin.test.js b/packages/field/test/FormControlMixin.test.js index 115b66af3..0325865c7 100644 --- a/packages/field/test/FormControlMixin.test.js +++ b/packages/field/test/FormControlMixin.test.js @@ -38,12 +38,21 @@ describe('FormControlMixin', () => { const elElem = await fixture(html` <${tag}> - + ${inputSlot} `); expect(elElem.label).to.equal('Email address', 'as an element'); }); + it('has a label that supports inner html', async () => { + const el = await fixture(html` + <${tag}> + + ${inputSlot} + `); + expect(el.label).to.equal('Email address'); + }); + it('can have a help-text', async () => { const elAttr = await fixture(html` <${tag} help-text="We will not send you any spam">${inputSlot} @@ -59,12 +68,21 @@ describe('FormControlMixin', () => { const elElem = await fixture(html` <${tag}> - + ${inputSlot} `); expect(elElem.helpText).to.equal('We will not send you any spam', 'as an element'); }); + it('can have a help-text that supports inner html', async () => { + const el = await fixture(html` + <${tag}> + + ${inputSlot} + `); + expect(el.helpText).to.equal('We will not send you any spam'); + }); + it('does not duplicate aria-describedby and aria-labelledby ids', async () => { const lionField = await fixture(` <${elem} help-text="This element will be disconnected/reconnected">${inputSlot} diff --git a/packages/input/stories/index.stories.mdx b/packages/input/stories/index.stories.mdx index b66f2f356..7c3c5b213 100644 --- a/packages/input/stories/index.stories.mdx +++ b/packages/input/stories/index.stories.mdx @@ -10,7 +10,7 @@ import '../lion-input.js'; `lion-input` component is a webcomponent that enhances the functionality of the native `` element. - + {html` `} @@ -25,7 +25,7 @@ import '../lion-input.js'; - Based on [field](?path=/docs/forms-system-overview--page) - Extra visual elements can be added via `slots` - **label**: can also be provided via the `label` attribute, but the slot can be used to change the `html` and `CSS` of the label. - For example add an `sr-only` class to the label to make it visually hidden. + For example add an `u-sr-only` class to the label to make it visually hidden. A label is always needed for accessibility reasons. - **help-text**: a helper text shown below the label to give extra clarification. - **prefix**: does not have an active use case yet, but the option is in place. @@ -49,9 +49,64 @@ import '@lion/input/lion-input.js'; ## Examples +### Label + +Can be provided via the `label` attribute, but the slot can be used to change the `html` and `CSS` of the label. +For example add an `u-sr-only` class to the label to make it (partially) visually hidden. +A label is always needed for accessibility reasons. + + + {html` + + + + + `} + + +```html + + + + +``` + ### Help-text - +A helper text shown below the label to give extra clarification. + +Just like the `label`, a `help-text` can be provided via the `help-text` attribute, a slot can be used to change the `html` and `CSS` of the help-text. +For example add an anchor with further explanation. + + {html`