components/elements/registry.jsjavascript
/**
* @module components/elements/registry
* @description Single registration point for all content-block elements.
* Each element folder exports its full definition
* `{ type, region, required, properties, component, adapter }` from its
* index.js (block contract in schema.js, component + props adapter next to
* it). Adding a new element = add the folder, import it here - rendering
* (ComponentRenderer), layout regions (SlidePage) and content validation
* (scripts/validate-content.mjs via elements/schemas.js) all pick it up
* from the registry.
*/
import storyTitle from "./StoryTitle";
import headline from "./Headline";
import disclaimer from "./Disclaimer";
import buttonList from "./ButtonList";
import buttonGrid from "./ButtonGrid";
import selectWidget from "./SelectWidget";
import quoteList from "./QuoteList";
import cardGrid from "./CardGrid";
import institutionBadge from "./InstitutionBadge";
import imageCardGrid from "./ImageCardGrid";
import textMediaWidget from "./TextMediaWidget";
import circleInfographic from "./CircleInfographic";
import bodyText from "./BodyText";
import stepTracker from "./StepTracker";
import chartGrid from "./ChartGrid";
import iconWheel from "./IconWheel";
import circleChain from "./CircleChain";
import processFlow from "./ProcessFlow";
/** All registered element definitions. */
export const ELEMENT_REGISTRY = [
storyTitle,
headline,
disclaimer,
buttonList,
buttonGrid,
selectWidget,
quoteList,
cardGrid,
institutionBadge,
imageCardGrid,
textMediaWidget,
circleInfographic,
bodyText,
stepTracker,
chartGrid,
iconWheel,
circleChain,
processFlow,
];
const byType = new Map(ELEMENT_REGISTRY.map((definition) => [definition.type, definition]));
/**
* The registered definition for a block type, or null for unknown types.
*
* @param {string} type - A block's `type` value, e.g. "quoteList".
* @returns {Object|null}
*/
export const getElementDefinition = (type) => byType.get(type) || null;
/**
* The layout region a content block renders in: the block's own `region`
* field if set, otherwise its element's default, otherwise "content".
* SlidePage wraps each region ("storyTitle" | "headline" | "content") in its
* own container.
*
* @param {Object} block - A content block, e.g. `{ type: "headline", text: "..." }`.
* @returns {string}
*/
export const getBlockRegion = (block) =>
block.region || byType.get(block.type)?.region || "content";