import { ComponentType, ReactNode, AnchorHTMLAttributes, CSSProperties, MouseEvent } from 'react';
type ComponentIdentifier = 'r-text' | 'something-else' | 'cloudinary-advanced-image' | 'r-video' | 'r-icon' | 'r-button' | 'r-divider' | 'r-embed' | 'r-list' | 'r-accordion' | 'r-mount';
declare const ComponentIdentifiers: Record;
type AttributeListForComponentTypes = {
[key: string]: string[];
};
type ComponentNameToModifyAttribute = {
[key: string]: string;
};
type DeviceTypeBasedAttributeValues = {
phone?: any;
tablet?: any;
desktop?: any;
all?: any;
};
type AttributeEditModeConfig = {
name: string;
/** Optional title shown above this attribute's editor in the modify panel. */
heading?: string;
/** Optional supporting text under the heading. */
subHeading?: string;
defaultValues?: DeviceTypeBasedAttributeValues;
/**
* When true, the Modify drawer does not show an editor for this attribute.
* The attribute still exists: defaults, prefills, and render still use it.
* RuleCMS also omits these from user-facing documentation.
*/
hiddenToUser?: boolean;
};
type DefaultAttributeValue = {
name: string;
defaultValues: DeviceTypeBasedAttributeValues;
};
type PageViewType = 'Preview' | 'Compose' | 'RenderedPage';
/**
* Extra props the embedding application supplied for one component instance,
* addressed by column id through `RuleCMSWidget`'s `componentProps`. widget-react
* only delivers the bag — it defines no keys — so each component documents which
* ones it honours (`r-button` reads `onClick`).
*
* Absent far more often than present: the composer never sends it, and neither
* does any host that did not address this particular instance.
*/
type WidgetInstanceProps = {
[key: string]: any;
};
type RenderedOrFunctionalComponentEntry = JSX.Element | ((props: {
componentAttributes?: {
[key: string]: any;
};
pageViewType: PageViewType;
styleProps: {
[key: string]: any;
} | undefined;
/** Host-app classes for this column, when the renderer decided this card carries them. */
className?: string;
/** Host-app props for this instance; see WidgetInstanceProps. */
widgetInstanceProps?: WidgetInstanceProps;
/**
* Host-supplied map of mount name → React component. Only `r-mount`
* reads it. Absent in the composer, and absent whenever the host
* passed no `mounts` on `RuleCMSWidget`.
*/
mounts?: {
[name: string]: ComponentType;
};
/**
* Nested content the render path resolved for this instance, for the
* components that are containers rather than leaves — `r-accordion`'s
* disclosure body is the first. Absent on every render path that exists
* today: the renderer instantiates components as leaves, and authoring a
* subtree into a component slot is unshipped platform work. A component
* that reads it must render identically without it.
*/
children?: ReactNode;
}) => JSX.Element);
/**
* What a component knows about the render it is being asked about, when
* widget-react calls `resolveNoContainer` or `resolveRendersOwnElement`. An
* object so the contract can grow without breaking existing resolvers.
*/
type NoContainerResolverContext = {
/** The component instance's attribute values (resolved for the active device). */
componentAttributes?: {
[key: string]: any;
};
/** The column styles widget-react is about to apply, one way or the other. */
styleProps?: {
[key: string]: any;
} | undefined;
};
/**
* Answers, for one specific render, "can this component carry the column's box
* styles itself?" — `false` — or "must widget-react put them on a wrapper
* div?" — `true`. Same meaning as the static `noContainer`, decided per render.
*
* Every component in this library exposes one; see
* `__docs__/PATTERNS_dynamic_no_container.md`.
*/
type ResolveNoContainer = (context: NoContainerResolverContext) => boolean;
/**
* Does this render produce a root element that can carry a class attribute?
* Unlike `resolveNoContainer` this is about the existence of an element, not
* about whether it can hold box styles: an inline `` answers `true`
* here and `true` to `resolveNoContainer`.
*
* A card whose resolver can return `true` MUST apply the `className` it
* receives to the element it renders. See
* `__docs__/PATTERNS_dynamic_no_container.md`.
*/
type ResolveRendersOwnElement = (context: NoContainerResolverContext) => boolean;
type DisplayCardEntry = {
id: string;
card: RenderedOrFunctionalComponentEntry;
defaultAttributeValues: DefaultAttributeValue[];
attributeEditModeConfigs: AttributeEditModeConfig[];
/**
* Per-render answer to whether column dimension styles need a wrapper div.
* widget-react calls this and ignores `noContainer` when it is present.
*/
resolveNoContainer?: ResolveNoContainer;
/**
* Static fallback used only by widget-react versions that predate
* `resolveNoContainer`. When true, column dimension styles are applied via a
* wrapper div rather than passed as styleProps to the component.
*/
noContainer?: boolean;
/**
* Per-render answer to whether this card's own root element can carry a
* `className`. A card whose resolver can return `true` MUST apply the
* `className` it receives to the element it renders.
*/
resolveRendersOwnElement?: ResolveRendersOwnElement;
};
type RenderCardEntry = {
id: string;
card: RenderedOrFunctionalComponentEntry;
defaultAttributeValues: DefaultAttributeValue[];
resolveNoContainer?: ResolveNoContainer;
noContainer?: boolean;
resolveRendersOwnElement?: ResolveRendersOwnElement;
};
type ComponentMetadata = {
defaultAttributeValues: DefaultAttributeValue[];
attributeEditModeConfigs: AttributeEditModeConfig[];
};
type ComponentMetadataForEditing = {
attributeListForComponentTypes: AttributeListForComponentTypes;
componentNameToModifyAttribute: ComponentNameToModifyAttribute;
componentMetadata: Record;
};
/**
* Structured palette-card data for the composer (mirrors widget-react's
* EditorPreviewEntry). Libraries provide data only; the composer owns the
* card template so palette cards always render consistently.
*/
type EditorPreviewCardEntry = {
id: string;
/** Compact glyph for the palette card: an emoji string or small JSX. */
icon: ReactNode;
/** Short name shown under the icon, e.g. "Text", "Image". */
label: string;
};
type CardEntry = DisplayCardEntry | EditorPreviewCardEntry;
type Card = {
title: string;
entries: CardEntry[] | DisplayCardEntry[];
};
type CardGroup = {
title: string;
cards: Card[];
showInitially?: boolean;
};
/**
* Editor-preview card groups hold ONLY structured palette entries. These
* mirror widget-react's LibraryCard / LibraryCardGroup so the editor surface
* stays assignable to the ComponentLibraryModule contract.
*/
type EditorPreviewCard = {
title: string;
entries: EditorPreviewCardEntry[];
};
type EditorPreviewCardGroup = {
title: string;
cards: EditorPreviewCard[];
showInitially?: boolean;
};
interface SourceComponentsPlugin {
components: Record;
}
/** Lucide `__iconNode` geometry: [tagName, attributes][]. Plain JSON. */
type IconNode = [string, Record][];
/**
* What an icon attribute stores. Geometry is stamped when the author picks
* the icon, not at publish, so the render path never needs the icon registry
* and every surface — composer, dev, staging, production — draws from the
* same value. `name` is kept so a later sync can re-resolve stale geometry.
*/
type IconAttributeValue = {
name: string;
iconNode: IconNode;
};
type PreviewComponents = Record;
/**
* Returns the source components plugin with a lookup map of render components.
* Results are cached after the first call.
*/
declare const getSourceComponentsPlugin: () => {
components: Record;
};
declare const getComponentMetadataForEditing: () => ComponentMetadataForEditing;
/**
* Returns the preview card groups for drag and drop functionality.
* This replaces the dragDropPreviewCardGroups export.
*/
declare const getPreviewCardGroups: () => EditorPreviewCardGroup[];
/**
* Returns a lookup map of preview components by entry ID.
* Results are cached after the first call.
*/
declare const getPreviewComponents: () => PreviewComponents;
/**
* ComponentLibraryModule conformance (the @rulecms/widget-react contract).
*
* This package is the DEFAULT component library. It conforms to the contract
* STRUCTURALLY — it has no dependency on @rulecms/widget-react (the
* devDependency-only type-conformance test in
* __tests__/contract-conformance.test.ts guarantees the shape). Consumers
* register it, e.g.:
*
* libraries: { default: () => import('@rulecms/source-components-react') }
*
* or statically import the module for SSR pages.
*/
declare const manifest: {
id: string;
version: string;
reactPeerRange: string;
};
/** The render surface: component type → renderable entry. */
declare const components: Record;
/**
* Optional `ComponentLibraryModule.stylesheet`. widget-react injects this
* once per library as an SSR `