useDocumentClassContext
Low-level access to the store behind useDocumentClass(): register or remove an html and body descriptor under an id you choose.
import { useDocumentClassContext } from '@salla.sa/twilight-theme-engine/providers';In plain words
useDocumentClass() is the friendly way to put classes on <body>. Underneath, it calls a small store with register(id, descriptor) and unregister(id).
This hook returns that store, or null without a provider, for the rare code that must manage a registration itself.
Signature
function useDocumentClassContext(): { store: DocumentElementStore } | null
// The store's shape (the type is not exported):
interface DocumentElementStore {
register(id: string, descriptor: DocumentElementDescriptor): void;
unregister(id: string): void;
subscribe(listener: () => void): () => void;
getSnapshot(): ReadonlyMap<string, DocumentElementDescriptor>;
getServerSnapshot(): ReadonlyMap<string, DocumentElementDescriptor>;
}Try it live
import { useEffect } from 'react';
import { useDocumentClassContext } from '@salla.sa/twilight-theme-engine/providers';
// Only for code that cannot call useDocumentClass(), such as an integration
// that decides when to add and remove the attributes itself.
export function useManualBodyClass(active: boolean) {
const ctx = useDocumentClassContext();
useEffect(() => {
if (!ctx || !active) return;
ctx.store.register('my-integration', { body: { class: 'playground-manual' } });
return () => ctx.store.unregister('my-integration');
}, [ctx, active]);
}
Example
import { useEffect } from 'react';
import { useDocumentClassContext } from '@salla.sa/twilight-theme-engine/providers';
export function useManualBodyClass(className: string, active: boolean) {
const ctx = useDocumentClassContext();
useEffect(() => {
if (!ctx || !active) return;
ctx.store.register('my-integration', { body: { class: className } });
return () => ctx.store.unregister('my-integration');
}, [ctx, className, active]);
}
How it behaves
registerstores or replaces the descriptor for an id and notifies subscribers;unregisternotifies only when the id existed. Each change creates a new snapshot, which triggers the DOM sync.DocumentElementDescriptor({ body?: attrs; html?: attrs }) is public from@salla.sa/twilight-theme-engine/utils.
Gotchas
Nothing unregisters for you. Pair every
registerwith anunregisterin the same effect cleanup, or the attributes stay on<body>for the rest of the visit.Ids are shared with
useDocumentClass()(which uses ReactuseId()values). Registering an id that already exists silently replaces that registration.