diff --git a/packages/fieldset/src/LionFieldset.js b/packages/fieldset/src/LionFieldset.js
index e0d25d468..6e04af64b 100644
--- a/packages/fieldset/src/LionFieldset.js
+++ b/packages/fieldset/src/LionFieldset.js
@@ -101,38 +101,25 @@ export class LionFieldset extends FormRegistrarMixin(
this.__createTypeAbsenceValidators();
this._checkForOutsideClick = this._checkForOutsideClick.bind(this);
+
+ this.addEventListener('focusin', this._syncFocused);
+ this.addEventListener('focusout', this._onFocusOut);
+ this.addEventListener('validation-done', this.__validate);
+ this.addEventListener('dirty-changed', this._syncDirty);
}
connectedCallback() {
- // eslint-disable-next-line wc/guard-super-call
- super.connectedCallback();
-
- this.addEventListener('focusin', this._updateTouchedClass);
- this.addEventListener('focusout', this._onFocusOut);
- this.addEventListener('focusin', this._syncFocused);
-
- this.addEventListener('validation-done', this.__validate);
- this.addEventListener('dirty-changed', this._syncDirty);
-
+ super.connectedCallback(); // eslint-disable-line wc/guard-super-call
this._setRole();
- document.addEventListener('click', this._checkForOutsideClick);
- }
-
- _checkForOutsideClick(event) {
- const outsideGroupClicked = !this.contains(event.target);
- if (outsideGroupClicked) {
- this.touched = true;
- }
}
disconnectedCallback() {
- // eslint-disable-next-line wc/guard-super-call
- super.disconnectedCallback();
- this.removeEventListener('validation-done', this.__validate);
- this.removeEventListener('touched-changed', this._updateTouched);
- this.removeEventListener('dirty-changed', this._syncDirty);
+ super.disconnectedCallback(); // eslint-disable-line wc/guard-super-call
- document.removeEventListener('click', this._checkForOutsideClick);
+ if (this.__hasActiveOutsideClickHandling) {
+ document.removeEventListener('click', this._checkForOutsideClick);
+ this.__hasActiveOutsideClickHandling = false;
+ }
}
updated(changedProps) {
@@ -162,6 +149,23 @@ export class LionFieldset extends FormRegistrarMixin(
if (changedProps.has('focused')) {
/** @deprecated use touched attribute instead */
this.classList[this.focused ? 'add' : 'remove']('state-focused');
+ if (this.focused === true) {
+ this.__setupOutsideClickHandling();
+ }
+ }
+ }
+
+ __setupOutsideClickHandling() {
+ if (!this.__hasActiveOutsideClickHandling) {
+ document.addEventListener('click', this._checkForOutsideClick);
+ this.__hasActiveOutsideClickHandling = true;
+ }
+ }
+
+ _checkForOutsideClick(event) {
+ const outsideGroupClicked = !this.contains(event.target);
+ if (outsideGroupClicked) {
+ this.touched = true;
}
}
diff --git a/packages/fieldset/stories/index.stories.js b/packages/fieldset/stories/index.stories.js
index a20479c5e..7c59afc00 100644
--- a/packages/fieldset/stories/index.stories.js
+++ b/packages/fieldset/stories/index.stories.js
@@ -84,52 +84,20 @@ storiesOf('Forms|Fieldset', module)
`,
)
- .add('Validation 2 inputs', () => {
- const input1IsTen = value => ({
- input1IsTen: value.input1 === 'cats' && value.input2 === 'dogs',
- });
- localize.locale = 'en-GB';
- try {
- localize.addData('en-GB', 'lion-validate+input1IsTen', {
- error: {
- input1IsTen: 'Input 1 needs to be "cats" and Input 2 needs to be "dogs"',
- },
- });
- } catch (error) {
- // expected as it's a demo
- }
-
- return html`
-
-
-
-
- `;
- })
.add('Validation', () => {
- function isFakeValidator() {
+ function isDemoValidator() {
return false;
}
- const fakeValidator = (...factoryParams) => [
- (...params) => ({ validator: isFakeValidator(...params) }),
+ const demoValidator = (...factoryParams) => [
+ (...params) => ({ validator: isDemoValidator(...params) }),
...factoryParams,
];
try {
localize.addData('en-GB', 'lion-validate+validator', {
error: {
- validator: 'Fake error message',
+ validator: 'Demo error message',
},
});
} catch (error) {
@@ -137,7 +105,7 @@ storiesOf('Forms|Fieldset', module)
}
return html`
-
+
`;
+ })
+ .add('Validation 2 inputs', () => {
+ const isCatsAndDogs = value => ({
+ isCatsAndDogs: value.input1 === 'cats' && value.input2 === 'dogs',
+ });
+ localize.locale = 'en-GB';
+ try {
+ localize.addData('en-GB', 'lion-validate+isCatsAndDogs', {
+ error: {
+ isCatsAndDogs:
+ '[Fieldset Error] Input 1 needs to be "cats" and Input 2 needs to be "dogs"',
+ },
+ });
+ } catch (error) {
+ // expected as it's a demo
+ }
+
+ return html`
+
+
+
+
+ `;
+ })
+ .add('Validation 2 fieldsets', () => {
+ const isCats = value => ({
+ isCats: value.input1 === 'cats',
+ });
+ localize.locale = 'en-GB';
+ try {
+ localize.addData('en-GB', 'lion-validate+isCats', {
+ error: {
+ isCats: '[Fieldset Nr. 1 Error] Input 1 needs to be "cats"',
+ },
+ });
+ } catch (error) {
+ // expected as it's a demo
+ }
+
+ const isDogs = value => ({
+ isDogs: value.input1 === 'dogs',
+ });
+ localize.locale = 'en-GB';
+ try {
+ localize.addData('en-GB', 'lion-validate+isDogs', {
+ error: {
+ isDogs: '[Fieldset Nr. 2 Error] Input 1 needs to be "dogs"',
+ },
+ });
+ } catch (error) {
+ // expected as it's a demo
+ }
+
+ return html`
+
+
+
+
+
+
+
+
+
+
+
+ `;
});
diff --git a/packages/fieldset/test/lion-fieldset.test.js b/packages/fieldset/test/lion-fieldset.test.js
index 7ba6fdff5..d07ca0aae 100644
--- a/packages/fieldset/test/lion-fieldset.test.js
+++ b/packages/fieldset/test/lion-fieldset.test.js
@@ -421,17 +421,30 @@ describe('', () => {
<${childTag} name="input2">${childTag}>
${tag}>
`);
+ const el2 = await fixture(html`
+ <${tag}>
+ <${childTag} name="input1">${childTag}>
+ <${childTag} name="input2">${childTag}>
+ ${tag}>
+ `);
+
await nextFrame();
const outside = await fixture(html`
`);
+ outside.click();
+ expect(el.touched, 'unfocused fieldset should stays untouched').to.be.false;
+
el.children[1].focus();
el.children[2].focus();
expect(el.touched).to.be.false;
outside.click(); // blur the group via a click
+ outside.focus(); // a real mouse click moves focus as well
expect(el.touched).to.be.true;
+
+ expect(el2.touched).to.be.false;
});
it('potentially shows fieldset error message on interaction change', async () => {