fix(switch): use ._showFeedbackConditionFor instead of .submitted

This commit is contained in:
Thijs Louisse 2021-04-08 18:16:46 +02:00
parent 0e910e3f80
commit 652f267b99
8 changed files with 88 additions and 12 deletions

View file

@ -0,0 +1,5 @@
---
'@lion/switch': patch
---
- use .\_showFeedbackConditionFor instead of .submitted

View file

@ -41,6 +41,13 @@ export const validation = () => {
static get validationTypes() { static get validationTypes() {
return [...super.validationTypes, 'info']; return [...super.validationTypes, 'info'];
} }
_showFeedbackConditionFor(type) {
if (type === 'info') {
return true;
}
return super._showFeedbackConditionFor(type);
}
}, },
); );
} }

View file

@ -196,12 +196,12 @@ const InteractionStateMixinImplementation = superclass =>
*/ */
// eslint-disable-next-line class-methods-use-this, no-unused-vars // eslint-disable-next-line class-methods-use-this, no-unused-vars
_showFeedbackConditionFor(type, meta) { _showFeedbackConditionFor(type, meta) {
const { touched, dirty, prefilled, submitted } = meta; return (meta.touched && meta.dirty) || meta.prefilled || meta.submitted;
return (touched && dirty) || prefilled || submitted;
} }
get _feedbackConditionMeta() { get _feedbackConditionMeta() {
return { return {
// @ts-ignore
...super._feedbackConditionMeta, ...super._feedbackConditionMeta,
submitted: this.submitted, submitted: this.submitted,
touched: this.touched, touched: this.touched,

View file

@ -652,11 +652,13 @@ export const ValidateMixinImplementation = superclass =>
/** /**
* Allows the end user to specify when a feedback message should be shown * Allows the end user to specify when a feedback message should be shown
* @example * @example
* showFeedbackConditionFor(type, defaultCondition) { * showFeedbackConditionFor(type, meta, defaultCondition) {
* if (type === 'info') { * if (type === 'info') {
* return true; * return return;
* } else if (type === 'prefilledOnly') {
* return meta.prefilled;
* } * }
* return defaultCondition(type); * return defaultCondition(type, meta);
* } * }
* @overridable * @overridable
* @param {string} type could be 'error', 'warning', 'info', 'success' or any other custom * @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 // Necessary typecast because types aren't smart enough to understand that we filter out undefined
const newShouldShowFeedbackFor = /** @type {string[]} */ (ctor.validationTypes 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(_ => !!_)); .filter(_ => !!_));
if (JSON.stringify(this.shouldShowFeedbackFor) !== JSON.stringify(newShouldShowFeedbackFor)) { if (JSON.stringify(this.shouldShowFeedbackFor) !== JSON.stringify(newShouldShowFeedbackFor)) {
@ -738,7 +748,13 @@ export const ValidateMixinImplementation = superclass =>
const types = ctor.validationTypes; const types = ctor.validationTypes;
// Sort all validators based on the type provided. // Sort all validators based on the type provided.
const res = validationResult 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)); .sort((a, b) => types.indexOf(a.type) - types.indexOf(b.type));
return res.slice(0, this._visibleMessagesAmount); return res.slice(0, this._visibleMessagesAmount);
} }

View file

@ -37,6 +37,7 @@ export declare class InteractionStateHost {
meta: InteractionStates, meta: InteractionStates,
currentCondition: Function, currentCondition: Function,
): boolean; ): boolean;
_feedbackConditionMeta: InteractionStates;
} }
export declare function InteractionStateImplementation<T extends Constructor<LitElement>>( export declare function InteractionStateImplementation<T extends Constructor<LitElement>>(

View file

@ -71,6 +71,7 @@ export declare class ValidateHost {
_hasFeedbackVisibleFor(type: string): boolean; _hasFeedbackVisibleFor(type: string): boolean;
_updateShouldShowFeedbackFor(): void; _updateShouldShowFeedbackFor(): void;
_prioritizeAndFilterFeedback(opts: { validationResult: Validator[] }): Validator[]; _prioritizeAndFilterFeedback(opts: { validationResult: Validator[] }): Validator[];
_feedbackConditionMeta: object;
} }
export declare function ValidateImplementation<T extends Constructor<LitElement>>( export declare function ValidateImplementation<T extends Constructor<LitElement>>(

View file

@ -91,7 +91,6 @@ export class LionSwitch extends ScopedElementsMixin(ChoiceInputMixin(LionField))
this._labelNode.addEventListener('click', this._toggleChecked); this._labelNode.addEventListener('click', this._toggleChecked);
} }
this._syncButtonSwitch(); this._syncButtonSwitch();
this.submitted = true;
} }
disconnectedCallback() { disconnectedCallback() {

View file

@ -1,12 +1,23 @@
import { expect, fixture as _fixture, html } from '@open-wc/testing'; import { expect, fixture as _fixture, html } from '@open-wc/testing';
import sinon from 'sinon'; import sinon from 'sinon';
import { Validator } from '@lion/form-core';
import { LionSwitch } from '@lion/switch';
import '@lion/switch/define'; import '@lion/switch/define';
/** /**
* @typedef {import('../src/LionSwitch').LionSwitch} LionSwitch
* @typedef {import('@lion/core').TemplateResult} TemplateResult * @typedef {import('@lion/core').TemplateResult} TemplateResult
*/ */
const IsTrue = class extends Validator {
static get validatorName() {
return 'IsTrue';
}
execute() {
return true;
}
};
/** /**
* @param {LionSwitch} lionSwitchEl * @param {LionSwitch} lionSwitchEl
*/ */
@ -138,8 +149,44 @@ describe('lion-switch', () => {
expect(handlerSpy.callCount).to.equal(1); expect(handlerSpy.callCount).to.equal(1);
}); });
it('is submitted by default', async () => { it('can be configured to show feedback messages immediately', async () => {
const el = await fixture(html`<lion-switch></lion-switch>`); const tagName = 'custom-switch';
expect(el.submitted).to.be.true; 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`<custom-switch
.validators="${[new IsTrue({}, { type: 'info' })]}"
.showFeedbackConditionFor="${(
/** @type {string} */ type,
/** @type {object} */ meta,
/** @type {(type: string, meta: object) => any} */ defaultCondition,
) => {
if (type === 'info') {
return true;
}
return defaultCondition(type, meta);
}}"
></custom-switch>`,
);
expect(el.showsFeedbackFor).to.eql(['info']);
}); });
}); });