From 9105f50ef3434ae9e78240f56f5d7a161e030a45 Mon Sep 17 00:00:00 2001 From: geniuspacs Date: Tue, 11 Nov 2025 09:44:17 +0100 Subject: [PATCH] fix(ValidateMixin): no dispatch validators on readOnly form items (#2610) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Eugenio Páez Casado --- .changeset/long-feet-battle.md | 5 +++ .../form-core/src/validate/ValidateMixin.js | 6 ++-- .../test-suites/ValidateMixin.suite.js | 34 +++++++++++++------ 3 files changed, 31 insertions(+), 14 deletions(-) create mode 100644 .changeset/long-feet-battle.md diff --git a/.changeset/long-feet-battle.md b/.changeset/long-feet-battle.md new file mode 100644 index 000000000..dcd2a09ce --- /dev/null +++ b/.changeset/long-feet-battle.md @@ -0,0 +1,5 @@ +--- +'@lion/ui': patch +--- + +fix(ValidateMixin): no dispatch validators on readOnly form items diff --git a/packages/ui/components/form-core/src/validate/ValidateMixin.js b/packages/ui/components/form-core/src/validate/ValidateMixin.js index 37095e497..5287c8706 100644 --- a/packages/ui/components/form-core/src/validate/ValidateMixin.js +++ b/packages/ui/components/form-core/src/validate/ValidateMixin.js @@ -1,15 +1,15 @@ /* eslint-disable class-methods-use-this, camelcase, no-param-reassign, max-classes-per-file */ -import { SlotMixin, DisabledMixin } from '@lion/ui/core.js'; +import { DisabledMixin, SlotMixin } from '@lion/ui/core.js'; import { dedupeMixin } from '@open-wc/dedupe-mixin'; // TODO: make form-core independent from localize import { getLocalizeManager } from '@lion/ui/localize-no-side-effects.js'; import { ScopedElementsMixin } from '../../../core/src/ScopedElementsMixin.js'; +import { FormControlMixin } from '../FormControlMixin.js'; import { AsyncQueue } from '../utils/AsyncQueue.js'; import { pascalCase } from '../utils/pascalCase.js'; import { SyncUpdatableMixin } from '../utils/SyncUpdatableMixin.js'; import { LionValidationFeedback } from './LionValidationFeedback.js'; import { Unparseable } from './Unparseable.js'; -import { FormControlMixin } from '../FormControlMixin.js'; // eslint-disable-next-line no-unused-vars import { ResultValidator as MetaValidator } from './ResultValidator.js'; // eslint-disable-next-line no-unused-vars @@ -399,7 +399,7 @@ export const ValidateMixinImplementation = superclass => this.__validateCompleteResolve = resolve; }); - if (this.disabled) { + if (this.disabled || this.readOnly) { this.__clearValidationResults(); this.__finishValidationPass(); this._updateFeedbackComponent(); diff --git a/packages/ui/components/form-core/test-suites/ValidateMixin.suite.js b/packages/ui/components/form-core/test-suites/ValidateMixin.suite.js index f65db5128..6e38d7292 100644 --- a/packages/ui/components/form-core/test-suites/ValidateMixin.suite.js +++ b/packages/ui/components/form-core/test-suites/ValidateMixin.suite.js @@ -1,26 +1,26 @@ -import { LitElement } from 'lit'; -import { aTimeout, defineCE, expect, fixture, html, unsafeStatic } from '@open-wc/testing'; import { - getFormControlMembers, - AsyncAlwaysInvalid, - AsyncAlwaysValid, AlwaysInvalid, AlwaysValid, + AsyncAlwaysInvalid, + AsyncAlwaysValid, + getFormControlMembers, } from '@lion/ui/form-core-test-helpers.js'; -import sinon from 'sinon'; import { - ResultValidator, - ValidateMixin, EqualsLength, - Unparseable, MaxLength, MinLength, - Validator, Required, + ResultValidator, + Unparseable, + ValidateMixin, + Validator, } from '@lion/ui/form-core.js'; +import { aTimeout, defineCE, expect, fixture, html, unsafeStatic } from '@open-wc/testing'; +import { LitElement } from 'lit'; +import sinon from 'sinon'; -import '@lion/ui/define/lion-validation-feedback.js'; import '@lion/ui/define/lion-field.js'; +import '@lion/ui/define/lion-validation-feedback.js'; /** * @typedef {import('@lion/ui/form-core.js').LionField} LionField @@ -631,6 +631,18 @@ export function runValidateMixinSuite(customConfig) { isCatValidator.param = 'Garfield'; expect(catSpy.callCount).to.equal(2); }); + + it('Validators will not be called on readOnly fields', async () => { + const el = /** @type {ValidateElement} */ ( + await fixture(html` + <${tag} .validators=${[new IsCat()]}>${lightDom} + `) + ); + + el.readOnly = true; + el.modelValue = 'dog'; + expect(el.validationStates.error.IsCat).to.be.undefined; + }); }); describe('Async Validator Integration', () => {