From 652f267b99d92896a236dd4b948abaf9c96eada7 Mon Sep 17 00:00:00 2001 From: Thijs Louisse Date: Thu, 8 Apr 2021 18:16:46 +0200 Subject: [PATCH] fix(switch): use ._showFeedbackConditionFor instead of .submitted --- .changeset/sharp-laws-scream.md | 5 ++ .../components/interaction/switch/features.md | 7 +++ .../form-core/src/InteractionStateMixin.js | 4 +- .../form-core/src/validate/ValidateMixin.js | 26 +++++++-- .../types/InteractionStateMixinTypes.d.ts | 1 + .../types/validate/ValidateMixinTypes.d.ts | 1 + packages/switch/src/LionSwitch.js | 1 - packages/switch/test/lion-switch.test.js | 55 +++++++++++++++++-- 8 files changed, 88 insertions(+), 12 deletions(-) create mode 100644 .changeset/sharp-laws-scream.md diff --git a/.changeset/sharp-laws-scream.md b/.changeset/sharp-laws-scream.md new file mode 100644 index 000000000..59214743f --- /dev/null +++ b/.changeset/sharp-laws-scream.md @@ -0,0 +1,5 @@ +--- +'@lion/switch': patch +--- + +- use .\_showFeedbackConditionFor instead of .submitted diff --git a/docs/components/interaction/switch/features.md b/docs/components/interaction/switch/features.md index 9eaaea0ce..8f0ea02cc 100644 --- a/docs/components/interaction/switch/features.md +++ b/docs/components/interaction/switch/features.md @@ -41,6 +41,13 @@ export const validation = () => { static get validationTypes() { return [...super.validationTypes, 'info']; } + + _showFeedbackConditionFor(type) { + if (type === 'info') { + return true; + } + return super._showFeedbackConditionFor(type); + } }, ); } diff --git a/packages/form-core/src/InteractionStateMixin.js b/packages/form-core/src/InteractionStateMixin.js index 6689630ad..d3a2c44c3 100644 --- a/packages/form-core/src/InteractionStateMixin.js +++ b/packages/form-core/src/InteractionStateMixin.js @@ -196,12 +196,12 @@ const InteractionStateMixinImplementation = superclass => */ // eslint-disable-next-line class-methods-use-this, no-unused-vars _showFeedbackConditionFor(type, meta) { - const { touched, dirty, prefilled, submitted } = meta; - return (touched && dirty) || prefilled || submitted; + return (meta.touched && meta.dirty) || meta.prefilled || meta.submitted; } get _feedbackConditionMeta() { return { + // @ts-ignore ...super._feedbackConditionMeta, submitted: this.submitted, touched: this.touched, diff --git a/packages/form-core/src/validate/ValidateMixin.js b/packages/form-core/src/validate/ValidateMixin.js index 510829df2..497287dcf 100644 --- a/packages/form-core/src/validate/ValidateMixin.js +++ b/packages/form-core/src/validate/ValidateMixin.js @@ -652,11 +652,13 @@ export const ValidateMixinImplementation = superclass => /** * Allows the end user to specify when a feedback message should be shown * @example - * showFeedbackConditionFor(type, defaultCondition) { + * showFeedbackConditionFor(type, meta, defaultCondition) { * if (type === 'info') { - * return true; + * return return; + * } else if (type === 'prefilledOnly') { + * return meta.prefilled; * } - * return defaultCondition(type); + * return defaultCondition(type, meta); * } * @overridable * @param {string} type could be 'error', 'warning', 'info', 'success' or any other custom @@ -715,7 +717,15 @@ export const ValidateMixinImplementation = superclass => // Necessary typecast because types aren't smart enough to understand that we filter out undefined const newShouldShowFeedbackFor = /** @type {string[]} */ (ctor.validationTypes - .map(type => (this.showFeedbackConditionFor(type) ? type : undefined)) + .map(type => + this.showFeedbackConditionFor( + type, + this._feedbackConditionMeta, + this._showFeedbackConditionFor.bind(this), + ) + ? type + : undefined, + ) .filter(_ => !!_)); if (JSON.stringify(this.shouldShowFeedbackFor) !== JSON.stringify(newShouldShowFeedbackFor)) { @@ -738,7 +748,13 @@ export const ValidateMixinImplementation = superclass => const types = ctor.validationTypes; // Sort all validators based on the type provided. const res = validationResult - .filter(v => this.showFeedbackConditionFor(v.type)) + .filter(v => + this.showFeedbackConditionFor( + v.type, + this._feedbackConditionMeta, + this._showFeedbackConditionFor.bind(this), + ), + ) .sort((a, b) => types.indexOf(a.type) - types.indexOf(b.type)); return res.slice(0, this._visibleMessagesAmount); } diff --git a/packages/form-core/types/InteractionStateMixinTypes.d.ts b/packages/form-core/types/InteractionStateMixinTypes.d.ts index 2dbf81a0c..9251f235a 100644 --- a/packages/form-core/types/InteractionStateMixinTypes.d.ts +++ b/packages/form-core/types/InteractionStateMixinTypes.d.ts @@ -37,6 +37,7 @@ export declare class InteractionStateHost { meta: InteractionStates, currentCondition: Function, ): boolean; + _feedbackConditionMeta: InteractionStates; } export declare function InteractionStateImplementation>( diff --git a/packages/form-core/types/validate/ValidateMixinTypes.d.ts b/packages/form-core/types/validate/ValidateMixinTypes.d.ts index 4e433a91c..37cb8ab3d 100644 --- a/packages/form-core/types/validate/ValidateMixinTypes.d.ts +++ b/packages/form-core/types/validate/ValidateMixinTypes.d.ts @@ -71,6 +71,7 @@ export declare class ValidateHost { _hasFeedbackVisibleFor(type: string): boolean; _updateShouldShowFeedbackFor(): void; _prioritizeAndFilterFeedback(opts: { validationResult: Validator[] }): Validator[]; + _feedbackConditionMeta: object; } export declare function ValidateImplementation>( diff --git a/packages/switch/src/LionSwitch.js b/packages/switch/src/LionSwitch.js index 574b96f6d..5bcfed026 100644 --- a/packages/switch/src/LionSwitch.js +++ b/packages/switch/src/LionSwitch.js @@ -91,7 +91,6 @@ export class LionSwitch extends ScopedElementsMixin(ChoiceInputMixin(LionField)) this._labelNode.addEventListener('click', this._toggleChecked); } this._syncButtonSwitch(); - this.submitted = true; } disconnectedCallback() { diff --git a/packages/switch/test/lion-switch.test.js b/packages/switch/test/lion-switch.test.js index 60c828cad..f42682c62 100644 --- a/packages/switch/test/lion-switch.test.js +++ b/packages/switch/test/lion-switch.test.js @@ -1,12 +1,23 @@ import { expect, fixture as _fixture, html } from '@open-wc/testing'; import sinon from 'sinon'; +import { Validator } from '@lion/form-core'; +import { LionSwitch } from '@lion/switch'; import '@lion/switch/define'; /** - * @typedef {import('../src/LionSwitch').LionSwitch} LionSwitch * @typedef {import('@lion/core').TemplateResult} TemplateResult */ +const IsTrue = class extends Validator { + static get validatorName() { + return 'IsTrue'; + } + + execute() { + return true; + } +}; + /** * @param {LionSwitch} lionSwitchEl */ @@ -138,8 +149,44 @@ describe('lion-switch', () => { expect(handlerSpy.callCount).to.equal(1); }); - it('is submitted by default', async () => { - const el = await fixture(html``); - expect(el.submitted).to.be.true; + it('can be configured to show feedback messages immediately', async () => { + const tagName = 'custom-switch'; + if (!customElements.get(tagName)) { + customElements.define( + tagName, + class CustomSwitch extends LionSwitch { + static get validationTypes() { + return [...super.validationTypes, 'info']; + } + + /** + * @param {string} type + * @param {object} meta + */ + _showFeedbackConditionFor(type, meta) { + if (type === 'info') { + return true; + } + return super._showFeedbackConditionFor(type, meta); + } + }, + ); + } + const el = await fixture( + html``, + ); + expect(el.showsFeedbackFor).to.eql(['info']); }); });