# `stringify-children` ## Purpose Helpers that translate a `` `children` block into a canonical ICU message body string so the message parser renders a missing-key fallback identically to a catalog entry. The module exists as a sibling of `` (rather than inline) so the trans component file stays within the per-file size budget and so the structurally-invalid-child branch can be unit-tested directly without going through React's JSX surface (which validates and rejects invalid children before they reach our `Children.forEach` callback). ## Features - `childrenToMessageString` — entry point that walks `Children.forEach` and concatenates each child's stringified form - `stringifyChild` — single-child stringifier, exported for direct unit testing of the defensive `TRANS_INVALID_CHILD` throw - Nested children are recursed; tag-wrapped children render as `...` with the same component-map semantics - Boolean, `null`, and `undefined` children render as the empty string (matches React's own rendering rules) - Defensive throw of `ReactI18nError(REACT_I18N.TRANS_INVALID_CHILD)` for any structurally-invalid value (functions, custom objects) ## Usage: Basic Example ```ts import { childrenToMessageString } from "@suaveplan/react-i18n/components/trans/stringify-children"; const body = childrenToMessageString( <>Hello {"{name}"}!, "absent.key" ); // body === "Hello {name}!" ``` ## Usage: Advanced Example The helpers operate purely on React children, so consumers can use them outside `` for snapshot / logging surfaces where a React-children tree needs a stable string serialisation: ```ts import { stringifyChild } from "@suaveplan/react-i18n/components/trans/stringify-children"; function snapshotChild(node: React.ReactNode): string { try { return stringifyChild(node, "snapshot"); } catch (err) { return `[invalid: ${(err as Error).message}]`; } } ``` ## API Reference ### `childrenToMessageString(children: ReactNode, key: string): string` Walks `React.Children.forEach` over `children` and concatenates each result of `stringifyChild`. Returns the literal `key` string when `children` is `null` or `undefined`. ### `stringifyChild(child: ReactNode, key: string): string` Stringifies one React child. Recurses into element children via `childrenToMessageString` for the tag body. Throws `ReactI18nError(REACT_I18N.TRANS_INVALID_CHILD)` with `context: { key }` for structurally-invalid input. ## Implementation Notes - The module is intentionally side-effect-free; both helpers are pure string returners with the single exception of the defensive throw. - Element children with no `props.children` produce `` rather than `key` — the nested-children helper reads the children prop with a fall-through to the empty string so the recursion does not mistakenly inject the outer key into a childless tag body. - The defensive throw exists for the edge case where TypeScript's `ReactNode` typing is bypassed by a caller who hand-constructs a child via `React.createElement`. In typical JSX usage React's own pre-render validation rejects invalid values before our callback runs.