diff --git a/.changeset/spicy-windows-move.md b/.changeset/spicy-windows-move.md new file mode 100644 index 0000000000..d024ff2459 --- /dev/null +++ b/.changeset/spicy-windows-move.md @@ -0,0 +1,5 @@ +--- +'@lion/ui': minor +--- + +[form-core] add a way to prevent registration of a form-element diff --git a/docs/fundamentals/systems/form/use-cases.md b/docs/fundamentals/systems/form/use-cases.md index 1ab06851eb..8226fb4928 100644 --- a/docs/fundamentals/systems/form/use-cases.md +++ b/docs/fundamentals/systems/form/use-cases.md @@ -82,6 +82,10 @@ export const main = () => { + class extends superclass { constructor() { super(); + /** + * In case the form component should not register itself, set this property to true + */ + this.preventRegistration = false; /** * The registrar this FormControl registers to, Usually a descendant of FormGroup or * ChoiceGroup @@ -45,13 +49,15 @@ const FormRegisteringMixinImplementation = superclass => connectedCallback() { super.connectedCallback(); - this.dispatchEvent( - new CustomEvent('form-element-register', { - detail: { element: this }, - bubbles: true, - composed: Boolean(this.allowCrossRootRegistration), - }), - ); + if (!this.preventRegistration) { + this.dispatchEvent( + new CustomEvent('form-element-register', { + detail: { element: this }, + bubbles: true, + composed: Boolean(this.allowCrossRootRegistration), + }), + ); + } } disconnectedCallback() { diff --git a/packages/ui/components/form-core/test-suites/FormRegistrationMixins.suite.js b/packages/ui/components/form-core/test-suites/FormRegistrationMixins.suite.js index 71864f515e..e7e863300b 100644 --- a/packages/ui/components/form-core/test-suites/FormRegistrationMixins.suite.js +++ b/packages/ui/components/form-core/test-suites/FormRegistrationMixins.suite.js @@ -286,6 +286,7 @@ export const runRegistrationSuite = customConfig => { expect(eventSpy.getCall(0).args[0].composed).to.equal(true); expect(el.formElements).to.deep.equal([el.shadowRoot?.querySelector('#child')]); }); + it('dispatches the form-element-register event with compose true if allowCrossRootRegistration is set', async () => { const eventSpy = sinon.spy(); /** @type {RegisteringClass} */ ( @@ -300,6 +301,7 @@ export const runRegistrationSuite = customConfig => { expect(eventSpy).to.have.been.calledOnce; expect(eventSpy.getCall(0).args[0].composed).to.equal(true); }); + it('dispatches the form-element-register event with compose false if allowCrossRootRegistration is not set', async () => { const eventSpy = sinon.spy(); /** @type {RegisteringClass} */ ( @@ -310,7 +312,29 @@ export const runRegistrationSuite = customConfig => { expect(eventSpy).to.have.been.calledOnce; expect(eventSpy.getCall(0).args[0].composed).to.equal(false); }); + + it('will not dispatch form-element-register event when it has "preventRegistration" set', async () => { + class BlockingFormElement extends FormRegisteringMixin(LitElement) { + constructor() { + super(); + this.preventRegistration = true; + } + } + const tagBlockingChildString = defineCE(BlockingFormElement); + const blockingChildTag = unsafeStatic(tagBlockingChildString); + const eventSpy = sinon.spy(); + /** @type {RegisteringClass} */ ( + await fixture(html` + <${blockingChildTag} + @form-element-register=${eventSpy} + > + + `) + ); + expect(eventSpy).not.to.have.been.calledOnce; + }); }); + describe('FormRegistrarPortalMixin', () => { it('forwards registrations to the .registrationTarget', async () => { const el = /** @type {RegistrarClass} */ (