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}
+ >
+ ${blockingChildTag}>
+ `)
+ );
+ expect(eventSpy).not.to.have.been.calledOnce;
+ });
});
+
describe('FormRegistrarPortalMixin', () => {
it('forwards registrations to the .registrationTarget', async () => {
const el = /** @type {RegistrarClass} */ (