UNPKG

@lobehub/ui

Version:

Lobe UI is an open-source UI component library for building AIGC web apps

1 lines 4.58 kB
{"version":3,"file":"StreamRenderer.mjs","names":["normalized: CSSProperties"],"sources":["../../../src/Highlighter/SyntaxHighlighter/StreamRenderer.tsx"],"sourcesContent":["'use client';\n\nimport { getTokenStyleObject } from '@shikijs/core';\nimport { cx } from 'antd-style';\nimport type { CSSProperties } from 'react';\nimport { memo } from 'react';\nimport type { BuiltinTheme, ThemedToken } from 'shiki';\n\nimport { useStreamHighlight } from '@/hooks/useStreamHighlight';\n\ninterface StreamRendererProps {\n children: string;\n className?: string;\n enableTransformer?: boolean;\n fallbackClassName?: string;\n language: string;\n style?: CSSProperties;\n theme?: BuiltinTheme;\n}\n\nconst normalizeStyleKeys = (style: Record<string, string | number>): CSSProperties => {\n const normalized: CSSProperties = {};\n Object.entries(style).forEach(([key, value]) => {\n const normalizedKey = key.replaceAll(/-([a-z])/g, (_, char) => char.toUpperCase());\n (normalized as Record<string, string | number>)[normalizedKey] = value;\n });\n return normalized;\n};\n\nconst getTokenInlineStyle = (token: ThemedToken): CSSProperties => {\n const rawStyle = token.htmlStyle || getTokenStyleObject(token);\n const baseStyle = normalizeStyleKeys(rawStyle);\n return { ...baseStyle, whiteSpace: 'pre' };\n};\n\nconst TokenSpan = memo(\n ({ token }: { token: ThemedToken }) => {\n return (\n <span key={token.content} style={getTokenInlineStyle(token)}>\n {token.content}\n </span>\n );\n },\n (prev, next) => prev.token === next.token,\n);\n\nconst TokenLine = memo(\n ({ line }: { line: ThemedToken[] }) => {\n if (!line.length) {\n return (\n <span className=\"line\">\n <span style={{ whiteSpace: 'pre' }}>{'\\u00A0'}</span>\n </span>\n );\n }\n\n return (\n <span className=\"line\">\n {line.map((token, tokenIndex) => (\n <TokenSpan key={`token-${tokenIndex}`} token={token} />\n ))}\n </span>\n );\n },\n (prev, next) => prev.line === next.line,\n);\n\nconst StreamRenderer = memo<StreamRendererProps>(\n ({ children, className, enableTransformer, fallbackClassName, language, style, theme }) => {\n // Safely handle empty or invalid children\n const safeChildren = children ?? '';\n\n const streaming = useStreamHighlight(safeChildren, {\n enableTransformer,\n language,\n streaming: true,\n theme,\n });\n\n const lines = streaming?.lines;\n const preStyle = streaming?.preStyle;\n\n if (!lines || lines.length === 0) {\n return (\n <div className={fallbackClassName} dir=\"ltr\" style={style}>\n <pre>\n <code>{safeChildren}</code>\n </pre>\n </div>\n );\n }\n\n return (\n <div className={className} dir=\"ltr\" style={style}>\n <pre className={cx('shiki', theme)} style={preStyle} tabIndex={0}>\n <code style={{ display: 'flex', flexDirection: 'column', whiteSpace: 'pre' }}>\n {lines.map((line, index) => (\n <TokenLine key={`line-${index}`} line={line} />\n ))}\n </code>\n </pre>\n </div>\n );\n },\n);\n\nStreamRenderer.displayName = 'StreamRenderer';\n\nexport default StreamRenderer;\n"],"mappings":";;;;;;;;;AAoBA,MAAM,sBAAsB,UAA0D;CACpF,MAAMA,aAA4B,EAAE;AACpC,QAAO,QAAQ,MAAM,CAAC,SAAS,CAAC,KAAK,WAAW;EAC9C,MAAM,gBAAgB,IAAI,WAAW,cAAc,GAAG,SAAS,KAAK,aAAa,CAAC;AAClF,EAAC,WAA+C,iBAAiB;GACjE;AACF,QAAO;;AAGT,MAAM,uBAAuB,UAAsC;AAGjE,QAAO;EAAE,GADS,mBADD,MAAM,aAAa,oBAAoB,MAAM,CAChB;EACvB,YAAY;EAAO;;AAG5C,MAAM,YAAY,MACf,EAAE,YAAoC;AACrC,QACE,oBAAC;EAAyB,OAAO,oBAAoB,MAAM;YACxD,MAAM;IADE,MAAM,QAEV;IAGV,MAAM,SAAS,KAAK,UAAU,KAAK,MACrC;AAED,MAAM,YAAY,MACf,EAAE,WAAoC;AACrC,KAAI,CAAC,KAAK,OACR,QACE,oBAAC;EAAK,WAAU;YACd,oBAAC;GAAK,OAAO,EAAE,YAAY,OAAO;aAAG;IAAgB;GAChD;AAIX,QACE,oBAAC;EAAK,WAAU;YACb,KAAK,KAAK,OAAO,eAChB,oBAAC,aAA6C,SAA9B,SAAS,aAA8B,CACvD;GACG;IAGV,MAAM,SAAS,KAAK,SAAS,KAAK,KACpC;AAED,MAAM,iBAAiB,MACpB,EAAE,UAAU,WAAW,mBAAmB,mBAAmB,UAAU,OAAO,YAAY;CAEzF,MAAM,eAAe,YAAY;CAEjC,MAAM,YAAY,mBAAmB,cAAc;EACjD;EACA;EACA,WAAW;EACX;EACD,CAAC;CAEF,MAAM,QAAQ,WAAW;CACzB,MAAM,WAAW,WAAW;AAE5B,KAAI,CAAC,SAAS,MAAM,WAAW,EAC7B,QACE,oBAAC;EAAI,WAAW;EAAmB,KAAI;EAAa;YAClD,oBAAC,mBACC,oBAAC,oBAAM,eAAoB,GACvB;GACF;AAIV,QACE,oBAAC;EAAe;EAAW,KAAI;EAAa;YAC1C,oBAAC;GAAI,WAAW,GAAG,SAAS,MAAM;GAAE,OAAO;GAAU,UAAU;aAC7D,oBAAC;IAAK,OAAO;KAAE,SAAS;KAAQ,eAAe;KAAU,YAAY;KAAO;cACzE,MAAM,KAAK,MAAM,UAChB,oBAAC,aAAsC,QAAvB,QAAQ,QAAuB,CAC/C;KACG;IACH;GACF;EAGX;AAED,eAAe,cAAc;AAE7B,6BAAe"}