// src/components/card-renderer.tsx // The Solid single-envelope dispatcher: pick the card for envelope.type and render it // with the envelope spread onto its props. Routing uses the ambient CardProvider // (useCardHost). Unknown type → CardFallback + a one-shot contract `error` emit. import { createMemo, untrack, Show, type JSX } from 'solid-js'; import { Dynamic } from 'solid-js/web'; import type { CardEnvelope } from '../primitives/card-contract'; import { useCardHost } from '../primitives/card-host'; import { mergeCardComponents, type CardComponentMap } from '../primitives/card-registry'; import { CardFallback } from './card-fallback'; export interface CardRendererProps { envelope: CardEnvelope; /** Add/override type→component entries (merged over the built-ins). */ types?: CardComponentMap; } export function CardRenderer(props: CardRendererProps): JSX.Element { const host = useCardHost(); const map = createMemo(() => mergeCardComponents(props.types)); const entry = createMemo(() => map()[props.envelope.type]); return ( } > {(comp) => } ); } /** Renders the fallback and emits exactly one `error` (untracked, on first render). */ function UnknownCard(props: { envelope: CardEnvelope }): JSX.Element { const host = useCardHost(); untrack(() => host?.emit({ kind: 'error', cardId: props.envelope.id, message: `Unsupported card type: ${props.envelope.type}`, }), ); return ; } /** Function sugar: renderCard(env) ≡ . */ export function renderCard( envelope: CardEnvelope, opts?: { types?: CardComponentMap }, ): JSX.Element { return ; }