markdown-flow-ui 0.2.4 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/assets/markdown-flow-ui.css +1 -1
  2. package/dist/components/ContentRender/CodeBlock.cjs.js.map +1 -1
  3. package/dist/components/ContentRender/CodeBlock.d.ts +1 -1
  4. package/dist/components/ContentRender/CodeBlock.es.js.map +1 -1
  5. package/dist/components/ContentRender/ContentRender.cjs.js.map +1 -1
  6. package/dist/components/ContentRender/ContentRender.es.js +6 -1
  7. package/dist/components/ContentRender/ContentRender.es.js.map +1 -1
  8. package/dist/components/MarkdownFlowEditor/locales/en-US.json.d.ts +70 -0
  9. package/dist/components/MarkdownFlowEditor/locales/fr-FR.json.d.ts +70 -0
  10. package/dist/components/MarkdownFlowEditor/locales/zh-CN.json.d.ts +70 -0
  11. package/dist/components/Slide/Slide.cjs.js +1 -1
  12. package/dist/components/Slide/Slide.cjs.js.map +1 -1
  13. package/dist/components/Slide/Slide.es.js +576 -594
  14. package/dist/components/Slide/Slide.es.js.map +1 -1
  15. package/dist/components/Slide/diff-utils.cjs.js +4 -4
  16. package/dist/components/Slide/diff-utils.cjs.js.map +1 -1
  17. package/dist/components/Slide/diff-utils.es.js +49 -49
  18. package/dist/components/Slide/diff-utils.es.js.map +1 -1
  19. package/dist/components/Slide/types.d.ts +1 -0
  20. package/dist/components/ui/inputGroup/input-group.cjs.js +1 -1
  21. package/dist/components/ui/inputGroup/input-group.cjs.js.map +1 -1
  22. package/dist/components/ui/inputGroup/input-group.d.ts +21 -1
  23. package/dist/components/ui/inputGroup/input-group.es.js +19 -17
  24. package/dist/components/ui/inputGroup/input-group.es.js.map +1 -1
  25. package/dist/components/ui/inputGroup/textarea.cjs.js.map +1 -1
  26. package/dist/components/ui/inputGroup/textarea.d.ts +2 -1
  27. package/dist/components/ui/inputGroup/textarea.es.js.map +1 -1
  28. package/dist/markdown-flow-ui-lib.css +1 -1
  29. package/package.json +1 -1
  30. package/dist/components/ContentRender/ContentRender.stories.d.ts +0 -37
  31. package/dist/components/ContentRender/MarkdownFlowInput.stories.d.ts +0 -33
  32. package/dist/components/MarkdownFlow/MarkdownFlow.stories.d.ts +0 -31
  33. package/dist/components/MarkdownFlowEditor/MarkdownFlowEditor.stories.d.ts +0 -64
  34. package/dist/components/Slide/Slide.stories.d.ts +0 -2590
@@ -1 +1 @@
1
- {"version":3,"file":"CodeBlock.cjs.js","sources":["../../../src/components/ContentRender/CodeBlock.tsx"],"sourcesContent":["import React, { useState, ReactNode } from \"react\";\nimport \"./CodeBlock.css\";\nimport { Copy, Check } from \"lucide-react\";\n\n/**\n * Props for the CodeBlock component.\n */\nexport interface CodeBlockProps {\n /** The code content and nested elements to render.*/\n children: React.ReactNode;\n /** Optional CSS class name for the pre element. */\n className?: string;\n /** Text to display on the copy button (i18n support). */\n copyButtonText?: string;\n /** Text to display when code is copied (i18n support). */\n copiedButtonText?: string;\n}\n\nconst getCodeString = (children: ReactNode): string => {\n let text = \"\";\n React.Children.forEach(children, (child) => {\n if (typeof child === \"string\") {\n text += child;\n } else if (\n React.isValidElement(child) &&\n (child?.props as { children?: ReactNode })?.children\n ) {\n text += getCodeString((child.props as { children: ReactNode }).children);\n }\n });\n return text;\n};\n\nconst CodeBlock: React.FC<CodeBlockProps> = ({\n children,\n className: preClassName,\n copyButtonText = \"Copy\",\n copiedButtonText = \"Copied\",\n}) => {\n const [isCopied, setIsCopied] = useState(false);\n const timeoutRef = React.useRef<number | null>(null);\n\n React.useEffect(() => {\n // Cleanup timeout on component unmount\n return () => {\n if (timeoutRef.current) {\n window.clearTimeout(timeoutRef.current);\n }\n };\n }, []);\n\n let codeClassName = \"\";\n React.Children.forEach(children, (child) => {\n if (React.isValidElement(child)) {\n const childProps = child.props as { className?: string };\n if (childProps.className) {\n codeClassName = childProps.className;\n }\n }\n });\n\n const match = /language-(\\w+)/.exec(codeClassName || \"\");\n const language = match ? match[1] : \"\";\n\n const handleCopy = async () => {\n const codeString = getCodeString(children);\n try {\n await navigator.clipboard.writeText(codeString);\n setIsCopied(true);\n\n if (timeoutRef.current) {\n window.clearTimeout(timeoutRef.current);\n }\n timeoutRef.current = window.setTimeout(() => {\n setIsCopied(false);\n }, 2000);\n } catch (err) {\n console.error(\"Failed to copy text: \", err);\n }\n };\n\n return (\n <div className=\"code-block-container\">\n <div className=\"code-block-header\">\n <span className=\"language-name\">{language}</span>\n <button onClick={handleCopy} className=\"copy-button\">\n {isCopied ? (\n <Check className=\"copy-icon\" />\n ) : (\n <Copy className=\"copy-icon\" />\n )}\n {isCopied ? copiedButtonText : copyButtonText}\n </button>\n </div>\n <pre className={preClassName}>{children}</pre>\n </div>\n );\n};\n\nCodeBlock.displayName = \"CodeBlock\";\nexport default CodeBlock;\n"],"names":["getCodeString","children","text","React","child","CodeBlock","preClassName","copyButtonText","copiedButtonText","isCopied","setIsCopied","useState","timeoutRef","codeClassName","childProps","match","language","handleCopy","codeString","err","jsxs","jsx","Check","Copy"],"mappings":"6WAkBMA,EAAiBC,GAAgC,CACrD,IAAIC,EAAO,GACX,OAAAC,EAAM,SAAS,QAAQF,EAAWG,GAAU,CACtC,OAAOA,GAAU,SACnBF,GAAQE,EAERD,EAAM,eAAeC,CAAK,GACzBA,GAAO,OAAoC,WAE5CF,GAAQF,EAAeI,EAAM,MAAkC,QAAQ,EAE3E,CAAC,EACMF,CACT,EAEMG,EAAsC,CAAC,CAC3C,SAAAJ,EACA,UAAWK,EACX,eAAAC,EAAiB,OACjB,iBAAAC,EAAmB,QACrB,IAAM,CACJ,KAAM,CAACC,EAAUC,CAAW,EAAIC,EAAAA,SAAS,EAAK,EACxCC,EAAaT,EAAM,OAAsB,IAAI,EAEnDA,EAAM,UAAU,IAEP,IAAM,CACPS,EAAW,SACb,OAAO,aAAaA,EAAW,OAAO,CAE1C,EACC,CAAA,CAAE,EAEL,IAAIC,EAAgB,GACpBV,EAAM,SAAS,QAAQF,EAAWG,GAAU,CAC1C,GAAID,EAAM,eAAeC,CAAK,EAAG,CAC/B,MAAMU,EAAaV,EAAM,MACrBU,EAAW,YACbD,EAAgBC,EAAW,UAE/B,CACF,CAAC,EAED,MAAMC,EAAQ,iBAAiB,KAAKF,GAAiB,EAAE,EACjDG,EAAWD,EAAQA,EAAM,CAAC,EAAI,GAE9BE,EAAa,SAAY,CAC7B,MAAMC,EAAalB,EAAcC,CAAQ,EACzC,GAAI,CACF,MAAM,UAAU,UAAU,UAAUiB,CAAU,EAC9CR,EAAY,EAAI,EAEZE,EAAW,SACb,OAAO,aAAaA,EAAW,OAAO,EAExCA,EAAW,QAAU,OAAO,WAAW,IAAM,CAC3CF,EAAY,EAAK,CACnB,EAAG,GAAI,CACT,OAASS,EAAK,CACZ,QAAQ,MAAM,wBAAyBA,CAAG,CAC5C,CACF,EAEA,OACEC,EAAAA,kBAAAA,KAAC,MAAA,CAAI,UAAU,uBACb,SAAA,CAAAA,EAAAA,kBAAAA,KAAC,MAAA,CAAI,UAAU,oBACb,SAAA,CAAAC,EAAAA,kBAAAA,IAAC,OAAA,CAAK,UAAU,gBAAiB,SAAAL,EAAS,EAC1CI,EAAAA,kBAAAA,KAAC,SAAA,CAAO,QAASH,EAAY,UAAU,cACpC,SAAA,CAAAR,EACCY,EAAAA,kBAAAA,IAACC,WAAM,UAAU,WAAA,CAAY,EAE7BD,EAAAA,kBAAAA,IAACE,EAAAA,QAAA,CAAK,UAAU,WAAA,CAAY,EAE7Bd,EAAWD,EAAmBD,CAAA,CAAA,CACjC,CAAA,EACF,EACAc,EAAAA,kBAAAA,IAAC,MAAA,CAAI,UAAWf,EAAe,SAAAL,CAAA,CAAS,CAAA,EAC1C,CAEJ,EAEAI,EAAU,YAAc"}
1
+ {"version":3,"file":"CodeBlock.cjs.js","sources":["../../../src/components/ContentRender/CodeBlock.tsx"],"sourcesContent":["import React, { useState, ReactNode } from \"react\";\nimport \"./CodeBlock.css\";\nimport { Copy, Check } from \"lucide-react\";\n\n/**\n * Props for the CodeBlock component.\n */\nexport interface CodeBlockProps {\n /** The code content and nested elements to render.*/\n children?: React.ReactNode;\n /** Optional CSS class name for the pre element. */\n className?: string;\n /** Text to display on the copy button (i18n support). */\n copyButtonText?: string;\n /** Text to display when code is copied (i18n support). */\n copiedButtonText?: string;\n}\n\nconst getCodeString = (children: ReactNode): string => {\n let text = \"\";\n React.Children.forEach(children, (child) => {\n if (typeof child === \"string\") {\n text += child;\n } else if (\n React.isValidElement(child) &&\n (child?.props as { children?: ReactNode })?.children\n ) {\n text += getCodeString((child.props as { children: ReactNode }).children);\n }\n });\n return text;\n};\n\nconst CodeBlock: React.FC<CodeBlockProps> = ({\n children,\n className: preClassName,\n copyButtonText = \"Copy\",\n copiedButtonText = \"Copied\",\n}) => {\n const [isCopied, setIsCopied] = useState(false);\n const timeoutRef = React.useRef<number | null>(null);\n\n React.useEffect(() => {\n // Cleanup timeout on component unmount\n return () => {\n if (timeoutRef.current) {\n window.clearTimeout(timeoutRef.current);\n }\n };\n }, []);\n\n let codeClassName = \"\";\n React.Children.forEach(children, (child) => {\n if (React.isValidElement(child)) {\n const childProps = child.props as { className?: string };\n if (childProps.className) {\n codeClassName = childProps.className;\n }\n }\n });\n\n const match = /language-(\\w+)/.exec(codeClassName || \"\");\n const language = match ? match[1] : \"\";\n\n const handleCopy = async () => {\n const codeString = getCodeString(children);\n try {\n await navigator.clipboard.writeText(codeString);\n setIsCopied(true);\n\n if (timeoutRef.current) {\n window.clearTimeout(timeoutRef.current);\n }\n timeoutRef.current = window.setTimeout(() => {\n setIsCopied(false);\n }, 2000);\n } catch (err) {\n console.error(\"Failed to copy text: \", err);\n }\n };\n\n return (\n <div className=\"code-block-container\">\n <div className=\"code-block-header\">\n <span className=\"language-name\">{language}</span>\n <button onClick={handleCopy} className=\"copy-button\">\n {isCopied ? (\n <Check className=\"copy-icon\" />\n ) : (\n <Copy className=\"copy-icon\" />\n )}\n {isCopied ? copiedButtonText : copyButtonText}\n </button>\n </div>\n <pre className={preClassName}>{children}</pre>\n </div>\n );\n};\n\nCodeBlock.displayName = \"CodeBlock\";\nexport default CodeBlock;\n"],"names":["getCodeString","children","text","React","child","CodeBlock","preClassName","copyButtonText","copiedButtonText","isCopied","setIsCopied","useState","timeoutRef","codeClassName","childProps","match","language","handleCopy","codeString","err","jsxs","jsx","Check","Copy"],"mappings":"6WAkBMA,EAAiBC,GAAgC,CACrD,IAAIC,EAAO,GACX,OAAAC,EAAM,SAAS,QAAQF,EAAWG,GAAU,CACtC,OAAOA,GAAU,SACnBF,GAAQE,EAERD,EAAM,eAAeC,CAAK,GACzBA,GAAO,OAAoC,WAE5CF,GAAQF,EAAeI,EAAM,MAAkC,QAAQ,EAE3E,CAAC,EACMF,CACT,EAEMG,EAAsC,CAAC,CAC3C,SAAAJ,EACA,UAAWK,EACX,eAAAC,EAAiB,OACjB,iBAAAC,EAAmB,QACrB,IAAM,CACJ,KAAM,CAACC,EAAUC,CAAW,EAAIC,EAAAA,SAAS,EAAK,EACxCC,EAAaT,EAAM,OAAsB,IAAI,EAEnDA,EAAM,UAAU,IAEP,IAAM,CACPS,EAAW,SACb,OAAO,aAAaA,EAAW,OAAO,CAE1C,EACC,CAAA,CAAE,EAEL,IAAIC,EAAgB,GACpBV,EAAM,SAAS,QAAQF,EAAWG,GAAU,CAC1C,GAAID,EAAM,eAAeC,CAAK,EAAG,CAC/B,MAAMU,EAAaV,EAAM,MACrBU,EAAW,YACbD,EAAgBC,EAAW,UAE/B,CACF,CAAC,EAED,MAAMC,EAAQ,iBAAiB,KAAKF,GAAiB,EAAE,EACjDG,EAAWD,EAAQA,EAAM,CAAC,EAAI,GAE9BE,EAAa,SAAY,CAC7B,MAAMC,EAAalB,EAAcC,CAAQ,EACzC,GAAI,CACF,MAAM,UAAU,UAAU,UAAUiB,CAAU,EAC9CR,EAAY,EAAI,EAEZE,EAAW,SACb,OAAO,aAAaA,EAAW,OAAO,EAExCA,EAAW,QAAU,OAAO,WAAW,IAAM,CAC3CF,EAAY,EAAK,CACnB,EAAG,GAAI,CACT,OAASS,EAAK,CACZ,QAAQ,MAAM,wBAAyBA,CAAG,CAC5C,CACF,EAEA,OACEC,EAAAA,kBAAAA,KAAC,MAAA,CAAI,UAAU,uBACb,SAAA,CAAAA,EAAAA,kBAAAA,KAAC,MAAA,CAAI,UAAU,oBACb,SAAA,CAAAC,EAAAA,kBAAAA,IAAC,OAAA,CAAK,UAAU,gBAAiB,SAAAL,EAAS,EAC1CI,EAAAA,kBAAAA,KAAC,SAAA,CAAO,QAASH,EAAY,UAAU,cACpC,SAAA,CAAAR,EACCY,EAAAA,kBAAAA,IAACC,WAAM,UAAU,WAAA,CAAY,EAE7BD,EAAAA,kBAAAA,IAACE,EAAAA,QAAA,CAAK,UAAU,WAAA,CAAY,EAE7Bd,EAAWD,EAAmBD,CAAA,CAAA,CACjC,CAAA,EACF,EACAc,EAAAA,kBAAAA,IAAC,MAAA,CAAI,UAAWf,EAAe,SAAAL,CAAA,CAAS,CAAA,EAC1C,CAEJ,EAEAI,EAAU,YAAc"}
@@ -4,7 +4,7 @@ import { default as React } from 'react';
4
4
  */
5
5
  export interface CodeBlockProps {
6
6
  /** The code content and nested elements to render.*/
7
- children: React.ReactNode;
7
+ children?: React.ReactNode;
8
8
  /** Optional CSS class name for the pre element. */
9
9
  className?: string;
10
10
  /** Text to display on the copy button (i18n support). */
@@ -1 +1 @@
1
- {"version":3,"file":"CodeBlock.es.js","sources":["../../../src/components/ContentRender/CodeBlock.tsx"],"sourcesContent":["import React, { useState, ReactNode } from \"react\";\nimport \"./CodeBlock.css\";\nimport { Copy, Check } from \"lucide-react\";\n\n/**\n * Props for the CodeBlock component.\n */\nexport interface CodeBlockProps {\n /** The code content and nested elements to render.*/\n children: React.ReactNode;\n /** Optional CSS class name for the pre element. */\n className?: string;\n /** Text to display on the copy button (i18n support). */\n copyButtonText?: string;\n /** Text to display when code is copied (i18n support). */\n copiedButtonText?: string;\n}\n\nconst getCodeString = (children: ReactNode): string => {\n let text = \"\";\n React.Children.forEach(children, (child) => {\n if (typeof child === \"string\") {\n text += child;\n } else if (\n React.isValidElement(child) &&\n (child?.props as { children?: ReactNode })?.children\n ) {\n text += getCodeString((child.props as { children: ReactNode }).children);\n }\n });\n return text;\n};\n\nconst CodeBlock: React.FC<CodeBlockProps> = ({\n children,\n className: preClassName,\n copyButtonText = \"Copy\",\n copiedButtonText = \"Copied\",\n}) => {\n const [isCopied, setIsCopied] = useState(false);\n const timeoutRef = React.useRef<number | null>(null);\n\n React.useEffect(() => {\n // Cleanup timeout on component unmount\n return () => {\n if (timeoutRef.current) {\n window.clearTimeout(timeoutRef.current);\n }\n };\n }, []);\n\n let codeClassName = \"\";\n React.Children.forEach(children, (child) => {\n if (React.isValidElement(child)) {\n const childProps = child.props as { className?: string };\n if (childProps.className) {\n codeClassName = childProps.className;\n }\n }\n });\n\n const match = /language-(\\w+)/.exec(codeClassName || \"\");\n const language = match ? match[1] : \"\";\n\n const handleCopy = async () => {\n const codeString = getCodeString(children);\n try {\n await navigator.clipboard.writeText(codeString);\n setIsCopied(true);\n\n if (timeoutRef.current) {\n window.clearTimeout(timeoutRef.current);\n }\n timeoutRef.current = window.setTimeout(() => {\n setIsCopied(false);\n }, 2000);\n } catch (err) {\n console.error(\"Failed to copy text: \", err);\n }\n };\n\n return (\n <div className=\"code-block-container\">\n <div className=\"code-block-header\">\n <span className=\"language-name\">{language}</span>\n <button onClick={handleCopy} className=\"copy-button\">\n {isCopied ? (\n <Check className=\"copy-icon\" />\n ) : (\n <Copy className=\"copy-icon\" />\n )}\n {isCopied ? copiedButtonText : copyButtonText}\n </button>\n </div>\n <pre className={preClassName}>{children}</pre>\n </div>\n );\n};\n\nCodeBlock.displayName = \"CodeBlock\";\nexport default CodeBlock;\n"],"names":["getCodeString","children","text","React","child","CodeBlock","preClassName","copyButtonText","copiedButtonText","isCopied","setIsCopied","useState","timeoutRef","codeClassName","childProps","match","language","handleCopy","codeString","err","jsxs","jsx","Check","Copy"],"mappings":";;;;;AAkBA,MAAMA,IAAgB,CAACC,MAAgC;AACrD,MAAIC,IAAO;AACXC,SAAAA,EAAM,SAAS,QAAQF,GAAU,CAACG,MAAU;AAC1C,IAAI,OAAOA,KAAU,WACnBF,KAAQE,IAERD,EAAM,eAAeC,CAAK,KACzBA,GAAO,OAAoC,aAE5CF,KAAQF,EAAeI,EAAM,MAAkC,QAAQ;AAAA,EAE3E,CAAC,GACMF;AACT,GAEMG,IAAsC,CAAC;AAAA,EAC3C,UAAAJ;AAAA,EACA,WAAWK;AAAA,EACX,gBAAAC,IAAiB;AAAA,EACjB,kBAAAC,IAAmB;AACrB,MAAM;AACJ,QAAM,CAACC,GAAUC,CAAW,IAAIC,EAAS,EAAK,GACxCC,IAAaT,EAAM,OAAsB,IAAI;AAEnDA,EAAAA,EAAM,UAAU,MAEP,MAAM;AACX,IAAIS,EAAW,WACb,OAAO,aAAaA,EAAW,OAAO;AAAA,EAE1C,GACC,CAAA,CAAE;AAEL,MAAIC,IAAgB;AACpBV,EAAAA,EAAM,SAAS,QAAQF,GAAU,CAACG,MAAU;AAC1C,QAAID,EAAM,eAAeC,CAAK,GAAG;AAC/B,YAAMU,IAAaV,EAAM;AACzB,MAAIU,EAAW,cACbD,IAAgBC,EAAW;AAAA,IAE/B;AAAA,EACF,CAAC;AAED,QAAMC,IAAQ,iBAAiB,KAAKF,KAAiB,EAAE,GACjDG,IAAWD,IAAQA,EAAM,CAAC,IAAI,IAE9BE,IAAa,YAAY;AAC7B,UAAMC,IAAalB,EAAcC,CAAQ;AACzC,QAAI;AACF,YAAM,UAAU,UAAU,UAAUiB,CAAU,GAC9CR,EAAY,EAAI,GAEZE,EAAW,WACb,OAAO,aAAaA,EAAW,OAAO,GAExCA,EAAW,UAAU,OAAO,WAAW,MAAM;AAC3C,QAAAF,EAAY,EAAK;AAAA,MACnB,GAAG,GAAI;AAAA,IACT,SAASS,GAAK;AACZ,cAAQ,MAAM,yBAAyBA,CAAG;AAAA,IAC5C;AAAA,EACF;AAEA,SACEC,gBAAAA,EAAAA,KAAC,OAAA,EAAI,WAAU,wBACb,UAAA;AAAA,IAAAA,gBAAAA,EAAAA,KAAC,OAAA,EAAI,WAAU,qBACb,UAAA;AAAA,MAAAC,gBAAAA,EAAAA,IAAC,QAAA,EAAK,WAAU,iBAAiB,UAAAL,GAAS;AAAA,MAC1CI,gBAAAA,EAAAA,KAAC,UAAA,EAAO,SAASH,GAAY,WAAU,eACpC,UAAA;AAAA,QAAAR,IACCY,gBAAAA,EAAAA,IAACC,KAAM,WAAU,YAAA,CAAY,IAE7BD,gBAAAA,EAAAA,IAACE,GAAA,EAAK,WAAU,YAAA,CAAY;AAAA,QAE7Bd,IAAWD,IAAmBD;AAAA,MAAA,EAAA,CACjC;AAAA,IAAA,GACF;AAAA,IACAc,gBAAAA,EAAAA,IAAC,OAAA,EAAI,WAAWf,GAAe,UAAAL,EAAA,CAAS;AAAA,EAAA,GAC1C;AAEJ;AAEAI,EAAU,cAAc;"}
1
+ {"version":3,"file":"CodeBlock.es.js","sources":["../../../src/components/ContentRender/CodeBlock.tsx"],"sourcesContent":["import React, { useState, ReactNode } from \"react\";\nimport \"./CodeBlock.css\";\nimport { Copy, Check } from \"lucide-react\";\n\n/**\n * Props for the CodeBlock component.\n */\nexport interface CodeBlockProps {\n /** The code content and nested elements to render.*/\n children?: React.ReactNode;\n /** Optional CSS class name for the pre element. */\n className?: string;\n /** Text to display on the copy button (i18n support). */\n copyButtonText?: string;\n /** Text to display when code is copied (i18n support). */\n copiedButtonText?: string;\n}\n\nconst getCodeString = (children: ReactNode): string => {\n let text = \"\";\n React.Children.forEach(children, (child) => {\n if (typeof child === \"string\") {\n text += child;\n } else if (\n React.isValidElement(child) &&\n (child?.props as { children?: ReactNode })?.children\n ) {\n text += getCodeString((child.props as { children: ReactNode }).children);\n }\n });\n return text;\n};\n\nconst CodeBlock: React.FC<CodeBlockProps> = ({\n children,\n className: preClassName,\n copyButtonText = \"Copy\",\n copiedButtonText = \"Copied\",\n}) => {\n const [isCopied, setIsCopied] = useState(false);\n const timeoutRef = React.useRef<number | null>(null);\n\n React.useEffect(() => {\n // Cleanup timeout on component unmount\n return () => {\n if (timeoutRef.current) {\n window.clearTimeout(timeoutRef.current);\n }\n };\n }, []);\n\n let codeClassName = \"\";\n React.Children.forEach(children, (child) => {\n if (React.isValidElement(child)) {\n const childProps = child.props as { className?: string };\n if (childProps.className) {\n codeClassName = childProps.className;\n }\n }\n });\n\n const match = /language-(\\w+)/.exec(codeClassName || \"\");\n const language = match ? match[1] : \"\";\n\n const handleCopy = async () => {\n const codeString = getCodeString(children);\n try {\n await navigator.clipboard.writeText(codeString);\n setIsCopied(true);\n\n if (timeoutRef.current) {\n window.clearTimeout(timeoutRef.current);\n }\n timeoutRef.current = window.setTimeout(() => {\n setIsCopied(false);\n }, 2000);\n } catch (err) {\n console.error(\"Failed to copy text: \", err);\n }\n };\n\n return (\n <div className=\"code-block-container\">\n <div className=\"code-block-header\">\n <span className=\"language-name\">{language}</span>\n <button onClick={handleCopy} className=\"copy-button\">\n {isCopied ? (\n <Check className=\"copy-icon\" />\n ) : (\n <Copy className=\"copy-icon\" />\n )}\n {isCopied ? copiedButtonText : copyButtonText}\n </button>\n </div>\n <pre className={preClassName}>{children}</pre>\n </div>\n );\n};\n\nCodeBlock.displayName = \"CodeBlock\";\nexport default CodeBlock;\n"],"names":["getCodeString","children","text","React","child","CodeBlock","preClassName","copyButtonText","copiedButtonText","isCopied","setIsCopied","useState","timeoutRef","codeClassName","childProps","match","language","handleCopy","codeString","err","jsxs","jsx","Check","Copy"],"mappings":";;;;;AAkBA,MAAMA,IAAgB,CAACC,MAAgC;AACrD,MAAIC,IAAO;AACXC,SAAAA,EAAM,SAAS,QAAQF,GAAU,CAACG,MAAU;AAC1C,IAAI,OAAOA,KAAU,WACnBF,KAAQE,IAERD,EAAM,eAAeC,CAAK,KACzBA,GAAO,OAAoC,aAE5CF,KAAQF,EAAeI,EAAM,MAAkC,QAAQ;AAAA,EAE3E,CAAC,GACMF;AACT,GAEMG,IAAsC,CAAC;AAAA,EAC3C,UAAAJ;AAAA,EACA,WAAWK;AAAA,EACX,gBAAAC,IAAiB;AAAA,EACjB,kBAAAC,IAAmB;AACrB,MAAM;AACJ,QAAM,CAACC,GAAUC,CAAW,IAAIC,EAAS,EAAK,GACxCC,IAAaT,EAAM,OAAsB,IAAI;AAEnDA,EAAAA,EAAM,UAAU,MAEP,MAAM;AACX,IAAIS,EAAW,WACb,OAAO,aAAaA,EAAW,OAAO;AAAA,EAE1C,GACC,CAAA,CAAE;AAEL,MAAIC,IAAgB;AACpBV,EAAAA,EAAM,SAAS,QAAQF,GAAU,CAACG,MAAU;AAC1C,QAAID,EAAM,eAAeC,CAAK,GAAG;AAC/B,YAAMU,IAAaV,EAAM;AACzB,MAAIU,EAAW,cACbD,IAAgBC,EAAW;AAAA,IAE/B;AAAA,EACF,CAAC;AAED,QAAMC,IAAQ,iBAAiB,KAAKF,KAAiB,EAAE,GACjDG,IAAWD,IAAQA,EAAM,CAAC,IAAI,IAE9BE,IAAa,YAAY;AAC7B,UAAMC,IAAalB,EAAcC,CAAQ;AACzC,QAAI;AACF,YAAM,UAAU,UAAU,UAAUiB,CAAU,GAC9CR,EAAY,EAAI,GAEZE,EAAW,WACb,OAAO,aAAaA,EAAW,OAAO,GAExCA,EAAW,UAAU,OAAO,WAAW,MAAM;AAC3C,QAAAF,EAAY,EAAK;AAAA,MACnB,GAAG,GAAI;AAAA,IACT,SAASS,GAAK;AACZ,cAAQ,MAAM,yBAAyBA,CAAG;AAAA,IAC5C;AAAA,EACF;AAEA,SACEC,gBAAAA,EAAAA,KAAC,OAAA,EAAI,WAAU,wBACb,UAAA;AAAA,IAAAA,gBAAAA,EAAAA,KAAC,OAAA,EAAI,WAAU,qBACb,UAAA;AAAA,MAAAC,gBAAAA,EAAAA,IAAC,QAAA,EAAK,WAAU,iBAAiB,UAAAL,GAAS;AAAA,MAC1CI,gBAAAA,EAAAA,KAAC,UAAA,EAAO,SAASH,GAAY,WAAU,eACpC,UAAA;AAAA,QAAAR,IACCY,gBAAAA,EAAAA,IAACC,KAAM,WAAU,YAAA,CAAY,IAE7BD,gBAAAA,EAAAA,IAACE,GAAA,EAAK,WAAU,YAAA,CAAY;AAAA,QAE7Bd,IAAWD,IAAmBD;AAAA,MAAA,EAAA,CACjC;AAAA,IAAA,GACF;AAAA,IACAc,gBAAAA,EAAAA,IAAC,OAAA,EAAI,WAAWf,GAAe,UAAAL,EAAA,CAAS;AAAA,EAAA,GAC1C;AAEJ;AAEAI,EAAU,cAAc;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ContentRender.cjs.js","sources":["../../../src/components/ContentRender/ContentRender.tsx"],"sourcesContent":["import \"highlight.js/styles/github.css\";\nimport \"katex/dist/katex.min.css\";\nimport React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport rehypeHighlight from \"rehype-highlight\";\nimport rehypeKatex from \"rehype-katex\";\nimport rehypeRaw from \"rehype-raw\";\nimport remarkBreaks from \"remark-breaks\";\nimport remarkFlow from \"remark-flow\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\nimport { CustomRenderBarProps, OnSendContentParams } from \"../types\";\nimport { sanitizeInvalidTagName } from \"./utils/sanitize-invalid-tag-name\";\nimport { stripSvgTextLineBreaks } from \"./utils/strip-svg-text-line-breaks\";\nimport \"./contentRender.css\";\nimport \"./github-markdown-light.css\";\nimport CodeBlock from \"./CodeBlock\";\nimport CustomButtonInputVariable, {\n ComponentsWithCustomVariable,\n} from \"./plugins/CustomVariable\";\nimport MermaidChart from \"./plugins/MermaidChart\";\nimport {\n preserveCustomVariableProperties,\n restoreCustomVariableProperties,\n} from \"./utils/custom-variable-props\";\nimport {\n highlightLanguages,\n subsetLanguages,\n} from \"./utils/highlight-languages\";\n// import { processMarkdownText } from \"./utils/process-markdown\";\nimport {\n parseMarkdownSegments,\n mermaidBlockIsComplete,\n} from \"./utils/mermaid-parse\";\nimport { normalizeInlineHtml } from \"./utils/normalize-inline-html\";\nimport IframeSandbox from \"./IframeSandbox\";\nimport {\n splitContentSegments,\n type RenderSegment,\n} from \"./utils/split-content\";\nimport {\n getInteractionDefaultValues,\n type InteractionDefaultValueOptions,\n} from \"../../lib/interaction-defaults\";\nimport type { MarkdownFlowLocale } from \"../../lib/locale\";\nimport { getContentRenderLocaleTexts } from \"./contentRenderI18n\";\n\nconst SANDBOX_TAG_HINT_PATTERN =\n /<(script|style|link|iframe|html|head|body|meta|title|base|template|div|section|article|main)\\b/i;\n\n// Define component Props type\nexport interface ContentRenderProps {\n content: string;\n contentType?: string;\n /** Locale used for built-in UI text when a more specific text prop is not provided. */\n locale?: MarkdownFlowLocale;\n /**\n * Callback invoked when the custom button after content is clicked.\n * This button is rendered via the `<custom-button-after-content>` tag in markdown content.\n * @example\n * ```tsx\n * <ContentRender\n * content=\"Hello <custom-button-after-content>Ask</custom-button-after-content>\"\n * onClickCustomButtonAfterContent={() => console.log('Button clicked')}\n * />\n * ```\n */\n customRenderBar?: CustomRenderBarProps;\n onClickCustomButtonAfterContent?: () => void;\n onSend?: (content: OnSendContentParams) => void;\n typingSpeed?: number;\n enableTypewriter?: boolean;\n onTypeFinished?: () => void;\n onTypewriterStateChange?: (state: ContentRenderTypewriterState) => void;\n userInput?: string;\n interactionDefaultValueOptions?: InteractionDefaultValueOptions;\n defaultButtonText?: string;\n defaultInputText?: string; // Text input by user\n defaultSelectedValues?: string[]; // Default selected values for multi-select\n readonly?: boolean;\n // Multi-select confirm button text (i18n support)\n confirmButtonText?: string;\n // Copy button text (i18n support)\n copyButtonText?: string;\n // Copied state text (i18n support)\n copiedButtonText?: string;\n // Dynamic interaction format for multi-select support\n dynamicInteractionFormat?: string;\n // Loading text before first HTML block renders inside iframe (i18n support)\n sandboxLoadingText?: string;\n // Loading text while styles are being generated inside iframe\n sandboxStyleLoadingText?: string;\n // Loading text while scripts are being cached/executed inside iframe\n sandboxScriptLoadingText?: string;\n // Disable sandbox loading overlays when upper layers have already entered an error state\n disableSandboxLoadingOverlay?: boolean;\n // Fullscreen button text for iframe sandbox\n sandboxFullscreenButtonText?: string;\n // Exit fullscreen button text for iframe sandbox\n sandboxExitFullscreenButtonText?: string;\n // Sandbox render mode\n sandboxMode?: \"content\" | \"blackboard\";\n beforeSend?: (param: OnSendContentParams) => boolean;\n // tooltipMinLength?: number; // Control minimum character length for tooltip display, default 10\n}\n\nexport interface ContentRenderTypewriterState {\n isTypewriterEnabled: boolean;\n isTyping: boolean;\n isComplete: boolean;\n renderedLength: number;\n totalLength: number;\n}\n\n// Render svg string via Shadow DOM to avoid markdown wrapping\nconst SvgBlockInShadow: React.FC<{ svg: string }> = ({ svg }) => {\n const hostRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n const shadowRoot = host.shadowRoot ?? host.attachShadow({ mode: \"open\" });\n const styleId = \"content-render-svg-style\";\n let styleEl = shadowRoot.getElementById(styleId) as HTMLStyleElement | null;\n\n if (!styleEl) {\n styleEl = document.createElement(\"style\");\n styleEl.id = styleId;\n // Keep intrinsic SVG width so the wrapper can scroll horizontally when needed\n styleEl.textContent = `\n svg { height: auto; display: inline-block; }\n svg.content-render-svg-el--responsive { width: 100%; max-width: 100%; }\n svg.content-render-svg-el--fixed { max-width: none; }\n `;\n shadowRoot.appendChild(styleEl);\n }\n\n const nodesToRemove = Array.from(shadowRoot.childNodes).filter(\n (node) => node !== styleEl\n );\n nodesToRemove.forEach((node) => shadowRoot.removeChild(node));\n\n const template = document.createElement(\"template\");\n const cleanedSvg = stripSvgTextLineBreaks(svg);\n template.innerHTML = cleanedSvg;\n shadowRoot.append(template.content.cloneNode(true));\n\n let hasResponsiveSvg = false;\n let hasFixedSvg = false;\n\n shadowRoot.querySelectorAll(\"svg\").forEach((svgEl) => {\n // Derive responsive sizing from viewBox so pure viewBox SVGs stay visible and fluid\n const viewBox = svgEl.getAttribute(\"viewBox\");\n if (!viewBox) return;\n\n const dimensions = viewBox\n .trim()\n .split(/[\\s,]+/)\n .map((value) => Number(value));\n\n if (dimensions.length !== 4 || dimensions.some(Number.isNaN)) return;\n\n const [, , viewBoxWidth, viewBoxHeight] = dimensions;\n const widthAttr = svgEl.getAttribute(\"width\");\n const heightAttr = svgEl.getAttribute(\"height\");\n const isRelativeLength = (value?: string | null) => {\n if (!value) return false;\n const normalized = value.trim().toLowerCase();\n return normalized === \"auto\" || normalized.endsWith(\"%\");\n };\n const toNumericLength = (value?: string | null) => {\n if (!value) return null;\n const normalized = value.trim().toLowerCase();\n if (normalized === \"auto\" || normalized.endsWith(\"%\")) {\n return null;\n }\n const parsed = Number.parseFloat(normalized);\n return Number.isNaN(parsed) ? null : parsed;\n };\n // Treat percentage/auto sizing as responsive so viewBox drives the layout\n const isWidthRelative = isRelativeLength(widthAttr);\n const isHeightRelative = isRelativeLength(heightAttr);\n const widthMissing = !widthAttr || widthAttr === \"0\";\n const heightMissing = !heightAttr || heightAttr === \"0\";\n const numericWidth = toNumericLength(widthAttr);\n const numericHeight = toNumericLength(heightAttr);\n const matchesViewBox =\n numericWidth === viewBoxWidth && numericHeight === viewBoxHeight;\n\n // Prefer responsive layout when sizing is relative or matches the viewBox\n const shouldUseResponsiveSize =\n isWidthRelative ||\n isHeightRelative ||\n (widthMissing && heightMissing) ||\n matchesViewBox;\n\n if (shouldUseResponsiveSize) {\n hasResponsiveSvg = true;\n svgEl.classList.add(\"content-render-svg-el--responsive\");\n svgEl.classList.remove(\"content-render-svg-el--fixed\");\n svgEl.style.width = \"100%\";\n svgEl.style.height = \"auto\";\n if (!svgEl.style.aspectRatio && viewBoxHeight > 0) {\n svgEl.style.aspectRatio = `${viewBoxWidth} / ${viewBoxHeight}`;\n }\n return;\n }\n\n hasFixedSvg = true;\n svgEl.classList.add(\"content-render-svg-el--fixed\");\n svgEl.classList.remove(\"content-render-svg-el--responsive\");\n if (widthMissing && viewBoxWidth > 0) {\n svgEl.setAttribute(\"width\", `${viewBoxWidth}`);\n }\n if (heightMissing && viewBoxHeight > 0) {\n svgEl.setAttribute(\"height\", `${viewBoxHeight}`);\n }\n });\n\n const hostResponsive = hasResponsiveSvg && !hasFixedSvg;\n host.classList.toggle(\"content-render-svg--responsive\", hostResponsive);\n host.classList.toggle(\"content-render-svg--fixed\", !hostResponsive);\n }, [svg]);\n\n return (\n <div className=\"content-render-svg-scroll\">\n <div className=\"content-render-svg\" ref={hostRef} />\n </div>\n );\n};\n\n// Extended component interface\ntype CustomComponents = ComponentsWithCustomVariable & {\n \"custom-button-after-content\"?: React.ComponentType<{\n children: React.ReactNode;\n }>;\n};\n\nconst remarkPlugins = [remarkGfm, remarkMath, remarkFlow, remarkBreaks];\n\nconst rehypePlugins = [\n preserveCustomVariableProperties,\n rehypeRaw,\n sanitizeInvalidTagName,\n restoreCustomVariableProperties,\n [rehypeHighlight, { languages: highlightLanguages, subset: subsetLanguages }],\n rehypeKatex,\n];\n\nexport const MarkdownRenderer: React.FC<{\n content: string;\n components: CustomComponents;\n}> = ({ content: markdownContent, components }) => (\n <div className=\"markdown-renderer\">\n <ReactMarkdown\n remarkPlugins={remarkPlugins}\n rehypePlugins={rehypePlugins}\n components={components}\n >\n {markdownContent}\n </ReactMarkdown>\n </div>\n);\n\nconst mergeNonSandboxSegments = (segments: RenderSegment[]) => {\n if (segments.length <= 1) return segments;\n const merged: RenderSegment[] = [];\n\n segments.forEach((segment) => {\n if (segment.type === \"sandbox\") {\n merged.push(segment);\n return;\n }\n\n const last = merged[merged.length - 1];\n if (last && last.type !== \"sandbox\") {\n merged[merged.length - 1] = {\n type: \"markdown\",\n value: `${last.value}${segment.value}`,\n };\n return;\n }\n\n merged.push({ type: \"markdown\", value: segment.value });\n });\n\n return merged;\n};\n\nconst splitTextByCharacterChunk = (value: string, chunkSize: number) => {\n const safeChunkSize = Math.max(1, chunkSize);\n const characters = Array.from(value);\n\n return {\n chunk: characters.slice(0, safeChunkSize).join(\"\"),\n rest: characters.slice(safeChunkSize).join(\"\"),\n };\n};\n\nconst ContentRender: React.FC<ContentRenderProps> = ({\n content,\n contentType,\n locale,\n customRenderBar,\n onSend,\n typingSpeed = 40,\n enableTypewriter = false,\n onTypeFinished,\n onTypewriterStateChange,\n userInput,\n interactionDefaultValueOptions,\n defaultButtonText,\n defaultInputText,\n defaultSelectedValues,\n readonly = false,\n confirmButtonText,\n copyButtonText,\n copiedButtonText,\n sandboxLoadingText,\n sandboxStyleLoadingText,\n sandboxScriptLoadingText,\n disableSandboxLoadingOverlay = false,\n sandboxFullscreenButtonText,\n sandboxExitFullscreenButtonText,\n sandboxMode = \"content\",\n onClickCustomButtonAfterContent,\n beforeSend,\n // tooltipMinLength,\n}) => {\n const localeTexts = getContentRenderLocaleTexts(locale);\n const resolvedConfirmButtonText =\n confirmButtonText || localeTexts.confirmButtonText;\n const resolvedCopyButtonText = copyButtonText || localeTexts.copyButtonText;\n const resolvedCopiedButtonText =\n copiedButtonText || localeTexts.copiedButtonText;\n const resolvedSandboxFullscreenButtonText =\n sandboxFullscreenButtonText || localeTexts.sandboxFullscreenButtonText;\n const resolvedSandboxExitFullscreenButtonText =\n sandboxExitFullscreenButtonText ||\n localeTexts.sandboxExitFullscreenButtonText;\n const shouldApplyTypewriterByContentType =\n !contentType || contentType === \"text\";\n const isTypewriterEnabled =\n Boolean(enableTypewriter) && shouldApplyTypewriterByContentType;\n const typewriterChunkSize = 2;\n const typewriterTickMs = Math.max(0, typingSpeed);\n const [displayContent, setDisplayContent] = useState(() =>\n isTypewriterEnabled ? \"\" : content\n );\n const pendingContentRef = useRef(\"\");\n const previousTypewriterEnabledRef = useRef(isTypewriterEnabled);\n const hasReportedTypeFinishedRef = useRef(false);\n\n useEffect(() => {\n const wasTypewriterEnabled = previousTypewriterEnabledRef.current;\n previousTypewriterEnabledRef.current = isTypewriterEnabled;\n hasReportedTypeFinishedRef.current = false;\n\n if (!isTypewriterEnabled) {\n pendingContentRef.current = \"\";\n setDisplayContent(content);\n return;\n }\n\n setDisplayContent((current) => {\n const shouldRestartTyping = !wasTypewriterEnabled;\n const canContinueTyping = content.startsWith(current);\n\n if (!shouldRestartTyping && !canContinueTyping) {\n pendingContentRef.current = \"\";\n return content;\n }\n\n const nextVisibleContent =\n shouldRestartTyping || !canContinueTyping ? \"\" : current;\n\n pendingContentRef.current = content.slice(nextVisibleContent.length);\n return nextVisibleContent;\n });\n }, [content, isTypewriterEnabled]);\n\n useEffect(() => {\n if (!isTypewriterEnabled) {\n return;\n }\n\n if (\n hasReportedTypeFinishedRef.current ||\n pendingContentRef.current ||\n displayContent !== content\n ) {\n return;\n }\n\n hasReportedTypeFinishedRef.current = true;\n onTypeFinished?.();\n }, [content, displayContent, isTypewriterEnabled, onTypeFinished]);\n\n useEffect(() => {\n if (!isTypewriterEnabled || !pendingContentRef.current) {\n return undefined;\n }\n\n const typewriterTimer = window.setTimeout(() => {\n setDisplayContent((current) => {\n const { chunk, rest } = splitTextByCharacterChunk(\n pendingContentRef.current,\n typewriterChunkSize\n );\n\n if (!chunk) {\n return current;\n }\n\n pendingContentRef.current = rest;\n return `${current}${chunk}`;\n });\n }, typewriterTickMs);\n\n return () => window.clearTimeout(typewriterTimer);\n }, [\n content,\n displayContent,\n isTypewriterEnabled,\n typewriterChunkSize,\n typewriterTickMs,\n ]);\n\n const typewriterState = useMemo<ContentRenderTypewriterState>(\n () => ({\n isTypewriterEnabled,\n isTyping: isTypewriterEnabled && displayContent !== content,\n isComplete: displayContent === content,\n renderedLength: displayContent.length,\n totalLength: content.length,\n }),\n [content, displayContent, isTypewriterEnabled]\n );\n\n useEffect(() => {\n onTypewriterStateChange?.(typewriterState);\n }, [onTypewriterStateChange, typewriterState]);\n\n const renderContent = isTypewriterEnabled ? displayContent : content;\n const normalizedContent = useMemo(\n () => normalizeInlineHtml(renderContent),\n [renderContent]\n );\n\n const interactionDefaults = useMemo(\n () =>\n getInteractionDefaultValues(\n renderContent,\n userInput,\n interactionDefaultValueOptions\n ),\n [interactionDefaultValueOptions, renderContent, userInput]\n );\n\n const resolvedDefaultButtonText =\n defaultButtonText?.trim() || interactionDefaults.buttonText;\n const resolvedDefaultInputText =\n defaultInputText?.trim() || interactionDefaults.inputText;\n const fallbackSelectedValues = useMemo(\n () =>\n userInput\n ? userInput\n .split(\",\")\n .map((value) => value.trim())\n .filter(Boolean)\n : undefined,\n [userInput]\n );\n const resolvedDefaultSelectedValues = defaultSelectedValues?.length\n ? defaultSelectedValues\n : interactionDefaults.selectedValues || fallbackSelectedValues;\n\n const components: CustomComponents = {\n \"custom-button-after-content\": ({\n children,\n }: {\n children: React.ReactNode;\n }) => {\n return (\n <button\n className=\"content-render-custom-button-after-content\"\n onClick={onClickCustomButtonAfterContent}\n >\n <span className=\"content-render-custom-button-after-content-inner\">\n {children}\n </span>\n </button>\n );\n },\n \"custom-variable\": (props) => (\n <CustomButtonInputVariable\n {...props}\n readonly={readonly}\n defaultButtonText={resolvedDefaultButtonText}\n defaultInputText={resolvedDefaultInputText}\n defaultSelectedValues={resolvedDefaultSelectedValues}\n onSend={onSend}\n beforeSend={beforeSend}\n locale={locale}\n confirmButtonText={resolvedConfirmButtonText}\n // tooltipMinLength={tooltipMinLength}\n />\n ),\n code: (props) => {\n const { className, children, ...rest } = props as {\n className?: string;\n children?: React.ReactNode;\n };\n const match = /language-(\\w+)/.exec(className || \"\");\n const language = match?.[1];\n if (language === \"mermaid\") {\n const chartContent = children?.toString().replace(/\\n$/, \"\") || \"\";\n const frozen = mermaidBlockIsComplete(renderContent, chartContent);\n return <MermaidChart chart={chartContent} frozen={frozen} />;\n }\n\n return (\n <code className={className} {...rest}>\n {children}\n </code>\n );\n },\n table: ({ ...props }) => (\n <div className=\"content-render-table-container\">\n <table className=\"content-render-table\" {...props} />\n </div>\n ),\n th: ({ ...props }) => <th className=\"content-render-th\" {...props} />,\n td: ({ ...props }) => <td className=\"content-render-td\" {...props} />,\n tr: ({ ...props }) => <tr className=\"content-render-tr\" {...props} />,\n li: ({ node, ...props }) => {\n const className = node?.properties?.className;\n const hasTaskListItem =\n (typeof className === \"string\" &&\n className.includes(\"task-list-item\")) ||\n (Array.isArray(className) && className.includes(\"task-list-item\"));\n if (hasTaskListItem) {\n return <li className=\"content-render-task-list-item\" {...props} />;\n }\n return <li {...props} />;\n },\n ol: ({ ...props }) => <ol className=\"content-render-ol\" {...props} />,\n ul: ({ ...props }) => <ul className=\"content-render-ul\" {...props} />,\n input: ({ ...props }) => {\n if (props.type === \"checkbox\") {\n return (\n <input\n type=\"checkbox\"\n className=\"content-render-checkbox\"\n disabled\n {...props}\n />\n );\n }\n return <input {...props} />;\n },\n a: ({ children, ...props }) => (\n <a target=\"_blank\" rel=\"noopener noreferrer\" {...props}>\n {children}\n </a>\n ),\n pre: (props) => (\n <CodeBlock\n {...props}\n copyButtonText={resolvedCopyButtonText}\n copiedButtonText={resolvedCopiedButtonText}\n />\n ),\n };\n\n const hasPotentialSandboxTags = useMemo(\n () => SANDBOX_TAG_HINT_PATTERN.test(renderContent),\n [renderContent]\n );\n\n const renderSegments = useMemo(\n () =>\n hasPotentialSandboxTags ? splitContentSegments(renderContent, true) : [],\n [renderContent, hasPotentialSandboxTags]\n );\n\n const hasSandbox = renderSegments.some(\n (segment) => segment.type === \"sandbox\"\n );\n const mergedRenderSegments = useMemo(\n () => mergeNonSandboxSegments(renderSegments),\n [renderSegments]\n );\n\n const segments = useMemo(\n () => parseMarkdownSegments(normalizedContent),\n [normalizedContent]\n );\n\n const renderMarkdownSegments = (raw: string, keyPrefix: string) => {\n const normalized = normalizeInlineHtml(raw);\n const parsed = parseMarkdownSegments(normalized);\n\n return parsed.map((seg, index) => {\n const key = `${keyPrefix}-${seg.type}-${index}`;\n\n if (seg.type === \"text\") {\n return (\n <MarkdownRenderer\n key={key}\n components={components}\n content={seg.value}\n />\n );\n }\n\n if (seg.type === \"mermaid\") {\n return (\n <MermaidChart key={key} chart={seg.value} frozen={!seg.complete} />\n );\n }\n\n if (seg.type === \"svg\") {\n return <SvgBlockInShadow key={key} svg={seg.value} />;\n }\n\n return null;\n });\n };\n\n if (hasSandbox) {\n return (\n <div className=\"content-render markdown-body\">\n {mergedRenderSegments.map((segment, idx) =>\n segment.type === \"sandbox\" ? (\n <IframeSandbox\n key={`sandbox-${idx}`}\n hideFullScreen\n type=\"sandbox\"\n content={segment.value}\n className=\"content-render-iframe\"\n locale={locale}\n loadingText={sandboxLoadingText}\n styleLoadingText={sandboxStyleLoadingText}\n scriptLoadingText={sandboxScriptLoadingText}\n disableLoadingOverlay={disableSandboxLoadingOverlay}\n fullScreenButtonText={resolvedSandboxFullscreenButtonText}\n exitFullScreenButtonText={resolvedSandboxExitFullscreenButtonText}\n mode={sandboxMode}\n />\n ) : (\n <React.Fragment key={`md-${idx}`}>\n {renderMarkdownSegments(segment.value, `md-${idx}`)}\n </React.Fragment>\n )\n )}\n </div>\n );\n }\n\n return (\n <div className=\"content-render markdown-body\">\n {segments.map((seg, index) => {\n if (seg.type === \"text\") {\n return (\n <MarkdownRenderer\n key={index}\n components={components}\n content={seg.value}\n />\n );\n }\n\n if (seg.type === \"mermaid\") {\n return (\n <MermaidChart\n key={index}\n chart={seg.value}\n frozen={!seg.complete}\n />\n );\n }\n\n if (seg.type === \"svg\") {\n return <SvgBlockInShadow key={index} svg={seg.value} />;\n }\n })}\n\n {customRenderBar && (\n <div className=\"content-render-custom-bar\">\n {React.createElement(customRenderBar, {\n content,\n displayContent: normalizedContent,\n onSend,\n })}\n </div>\n )}\n </div>\n );\n};\n\nexport default ContentRender;\n"],"names":["SANDBOX_TAG_HINT_PATTERN","SvgBlockInShadow","svg","hostRef","useRef","useEffect","host","shadowRoot","styleId","styleEl","node","template","cleanedSvg","stripSvgTextLineBreaks","hasResponsiveSvg","hasFixedSvg","svgEl","viewBox","dimensions","value","viewBoxWidth","viewBoxHeight","widthAttr","heightAttr","isRelativeLength","normalized","toNumericLength","parsed","isWidthRelative","isHeightRelative","widthMissing","heightMissing","numericWidth","numericHeight","hostResponsive","jsx","remarkPlugins","remarkGfm","remarkMath","remarkFlow","remarkBreaks","rehypePlugins","preserveCustomVariableProperties","rehypeRaw","sanitizeInvalidTagName","restoreCustomVariableProperties","rehypeHighlight","highlightLanguages","subsetLanguages","rehypeKatex","MarkdownRenderer","markdownContent","components","ReactMarkdown","mergeNonSandboxSegments","segments","merged","segment","last","splitTextByCharacterChunk","chunkSize","safeChunkSize","characters","ContentRender","content","contentType","locale","customRenderBar","onSend","typingSpeed","enableTypewriter","onTypeFinished","onTypewriterStateChange","userInput","interactionDefaultValueOptions","defaultButtonText","defaultInputText","defaultSelectedValues","readonly","confirmButtonText","copyButtonText","copiedButtonText","sandboxLoadingText","sandboxStyleLoadingText","sandboxScriptLoadingText","disableSandboxLoadingOverlay","sandboxFullscreenButtonText","sandboxExitFullscreenButtonText","sandboxMode","onClickCustomButtonAfterContent","beforeSend","localeTexts","getContentRenderLocaleTexts","resolvedConfirmButtonText","resolvedCopyButtonText","resolvedCopiedButtonText","resolvedSandboxFullscreenButtonText","resolvedSandboxExitFullscreenButtonText","isTypewriterEnabled","typewriterChunkSize","typewriterTickMs","displayContent","setDisplayContent","useState","pendingContentRef","previousTypewriterEnabledRef","hasReportedTypeFinishedRef","wasTypewriterEnabled","current","shouldRestartTyping","canContinueTyping","nextVisibleContent","typewriterTimer","chunk","rest","typewriterState","useMemo","renderContent","normalizedContent","normalizeInlineHtml","interactionDefaults","getInteractionDefaultValues","resolvedDefaultButtonText","resolvedDefaultInputText","fallbackSelectedValues","resolvedDefaultSelectedValues","children","props","CustomButtonInputVariable","className","chartContent","frozen","mermaidBlockIsComplete","MermaidChart","CodeBlock","hasPotentialSandboxTags","renderSegments","splitContentSegments","hasSandbox","mergedRenderSegments","parseMarkdownSegments","renderMarkdownSegments","raw","keyPrefix","seg","index","key","idx","IframeSandbox","React","jsxs"],"mappings":"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"}
1
+ {"version":3,"file":"ContentRender.cjs.js","sources":["../../../src/components/ContentRender/ContentRender.tsx"],"sourcesContent":["import \"highlight.js/styles/github.css\";\nimport \"katex/dist/katex.min.css\";\nimport React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport rehypeHighlight from \"rehype-highlight\";\nimport rehypeKatex from \"rehype-katex\";\nimport rehypeRaw from \"rehype-raw\";\nimport remarkBreaks from \"remark-breaks\";\nimport remarkFlow from \"remark-flow\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\nimport type { PluggableList } from \"unified\";\nimport { CustomRenderBarProps, OnSendContentParams } from \"../types\";\nimport { sanitizeInvalidTagName } from \"./utils/sanitize-invalid-tag-name\";\nimport { stripSvgTextLineBreaks } from \"./utils/strip-svg-text-line-breaks\";\nimport \"./contentRender.css\";\nimport \"./github-markdown-light.css\";\nimport CodeBlock from \"./CodeBlock\";\nimport CustomButtonInputVariable, {\n ComponentsWithCustomVariable,\n} from \"./plugins/CustomVariable\";\nimport MermaidChart from \"./plugins/MermaidChart\";\nimport {\n preserveCustomVariableProperties,\n restoreCustomVariableProperties,\n} from \"./utils/custom-variable-props\";\nimport {\n highlightLanguages,\n subsetLanguages,\n} from \"./utils/highlight-languages\";\n// import { processMarkdownText } from \"./utils/process-markdown\";\nimport {\n parseMarkdownSegments,\n mermaidBlockIsComplete,\n} from \"./utils/mermaid-parse\";\nimport { normalizeInlineHtml } from \"./utils/normalize-inline-html\";\nimport IframeSandbox from \"./IframeSandbox\";\nimport {\n splitContentSegments,\n type RenderSegment,\n} from \"./utils/split-content\";\nimport {\n getInteractionDefaultValues,\n type InteractionDefaultValueOptions,\n} from \"../../lib/interaction-defaults\";\nimport type { MarkdownFlowLocale } from \"../../lib/locale\";\nimport { getContentRenderLocaleTexts } from \"./contentRenderI18n\";\n\nconst SANDBOX_TAG_HINT_PATTERN =\n /<(script|style|link|iframe|html|head|body|meta|title|base|template|div|section|article|main)\\b/i;\n\n// Define component Props type\nexport interface ContentRenderProps {\n content: string;\n contentType?: string;\n /** Locale used for built-in UI text when a more specific text prop is not provided. */\n locale?: MarkdownFlowLocale;\n /**\n * Callback invoked when the custom button after content is clicked.\n * This button is rendered via the `<custom-button-after-content>` tag in markdown content.\n * @example\n * ```tsx\n * <ContentRender\n * content=\"Hello <custom-button-after-content>Ask</custom-button-after-content>\"\n * onClickCustomButtonAfterContent={() => console.log('Button clicked')}\n * />\n * ```\n */\n customRenderBar?: CustomRenderBarProps;\n onClickCustomButtonAfterContent?: () => void;\n onSend?: (content: OnSendContentParams) => void;\n typingSpeed?: number;\n enableTypewriter?: boolean;\n onTypeFinished?: () => void;\n onTypewriterStateChange?: (state: ContentRenderTypewriterState) => void;\n userInput?: string;\n interactionDefaultValueOptions?: InteractionDefaultValueOptions;\n defaultButtonText?: string;\n defaultInputText?: string; // Text input by user\n defaultSelectedValues?: string[]; // Default selected values for multi-select\n readonly?: boolean;\n // Multi-select confirm button text (i18n support)\n confirmButtonText?: string;\n // Copy button text (i18n support)\n copyButtonText?: string;\n // Copied state text (i18n support)\n copiedButtonText?: string;\n // Dynamic interaction format for multi-select support\n dynamicInteractionFormat?: string;\n // Loading text before first HTML block renders inside iframe (i18n support)\n sandboxLoadingText?: string;\n // Loading text while styles are being generated inside iframe\n sandboxStyleLoadingText?: string;\n // Loading text while scripts are being cached/executed inside iframe\n sandboxScriptLoadingText?: string;\n // Disable sandbox loading overlays when upper layers have already entered an error state\n disableSandboxLoadingOverlay?: boolean;\n // Fullscreen button text for iframe sandbox\n sandboxFullscreenButtonText?: string;\n // Exit fullscreen button text for iframe sandbox\n sandboxExitFullscreenButtonText?: string;\n // Sandbox render mode\n sandboxMode?: \"content\" | \"blackboard\";\n beforeSend?: (param: OnSendContentParams) => boolean;\n // tooltipMinLength?: number; // Control minimum character length for tooltip display, default 10\n}\n\nexport interface ContentRenderTypewriterState {\n isTypewriterEnabled: boolean;\n isTyping: boolean;\n isComplete: boolean;\n renderedLength: number;\n totalLength: number;\n}\n\n// Render svg string via Shadow DOM to avoid markdown wrapping\nconst SvgBlockInShadow: React.FC<{ svg: string }> = ({ svg }) => {\n const hostRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n const shadowRoot = host.shadowRoot ?? host.attachShadow({ mode: \"open\" });\n const styleId = \"content-render-svg-style\";\n let styleEl = shadowRoot.getElementById(styleId) as HTMLStyleElement | null;\n\n if (!styleEl) {\n styleEl = document.createElement(\"style\");\n styleEl.id = styleId;\n // Keep intrinsic SVG width so the wrapper can scroll horizontally when needed\n styleEl.textContent = `\n svg { height: auto; display: inline-block; }\n svg.content-render-svg-el--responsive { width: 100%; max-width: 100%; }\n svg.content-render-svg-el--fixed { max-width: none; }\n `;\n shadowRoot.appendChild(styleEl);\n }\n\n const nodesToRemove = Array.from(shadowRoot.childNodes).filter(\n (node) => node !== styleEl\n );\n nodesToRemove.forEach((node) => shadowRoot.removeChild(node));\n\n const template = document.createElement(\"template\");\n const cleanedSvg = stripSvgTextLineBreaks(svg);\n template.innerHTML = cleanedSvg;\n shadowRoot.append(template.content.cloneNode(true));\n\n let hasResponsiveSvg = false;\n let hasFixedSvg = false;\n\n shadowRoot.querySelectorAll(\"svg\").forEach((svgEl) => {\n // Derive responsive sizing from viewBox so pure viewBox SVGs stay visible and fluid\n const viewBox = svgEl.getAttribute(\"viewBox\");\n if (!viewBox) return;\n\n const dimensions = viewBox\n .trim()\n .split(/[\\s,]+/)\n .map((value) => Number(value));\n\n if (dimensions.length !== 4 || dimensions.some(Number.isNaN)) return;\n\n const [, , viewBoxWidth, viewBoxHeight] = dimensions;\n const widthAttr = svgEl.getAttribute(\"width\");\n const heightAttr = svgEl.getAttribute(\"height\");\n const isRelativeLength = (value?: string | null) => {\n if (!value) return false;\n const normalized = value.trim().toLowerCase();\n return normalized === \"auto\" || normalized.endsWith(\"%\");\n };\n const toNumericLength = (value?: string | null) => {\n if (!value) return null;\n const normalized = value.trim().toLowerCase();\n if (normalized === \"auto\" || normalized.endsWith(\"%\")) {\n return null;\n }\n const parsed = Number.parseFloat(normalized);\n return Number.isNaN(parsed) ? null : parsed;\n };\n // Treat percentage/auto sizing as responsive so viewBox drives the layout\n const isWidthRelative = isRelativeLength(widthAttr);\n const isHeightRelative = isRelativeLength(heightAttr);\n const widthMissing = !widthAttr || widthAttr === \"0\";\n const heightMissing = !heightAttr || heightAttr === \"0\";\n const numericWidth = toNumericLength(widthAttr);\n const numericHeight = toNumericLength(heightAttr);\n const matchesViewBox =\n numericWidth === viewBoxWidth && numericHeight === viewBoxHeight;\n\n // Prefer responsive layout when sizing is relative or matches the viewBox\n const shouldUseResponsiveSize =\n isWidthRelative ||\n isHeightRelative ||\n (widthMissing && heightMissing) ||\n matchesViewBox;\n\n if (shouldUseResponsiveSize) {\n hasResponsiveSvg = true;\n svgEl.classList.add(\"content-render-svg-el--responsive\");\n svgEl.classList.remove(\"content-render-svg-el--fixed\");\n svgEl.style.width = \"100%\";\n svgEl.style.height = \"auto\";\n if (!svgEl.style.aspectRatio && viewBoxHeight > 0) {\n svgEl.style.aspectRatio = `${viewBoxWidth} / ${viewBoxHeight}`;\n }\n return;\n }\n\n hasFixedSvg = true;\n svgEl.classList.add(\"content-render-svg-el--fixed\");\n svgEl.classList.remove(\"content-render-svg-el--responsive\");\n if (widthMissing && viewBoxWidth > 0) {\n svgEl.setAttribute(\"width\", `${viewBoxWidth}`);\n }\n if (heightMissing && viewBoxHeight > 0) {\n svgEl.setAttribute(\"height\", `${viewBoxHeight}`);\n }\n });\n\n const hostResponsive = hasResponsiveSvg && !hasFixedSvg;\n host.classList.toggle(\"content-render-svg--responsive\", hostResponsive);\n host.classList.toggle(\"content-render-svg--fixed\", !hostResponsive);\n }, [svg]);\n\n return (\n <div className=\"content-render-svg-scroll\">\n <div className=\"content-render-svg\" ref={hostRef} />\n </div>\n );\n};\n\n// Extended component interface\ntype CustomComponents = ComponentsWithCustomVariable & {\n \"custom-button-after-content\"?: React.ComponentType<{\n children: React.ReactNode;\n }>;\n};\n\nconst remarkPlugins: PluggableList = [\n remarkGfm,\n remarkMath,\n remarkFlow,\n remarkBreaks,\n];\n\nconst rehypePlugins: PluggableList = [\n preserveCustomVariableProperties,\n rehypeRaw,\n sanitizeInvalidTagName,\n restoreCustomVariableProperties,\n [rehypeHighlight, { languages: highlightLanguages, subset: subsetLanguages }],\n rehypeKatex,\n];\n\nexport const MarkdownRenderer: React.FC<{\n content: string;\n components: CustomComponents;\n}> = ({ content: markdownContent, components }) => (\n <div className=\"markdown-renderer\">\n <ReactMarkdown\n remarkPlugins={remarkPlugins}\n rehypePlugins={rehypePlugins}\n components={components}\n >\n {markdownContent}\n </ReactMarkdown>\n </div>\n);\n\nconst mergeNonSandboxSegments = (segments: RenderSegment[]) => {\n if (segments.length <= 1) return segments;\n const merged: RenderSegment[] = [];\n\n segments.forEach((segment) => {\n if (segment.type === \"sandbox\") {\n merged.push(segment);\n return;\n }\n\n const last = merged[merged.length - 1];\n if (last && last.type !== \"sandbox\") {\n merged[merged.length - 1] = {\n type: \"markdown\",\n value: `${last.value}${segment.value}`,\n };\n return;\n }\n\n merged.push({ type: \"markdown\", value: segment.value });\n });\n\n return merged;\n};\n\nconst splitTextByCharacterChunk = (value: string, chunkSize: number) => {\n const safeChunkSize = Math.max(1, chunkSize);\n const characters = Array.from(value);\n\n return {\n chunk: characters.slice(0, safeChunkSize).join(\"\"),\n rest: characters.slice(safeChunkSize).join(\"\"),\n };\n};\n\nconst ContentRender: React.FC<ContentRenderProps> = ({\n content,\n contentType,\n locale,\n customRenderBar,\n onSend,\n typingSpeed = 40,\n enableTypewriter = false,\n onTypeFinished,\n onTypewriterStateChange,\n userInput,\n interactionDefaultValueOptions,\n defaultButtonText,\n defaultInputText,\n defaultSelectedValues,\n readonly = false,\n confirmButtonText,\n copyButtonText,\n copiedButtonText,\n sandboxLoadingText,\n sandboxStyleLoadingText,\n sandboxScriptLoadingText,\n disableSandboxLoadingOverlay = false,\n sandboxFullscreenButtonText,\n sandboxExitFullscreenButtonText,\n sandboxMode = \"content\",\n onClickCustomButtonAfterContent,\n beforeSend,\n // tooltipMinLength,\n}) => {\n const localeTexts = getContentRenderLocaleTexts(locale);\n const resolvedConfirmButtonText =\n confirmButtonText || localeTexts.confirmButtonText;\n const resolvedCopyButtonText = copyButtonText || localeTexts.copyButtonText;\n const resolvedCopiedButtonText =\n copiedButtonText || localeTexts.copiedButtonText;\n const resolvedSandboxFullscreenButtonText =\n sandboxFullscreenButtonText || localeTexts.sandboxFullscreenButtonText;\n const resolvedSandboxExitFullscreenButtonText =\n sandboxExitFullscreenButtonText ||\n localeTexts.sandboxExitFullscreenButtonText;\n const shouldApplyTypewriterByContentType =\n !contentType || contentType === \"text\";\n const isTypewriterEnabled =\n Boolean(enableTypewriter) && shouldApplyTypewriterByContentType;\n const typewriterChunkSize = 2;\n const typewriterTickMs = Math.max(0, typingSpeed);\n const [displayContent, setDisplayContent] = useState(() =>\n isTypewriterEnabled ? \"\" : content\n );\n const pendingContentRef = useRef(\"\");\n const previousTypewriterEnabledRef = useRef(isTypewriterEnabled);\n const hasReportedTypeFinishedRef = useRef(false);\n\n useEffect(() => {\n const wasTypewriterEnabled = previousTypewriterEnabledRef.current;\n previousTypewriterEnabledRef.current = isTypewriterEnabled;\n hasReportedTypeFinishedRef.current = false;\n\n if (!isTypewriterEnabled) {\n pendingContentRef.current = \"\";\n setDisplayContent(content);\n return;\n }\n\n setDisplayContent((current) => {\n const shouldRestartTyping = !wasTypewriterEnabled;\n const canContinueTyping = content.startsWith(current);\n\n if (!shouldRestartTyping && !canContinueTyping) {\n pendingContentRef.current = \"\";\n return content;\n }\n\n const nextVisibleContent =\n shouldRestartTyping || !canContinueTyping ? \"\" : current;\n\n pendingContentRef.current = content.slice(nextVisibleContent.length);\n return nextVisibleContent;\n });\n }, [content, isTypewriterEnabled]);\n\n useEffect(() => {\n if (!isTypewriterEnabled) {\n return;\n }\n\n if (\n hasReportedTypeFinishedRef.current ||\n pendingContentRef.current ||\n displayContent !== content\n ) {\n return;\n }\n\n hasReportedTypeFinishedRef.current = true;\n onTypeFinished?.();\n }, [content, displayContent, isTypewriterEnabled, onTypeFinished]);\n\n useEffect(() => {\n if (!isTypewriterEnabled || !pendingContentRef.current) {\n return undefined;\n }\n\n const typewriterTimer = window.setTimeout(() => {\n setDisplayContent((current) => {\n const { chunk, rest } = splitTextByCharacterChunk(\n pendingContentRef.current,\n typewriterChunkSize\n );\n\n if (!chunk) {\n return current;\n }\n\n pendingContentRef.current = rest;\n return `${current}${chunk}`;\n });\n }, typewriterTickMs);\n\n return () => window.clearTimeout(typewriterTimer);\n }, [\n content,\n displayContent,\n isTypewriterEnabled,\n typewriterChunkSize,\n typewriterTickMs,\n ]);\n\n const typewriterState = useMemo<ContentRenderTypewriterState>(\n () => ({\n isTypewriterEnabled,\n isTyping: isTypewriterEnabled && displayContent !== content,\n isComplete: displayContent === content,\n renderedLength: displayContent.length,\n totalLength: content.length,\n }),\n [content, displayContent, isTypewriterEnabled]\n );\n\n useEffect(() => {\n onTypewriterStateChange?.(typewriterState);\n }, [onTypewriterStateChange, typewriterState]);\n\n const renderContent = isTypewriterEnabled ? displayContent : content;\n const normalizedContent = useMemo(\n () => normalizeInlineHtml(renderContent),\n [renderContent]\n );\n\n const interactionDefaults = useMemo(\n () =>\n getInteractionDefaultValues(\n renderContent,\n userInput,\n interactionDefaultValueOptions\n ),\n [interactionDefaultValueOptions, renderContent, userInput]\n );\n\n const resolvedDefaultButtonText =\n defaultButtonText?.trim() || interactionDefaults.buttonText;\n const resolvedDefaultInputText =\n defaultInputText?.trim() || interactionDefaults.inputText;\n const fallbackSelectedValues = useMemo(\n () =>\n userInput\n ? userInput\n .split(\",\")\n .map((value) => value.trim())\n .filter(Boolean)\n : undefined,\n [userInput]\n );\n const resolvedDefaultSelectedValues = defaultSelectedValues?.length\n ? defaultSelectedValues\n : interactionDefaults.selectedValues || fallbackSelectedValues;\n\n const components: CustomComponents = {\n \"custom-button-after-content\": ({\n children,\n }: {\n children: React.ReactNode;\n }) => {\n return (\n <button\n className=\"content-render-custom-button-after-content\"\n onClick={onClickCustomButtonAfterContent}\n >\n <span className=\"content-render-custom-button-after-content-inner\">\n {children}\n </span>\n </button>\n );\n },\n \"custom-variable\": (props) => (\n <CustomButtonInputVariable\n {...props}\n readonly={readonly}\n defaultButtonText={resolvedDefaultButtonText}\n defaultInputText={resolvedDefaultInputText}\n defaultSelectedValues={resolvedDefaultSelectedValues}\n onSend={onSend}\n beforeSend={beforeSend}\n locale={locale}\n confirmButtonText={resolvedConfirmButtonText}\n // tooltipMinLength={tooltipMinLength}\n />\n ),\n code: (props) => {\n const { className, children, ...rest } = props as {\n className?: string;\n children?: React.ReactNode;\n };\n const match = /language-(\\w+)/.exec(className || \"\");\n const language = match?.[1];\n if (language === \"mermaid\") {\n const chartContent = children?.toString().replace(/\\n$/, \"\") || \"\";\n const frozen = mermaidBlockIsComplete(renderContent, chartContent);\n return <MermaidChart chart={chartContent} frozen={frozen} />;\n }\n\n return (\n <code className={className} {...rest}>\n {children}\n </code>\n );\n },\n table: ({ ...props }) => (\n <div className=\"content-render-table-container\">\n <table className=\"content-render-table\" {...props} />\n </div>\n ),\n th: ({ ...props }) => <th className=\"content-render-th\" {...props} />,\n td: ({ ...props }) => <td className=\"content-render-td\" {...props} />,\n tr: ({ ...props }) => <tr className=\"content-render-tr\" {...props} />,\n li: ({ node, ...props }) => {\n const className = node?.properties?.className;\n const hasTaskListItem =\n (typeof className === \"string\" &&\n className.includes(\"task-list-item\")) ||\n (Array.isArray(className) && className.includes(\"task-list-item\"));\n if (hasTaskListItem) {\n return <li className=\"content-render-task-list-item\" {...props} />;\n }\n return <li {...props} />;\n },\n ol: ({ ...props }) => <ol className=\"content-render-ol\" {...props} />,\n ul: ({ ...props }) => <ul className=\"content-render-ul\" {...props} />,\n input: ({ ...props }) => {\n if (props.type === \"checkbox\") {\n return (\n <input\n type=\"checkbox\"\n className=\"content-render-checkbox\"\n disabled\n {...props}\n />\n );\n }\n return <input {...props} />;\n },\n a: ({ children, ...props }) => (\n <a target=\"_blank\" rel=\"noopener noreferrer\" {...props}>\n {children}\n </a>\n ),\n pre: (props) => (\n <CodeBlock\n {...props}\n copyButtonText={resolvedCopyButtonText}\n copiedButtonText={resolvedCopiedButtonText}\n />\n ),\n };\n\n const hasPotentialSandboxTags = useMemo(\n () => SANDBOX_TAG_HINT_PATTERN.test(renderContent),\n [renderContent]\n );\n\n const renderSegments = useMemo(\n () =>\n hasPotentialSandboxTags ? splitContentSegments(renderContent, true) : [],\n [renderContent, hasPotentialSandboxTags]\n );\n\n const hasSandbox = renderSegments.some(\n (segment) => segment.type === \"sandbox\"\n );\n const mergedRenderSegments = useMemo(\n () => mergeNonSandboxSegments(renderSegments),\n [renderSegments]\n );\n\n const segments = useMemo(\n () => parseMarkdownSegments(normalizedContent),\n [normalizedContent]\n );\n\n const renderMarkdownSegments = (raw: string, keyPrefix: string) => {\n const normalized = normalizeInlineHtml(raw);\n const parsed = parseMarkdownSegments(normalized);\n\n return parsed.map((seg, index) => {\n const key = `${keyPrefix}-${seg.type}-${index}`;\n\n if (seg.type === \"text\") {\n return (\n <MarkdownRenderer\n key={key}\n components={components}\n content={seg.value}\n />\n );\n }\n\n if (seg.type === \"mermaid\") {\n return (\n <MermaidChart key={key} chart={seg.value} frozen={!seg.complete} />\n );\n }\n\n if (seg.type === \"svg\") {\n return <SvgBlockInShadow key={key} svg={seg.value} />;\n }\n\n return null;\n });\n };\n\n if (hasSandbox) {\n return (\n <div className=\"content-render markdown-body\">\n {mergedRenderSegments.map((segment, idx) =>\n segment.type === \"sandbox\" ? (\n <IframeSandbox\n key={`sandbox-${idx}`}\n hideFullScreen\n type=\"sandbox\"\n content={segment.value}\n className=\"content-render-iframe\"\n locale={locale}\n loadingText={sandboxLoadingText}\n styleLoadingText={sandboxStyleLoadingText}\n scriptLoadingText={sandboxScriptLoadingText}\n disableLoadingOverlay={disableSandboxLoadingOverlay}\n fullScreenButtonText={resolvedSandboxFullscreenButtonText}\n exitFullScreenButtonText={resolvedSandboxExitFullscreenButtonText}\n mode={sandboxMode}\n />\n ) : (\n <React.Fragment key={`md-${idx}`}>\n {renderMarkdownSegments(segment.value, `md-${idx}`)}\n </React.Fragment>\n )\n )}\n </div>\n );\n }\n\n return (\n <div className=\"content-render markdown-body\">\n {segments.map((seg, index) => {\n if (seg.type === \"text\") {\n return (\n <MarkdownRenderer\n key={index}\n components={components}\n content={seg.value}\n />\n );\n }\n\n if (seg.type === \"mermaid\") {\n return (\n <MermaidChart\n key={index}\n chart={seg.value}\n frozen={!seg.complete}\n />\n );\n }\n\n if (seg.type === \"svg\") {\n return <SvgBlockInShadow key={index} svg={seg.value} />;\n }\n })}\n\n {customRenderBar && (\n <div className=\"content-render-custom-bar\">\n {React.createElement(customRenderBar, {\n content,\n displayContent: normalizedContent,\n onSend,\n })}\n </div>\n )}\n </div>\n );\n};\n\nexport default ContentRender;\n"],"names":["SANDBOX_TAG_HINT_PATTERN","SvgBlockInShadow","svg","hostRef","useRef","useEffect","host","shadowRoot","styleId","styleEl","node","template","cleanedSvg","stripSvgTextLineBreaks","hasResponsiveSvg","hasFixedSvg","svgEl","viewBox","dimensions","value","viewBoxWidth","viewBoxHeight","widthAttr","heightAttr","isRelativeLength","normalized","toNumericLength","parsed","isWidthRelative","isHeightRelative","widthMissing","heightMissing","numericWidth","numericHeight","hostResponsive","jsx","remarkPlugins","remarkGfm","remarkMath","remarkFlow","remarkBreaks","rehypePlugins","preserveCustomVariableProperties","rehypeRaw","sanitizeInvalidTagName","restoreCustomVariableProperties","rehypeHighlight","highlightLanguages","subsetLanguages","rehypeKatex","MarkdownRenderer","markdownContent","components","ReactMarkdown","mergeNonSandboxSegments","segments","merged","segment","last","splitTextByCharacterChunk","chunkSize","safeChunkSize","characters","ContentRender","content","contentType","locale","customRenderBar","onSend","typingSpeed","enableTypewriter","onTypeFinished","onTypewriterStateChange","userInput","interactionDefaultValueOptions","defaultButtonText","defaultInputText","defaultSelectedValues","readonly","confirmButtonText","copyButtonText","copiedButtonText","sandboxLoadingText","sandboxStyleLoadingText","sandboxScriptLoadingText","disableSandboxLoadingOverlay","sandboxFullscreenButtonText","sandboxExitFullscreenButtonText","sandboxMode","onClickCustomButtonAfterContent","beforeSend","localeTexts","getContentRenderLocaleTexts","resolvedConfirmButtonText","resolvedCopyButtonText","resolvedCopiedButtonText","resolvedSandboxFullscreenButtonText","resolvedSandboxExitFullscreenButtonText","isTypewriterEnabled","typewriterChunkSize","typewriterTickMs","displayContent","setDisplayContent","useState","pendingContentRef","previousTypewriterEnabledRef","hasReportedTypeFinishedRef","wasTypewriterEnabled","current","shouldRestartTyping","canContinueTyping","nextVisibleContent","typewriterTimer","chunk","rest","typewriterState","useMemo","renderContent","normalizedContent","normalizeInlineHtml","interactionDefaults","getInteractionDefaultValues","resolvedDefaultButtonText","resolvedDefaultInputText","fallbackSelectedValues","resolvedDefaultSelectedValues","children","props","CustomButtonInputVariable","className","chartContent","frozen","mermaidBlockIsComplete","MermaidChart","CodeBlock","hasPotentialSandboxTags","renderSegments","splitContentSegments","hasSandbox","mergedRenderSegments","parseMarkdownSegments","renderMarkdownSegments","raw","keyPrefix","seg","index","key","idx","IframeSandbox","React","jsxs"],"mappings":"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"}
@@ -68,7 +68,12 @@ const _e = /<(script|style|link|iframe|html|head|body|meta|title|base|template|d
68
68
  const z = h && !S;
69
69
  i.classList.toggle("content-render-svg--responsive", z), i.classList.toggle("content-render-svg--fixed", !z);
70
70
  }, [r]), /* @__PURE__ */ t.jsx("div", { className: "content-render-svg-scroll", children: /* @__PURE__ */ t.jsx("div", { className: "content-render-svg", ref: s }) });
71
- }, Ee = [De, Pe, Te, We], Ge = [
71
+ }, Ee = [
72
+ De,
73
+ Pe,
74
+ Te,
75
+ We
76
+ ], Ge = [
72
77
  Be,
73
78
  Ie,
74
79
  we,
@@ -1 +1 @@
1
- {"version":3,"file":"ContentRender.es.js","sources":["../../../src/components/ContentRender/ContentRender.tsx"],"sourcesContent":["import \"highlight.js/styles/github.css\";\nimport \"katex/dist/katex.min.css\";\nimport React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport rehypeHighlight from \"rehype-highlight\";\nimport rehypeKatex from \"rehype-katex\";\nimport rehypeRaw from \"rehype-raw\";\nimport remarkBreaks from \"remark-breaks\";\nimport remarkFlow from \"remark-flow\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\nimport { CustomRenderBarProps, OnSendContentParams } from \"../types\";\nimport { sanitizeInvalidTagName } from \"./utils/sanitize-invalid-tag-name\";\nimport { stripSvgTextLineBreaks } from \"./utils/strip-svg-text-line-breaks\";\nimport \"./contentRender.css\";\nimport \"./github-markdown-light.css\";\nimport CodeBlock from \"./CodeBlock\";\nimport CustomButtonInputVariable, {\n ComponentsWithCustomVariable,\n} from \"./plugins/CustomVariable\";\nimport MermaidChart from \"./plugins/MermaidChart\";\nimport {\n preserveCustomVariableProperties,\n restoreCustomVariableProperties,\n} from \"./utils/custom-variable-props\";\nimport {\n highlightLanguages,\n subsetLanguages,\n} from \"./utils/highlight-languages\";\n// import { processMarkdownText } from \"./utils/process-markdown\";\nimport {\n parseMarkdownSegments,\n mermaidBlockIsComplete,\n} from \"./utils/mermaid-parse\";\nimport { normalizeInlineHtml } from \"./utils/normalize-inline-html\";\nimport IframeSandbox from \"./IframeSandbox\";\nimport {\n splitContentSegments,\n type RenderSegment,\n} from \"./utils/split-content\";\nimport {\n getInteractionDefaultValues,\n type InteractionDefaultValueOptions,\n} from \"../../lib/interaction-defaults\";\nimport type { MarkdownFlowLocale } from \"../../lib/locale\";\nimport { getContentRenderLocaleTexts } from \"./contentRenderI18n\";\n\nconst SANDBOX_TAG_HINT_PATTERN =\n /<(script|style|link|iframe|html|head|body|meta|title|base|template|div|section|article|main)\\b/i;\n\n// Define component Props type\nexport interface ContentRenderProps {\n content: string;\n contentType?: string;\n /** Locale used for built-in UI text when a more specific text prop is not provided. */\n locale?: MarkdownFlowLocale;\n /**\n * Callback invoked when the custom button after content is clicked.\n * This button is rendered via the `<custom-button-after-content>` tag in markdown content.\n * @example\n * ```tsx\n * <ContentRender\n * content=\"Hello <custom-button-after-content>Ask</custom-button-after-content>\"\n * onClickCustomButtonAfterContent={() => console.log('Button clicked')}\n * />\n * ```\n */\n customRenderBar?: CustomRenderBarProps;\n onClickCustomButtonAfterContent?: () => void;\n onSend?: (content: OnSendContentParams) => void;\n typingSpeed?: number;\n enableTypewriter?: boolean;\n onTypeFinished?: () => void;\n onTypewriterStateChange?: (state: ContentRenderTypewriterState) => void;\n userInput?: string;\n interactionDefaultValueOptions?: InteractionDefaultValueOptions;\n defaultButtonText?: string;\n defaultInputText?: string; // Text input by user\n defaultSelectedValues?: string[]; // Default selected values for multi-select\n readonly?: boolean;\n // Multi-select confirm button text (i18n support)\n confirmButtonText?: string;\n // Copy button text (i18n support)\n copyButtonText?: string;\n // Copied state text (i18n support)\n copiedButtonText?: string;\n // Dynamic interaction format for multi-select support\n dynamicInteractionFormat?: string;\n // Loading text before first HTML block renders inside iframe (i18n support)\n sandboxLoadingText?: string;\n // Loading text while styles are being generated inside iframe\n sandboxStyleLoadingText?: string;\n // Loading text while scripts are being cached/executed inside iframe\n sandboxScriptLoadingText?: string;\n // Disable sandbox loading overlays when upper layers have already entered an error state\n disableSandboxLoadingOverlay?: boolean;\n // Fullscreen button text for iframe sandbox\n sandboxFullscreenButtonText?: string;\n // Exit fullscreen button text for iframe sandbox\n sandboxExitFullscreenButtonText?: string;\n // Sandbox render mode\n sandboxMode?: \"content\" | \"blackboard\";\n beforeSend?: (param: OnSendContentParams) => boolean;\n // tooltipMinLength?: number; // Control minimum character length for tooltip display, default 10\n}\n\nexport interface ContentRenderTypewriterState {\n isTypewriterEnabled: boolean;\n isTyping: boolean;\n isComplete: boolean;\n renderedLength: number;\n totalLength: number;\n}\n\n// Render svg string via Shadow DOM to avoid markdown wrapping\nconst SvgBlockInShadow: React.FC<{ svg: string }> = ({ svg }) => {\n const hostRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n const shadowRoot = host.shadowRoot ?? host.attachShadow({ mode: \"open\" });\n const styleId = \"content-render-svg-style\";\n let styleEl = shadowRoot.getElementById(styleId) as HTMLStyleElement | null;\n\n if (!styleEl) {\n styleEl = document.createElement(\"style\");\n styleEl.id = styleId;\n // Keep intrinsic SVG width so the wrapper can scroll horizontally when needed\n styleEl.textContent = `\n svg { height: auto; display: inline-block; }\n svg.content-render-svg-el--responsive { width: 100%; max-width: 100%; }\n svg.content-render-svg-el--fixed { max-width: none; }\n `;\n shadowRoot.appendChild(styleEl);\n }\n\n const nodesToRemove = Array.from(shadowRoot.childNodes).filter(\n (node) => node !== styleEl\n );\n nodesToRemove.forEach((node) => shadowRoot.removeChild(node));\n\n const template = document.createElement(\"template\");\n const cleanedSvg = stripSvgTextLineBreaks(svg);\n template.innerHTML = cleanedSvg;\n shadowRoot.append(template.content.cloneNode(true));\n\n let hasResponsiveSvg = false;\n let hasFixedSvg = false;\n\n shadowRoot.querySelectorAll(\"svg\").forEach((svgEl) => {\n // Derive responsive sizing from viewBox so pure viewBox SVGs stay visible and fluid\n const viewBox = svgEl.getAttribute(\"viewBox\");\n if (!viewBox) return;\n\n const dimensions = viewBox\n .trim()\n .split(/[\\s,]+/)\n .map((value) => Number(value));\n\n if (dimensions.length !== 4 || dimensions.some(Number.isNaN)) return;\n\n const [, , viewBoxWidth, viewBoxHeight] = dimensions;\n const widthAttr = svgEl.getAttribute(\"width\");\n const heightAttr = svgEl.getAttribute(\"height\");\n const isRelativeLength = (value?: string | null) => {\n if (!value) return false;\n const normalized = value.trim().toLowerCase();\n return normalized === \"auto\" || normalized.endsWith(\"%\");\n };\n const toNumericLength = (value?: string | null) => {\n if (!value) return null;\n const normalized = value.trim().toLowerCase();\n if (normalized === \"auto\" || normalized.endsWith(\"%\")) {\n return null;\n }\n const parsed = Number.parseFloat(normalized);\n return Number.isNaN(parsed) ? null : parsed;\n };\n // Treat percentage/auto sizing as responsive so viewBox drives the layout\n const isWidthRelative = isRelativeLength(widthAttr);\n const isHeightRelative = isRelativeLength(heightAttr);\n const widthMissing = !widthAttr || widthAttr === \"0\";\n const heightMissing = !heightAttr || heightAttr === \"0\";\n const numericWidth = toNumericLength(widthAttr);\n const numericHeight = toNumericLength(heightAttr);\n const matchesViewBox =\n numericWidth === viewBoxWidth && numericHeight === viewBoxHeight;\n\n // Prefer responsive layout when sizing is relative or matches the viewBox\n const shouldUseResponsiveSize =\n isWidthRelative ||\n isHeightRelative ||\n (widthMissing && heightMissing) ||\n matchesViewBox;\n\n if (shouldUseResponsiveSize) {\n hasResponsiveSvg = true;\n svgEl.classList.add(\"content-render-svg-el--responsive\");\n svgEl.classList.remove(\"content-render-svg-el--fixed\");\n svgEl.style.width = \"100%\";\n svgEl.style.height = \"auto\";\n if (!svgEl.style.aspectRatio && viewBoxHeight > 0) {\n svgEl.style.aspectRatio = `${viewBoxWidth} / ${viewBoxHeight}`;\n }\n return;\n }\n\n hasFixedSvg = true;\n svgEl.classList.add(\"content-render-svg-el--fixed\");\n svgEl.classList.remove(\"content-render-svg-el--responsive\");\n if (widthMissing && viewBoxWidth > 0) {\n svgEl.setAttribute(\"width\", `${viewBoxWidth}`);\n }\n if (heightMissing && viewBoxHeight > 0) {\n svgEl.setAttribute(\"height\", `${viewBoxHeight}`);\n }\n });\n\n const hostResponsive = hasResponsiveSvg && !hasFixedSvg;\n host.classList.toggle(\"content-render-svg--responsive\", hostResponsive);\n host.classList.toggle(\"content-render-svg--fixed\", !hostResponsive);\n }, [svg]);\n\n return (\n <div className=\"content-render-svg-scroll\">\n <div className=\"content-render-svg\" ref={hostRef} />\n </div>\n );\n};\n\n// Extended component interface\ntype CustomComponents = ComponentsWithCustomVariable & {\n \"custom-button-after-content\"?: React.ComponentType<{\n children: React.ReactNode;\n }>;\n};\n\nconst remarkPlugins = [remarkGfm, remarkMath, remarkFlow, remarkBreaks];\n\nconst rehypePlugins = [\n preserveCustomVariableProperties,\n rehypeRaw,\n sanitizeInvalidTagName,\n restoreCustomVariableProperties,\n [rehypeHighlight, { languages: highlightLanguages, subset: subsetLanguages }],\n rehypeKatex,\n];\n\nexport const MarkdownRenderer: React.FC<{\n content: string;\n components: CustomComponents;\n}> = ({ content: markdownContent, components }) => (\n <div className=\"markdown-renderer\">\n <ReactMarkdown\n remarkPlugins={remarkPlugins}\n rehypePlugins={rehypePlugins}\n components={components}\n >\n {markdownContent}\n </ReactMarkdown>\n </div>\n);\n\nconst mergeNonSandboxSegments = (segments: RenderSegment[]) => {\n if (segments.length <= 1) return segments;\n const merged: RenderSegment[] = [];\n\n segments.forEach((segment) => {\n if (segment.type === \"sandbox\") {\n merged.push(segment);\n return;\n }\n\n const last = merged[merged.length - 1];\n if (last && last.type !== \"sandbox\") {\n merged[merged.length - 1] = {\n type: \"markdown\",\n value: `${last.value}${segment.value}`,\n };\n return;\n }\n\n merged.push({ type: \"markdown\", value: segment.value });\n });\n\n return merged;\n};\n\nconst splitTextByCharacterChunk = (value: string, chunkSize: number) => {\n const safeChunkSize = Math.max(1, chunkSize);\n const characters = Array.from(value);\n\n return {\n chunk: characters.slice(0, safeChunkSize).join(\"\"),\n rest: characters.slice(safeChunkSize).join(\"\"),\n };\n};\n\nconst ContentRender: React.FC<ContentRenderProps> = ({\n content,\n contentType,\n locale,\n customRenderBar,\n onSend,\n typingSpeed = 40,\n enableTypewriter = false,\n onTypeFinished,\n onTypewriterStateChange,\n userInput,\n interactionDefaultValueOptions,\n defaultButtonText,\n defaultInputText,\n defaultSelectedValues,\n readonly = false,\n confirmButtonText,\n copyButtonText,\n copiedButtonText,\n sandboxLoadingText,\n sandboxStyleLoadingText,\n sandboxScriptLoadingText,\n disableSandboxLoadingOverlay = false,\n sandboxFullscreenButtonText,\n sandboxExitFullscreenButtonText,\n sandboxMode = \"content\",\n onClickCustomButtonAfterContent,\n beforeSend,\n // tooltipMinLength,\n}) => {\n const localeTexts = getContentRenderLocaleTexts(locale);\n const resolvedConfirmButtonText =\n confirmButtonText || localeTexts.confirmButtonText;\n const resolvedCopyButtonText = copyButtonText || localeTexts.copyButtonText;\n const resolvedCopiedButtonText =\n copiedButtonText || localeTexts.copiedButtonText;\n const resolvedSandboxFullscreenButtonText =\n sandboxFullscreenButtonText || localeTexts.sandboxFullscreenButtonText;\n const resolvedSandboxExitFullscreenButtonText =\n sandboxExitFullscreenButtonText ||\n localeTexts.sandboxExitFullscreenButtonText;\n const shouldApplyTypewriterByContentType =\n !contentType || contentType === \"text\";\n const isTypewriterEnabled =\n Boolean(enableTypewriter) && shouldApplyTypewriterByContentType;\n const typewriterChunkSize = 2;\n const typewriterTickMs = Math.max(0, typingSpeed);\n const [displayContent, setDisplayContent] = useState(() =>\n isTypewriterEnabled ? \"\" : content\n );\n const pendingContentRef = useRef(\"\");\n const previousTypewriterEnabledRef = useRef(isTypewriterEnabled);\n const hasReportedTypeFinishedRef = useRef(false);\n\n useEffect(() => {\n const wasTypewriterEnabled = previousTypewriterEnabledRef.current;\n previousTypewriterEnabledRef.current = isTypewriterEnabled;\n hasReportedTypeFinishedRef.current = false;\n\n if (!isTypewriterEnabled) {\n pendingContentRef.current = \"\";\n setDisplayContent(content);\n return;\n }\n\n setDisplayContent((current) => {\n const shouldRestartTyping = !wasTypewriterEnabled;\n const canContinueTyping = content.startsWith(current);\n\n if (!shouldRestartTyping && !canContinueTyping) {\n pendingContentRef.current = \"\";\n return content;\n }\n\n const nextVisibleContent =\n shouldRestartTyping || !canContinueTyping ? \"\" : current;\n\n pendingContentRef.current = content.slice(nextVisibleContent.length);\n return nextVisibleContent;\n });\n }, [content, isTypewriterEnabled]);\n\n useEffect(() => {\n if (!isTypewriterEnabled) {\n return;\n }\n\n if (\n hasReportedTypeFinishedRef.current ||\n pendingContentRef.current ||\n displayContent !== content\n ) {\n return;\n }\n\n hasReportedTypeFinishedRef.current = true;\n onTypeFinished?.();\n }, [content, displayContent, isTypewriterEnabled, onTypeFinished]);\n\n useEffect(() => {\n if (!isTypewriterEnabled || !pendingContentRef.current) {\n return undefined;\n }\n\n const typewriterTimer = window.setTimeout(() => {\n setDisplayContent((current) => {\n const { chunk, rest } = splitTextByCharacterChunk(\n pendingContentRef.current,\n typewriterChunkSize\n );\n\n if (!chunk) {\n return current;\n }\n\n pendingContentRef.current = rest;\n return `${current}${chunk}`;\n });\n }, typewriterTickMs);\n\n return () => window.clearTimeout(typewriterTimer);\n }, [\n content,\n displayContent,\n isTypewriterEnabled,\n typewriterChunkSize,\n typewriterTickMs,\n ]);\n\n const typewriterState = useMemo<ContentRenderTypewriterState>(\n () => ({\n isTypewriterEnabled,\n isTyping: isTypewriterEnabled && displayContent !== content,\n isComplete: displayContent === content,\n renderedLength: displayContent.length,\n totalLength: content.length,\n }),\n [content, displayContent, isTypewriterEnabled]\n );\n\n useEffect(() => {\n onTypewriterStateChange?.(typewriterState);\n }, [onTypewriterStateChange, typewriterState]);\n\n const renderContent = isTypewriterEnabled ? displayContent : content;\n const normalizedContent = useMemo(\n () => normalizeInlineHtml(renderContent),\n [renderContent]\n );\n\n const interactionDefaults = useMemo(\n () =>\n getInteractionDefaultValues(\n renderContent,\n userInput,\n interactionDefaultValueOptions\n ),\n [interactionDefaultValueOptions, renderContent, userInput]\n );\n\n const resolvedDefaultButtonText =\n defaultButtonText?.trim() || interactionDefaults.buttonText;\n const resolvedDefaultInputText =\n defaultInputText?.trim() || interactionDefaults.inputText;\n const fallbackSelectedValues = useMemo(\n () =>\n userInput\n ? userInput\n .split(\",\")\n .map((value) => value.trim())\n .filter(Boolean)\n : undefined,\n [userInput]\n );\n const resolvedDefaultSelectedValues = defaultSelectedValues?.length\n ? defaultSelectedValues\n : interactionDefaults.selectedValues || fallbackSelectedValues;\n\n const components: CustomComponents = {\n \"custom-button-after-content\": ({\n children,\n }: {\n children: React.ReactNode;\n }) => {\n return (\n <button\n className=\"content-render-custom-button-after-content\"\n onClick={onClickCustomButtonAfterContent}\n >\n <span className=\"content-render-custom-button-after-content-inner\">\n {children}\n </span>\n </button>\n );\n },\n \"custom-variable\": (props) => (\n <CustomButtonInputVariable\n {...props}\n readonly={readonly}\n defaultButtonText={resolvedDefaultButtonText}\n defaultInputText={resolvedDefaultInputText}\n defaultSelectedValues={resolvedDefaultSelectedValues}\n onSend={onSend}\n beforeSend={beforeSend}\n locale={locale}\n confirmButtonText={resolvedConfirmButtonText}\n // tooltipMinLength={tooltipMinLength}\n />\n ),\n code: (props) => {\n const { className, children, ...rest } = props as {\n className?: string;\n children?: React.ReactNode;\n };\n const match = /language-(\\w+)/.exec(className || \"\");\n const language = match?.[1];\n if (language === \"mermaid\") {\n const chartContent = children?.toString().replace(/\\n$/, \"\") || \"\";\n const frozen = mermaidBlockIsComplete(renderContent, chartContent);\n return <MermaidChart chart={chartContent} frozen={frozen} />;\n }\n\n return (\n <code className={className} {...rest}>\n {children}\n </code>\n );\n },\n table: ({ ...props }) => (\n <div className=\"content-render-table-container\">\n <table className=\"content-render-table\" {...props} />\n </div>\n ),\n th: ({ ...props }) => <th className=\"content-render-th\" {...props} />,\n td: ({ ...props }) => <td className=\"content-render-td\" {...props} />,\n tr: ({ ...props }) => <tr className=\"content-render-tr\" {...props} />,\n li: ({ node, ...props }) => {\n const className = node?.properties?.className;\n const hasTaskListItem =\n (typeof className === \"string\" &&\n className.includes(\"task-list-item\")) ||\n (Array.isArray(className) && className.includes(\"task-list-item\"));\n if (hasTaskListItem) {\n return <li className=\"content-render-task-list-item\" {...props} />;\n }\n return <li {...props} />;\n },\n ol: ({ ...props }) => <ol className=\"content-render-ol\" {...props} />,\n ul: ({ ...props }) => <ul className=\"content-render-ul\" {...props} />,\n input: ({ ...props }) => {\n if (props.type === \"checkbox\") {\n return (\n <input\n type=\"checkbox\"\n className=\"content-render-checkbox\"\n disabled\n {...props}\n />\n );\n }\n return <input {...props} />;\n },\n a: ({ children, ...props }) => (\n <a target=\"_blank\" rel=\"noopener noreferrer\" {...props}>\n {children}\n </a>\n ),\n pre: (props) => (\n <CodeBlock\n {...props}\n copyButtonText={resolvedCopyButtonText}\n copiedButtonText={resolvedCopiedButtonText}\n />\n ),\n };\n\n const hasPotentialSandboxTags = useMemo(\n () => SANDBOX_TAG_HINT_PATTERN.test(renderContent),\n [renderContent]\n );\n\n const renderSegments = useMemo(\n () =>\n hasPotentialSandboxTags ? splitContentSegments(renderContent, true) : [],\n [renderContent, hasPotentialSandboxTags]\n );\n\n const hasSandbox = renderSegments.some(\n (segment) => segment.type === \"sandbox\"\n );\n const mergedRenderSegments = useMemo(\n () => mergeNonSandboxSegments(renderSegments),\n [renderSegments]\n );\n\n const segments = useMemo(\n () => parseMarkdownSegments(normalizedContent),\n [normalizedContent]\n );\n\n const renderMarkdownSegments = (raw: string, keyPrefix: string) => {\n const normalized = normalizeInlineHtml(raw);\n const parsed = parseMarkdownSegments(normalized);\n\n return parsed.map((seg, index) => {\n const key = `${keyPrefix}-${seg.type}-${index}`;\n\n if (seg.type === \"text\") {\n return (\n <MarkdownRenderer\n key={key}\n components={components}\n content={seg.value}\n />\n );\n }\n\n if (seg.type === \"mermaid\") {\n return (\n <MermaidChart key={key} chart={seg.value} frozen={!seg.complete} />\n );\n }\n\n if (seg.type === \"svg\") {\n return <SvgBlockInShadow key={key} svg={seg.value} />;\n }\n\n return null;\n });\n };\n\n if (hasSandbox) {\n return (\n <div className=\"content-render markdown-body\">\n {mergedRenderSegments.map((segment, idx) =>\n segment.type === \"sandbox\" ? (\n <IframeSandbox\n key={`sandbox-${idx}`}\n hideFullScreen\n type=\"sandbox\"\n content={segment.value}\n className=\"content-render-iframe\"\n locale={locale}\n loadingText={sandboxLoadingText}\n styleLoadingText={sandboxStyleLoadingText}\n scriptLoadingText={sandboxScriptLoadingText}\n disableLoadingOverlay={disableSandboxLoadingOverlay}\n fullScreenButtonText={resolvedSandboxFullscreenButtonText}\n exitFullScreenButtonText={resolvedSandboxExitFullscreenButtonText}\n mode={sandboxMode}\n />\n ) : (\n <React.Fragment key={`md-${idx}`}>\n {renderMarkdownSegments(segment.value, `md-${idx}`)}\n </React.Fragment>\n )\n )}\n </div>\n );\n }\n\n return (\n <div className=\"content-render markdown-body\">\n {segments.map((seg, index) => {\n if (seg.type === \"text\") {\n return (\n <MarkdownRenderer\n key={index}\n components={components}\n content={seg.value}\n />\n );\n }\n\n if (seg.type === \"mermaid\") {\n return (\n <MermaidChart\n key={index}\n chart={seg.value}\n frozen={!seg.complete}\n />\n );\n }\n\n if (seg.type === \"svg\") {\n return <SvgBlockInShadow key={index} svg={seg.value} />;\n }\n })}\n\n {customRenderBar && (\n <div className=\"content-render-custom-bar\">\n {React.createElement(customRenderBar, {\n content,\n displayContent: normalizedContent,\n onSend,\n })}\n </div>\n )}\n </div>\n );\n};\n\nexport default ContentRender;\n"],"names":["SANDBOX_TAG_HINT_PATTERN","SvgBlockInShadow","svg","hostRef","useRef","useEffect","host","shadowRoot","styleId","styleEl","node","template","cleanedSvg","stripSvgTextLineBreaks","hasResponsiveSvg","hasFixedSvg","svgEl","viewBox","dimensions","value","viewBoxWidth","viewBoxHeight","widthAttr","heightAttr","isRelativeLength","normalized","toNumericLength","parsed","isWidthRelative","isHeightRelative","widthMissing","heightMissing","numericWidth","numericHeight","hostResponsive","jsx","remarkPlugins","remarkGfm","remarkMath","remarkFlow","remarkBreaks","rehypePlugins","preserveCustomVariableProperties","rehypeRaw","sanitizeInvalidTagName","restoreCustomVariableProperties","rehypeHighlight","highlightLanguages","subsetLanguages","rehypeKatex","MarkdownRenderer","markdownContent","components","ReactMarkdown","mergeNonSandboxSegments","segments","merged","segment","last","splitTextByCharacterChunk","chunkSize","safeChunkSize","characters","ContentRender","content","contentType","locale","customRenderBar","onSend","typingSpeed","enableTypewriter","onTypeFinished","onTypewriterStateChange","userInput","interactionDefaultValueOptions","defaultButtonText","defaultInputText","defaultSelectedValues","readonly","confirmButtonText","copyButtonText","copiedButtonText","sandboxLoadingText","sandboxStyleLoadingText","sandboxScriptLoadingText","disableSandboxLoadingOverlay","sandboxFullscreenButtonText","sandboxExitFullscreenButtonText","sandboxMode","onClickCustomButtonAfterContent","beforeSend","localeTexts","getContentRenderLocaleTexts","resolvedConfirmButtonText","resolvedCopyButtonText","resolvedCopiedButtonText","resolvedSandboxFullscreenButtonText","resolvedSandboxExitFullscreenButtonText","isTypewriterEnabled","typewriterChunkSize","typewriterTickMs","displayContent","setDisplayContent","useState","pendingContentRef","previousTypewriterEnabledRef","hasReportedTypeFinishedRef","wasTypewriterEnabled","current","shouldRestartTyping","canContinueTyping","nextVisibleContent","typewriterTimer","chunk","rest","typewriterState","useMemo","renderContent","normalizedContent","normalizeInlineHtml","interactionDefaults","getInteractionDefaultValues","resolvedDefaultButtonText","resolvedDefaultInputText","fallbackSelectedValues","resolvedDefaultSelectedValues","children","props","CustomButtonInputVariable","className","chartContent","frozen","mermaidBlockIsComplete","MermaidChart","CodeBlock","hasPotentialSandboxTags","renderSegments","splitContentSegments","hasSandbox","mergedRenderSegments","parseMarkdownSegments","renderMarkdownSegments","raw","keyPrefix","seg","index","key","idx","IframeSandbox","React","jsxs"],"mappings":"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"}
1
+ {"version":3,"file":"ContentRender.es.js","sources":["../../../src/components/ContentRender/ContentRender.tsx"],"sourcesContent":["import \"highlight.js/styles/github.css\";\nimport \"katex/dist/katex.min.css\";\nimport React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport rehypeHighlight from \"rehype-highlight\";\nimport rehypeKatex from \"rehype-katex\";\nimport rehypeRaw from \"rehype-raw\";\nimport remarkBreaks from \"remark-breaks\";\nimport remarkFlow from \"remark-flow\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\nimport type { PluggableList } from \"unified\";\nimport { CustomRenderBarProps, OnSendContentParams } from \"../types\";\nimport { sanitizeInvalidTagName } from \"./utils/sanitize-invalid-tag-name\";\nimport { stripSvgTextLineBreaks } from \"./utils/strip-svg-text-line-breaks\";\nimport \"./contentRender.css\";\nimport \"./github-markdown-light.css\";\nimport CodeBlock from \"./CodeBlock\";\nimport CustomButtonInputVariable, {\n ComponentsWithCustomVariable,\n} from \"./plugins/CustomVariable\";\nimport MermaidChart from \"./plugins/MermaidChart\";\nimport {\n preserveCustomVariableProperties,\n restoreCustomVariableProperties,\n} from \"./utils/custom-variable-props\";\nimport {\n highlightLanguages,\n subsetLanguages,\n} from \"./utils/highlight-languages\";\n// import { processMarkdownText } from \"./utils/process-markdown\";\nimport {\n parseMarkdownSegments,\n mermaidBlockIsComplete,\n} from \"./utils/mermaid-parse\";\nimport { normalizeInlineHtml } from \"./utils/normalize-inline-html\";\nimport IframeSandbox from \"./IframeSandbox\";\nimport {\n splitContentSegments,\n type RenderSegment,\n} from \"./utils/split-content\";\nimport {\n getInteractionDefaultValues,\n type InteractionDefaultValueOptions,\n} from \"../../lib/interaction-defaults\";\nimport type { MarkdownFlowLocale } from \"../../lib/locale\";\nimport { getContentRenderLocaleTexts } from \"./contentRenderI18n\";\n\nconst SANDBOX_TAG_HINT_PATTERN =\n /<(script|style|link|iframe|html|head|body|meta|title|base|template|div|section|article|main)\\b/i;\n\n// Define component Props type\nexport interface ContentRenderProps {\n content: string;\n contentType?: string;\n /** Locale used for built-in UI text when a more specific text prop is not provided. */\n locale?: MarkdownFlowLocale;\n /**\n * Callback invoked when the custom button after content is clicked.\n * This button is rendered via the `<custom-button-after-content>` tag in markdown content.\n * @example\n * ```tsx\n * <ContentRender\n * content=\"Hello <custom-button-after-content>Ask</custom-button-after-content>\"\n * onClickCustomButtonAfterContent={() => console.log('Button clicked')}\n * />\n * ```\n */\n customRenderBar?: CustomRenderBarProps;\n onClickCustomButtonAfterContent?: () => void;\n onSend?: (content: OnSendContentParams) => void;\n typingSpeed?: number;\n enableTypewriter?: boolean;\n onTypeFinished?: () => void;\n onTypewriterStateChange?: (state: ContentRenderTypewriterState) => void;\n userInput?: string;\n interactionDefaultValueOptions?: InteractionDefaultValueOptions;\n defaultButtonText?: string;\n defaultInputText?: string; // Text input by user\n defaultSelectedValues?: string[]; // Default selected values for multi-select\n readonly?: boolean;\n // Multi-select confirm button text (i18n support)\n confirmButtonText?: string;\n // Copy button text (i18n support)\n copyButtonText?: string;\n // Copied state text (i18n support)\n copiedButtonText?: string;\n // Dynamic interaction format for multi-select support\n dynamicInteractionFormat?: string;\n // Loading text before first HTML block renders inside iframe (i18n support)\n sandboxLoadingText?: string;\n // Loading text while styles are being generated inside iframe\n sandboxStyleLoadingText?: string;\n // Loading text while scripts are being cached/executed inside iframe\n sandboxScriptLoadingText?: string;\n // Disable sandbox loading overlays when upper layers have already entered an error state\n disableSandboxLoadingOverlay?: boolean;\n // Fullscreen button text for iframe sandbox\n sandboxFullscreenButtonText?: string;\n // Exit fullscreen button text for iframe sandbox\n sandboxExitFullscreenButtonText?: string;\n // Sandbox render mode\n sandboxMode?: \"content\" | \"blackboard\";\n beforeSend?: (param: OnSendContentParams) => boolean;\n // tooltipMinLength?: number; // Control minimum character length for tooltip display, default 10\n}\n\nexport interface ContentRenderTypewriterState {\n isTypewriterEnabled: boolean;\n isTyping: boolean;\n isComplete: boolean;\n renderedLength: number;\n totalLength: number;\n}\n\n// Render svg string via Shadow DOM to avoid markdown wrapping\nconst SvgBlockInShadow: React.FC<{ svg: string }> = ({ svg }) => {\n const hostRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n const shadowRoot = host.shadowRoot ?? host.attachShadow({ mode: \"open\" });\n const styleId = \"content-render-svg-style\";\n let styleEl = shadowRoot.getElementById(styleId) as HTMLStyleElement | null;\n\n if (!styleEl) {\n styleEl = document.createElement(\"style\");\n styleEl.id = styleId;\n // Keep intrinsic SVG width so the wrapper can scroll horizontally when needed\n styleEl.textContent = `\n svg { height: auto; display: inline-block; }\n svg.content-render-svg-el--responsive { width: 100%; max-width: 100%; }\n svg.content-render-svg-el--fixed { max-width: none; }\n `;\n shadowRoot.appendChild(styleEl);\n }\n\n const nodesToRemove = Array.from(shadowRoot.childNodes).filter(\n (node) => node !== styleEl\n );\n nodesToRemove.forEach((node) => shadowRoot.removeChild(node));\n\n const template = document.createElement(\"template\");\n const cleanedSvg = stripSvgTextLineBreaks(svg);\n template.innerHTML = cleanedSvg;\n shadowRoot.append(template.content.cloneNode(true));\n\n let hasResponsiveSvg = false;\n let hasFixedSvg = false;\n\n shadowRoot.querySelectorAll(\"svg\").forEach((svgEl) => {\n // Derive responsive sizing from viewBox so pure viewBox SVGs stay visible and fluid\n const viewBox = svgEl.getAttribute(\"viewBox\");\n if (!viewBox) return;\n\n const dimensions = viewBox\n .trim()\n .split(/[\\s,]+/)\n .map((value) => Number(value));\n\n if (dimensions.length !== 4 || dimensions.some(Number.isNaN)) return;\n\n const [, , viewBoxWidth, viewBoxHeight] = dimensions;\n const widthAttr = svgEl.getAttribute(\"width\");\n const heightAttr = svgEl.getAttribute(\"height\");\n const isRelativeLength = (value?: string | null) => {\n if (!value) return false;\n const normalized = value.trim().toLowerCase();\n return normalized === \"auto\" || normalized.endsWith(\"%\");\n };\n const toNumericLength = (value?: string | null) => {\n if (!value) return null;\n const normalized = value.trim().toLowerCase();\n if (normalized === \"auto\" || normalized.endsWith(\"%\")) {\n return null;\n }\n const parsed = Number.parseFloat(normalized);\n return Number.isNaN(parsed) ? null : parsed;\n };\n // Treat percentage/auto sizing as responsive so viewBox drives the layout\n const isWidthRelative = isRelativeLength(widthAttr);\n const isHeightRelative = isRelativeLength(heightAttr);\n const widthMissing = !widthAttr || widthAttr === \"0\";\n const heightMissing = !heightAttr || heightAttr === \"0\";\n const numericWidth = toNumericLength(widthAttr);\n const numericHeight = toNumericLength(heightAttr);\n const matchesViewBox =\n numericWidth === viewBoxWidth && numericHeight === viewBoxHeight;\n\n // Prefer responsive layout when sizing is relative or matches the viewBox\n const shouldUseResponsiveSize =\n isWidthRelative ||\n isHeightRelative ||\n (widthMissing && heightMissing) ||\n matchesViewBox;\n\n if (shouldUseResponsiveSize) {\n hasResponsiveSvg = true;\n svgEl.classList.add(\"content-render-svg-el--responsive\");\n svgEl.classList.remove(\"content-render-svg-el--fixed\");\n svgEl.style.width = \"100%\";\n svgEl.style.height = \"auto\";\n if (!svgEl.style.aspectRatio && viewBoxHeight > 0) {\n svgEl.style.aspectRatio = `${viewBoxWidth} / ${viewBoxHeight}`;\n }\n return;\n }\n\n hasFixedSvg = true;\n svgEl.classList.add(\"content-render-svg-el--fixed\");\n svgEl.classList.remove(\"content-render-svg-el--responsive\");\n if (widthMissing && viewBoxWidth > 0) {\n svgEl.setAttribute(\"width\", `${viewBoxWidth}`);\n }\n if (heightMissing && viewBoxHeight > 0) {\n svgEl.setAttribute(\"height\", `${viewBoxHeight}`);\n }\n });\n\n const hostResponsive = hasResponsiveSvg && !hasFixedSvg;\n host.classList.toggle(\"content-render-svg--responsive\", hostResponsive);\n host.classList.toggle(\"content-render-svg--fixed\", !hostResponsive);\n }, [svg]);\n\n return (\n <div className=\"content-render-svg-scroll\">\n <div className=\"content-render-svg\" ref={hostRef} />\n </div>\n );\n};\n\n// Extended component interface\ntype CustomComponents = ComponentsWithCustomVariable & {\n \"custom-button-after-content\"?: React.ComponentType<{\n children: React.ReactNode;\n }>;\n};\n\nconst remarkPlugins: PluggableList = [\n remarkGfm,\n remarkMath,\n remarkFlow,\n remarkBreaks,\n];\n\nconst rehypePlugins: PluggableList = [\n preserveCustomVariableProperties,\n rehypeRaw,\n sanitizeInvalidTagName,\n restoreCustomVariableProperties,\n [rehypeHighlight, { languages: highlightLanguages, subset: subsetLanguages }],\n rehypeKatex,\n];\n\nexport const MarkdownRenderer: React.FC<{\n content: string;\n components: CustomComponents;\n}> = ({ content: markdownContent, components }) => (\n <div className=\"markdown-renderer\">\n <ReactMarkdown\n remarkPlugins={remarkPlugins}\n rehypePlugins={rehypePlugins}\n components={components}\n >\n {markdownContent}\n </ReactMarkdown>\n </div>\n);\n\nconst mergeNonSandboxSegments = (segments: RenderSegment[]) => {\n if (segments.length <= 1) return segments;\n const merged: RenderSegment[] = [];\n\n segments.forEach((segment) => {\n if (segment.type === \"sandbox\") {\n merged.push(segment);\n return;\n }\n\n const last = merged[merged.length - 1];\n if (last && last.type !== \"sandbox\") {\n merged[merged.length - 1] = {\n type: \"markdown\",\n value: `${last.value}${segment.value}`,\n };\n return;\n }\n\n merged.push({ type: \"markdown\", value: segment.value });\n });\n\n return merged;\n};\n\nconst splitTextByCharacterChunk = (value: string, chunkSize: number) => {\n const safeChunkSize = Math.max(1, chunkSize);\n const characters = Array.from(value);\n\n return {\n chunk: characters.slice(0, safeChunkSize).join(\"\"),\n rest: characters.slice(safeChunkSize).join(\"\"),\n };\n};\n\nconst ContentRender: React.FC<ContentRenderProps> = ({\n content,\n contentType,\n locale,\n customRenderBar,\n onSend,\n typingSpeed = 40,\n enableTypewriter = false,\n onTypeFinished,\n onTypewriterStateChange,\n userInput,\n interactionDefaultValueOptions,\n defaultButtonText,\n defaultInputText,\n defaultSelectedValues,\n readonly = false,\n confirmButtonText,\n copyButtonText,\n copiedButtonText,\n sandboxLoadingText,\n sandboxStyleLoadingText,\n sandboxScriptLoadingText,\n disableSandboxLoadingOverlay = false,\n sandboxFullscreenButtonText,\n sandboxExitFullscreenButtonText,\n sandboxMode = \"content\",\n onClickCustomButtonAfterContent,\n beforeSend,\n // tooltipMinLength,\n}) => {\n const localeTexts = getContentRenderLocaleTexts(locale);\n const resolvedConfirmButtonText =\n confirmButtonText || localeTexts.confirmButtonText;\n const resolvedCopyButtonText = copyButtonText || localeTexts.copyButtonText;\n const resolvedCopiedButtonText =\n copiedButtonText || localeTexts.copiedButtonText;\n const resolvedSandboxFullscreenButtonText =\n sandboxFullscreenButtonText || localeTexts.sandboxFullscreenButtonText;\n const resolvedSandboxExitFullscreenButtonText =\n sandboxExitFullscreenButtonText ||\n localeTexts.sandboxExitFullscreenButtonText;\n const shouldApplyTypewriterByContentType =\n !contentType || contentType === \"text\";\n const isTypewriterEnabled =\n Boolean(enableTypewriter) && shouldApplyTypewriterByContentType;\n const typewriterChunkSize = 2;\n const typewriterTickMs = Math.max(0, typingSpeed);\n const [displayContent, setDisplayContent] = useState(() =>\n isTypewriterEnabled ? \"\" : content\n );\n const pendingContentRef = useRef(\"\");\n const previousTypewriterEnabledRef = useRef(isTypewriterEnabled);\n const hasReportedTypeFinishedRef = useRef(false);\n\n useEffect(() => {\n const wasTypewriterEnabled = previousTypewriterEnabledRef.current;\n previousTypewriterEnabledRef.current = isTypewriterEnabled;\n hasReportedTypeFinishedRef.current = false;\n\n if (!isTypewriterEnabled) {\n pendingContentRef.current = \"\";\n setDisplayContent(content);\n return;\n }\n\n setDisplayContent((current) => {\n const shouldRestartTyping = !wasTypewriterEnabled;\n const canContinueTyping = content.startsWith(current);\n\n if (!shouldRestartTyping && !canContinueTyping) {\n pendingContentRef.current = \"\";\n return content;\n }\n\n const nextVisibleContent =\n shouldRestartTyping || !canContinueTyping ? \"\" : current;\n\n pendingContentRef.current = content.slice(nextVisibleContent.length);\n return nextVisibleContent;\n });\n }, [content, isTypewriterEnabled]);\n\n useEffect(() => {\n if (!isTypewriterEnabled) {\n return;\n }\n\n if (\n hasReportedTypeFinishedRef.current ||\n pendingContentRef.current ||\n displayContent !== content\n ) {\n return;\n }\n\n hasReportedTypeFinishedRef.current = true;\n onTypeFinished?.();\n }, [content, displayContent, isTypewriterEnabled, onTypeFinished]);\n\n useEffect(() => {\n if (!isTypewriterEnabled || !pendingContentRef.current) {\n return undefined;\n }\n\n const typewriterTimer = window.setTimeout(() => {\n setDisplayContent((current) => {\n const { chunk, rest } = splitTextByCharacterChunk(\n pendingContentRef.current,\n typewriterChunkSize\n );\n\n if (!chunk) {\n return current;\n }\n\n pendingContentRef.current = rest;\n return `${current}${chunk}`;\n });\n }, typewriterTickMs);\n\n return () => window.clearTimeout(typewriterTimer);\n }, [\n content,\n displayContent,\n isTypewriterEnabled,\n typewriterChunkSize,\n typewriterTickMs,\n ]);\n\n const typewriterState = useMemo<ContentRenderTypewriterState>(\n () => ({\n isTypewriterEnabled,\n isTyping: isTypewriterEnabled && displayContent !== content,\n isComplete: displayContent === content,\n renderedLength: displayContent.length,\n totalLength: content.length,\n }),\n [content, displayContent, isTypewriterEnabled]\n );\n\n useEffect(() => {\n onTypewriterStateChange?.(typewriterState);\n }, [onTypewriterStateChange, typewriterState]);\n\n const renderContent = isTypewriterEnabled ? displayContent : content;\n const normalizedContent = useMemo(\n () => normalizeInlineHtml(renderContent),\n [renderContent]\n );\n\n const interactionDefaults = useMemo(\n () =>\n getInteractionDefaultValues(\n renderContent,\n userInput,\n interactionDefaultValueOptions\n ),\n [interactionDefaultValueOptions, renderContent, userInput]\n );\n\n const resolvedDefaultButtonText =\n defaultButtonText?.trim() || interactionDefaults.buttonText;\n const resolvedDefaultInputText =\n defaultInputText?.trim() || interactionDefaults.inputText;\n const fallbackSelectedValues = useMemo(\n () =>\n userInput\n ? userInput\n .split(\",\")\n .map((value) => value.trim())\n .filter(Boolean)\n : undefined,\n [userInput]\n );\n const resolvedDefaultSelectedValues = defaultSelectedValues?.length\n ? defaultSelectedValues\n : interactionDefaults.selectedValues || fallbackSelectedValues;\n\n const components: CustomComponents = {\n \"custom-button-after-content\": ({\n children,\n }: {\n children: React.ReactNode;\n }) => {\n return (\n <button\n className=\"content-render-custom-button-after-content\"\n onClick={onClickCustomButtonAfterContent}\n >\n <span className=\"content-render-custom-button-after-content-inner\">\n {children}\n </span>\n </button>\n );\n },\n \"custom-variable\": (props) => (\n <CustomButtonInputVariable\n {...props}\n readonly={readonly}\n defaultButtonText={resolvedDefaultButtonText}\n defaultInputText={resolvedDefaultInputText}\n defaultSelectedValues={resolvedDefaultSelectedValues}\n onSend={onSend}\n beforeSend={beforeSend}\n locale={locale}\n confirmButtonText={resolvedConfirmButtonText}\n // tooltipMinLength={tooltipMinLength}\n />\n ),\n code: (props) => {\n const { className, children, ...rest } = props as {\n className?: string;\n children?: React.ReactNode;\n };\n const match = /language-(\\w+)/.exec(className || \"\");\n const language = match?.[1];\n if (language === \"mermaid\") {\n const chartContent = children?.toString().replace(/\\n$/, \"\") || \"\";\n const frozen = mermaidBlockIsComplete(renderContent, chartContent);\n return <MermaidChart chart={chartContent} frozen={frozen} />;\n }\n\n return (\n <code className={className} {...rest}>\n {children}\n </code>\n );\n },\n table: ({ ...props }) => (\n <div className=\"content-render-table-container\">\n <table className=\"content-render-table\" {...props} />\n </div>\n ),\n th: ({ ...props }) => <th className=\"content-render-th\" {...props} />,\n td: ({ ...props }) => <td className=\"content-render-td\" {...props} />,\n tr: ({ ...props }) => <tr className=\"content-render-tr\" {...props} />,\n li: ({ node, ...props }) => {\n const className = node?.properties?.className;\n const hasTaskListItem =\n (typeof className === \"string\" &&\n className.includes(\"task-list-item\")) ||\n (Array.isArray(className) && className.includes(\"task-list-item\"));\n if (hasTaskListItem) {\n return <li className=\"content-render-task-list-item\" {...props} />;\n }\n return <li {...props} />;\n },\n ol: ({ ...props }) => <ol className=\"content-render-ol\" {...props} />,\n ul: ({ ...props }) => <ul className=\"content-render-ul\" {...props} />,\n input: ({ ...props }) => {\n if (props.type === \"checkbox\") {\n return (\n <input\n type=\"checkbox\"\n className=\"content-render-checkbox\"\n disabled\n {...props}\n />\n );\n }\n return <input {...props} />;\n },\n a: ({ children, ...props }) => (\n <a target=\"_blank\" rel=\"noopener noreferrer\" {...props}>\n {children}\n </a>\n ),\n pre: (props) => (\n <CodeBlock\n {...props}\n copyButtonText={resolvedCopyButtonText}\n copiedButtonText={resolvedCopiedButtonText}\n />\n ),\n };\n\n const hasPotentialSandboxTags = useMemo(\n () => SANDBOX_TAG_HINT_PATTERN.test(renderContent),\n [renderContent]\n );\n\n const renderSegments = useMemo(\n () =>\n hasPotentialSandboxTags ? splitContentSegments(renderContent, true) : [],\n [renderContent, hasPotentialSandboxTags]\n );\n\n const hasSandbox = renderSegments.some(\n (segment) => segment.type === \"sandbox\"\n );\n const mergedRenderSegments = useMemo(\n () => mergeNonSandboxSegments(renderSegments),\n [renderSegments]\n );\n\n const segments = useMemo(\n () => parseMarkdownSegments(normalizedContent),\n [normalizedContent]\n );\n\n const renderMarkdownSegments = (raw: string, keyPrefix: string) => {\n const normalized = normalizeInlineHtml(raw);\n const parsed = parseMarkdownSegments(normalized);\n\n return parsed.map((seg, index) => {\n const key = `${keyPrefix}-${seg.type}-${index}`;\n\n if (seg.type === \"text\") {\n return (\n <MarkdownRenderer\n key={key}\n components={components}\n content={seg.value}\n />\n );\n }\n\n if (seg.type === \"mermaid\") {\n return (\n <MermaidChart key={key} chart={seg.value} frozen={!seg.complete} />\n );\n }\n\n if (seg.type === \"svg\") {\n return <SvgBlockInShadow key={key} svg={seg.value} />;\n }\n\n return null;\n });\n };\n\n if (hasSandbox) {\n return (\n <div className=\"content-render markdown-body\">\n {mergedRenderSegments.map((segment, idx) =>\n segment.type === \"sandbox\" ? (\n <IframeSandbox\n key={`sandbox-${idx}`}\n hideFullScreen\n type=\"sandbox\"\n content={segment.value}\n className=\"content-render-iframe\"\n locale={locale}\n loadingText={sandboxLoadingText}\n styleLoadingText={sandboxStyleLoadingText}\n scriptLoadingText={sandboxScriptLoadingText}\n disableLoadingOverlay={disableSandboxLoadingOverlay}\n fullScreenButtonText={resolvedSandboxFullscreenButtonText}\n exitFullScreenButtonText={resolvedSandboxExitFullscreenButtonText}\n mode={sandboxMode}\n />\n ) : (\n <React.Fragment key={`md-${idx}`}>\n {renderMarkdownSegments(segment.value, `md-${idx}`)}\n </React.Fragment>\n )\n )}\n </div>\n );\n }\n\n return (\n <div className=\"content-render markdown-body\">\n {segments.map((seg, index) => {\n if (seg.type === \"text\") {\n return (\n <MarkdownRenderer\n key={index}\n components={components}\n content={seg.value}\n />\n );\n }\n\n if (seg.type === \"mermaid\") {\n return (\n <MermaidChart\n key={index}\n chart={seg.value}\n frozen={!seg.complete}\n />\n );\n }\n\n if (seg.type === \"svg\") {\n return <SvgBlockInShadow key={index} svg={seg.value} />;\n }\n })}\n\n {customRenderBar && (\n <div className=\"content-render-custom-bar\">\n {React.createElement(customRenderBar, {\n content,\n displayContent: normalizedContent,\n onSend,\n })}\n </div>\n )}\n </div>\n );\n};\n\nexport default ContentRender;\n"],"names":["SANDBOX_TAG_HINT_PATTERN","SvgBlockInShadow","svg","hostRef","useRef","useEffect","host","shadowRoot","styleId","styleEl","node","template","cleanedSvg","stripSvgTextLineBreaks","hasResponsiveSvg","hasFixedSvg","svgEl","viewBox","dimensions","value","viewBoxWidth","viewBoxHeight","widthAttr","heightAttr","isRelativeLength","normalized","toNumericLength","parsed","isWidthRelative","isHeightRelative","widthMissing","heightMissing","numericWidth","numericHeight","hostResponsive","jsx","remarkPlugins","remarkGfm","remarkMath","remarkFlow","remarkBreaks","rehypePlugins","preserveCustomVariableProperties","rehypeRaw","sanitizeInvalidTagName","restoreCustomVariableProperties","rehypeHighlight","highlightLanguages","subsetLanguages","rehypeKatex","MarkdownRenderer","markdownContent","components","ReactMarkdown","mergeNonSandboxSegments","segments","merged","segment","last","splitTextByCharacterChunk","chunkSize","safeChunkSize","characters","ContentRender","content","contentType","locale","customRenderBar","onSend","typingSpeed","enableTypewriter","onTypeFinished","onTypewriterStateChange","userInput","interactionDefaultValueOptions","defaultButtonText","defaultInputText","defaultSelectedValues","readonly","confirmButtonText","copyButtonText","copiedButtonText","sandboxLoadingText","sandboxStyleLoadingText","sandboxScriptLoadingText","disableSandboxLoadingOverlay","sandboxFullscreenButtonText","sandboxExitFullscreenButtonText","sandboxMode","onClickCustomButtonAfterContent","beforeSend","localeTexts","getContentRenderLocaleTexts","resolvedConfirmButtonText","resolvedCopyButtonText","resolvedCopiedButtonText","resolvedSandboxFullscreenButtonText","resolvedSandboxExitFullscreenButtonText","isTypewriterEnabled","typewriterChunkSize","typewriterTickMs","displayContent","setDisplayContent","useState","pendingContentRef","previousTypewriterEnabledRef","hasReportedTypeFinishedRef","wasTypewriterEnabled","current","shouldRestartTyping","canContinueTyping","nextVisibleContent","typewriterTimer","chunk","rest","typewriterState","useMemo","renderContent","normalizedContent","normalizeInlineHtml","interactionDefaults","getInteractionDefaultValues","resolvedDefaultButtonText","resolvedDefaultInputText","fallbackSelectedValues","resolvedDefaultSelectedValues","children","props","CustomButtonInputVariable","className","chartContent","frozen","mermaidBlockIsComplete","MermaidChart","CodeBlock","hasPotentialSandboxTags","renderSegments","splitContentSegments","hasSandbox","mergedRenderSegments","parseMarkdownSegments","renderMarkdownSegments","raw","keyPrefix","seg","index","key","idx","IframeSandbox","React","jsxs"],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ declare const _default: {
2
+ "placeholder": "Type '/' to insert content",
3
+ "placeholderCodeEdit": "Please enter your content",
4
+ "placeholderQuickEdit": "Please enter your content, type '/' for more",
5
+ "dialogTitle": "Settings",
6
+ "dialogTitleImage": "Add Image",
7
+ "dialogTitleVideo": "Add Video",
8
+ "imageUrlPlaceholder": "Please enter image URL",
9
+ "imageUrlLabel": "URL",
10
+ "imageRunButton": "Preview",
11
+ "imageTitlePlaceholder": "Please enter image title",
12
+ "imageUseButton": "Use Image",
13
+ "imageDefaultTitle": "Image name",
14
+ "imageUploadLabel": "Upload",
15
+ "imageUploadPlaceholder": "Drag files or click to upload",
16
+ "imageUploading": "Uploading...",
17
+ "imageUploadSuccess": "Upload complete",
18
+ "imageUploadError": "Upload failed, please retry",
19
+ "fixedTextPlaceholder": "Add fixed text",
20
+ "fixedTextTooltip": "Fixed text",
21
+ "slashDivider": "Divider",
22
+ "imageTitleLabel": "Image Title",
23
+ "imageScaleLabel": "Scale",
24
+ "imageCancelButton": "Cancel",
25
+ "imageUrlRequired": "Please enter image URL",
26
+ "imageInvalidUrl": "Please enter a valid image URL",
27
+ "videoUrlPlaceholder": "Please enter Bilibili or YouTube video URL",
28
+ "videoUrlLabel": "URL",
29
+ "videoRunButton": "Preview",
30
+ "videoUseButton": "Use Resource",
31
+ "videoTitlePlaceholder": "Please enter video title",
32
+ "videoTitleLabel": "Title",
33
+ "videoDefaultTitle": "Video Title",
34
+ "videoDefaultTitleBilibili": "Bilibili Video",
35
+ "videoDefaultTitleYoutube": "YouTube Video",
36
+ "videoInvalidUrl": "Please enter a valid Bilibili or YouTube video URL",
37
+ "videoCancelButton": "Cancel",
38
+ "videoUseVideoButton": "Use Video",
39
+ "videoPreviewPlaceholder": "Preview will appear here",
40
+ "slashImage": "Image",
41
+ "slashVideo": "Video",
42
+ "slashVariable": "Variable",
43
+ "slashFixedText": "Fixed Text",
44
+ "dialogTitleVariable": "Select Variable",
45
+ "variableSearchPlaceholder": "Search variable",
46
+ "variableNotFound": "No variables found",
47
+ "variableEmpty": "No variables yet",
48
+ "variableNamePlaceholder": "Variable name",
49
+ "variableAlreadyExists": "Variable already exists",
50
+ "variableNameInvalid": "Use letters, numbers, or underscores without spaces",
51
+ "variableSectionSystem": "System Variables",
52
+ "variableSectionCustom": "Custom Variables",
53
+ "variableAddNew": "Add variable",
54
+ "toolbarInsertNewVariable": "Insert new variable",
55
+ "toolbarInsertExistingVariable": "Insert existing variable",
56
+ "toolbarConfirmOutput": "Insert confirm output",
57
+ "toolbarInsertLink": "Insert link",
58
+ "toolbarInsertButton": "Insert button",
59
+ "toolbarInsertSingleChoice": "Insert single choice",
60
+ "toolbarChoiceOption1": "Option 1",
61
+ "toolbarChoiceOption2": "Option 2",
62
+ "toolbarInsertMultiChoice": "Insert multi choice",
63
+ "toolbarInsertInput": "Insert input",
64
+ "toolbarInputPlaceholder": "Please enter",
65
+ "toolbarInsertImage": "Insert image",
66
+ "toolbarInsertVideo": "Insert video"
67
+ }
68
+ ;
69
+
70
+ export default _default;
@@ -0,0 +1,70 @@
1
+ declare const _default: {
2
+ "placeholder": "Tapez '/' pour insérer du contenu",
3
+ "placeholderCodeEdit": "Veuillez saisir votre contenu",
4
+ "placeholderQuickEdit": "Veuillez saisir votre contenu, tapez '/' pour plus d'options",
5
+ "dialogTitle": "Paramètres",
6
+ "dialogTitleImage": "Ajouter une image",
7
+ "dialogTitleVideo": "Ajouter une vidéo",
8
+ "imageUrlPlaceholder": "Veuillez saisir l'URL de l'image",
9
+ "imageUrlLabel": "URL",
10
+ "imageRunButton": "Prévisualiser",
11
+ "imageTitlePlaceholder": "Veuillez saisir le titre de l'image",
12
+ "imageUseButton": "Utiliser l'image",
13
+ "imageDefaultTitle": "Nom de l'image",
14
+ "imageUploadLabel": "Téléverser",
15
+ "imageUploadPlaceholder": "Glissez les fichiers ici ou cliquez pour téléverser",
16
+ "imageUploading": "Téléversement en cours...",
17
+ "imageUploadSuccess": "Téléversement terminé",
18
+ "imageUploadError": "Échec du téléversement, veuillez réessayer",
19
+ "fixedTextPlaceholder": "Ajouter un texte fixe",
20
+ "fixedTextTooltip": "Texte fixe",
21
+ "slashDivider": "Séparateur",
22
+ "imageTitleLabel": "Titre de l'image",
23
+ "imageScaleLabel": "Échelle",
24
+ "imageCancelButton": "Annuler",
25
+ "imageUrlRequired": "Veuillez saisir l'URL de l'image",
26
+ "imageInvalidUrl": "Veuillez saisir une URL d'image valide",
27
+ "videoUrlPlaceholder": "Veuillez saisir une URL de vidéo Bilibili ou YouTube",
28
+ "videoUrlLabel": "URL",
29
+ "videoRunButton": "Prévisualiser",
30
+ "videoUseButton": "Utiliser la ressource",
31
+ "videoTitlePlaceholder": "Veuillez saisir le titre de la vidéo",
32
+ "videoTitleLabel": "Titre",
33
+ "videoDefaultTitle": "Titre de la vidéo",
34
+ "videoDefaultTitleBilibili": "Vidéo Bilibili",
35
+ "videoDefaultTitleYoutube": "Vidéo YouTube",
36
+ "videoInvalidUrl": "Veuillez saisir une URL Bilibili ou YouTube valide",
37
+ "videoCancelButton": "Annuler",
38
+ "videoUseVideoButton": "Utiliser la vidéo",
39
+ "videoPreviewPlaceholder": "L'aperçu s'affichera ici",
40
+ "slashImage": "Image",
41
+ "slashVideo": "Vidéo",
42
+ "slashVariable": "Variable",
43
+ "slashFixedText": "Texte fixe",
44
+ "dialogTitleVariable": "Sélectionner une variable",
45
+ "variableSearchPlaceholder": "Rechercher une variable",
46
+ "variableNotFound": "Aucune variable trouvée",
47
+ "variableEmpty": "Aucune variable pour le moment",
48
+ "variableNamePlaceholder": "Nom de la variable",
49
+ "variableAlreadyExists": "La variable existe déjà",
50
+ "variableNameInvalid": "Utilisez des lettres, des chiffres ou des underscores sans espaces",
51
+ "variableSectionSystem": "Variables système",
52
+ "variableSectionCustom": "Variables personnalisées",
53
+ "variableAddNew": "Ajouter une variable",
54
+ "toolbarInsertNewVariable": "Insérer une nouvelle variable",
55
+ "toolbarInsertExistingVariable": "Insérer une variable existante",
56
+ "toolbarConfirmOutput": "Insérer une sortie de confirmation",
57
+ "toolbarInsertLink": "Insérer un lien",
58
+ "toolbarInsertButton": "Insérer un bouton",
59
+ "toolbarInsertSingleChoice": "Insérer un choix unique",
60
+ "toolbarChoiceOption1": "Option 1",
61
+ "toolbarChoiceOption2": "Option 2",
62
+ "toolbarInsertMultiChoice": "Insérer un choix multiple",
63
+ "toolbarInsertInput": "Insérer un champ de saisie",
64
+ "toolbarInputPlaceholder": "Veuillez saisir",
65
+ "toolbarInsertImage": "Insérer une image",
66
+ "toolbarInsertVideo": "Insérer une vidéo"
67
+ }
68
+ ;
69
+
70
+ export default _default;