Skip to content
Comvi

@comvi/core/rich-text

View .md

The rich-text toolbox every framework’s <T> runs on. /rich-text is pure. /tags re-exports all of it and registers ambient <tag> syntax for plain t() as an import side effect.

  • @comvi/core/rich-text: prepareTranslation, getPendingHandlerName, childrenToArray, registerTagSyntax, createElement, createTextNode, createFragment, isVirtualNode; types PrepareTranslationProps, PrepareTranslationSource, PreparedTranslation, PendingHandler, TagComponentsMap, TagComponentConfig, VirtualNode, ElementNode, TextNode, FragmentNode, TranslationResult.
  • @comvi/core/tags: everything above, plus tagSyntaxExtension; type SyntaxExtension.
function prepareTranslation(i18n: PrepareTranslationSource, props: PrepareTranslationProps): PreparedTranslation
interface PrepareTranslationSource {
tRaw(key: string, params?: TranslationParams): TranslationResult;
hasTranslation(key: string, locale?: string, namespace?: string, checkFallbacks?: boolean): boolean;
}
Prop Type Meaning
i18nKey string The key
params TranslationParams Interpolation params
ns string Overrides a same-named params key unless undefined
locale string Same
fallback string Same
markers boolean Same
components TagComponentsMap Tag name to handler; strings and string-target configs render directly, anything else is opaque
Returned Type Meaning
content TranslationResult Marker element nodes stand in for opaque handlers
pendingHandlers PendingHandler[] { name, marker, handler, props? } per opaque handler; [] when none
isMissing boolean The result is the key itself; a set fallback or an onMissingKey value makes it false

TagComponentConfig is { tag?, component?, props? }; tag and component are aliases.

src/prepare-demo.ts
import { createI18n } from '@comvi/core';
import { prepareTranslation } from '@comvi/core/rich-text';
const i18n = createI18n({
locale: 'en',
messages: { en: { tos: 'Read our <link>terms</link>' } },
});
const { content, pendingHandlers, isMissing } = prepareTranslation(i18n, {
i18nKey: 'tos',
components: { link: { tag: 'a', props: { href: '/terms' } } },
});
function registerTagSyntax(): () => void
const tagSyntaxExtension: SyntaxExtension

Registers <tag> parsing for plain t() process-wide; idempotent, and the return value unregisters. import '@comvi/core/tags' calls it at module scope. tagSyntaxExtension is the grammar itself, which prepareTranslation passes per call through tagInterpolation.extensions. Ambient registration is per bundle, so a server graph needs its own import.

function childrenToArray(children: TranslationResult): (string | VirtualNode)[]
function getPendingHandlerName(tag: string): string | undefined
function createElement(tag: string, props?: Record<string, unknown>, children?: Array<VirtualNode | string>): ElementNode
function createTextNode(text: string): TextNode
function createFragment(children: Array<VirtualNode | string>, key?: string | number): FragmentNode
function isVirtualNode(value: unknown): value is VirtualNode
Helper Meaning
childrenToArray(children) '' becomes []
getPendingHandlerName(tag) The handler name a marker tag carries, else undefined
createElement(tag, props?, children?) children is one array argument. Also on the @comvi/core root
createTextNode(text) Not on the root
createFragment(children, key?) Not on the root
isVirtualNode(value) True only for a node built by createElement, createTextNode or createFragment; an object literal of the same shape, a Vue VNode or a React element is not one. Also on the root