Skip to main content

Form extensions

A form-scoped registry of extra nodes — dialogs, overlays — that a component deep inside a form registers by id, and that FormShell renders at the form root.

The node ends up inside the react-hook-form and record contexts without being nested where the registrant sits, so it can read and write the form's fields. No portal is involved.

useFormExtensions​

import {useFormExtensions} from 'habarico';

const {formExtensions, registerFormExtension, unregisterFormExtension} = useFormExtensions();
NameTypeDescription
formExtensionsRecord<string, ReactNode>The current registry — what FormShell renders
registerFormExtension(id: string, node: ReactNode) => voidRegisters (or replaces) the node under that id
unregisterFormExtension(id: string) => voidRemoves it again

Example​

const AI_ASSISTANT_ID = 'ai-assistant';

const {registerFormExtension, unregisterFormExtension} = useFormExtensions();

useEffect(() => {
registerFormExtension(AI_ASSISTANT_ID, <MyFormOverlay />);
}, [registerFormExtension]);

useEffect(() => () => unregisterFormExtension(AI_ASSISTANT_ID), [unregisterFormExtension]);

Registering under an id that already exists replaces the node, so re-registering on every render of a changed node is safe — but unregister on unmount, otherwise a stale extension is rendered into the next form.

caution

Outside a FormExtensionsProvider the hook returns a no-op registry: an empty formExtensions and register/unregister functions that do nothing. Nothing throws, and nothing renders either — which is why a component relying on this API silently does nothing outside a form. SchemaAdmin provides the registry around the whole admin.

See also​