import { component } from '@ministryofjustice/hmpps-forge/core/components' import type { BlockDefinition, ComponentOptions, ForgeComponent, ResolvedPropsOf, } from '@ministryofjustice/hmpps-forge/core/components' import type { RawHtml } from '../runtime/jsx-runtime' /** * Defines a component whose render is written in JSX - `component()` with the output * pinned to the JSX runtime's `RawHtml`, stringified at the boundary so the registry * entry produces the same plain HTML strings as every other component. * * No renderer is involved: JSX compiles to direct string building, so unlike * `nunjucksComponent` there is no environment to inject. * * @experimental Part of the experimental JSX component API - may change or be removed * in a minor release. * * @example * ```tsx * export interface MyBadge extends BlockDefinition { * text: ResolvableString * } * * export const MyBadge = jsxComponent('myBadge', { * render: props => {props.text}, * }) * ``` */ export function jsxComponent( variant: string, options: ComponentOptions, ): ForgeComponent { // TBlock is still generic here, so the conditional options type is unresolved - read // the render through a minimal shape, as component() itself does with its options. const { render } = options as { render: (props: ResolvedPropsOf, renderer: undefined) => RawHtml } const stringOptions = { ...options, render: (props: ResolvedPropsOf) => String(render(props, undefined)), } as unknown as ComponentOptions return component(variant, stringOptions) }