/** @jsxImportSource react */ import type { CSSProperties, ReactNode } from "react"; import { StyledText, type AsciiTextProps, type StyledTextChunk, type TextProps, } from "../../../../ui/host"; import { WEB_CELL_WIDTH } from "../input-host"; import { renderAsciiText } from "../../../../ui/ascii-font"; import { webAsciiTextLines, webAsciiTextWordmarkVariant } from "./ascii-text"; import { BlockGlyphCanvas } from "./block-glyph-canvas"; import { mouseHandlers } from "./mouse"; import { cleanDomProps, commonStyle, textStyle } from "./style"; // Read per render: the cell width tracks the configured font size. function wordmarkCharWidthPx(): number { return Math.max(10, WEB_CELL_WIDTH); } // Matches the legacy wordmark text rendering: one cell per glyph, 12px rows. const BLOCK_GLYPH_CELL_WIDTH = 8; const BLOCK_GLYPH_CELL_HEIGHT = 12; interface WebAsciiTextProps extends AsciiTextProps { desktopPlatform?: string; } function isStyledTextContent(value: unknown): value is { chunks: StyledTextChunk[] } { return value instanceof StyledText || (!!value && typeof value === "object" && Array.isArray((value as { chunks?: unknown }).chunks)); } function styledTextChunkStyle(baseProps: TextProps, chunk: StyledTextChunk): CSSProperties { const style = textStyle({ ...baseProps, fg: typeof chunk.fg === "string" ? chunk.fg : baseProps.fg, bg: typeof chunk.bg === "string" ? chunk.bg : baseProps.bg, attributes: chunk.attributes, }); style.display = "inline"; style.width = undefined; style.maxWidth = undefined; style.minWidth = undefined; style.flexShrink = undefined; return style; } function renderTextContent(children: ReactNode, content: TextProps["content"], baseProps: TextProps): ReactNode { const resolved = children ?? content; if (!isStyledTextContent(resolved)) return resolved as ReactNode; return resolved.chunks.map((chunk, index) => ( {chunk.text} )); } export function WebText({ children, ...props }: TextProps) { return ( {renderTextContent(children, props.content, props)} ); } export function WebSpan({ children, ...props }: TextProps) { return ( {children as ReactNode} ); } export function WebStrong({ children, ...props }: TextProps) { return ( {children as ReactNode} ); } export function WebUnderline({ children, ...props }: TextProps) { return ( {children as ReactNode} ); } export function WebAsciiText({ text, font = "tiny", color, fg, bg, backgroundColor, selectable = false, desktopPlatform, scale, ...props }: WebAsciiTextProps) { if (scale != null) { return (