fix(switch): use ._showFeedbackConditionFor instead of .submitted
This commit is contained in:
parent
0e910e3f80
commit
652f267b99
8 changed files with 88 additions and 12 deletions
5
.changeset/sharp-laws-scream.md
Normal file
5
.changeset/sharp-laws-scream.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'@lion/switch': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
- use .\_showFeedbackConditionFor instead of .submitted
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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>>(
|
||||||
|
|
|
||||||
|
|
@ -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>>(
|
||||||
|
|
|
||||||
|
|
@ -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() {
|
||||||
|
|
|
||||||
|
|
@ -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']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue