@wrnexus/block-editor
Reusable editor state, DOM surfaces, inspector drafts, clipboard-download UI, selection actions, and explicit block/preset composition.
Configure a builder
import { createBuilderKit, createBlockEditorState, mountBlockCanvas } from "@wrnexus/block-editor";
import { emailEditorBlocks } from "@wrnexus/email-renderer/create";
import { emailPresets } from "@wrnexus/email-renderer/presets";
const builder = createBuilderKit({
blocks: [...emailEditorBlocks, myTrustedBlockDefinition],
presets: [...emailPresets, myTrustedSectionPreset],
});
const palette = builder.blocks(); // manifests: name, icon, category, schemas
const presets = builder.presets();
const node = builder.createBlock("custom.my-block", { id: () => crypto.randomUUID() });
Definitions use defineBlock from @wrnexus/blocks: manifest, create,
renderers, textRenderer, inspector controls, and migrations. Presets have
id, localized name, icon, and create({ id }). Registration is
explicit and frozen; duplicates and invalid created trees throw before insertion.
Factories must return schema-valid instances. Placement still goes through the
document-kind command validator; kit validation is not publish authorization.
Use the same trusted definitions in your document kind and server renderer. Adding a block to a palette alone does not enable its rendering or publishing. The built-in email production adapter currently uses its core email kind; custom email target composition and a complete high-level editor component remain work in progress.
The package exports InspectorDrafts, builderOutlineLabel,
builderDragAnnouncement, updateBuilderCanvas, showBuilderBlockActions,
editBuilderText, showImageFallbacks, and offerBuilderDownload.
These are low-level reusable surfaces, not a drop-in complete studio yet.
The host owns authenticated load/save/render/asset service callbacks.
createBlockEditorState uses validated commands; host applications must actually
wire it rather than assuming all application mutations already use that state.