@kushagradhawan/kookie-blocks 0.1.13 → 0.1.15

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 (143) hide show
  1. package/dist/cjs/components/code/{CodeBlock.d.ts → code-block.d.ts} +1 -1
  2. package/dist/cjs/components/code/code-block.d.ts.map +1 -0
  3. package/dist/cjs/components/code/code-block.js +2 -0
  4. package/dist/cjs/components/code/code-block.js.map +7 -0
  5. package/dist/{esm/components/code/CopyButton.d.ts → cjs/components/code/copy-button.d.ts} +1 -1
  6. package/dist/cjs/components/code/copy-button.d.ts.map +1 -0
  7. package/dist/cjs/components/code/{CopyButton.js → copy-button.js} +1 -1
  8. package/dist/cjs/components/code/{CopyButton.js.map → copy-button.js.map} +2 -2
  9. package/dist/cjs/components/code/index.d.ts +3 -3
  10. package/dist/cjs/components/code/index.d.ts.map +1 -1
  11. package/dist/cjs/components/code/index.js +1 -1
  12. package/dist/cjs/components/code/index.js.map +3 -3
  13. package/dist/{esm/components/code/LanguageBadge.d.ts → cjs/components/code/language-badge.d.ts} +1 -1
  14. package/dist/cjs/components/code/language-badge.d.ts.map +1 -0
  15. package/dist/cjs/components/code/{LanguageBadge.js → language-badge.js} +1 -1
  16. package/dist/cjs/components/code/{LanguageBadge.js.map → language-badge.js.map} +2 -2
  17. package/dist/{esm/components/code/PreviewSection.d.ts → cjs/components/code/preview-section.d.ts} +1 -1
  18. package/dist/cjs/components/code/preview-section.d.ts.map +1 -0
  19. package/dist/cjs/components/code/{PreviewSection.js → preview-section.js} +1 -1
  20. package/dist/cjs/components/code/{PreviewSection.js.map → preview-section.js.map} +2 -2
  21. package/dist/{esm/components/code/SyntaxHighlighter.d.ts → cjs/components/code/syntax-highlighter.d.ts} +1 -1
  22. package/dist/cjs/components/code/syntax-highlighter.d.ts.map +1 -0
  23. package/dist/cjs/components/code/{SyntaxHighlighter.js → syntax-highlighter.js} +1 -1
  24. package/dist/cjs/components/code/{SyntaxHighlighter.js.map → syntax-highlighter.js.map} +2 -2
  25. package/dist/{esm/components/code/useCodeCard.d.ts → cjs/components/code/use-code-card.d.ts} +1 -1
  26. package/dist/cjs/components/code/use-code-card.d.ts.map +1 -0
  27. package/dist/cjs/components/code/{useCodeCard.js → use-code-card.js} +1 -1
  28. package/dist/cjs/components/code/{useCodeCard.js.map → use-code-card.js.map} +2 -2
  29. package/dist/cjs/components/hero/{Hero.d.ts → hero.d.ts} +1 -1
  30. package/dist/cjs/components/hero/{Hero.d.ts.map → hero.d.ts.map} +1 -1
  31. package/dist/cjs/components/hero/{Hero.js → hero.js} +1 -1
  32. package/dist/cjs/components/hero/{Hero.js.map → hero.js.map} +2 -2
  33. package/dist/cjs/components/hero/index.d.ts +1 -1
  34. package/dist/cjs/components/hero/index.js +1 -1
  35. package/dist/cjs/components/hero/index.js.map +2 -2
  36. package/dist/{esm/components/markdown/createMarkdownComponents.d.ts → cjs/components/markdown/create-markdown-components.d.ts} +1 -1
  37. package/dist/cjs/components/markdown/create-markdown-components.d.ts.map +1 -0
  38. package/dist/cjs/components/markdown/{createMarkdownComponents.js → create-markdown-components.js} +2 -2
  39. package/dist/cjs/components/markdown/create-markdown-components.js.map +7 -0
  40. package/dist/cjs/components/markdown/index.d.ts +4 -4
  41. package/dist/cjs/components/markdown/index.d.ts.map +1 -1
  42. package/dist/cjs/components/markdown/index.js +1 -1
  43. package/dist/cjs/components/markdown/index.js.map +3 -3
  44. package/dist/{esm/components/markdown/StreamingMarkdown.d.ts → cjs/components/markdown/streaming-markdown.d.ts} +1 -1
  45. package/dist/cjs/components/markdown/streaming-markdown.d.ts.map +1 -0
  46. package/dist/cjs/components/markdown/streaming-markdown.js +2 -0
  47. package/dist/cjs/components/markdown/streaming-markdown.js.map +7 -0
  48. package/dist/{esm/components/markdown/utils/markdownStreaming.d.ts → cjs/components/markdown/utils/markdown-streaming.d.ts} +1 -1
  49. package/dist/cjs/components/markdown/utils/markdown-streaming.d.ts.map +1 -0
  50. package/dist/cjs/components/markdown/utils/{markdownStreaming.js → markdown-streaming.js} +1 -1
  51. package/dist/cjs/components/markdown/utils/{markdownStreaming.js.map → markdown-streaming.js.map} +2 -2
  52. package/dist/esm/components/code/{CodeBlock.d.ts → code-block.d.ts} +1 -1
  53. package/dist/esm/components/code/code-block.d.ts.map +1 -0
  54. package/dist/esm/components/code/code-block.js +2 -0
  55. package/dist/esm/components/code/code-block.js.map +7 -0
  56. package/dist/{cjs/components/code/CopyButton.d.ts → esm/components/code/copy-button.d.ts} +1 -1
  57. package/dist/esm/components/code/copy-button.d.ts.map +1 -0
  58. package/dist/esm/components/code/{CopyButton.js → copy-button.js} +1 -1
  59. package/dist/esm/components/code/{CopyButton.js.map → copy-button.js.map} +1 -1
  60. package/dist/esm/components/code/index.d.ts +3 -3
  61. package/dist/esm/components/code/index.d.ts.map +1 -1
  62. package/dist/esm/components/code/index.js +1 -1
  63. package/dist/esm/components/code/index.js.map +2 -2
  64. package/dist/{cjs/components/code/LanguageBadge.d.ts → esm/components/code/language-badge.d.ts} +1 -1
  65. package/dist/esm/components/code/language-badge.d.ts.map +1 -0
  66. package/dist/esm/components/code/{LanguageBadge.js → language-badge.js} +1 -1
  67. package/dist/esm/components/code/{LanguageBadge.js.map → language-badge.js.map} +1 -1
  68. package/dist/{cjs/components/code/PreviewSection.d.ts → esm/components/code/preview-section.d.ts} +1 -1
  69. package/dist/esm/components/code/preview-section.d.ts.map +1 -0
  70. package/dist/esm/components/code/{PreviewSection.js → preview-section.js} +1 -1
  71. package/dist/esm/components/code/{PreviewSection.js.map → preview-section.js.map} +1 -1
  72. package/dist/{cjs/components/code/SyntaxHighlighter.d.ts → esm/components/code/syntax-highlighter.d.ts} +1 -1
  73. package/dist/esm/components/code/syntax-highlighter.d.ts.map +1 -0
  74. package/dist/esm/components/code/{SyntaxHighlighter.js → syntax-highlighter.js} +1 -1
  75. package/dist/esm/components/code/{SyntaxHighlighter.js.map → syntax-highlighter.js.map} +1 -1
  76. package/dist/{cjs/components/code/useCodeCard.d.ts → esm/components/code/use-code-card.d.ts} +1 -1
  77. package/dist/esm/components/code/use-code-card.d.ts.map +1 -0
  78. package/dist/esm/components/code/{useCodeCard.js → use-code-card.js} +1 -1
  79. package/dist/esm/components/code/{useCodeCard.js.map → use-code-card.js.map} +1 -1
  80. package/dist/esm/components/hero/{Hero.d.ts → hero.d.ts} +1 -1
  81. package/dist/esm/components/hero/{Hero.d.ts.map → hero.d.ts.map} +1 -1
  82. package/dist/esm/components/hero/{Hero.js → hero.js} +1 -1
  83. package/dist/esm/components/hero/{Hero.js.map → hero.js.map} +1 -1
  84. package/dist/esm/components/hero/index.d.ts +1 -1
  85. package/dist/esm/components/hero/index.js +1 -1
  86. package/dist/esm/components/hero/index.js.map +1 -1
  87. package/dist/{cjs/components/markdown/createMarkdownComponents.d.ts → esm/components/markdown/create-markdown-components.d.ts} +1 -1
  88. package/dist/esm/components/markdown/create-markdown-components.d.ts.map +1 -0
  89. package/dist/esm/components/markdown/{createMarkdownComponents.js → create-markdown-components.js} +2 -2
  90. package/dist/esm/components/markdown/{createMarkdownComponents.js.map → create-markdown-components.js.map} +2 -2
  91. package/dist/esm/components/markdown/index.d.ts +4 -4
  92. package/dist/esm/components/markdown/index.d.ts.map +1 -1
  93. package/dist/esm/components/markdown/index.js +1 -1
  94. package/dist/esm/components/markdown/index.js.map +2 -2
  95. package/dist/{cjs/components/markdown/StreamingMarkdown.d.ts → esm/components/markdown/streaming-markdown.d.ts} +1 -1
  96. package/dist/esm/components/markdown/streaming-markdown.d.ts.map +1 -0
  97. package/dist/esm/components/markdown/streaming-markdown.js +2 -0
  98. package/dist/esm/components/markdown/streaming-markdown.js.map +7 -0
  99. package/dist/{cjs/components/markdown/utils/markdownStreaming.d.ts → esm/components/markdown/utils/markdown-streaming.d.ts} +1 -1
  100. package/dist/esm/components/markdown/utils/markdown-streaming.d.ts.map +1 -0
  101. package/dist/esm/components/markdown/utils/{markdownStreaming.js → markdown-streaming.js} +1 -1
  102. package/dist/esm/components/markdown/utils/{markdownStreaming.js.map → markdown-streaming.js.map} +1 -1
  103. package/package.json +1 -1
  104. package/src/components/code/{CodeBlock.tsx → code-block.tsx} +2 -2
  105. package/src/components/code/index.ts +3 -3
  106. package/src/components/hero/index.ts +1 -1
  107. package/src/components/markdown/{createMarkdownComponents.tsx → create-markdown-components.tsx} +6 -7
  108. package/src/components/markdown/index.ts +4 -5
  109. package/src/components/markdown/{StreamingMarkdown.tsx → streaming-markdown.tsx} +2 -2
  110. package/dist/cjs/components/code/CodeBlock.d.ts.map +0 -1
  111. package/dist/cjs/components/code/CodeBlock.js +0 -2
  112. package/dist/cjs/components/code/CodeBlock.js.map +0 -7
  113. package/dist/cjs/components/code/CopyButton.d.ts.map +0 -1
  114. package/dist/cjs/components/code/LanguageBadge.d.ts.map +0 -1
  115. package/dist/cjs/components/code/PreviewSection.d.ts.map +0 -1
  116. package/dist/cjs/components/code/SyntaxHighlighter.d.ts.map +0 -1
  117. package/dist/cjs/components/code/useCodeCard.d.ts.map +0 -1
  118. package/dist/cjs/components/markdown/StreamingMarkdown.d.ts.map +0 -1
  119. package/dist/cjs/components/markdown/StreamingMarkdown.js +0 -2
  120. package/dist/cjs/components/markdown/StreamingMarkdown.js.map +0 -7
  121. package/dist/cjs/components/markdown/createMarkdownComponents.d.ts.map +0 -1
  122. package/dist/cjs/components/markdown/createMarkdownComponents.js.map +0 -7
  123. package/dist/cjs/components/markdown/utils/markdownStreaming.d.ts.map +0 -1
  124. package/dist/esm/components/code/CodeBlock.d.ts.map +0 -1
  125. package/dist/esm/components/code/CodeBlock.js +0 -2
  126. package/dist/esm/components/code/CodeBlock.js.map +0 -7
  127. package/dist/esm/components/code/CopyButton.d.ts.map +0 -1
  128. package/dist/esm/components/code/LanguageBadge.d.ts.map +0 -1
  129. package/dist/esm/components/code/PreviewSection.d.ts.map +0 -1
  130. package/dist/esm/components/code/SyntaxHighlighter.d.ts.map +0 -1
  131. package/dist/esm/components/code/useCodeCard.d.ts.map +0 -1
  132. package/dist/esm/components/markdown/StreamingMarkdown.d.ts.map +0 -1
  133. package/dist/esm/components/markdown/StreamingMarkdown.js +0 -2
  134. package/dist/esm/components/markdown/StreamingMarkdown.js.map +0 -7
  135. package/dist/esm/components/markdown/createMarkdownComponents.d.ts.map +0 -1
  136. package/dist/esm/components/markdown/utils/markdownStreaming.d.ts.map +0 -1
  137. /package/src/components/code/{CopyButton.tsx → copy-button.tsx} +0 -0
  138. /package/src/components/code/{LanguageBadge.tsx → language-badge.tsx} +0 -0
  139. /package/src/components/code/{PreviewSection.tsx → preview-section.tsx} +0 -0
  140. /package/src/components/code/{SyntaxHighlighter.tsx → syntax-highlighter.tsx} +0 -0
  141. /package/src/components/code/{useCodeCard.ts → use-code-card.ts} +0 -0
  142. /package/src/components/hero/{Hero.tsx → hero.tsx} +0 -0
  143. /package/src/components/markdown/utils/{markdownStreaming.ts → markdown-streaming.ts} +0 -0
@@ -29,4 +29,4 @@ export declare function completeUnterminatedMarkdown(content: string): string;
29
29
  export declare function parseMarkdownIntoBlocks(content: string, parser?: (content: string) => Array<{
30
30
  raw?: string;
31
31
  }>): string[];
32
- //# sourceMappingURL=markdownStreaming.d.ts.map
32
+ //# sourceMappingURL=markdown-streaming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-streaming.d.ts","sourceRoot":"","sources":["../../../../../src/components/markdown/utils/markdown-streaming.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA2IH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAsGpE;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,KAAK,CAAC;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GACpD,MAAM,EAAE,CAuBV"}
@@ -2,4 +2,4 @@ function f(e,r){const n=r==="**"?"\\*\\*":"__",t=new RegExp(n,"g");if((e.match(t
2
2
  `,s=r<e.length-1&&e[r+1]===" ";return t&&s}function u(e,r){let n=0,t=-1;for(let i=0;i<e.length;i++)if(e[i]===r){if(g(e,i,r))continue;const a=i>0&&e[i-1]===r,l=i<e.length-1&&e[i+1]===r;if(a||l){l&&i++;continue}n++,t=i}return n%2===0||t===-1?!1:t===e.length-1?t>0:e.slice(t+1).length>0}function m(e){const r=/```/g,n=[];let t;for(;(t=r.exec(e))!==null;)n.push(t.index);return n.length%2===1}function d(e){if(!e.trim())return e;const r=e.trimEnd(),n=e.slice(r.length);let t=r;if(t.match(/```[\w-]*$/)&&!t.includes("```\n")&&!t.match(/```[\w-]+\n/)||m(t))return t+="\n```",t+n;if((t.replace(/```[\w-]*/g,"").match(/`/g)||[]).length%2===1)return t+="`",t+n;if(t.match(/\[([^\]]*)\]\(([^)]*)$/))return t+=")",t+n;if(f(t,"**"))return t+="**",t+n;if(f(t,"__"))return t+="__",t+n;if(h(t))return t+="~~",t+n;const o=t.split(`
3
3
  `),c=o[o.length-1];return c.match(/^#{1,6}\s+.+$/)||c.match(/^(\s*)([-*+]|\d+\.)\s+.+$/)||c.match(/^>\s+.+$/)?(t+=`
4
4
  `,t+n):u(t,"*")?(t+="*",t+n):(u(t,"_")&&(t+="_"),t+n)}function p(e,r){if(!e.trim())return[];const n=d(e);return r?r(n).map(s=>"raw"in s&&typeof s.raw=="string"?s.raw:"").filter(s=>!!s.trim()):[n]}export{d as completeUnterminatedMarkdown,p as parseMarkdownIntoBlocks};
5
- //# sourceMappingURL=markdownStreaming.js.map
5
+ //# sourceMappingURL=markdown-streaming.js.map
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../../../src/components/markdown/utils/markdownStreaming.ts"],
3
+ "sources": ["../../../../../src/components/markdown/utils/markdown-streaming.ts"],
4
4
  "sourcesContent": ["/**\n * Utilities for handling streaming markdown content.\n * Completes unterminated markdown blocks to enable proper parsing during streaming.\n */\n\n/**\n * Checks if there's an unpaired double marker (** or __) with content after the last opener.\n * Returns true only if there's text after the unclosed marker (not just the marker itself).\n */\nfunction hasUnpairedDoubleMarkerWithContent(content: string, marker: string): boolean {\n const escaped = marker === \"**\" ? \"\\\\*\\\\*\" : \"__\";\n const regex = new RegExp(escaped, \"g\");\n const matches = content.match(regex) || [];\n\n if (matches.length % 2 === 0) {\n return false; // All paired\n }\n\n // Find the last occurrence of the marker - there should be content after it\n const lastIndex = content.lastIndexOf(marker);\n if (lastIndex === -1) {\n return false;\n }\n\n // Check if there's actual content after the marker\n const afterMarker = content.slice(lastIndex + marker.length);\n return afterMarker.length > 0;\n}\n\n/**\n * Checks if there's an unpaired strikethrough with content after the last opener.\n */\nfunction hasUnpairedStrikethroughWithContent(content: string): boolean {\n const matches = content.match(/~~/g) || [];\n\n if (matches.length % 2 === 0) {\n return false; // All paired\n }\n\n // Find the last occurrence - there should be content after it\n const lastIndex = content.lastIndexOf(\"~~\");\n if (lastIndex === -1) {\n return false;\n }\n\n const afterMarker = content.slice(lastIndex + 2);\n return afterMarker.length > 0;\n}\n\n/**\n * Checks if a marker at position i is a list marker (at start of line followed by space).\n */\nfunction isListMarker(content: string, i: number, marker: string): boolean {\n // Only * can be a list marker (not _)\n if (marker !== \"*\") {\n return false;\n }\n\n // Check if at start of line (or start of content)\n const isStartOfLine = i === 0 || content[i - 1] === \"\\n\";\n // Check if followed by space\n const followedBySpace = i < content.length - 1 && content[i + 1] === \" \";\n\n return isStartOfLine && followedBySpace;\n}\n\n/**\n * Checks if there's an unpaired single italic marker (* or _) that needs closing.\n * Must distinguish from bold markers (** or __) and list markers (* ).\n *\n * Returns true if:\n * - There's an odd number of single markers (not part of double markers or list markers)\n * - Either there's content after the last marker, OR the content ends with the marker\n */\nfunction hasUnpairedItalicWithContent(content: string, marker: string): boolean {\n // Count single markers (not part of double markers or list markers)\n let singleCount = 0;\n let lastSingleIndex = -1;\n\n for (let i = 0; i < content.length; i++) {\n if (content[i] === marker) {\n // Check if it's a list marker\n if (isListMarker(content, i, marker)) {\n continue;\n }\n\n // Check if it's part of a double marker\n const prevIsMarker = i > 0 && content[i - 1] === marker;\n const nextIsMarker = i < content.length - 1 && content[i + 1] === marker;\n\n if (prevIsMarker || nextIsMarker) {\n // Part of ** or __, skip\n if (nextIsMarker) {\n i++; // Skip the next one too\n }\n continue;\n }\n\n singleCount++;\n lastSingleIndex = i;\n }\n }\n\n if (singleCount % 2 === 0) {\n return false; // All paired\n }\n\n if (lastSingleIndex === -1) {\n return false;\n }\n\n // If content ends with the marker, it's an opener that needs closing\n // (e.g., \"*text* more *\" - the last * is a new opener)\n // BUT only if there's content before it (not just a lone marker)\n if (lastSingleIndex === content.length - 1) {\n // Must have content before the marker for it to be a meaningful opener\n return lastSingleIndex > 0;\n }\n\n // Otherwise, check if there's content after the last unpaired marker\n const afterMarker = content.slice(lastSingleIndex + 1);\n return afterMarker.length > 0;\n}\n\n/**\n * Checks if content has an unclosed code block.\n * Returns true if the last ``` opens a block that isn't closed.\n */\nfunction hasUnclosedCodeBlock(content: string): boolean {\n // Find all ``` occurrences\n const fenceRegex = /```/g;\n const matches: number[] = [];\n let match;\n\n while ((match = fenceRegex.exec(content)) !== null) {\n matches.push(match.index);\n }\n\n // Odd number of fences means unclosed\n return matches.length % 2 === 1;\n}\n\n/**\n * Completes unterminated markdown syntax at the end of content.\n * This allows streaming markdown to be parsed correctly even when syntax is incomplete.\n *\n * Handles:\n * - Headings (# Heading)\n * - Inline code (`code)\n * - Bold (**text or __text)\n * - Italic (*text or _text)\n * - Links ([text](url or [text]()\n * - Code blocks (```language\\ncode)\n * - Lists (- item or * item or 1. item)\n * - Blockquotes (> text)\n * - Strikethrough (~~text)\n */\nexport function completeUnterminatedMarkdown(content: string): string {\n if (!content.trim()) {\n return content;\n }\n\n // Work backwards from the end to find the last incomplete markdown pattern\n const trimmed = content.trimEnd();\n const trailingWhitespace = content.slice(trimmed.length);\n let result = trimmed;\n\n // Check for incomplete code fence without newline yet (e.g., \"```python\" with no \\n)\n // This must come before the code block check\n const incompleteFenceMatch = result.match(/```[\\w-]*$/);\n if (incompleteFenceMatch && !result.includes(\"```\\n\") && !result.match(/```[\\w-]+\\n/)) {\n // Code fence just started, hasn't gotten content yet - add newline and closing\n result += \"\\n```\";\n return result + trailingWhitespace;\n }\n\n // Check for incomplete code blocks using fence counting\n if (hasUnclosedCodeBlock(result)) {\n result += \"\\n```\";\n return result + trailingWhitespace;\n }\n\n // Check for incomplete inline code (backticks)\n // Count backticks that are NOT part of code fences\n // First, remove all code fence markers to count only inline backticks\n const withoutFences = result.replace(/```[\\w-]*/g, \"\");\n const backtickCount = (withoutFences.match(/`/g) || []).length;\n if (backtickCount % 2 === 1) {\n result += \"`\";\n return result + trailingWhitespace;\n }\n\n // Check for incomplete links [text](url\n const linkMatch = result.match(/\\[([^\\]]*)\\]\\(([^)]*)$/);\n if (linkMatch) {\n // Incomplete link - close the URL part\n result += \")\";\n return result + trailingWhitespace;\n }\n\n // Check for incomplete bold (**text or __text)\n // Only complete if there's actual content after the marker\n if (hasUnpairedDoubleMarkerWithContent(result, \"**\")) {\n result += \"**\";\n return result + trailingWhitespace;\n }\n\n if (hasUnpairedDoubleMarkerWithContent(result, \"__\")) {\n result += \"__\";\n return result + trailingWhitespace;\n }\n\n // Check for incomplete strikethrough (~~text)\n if (hasUnpairedStrikethroughWithContent(result)) {\n result += \"~~\";\n return result + trailingWhitespace;\n }\n\n // Check structural elements BEFORE italic to avoid false positives\n // (e.g., \"* item\" is a list, not italic)\n const lines = result.split(\"\\n\");\n const lastLine = lines[lines.length - 1];\n\n // Check for incomplete headings (# Heading without newline)\n // Look for # at the start of the last line\n if (lastLine.match(/^#{1,6}\\s+.+$/)) {\n // Heading without trailing newline - add one for proper parsing\n result += \"\\n\";\n return result + trailingWhitespace;\n }\n\n // Check for incomplete list items (- item, * item, 1. item)\n // Look for list markers at the start of the last line\n if (lastLine.match(/^(\\s*)([-*+]|\\d+\\.)\\s+.+$/)) {\n // List item without trailing newline - add one for proper parsing\n result += \"\\n\";\n return result + trailingWhitespace;\n }\n\n // Check for incomplete blockquotes (> text)\n if (lastLine.match(/^>\\s+.+$/)) {\n // Blockquote without trailing newline - add one for proper parsing\n result += \"\\n\";\n return result + trailingWhitespace;\n }\n\n // Check for incomplete italic (*text or _text) AFTER structural elements\n // This prevents \"* item\" from being treated as italic\n if (hasUnpairedItalicWithContent(result, \"*\")) {\n result += \"*\";\n return result + trailingWhitespace;\n }\n\n if (hasUnpairedItalicWithContent(result, \"_\")) {\n result += \"_\";\n return result + trailingWhitespace;\n }\n\n return result + trailingWhitespace;\n}\n\n/**\n * Parses markdown content into blocks for efficient rendering.\n * Each block is a separate markdown token that can be memoized independently.\n *\n * @param content - The markdown content to parse\n * @param parser - Optional parser function (defaults to using marked.lexer)\n * @returns Array of markdown block strings\n */\nexport function parseMarkdownIntoBlocks(\n content: string,\n parser?: (content: string) => Array<{ raw?: string }>\n): string[] {\n if (!content.trim()) {\n return [];\n }\n\n // Complete unterminated markdown blocks for streaming support\n const completedContent = completeUnterminatedMarkdown(content);\n\n // If no parser provided, return the content as a single block\n // This allows usage without marked dependency\n if (!parser) {\n return [completedContent];\n }\n\n const tokens = parser(completedContent);\n return tokens\n .map((token) => {\n if (\"raw\" in token && typeof token.raw === \"string\") {\n return token.raw;\n }\n return \"\";\n })\n .filter((raw) => Boolean(raw.trim()));\n}\n\n"],
5
5
  "mappings": "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",
6
6
  "names": ["hasUnpairedDoubleMarkerWithContent", "content", "marker", "escaped", "regex", "lastIndex", "hasUnpairedStrikethroughWithContent", "isListMarker", "i", "isStartOfLine", "followedBySpace", "hasUnpairedItalicWithContent", "singleCount", "lastSingleIndex", "prevIsMarker", "nextIsMarker", "hasUnclosedCodeBlock", "fenceRegex", "matches", "match", "completeUnterminatedMarkdown", "trimmed", "trailingWhitespace", "result", "lines", "lastLine", "parseMarkdownIntoBlocks", "parser", "completedContent", "token", "raw"]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kushagradhawan/kookie-blocks",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/KushagraDhawan1997/kookie-blocks.git"
@@ -5,8 +5,8 @@ import { Copy01Icon, Tick01Icon, ArrowDown01Icon } from "@hugeicons/core-free-ic
5
5
  import { codeToHtml, type BundledLanguage, type BundledTheme } from "shiki";
6
6
  import type { CodeBlockProps, ShikiConfig, PreviewBackgroundProps } from "./types";
7
7
  import { extractTextFromChildren, extractLanguageFromChildren } from "./types";
8
- import { useCodeCard } from "./useCodeCard";
9
- import { LanguageBadge } from "./LanguageBadge";
8
+ import { useCodeCard } from "./use-code-card";
9
+ import { LanguageBadge } from "./language-badge";
10
10
 
11
11
  const CodeBlockContext = createContext<boolean>(false);
12
12
 
@@ -1,6 +1,6 @@
1
1
  // Public API
2
- export { CodeBlock, useCodeBlockContext } from "./CodeBlock";
3
- export { useCodeCard } from "./useCodeCard";
4
- export { LanguageBadge, formatLanguageForDisplay } from "./LanguageBadge";
2
+ export { CodeBlock, useCodeBlockContext } from "./code-block";
3
+ export { useCodeCard } from "./use-code-card";
4
+ export { LanguageBadge, formatLanguageForDisplay } from "./language-badge";
5
5
  export type { CodeBlockProps, ShikiConfig, PreviewBackgroundProps } from "./types";
6
6
  export { extractTextFromChildren, extractLanguageFromChildren, isReactElement } from "./types";
@@ -1 +1 @@
1
- export { Hero } from './Hero';
1
+ export { Hero } from './hero';
@@ -59,24 +59,24 @@ export function createMarkdownComponents(options: MarkdownComponentOptions = {})
59
59
  const { codeBlockCollapsible = false, imageComponent, inlineCodeHighContrast = true } = options;
60
60
 
61
61
  return {
62
- // Headings with consistent visual hierarchy
62
+ // Headings with consistent visual hierarchy (9-6-5-4-3-2)
63
63
  h1: ({ children }: MarkdownChildrenProps) => (
64
- <Heading size="8" weight="medium" as="h1" style={{ marginTop: "1rem", marginBottom: "0.5rem" }}>
64
+ <Heading size="9" weight="medium" as="h1" style={{ marginTop: "1rem", marginBottom: "0.5rem" }}>
65
65
  {children}
66
66
  </Heading>
67
67
  ),
68
68
  h2: ({ children }: MarkdownChildrenProps) => (
69
- <Heading weight="medium" size="5" as="h2" style={{ marginTop: "0.875rem", marginBottom: "0.5rem" }}>
69
+ <Heading weight="medium" size="6" as="h2" style={{ marginTop: "0.875rem", marginBottom: "0.5rem" }}>
70
70
  {children}
71
71
  </Heading>
72
72
  ),
73
73
  h3: ({ children }: MarkdownChildrenProps) => (
74
- <Heading weight="medium" size="4" as="h3" style={{ marginTop: "0.75rem", marginBottom: "0.5rem" }}>
74
+ <Heading weight="medium" size="5" as="h3" style={{ marginTop: "0.75rem", marginBottom: "0.5rem" }}>
75
75
  {children}
76
76
  </Heading>
77
77
  ),
78
78
  h4: ({ children }: MarkdownChildrenProps) => (
79
- <Heading weight="medium" size="3" as="h4" style={{ marginTop: "0.625rem", marginBottom: "0.5rem" }}>
79
+ <Heading weight="medium" size="4" as="h4" style={{ marginTop: "0.625rem", marginBottom: "0.5rem" }}>
80
80
  {children}
81
81
  </Heading>
82
82
  ),
@@ -86,7 +86,7 @@ export function createMarkdownComponents(options: MarkdownComponentOptions = {})
86
86
  </Heading>
87
87
  ),
88
88
  h6: ({ children }: MarkdownChildrenProps) => (
89
- <Heading weight="medium" size="3" as="h6" style={{ marginTop: "0.5rem", marginBottom: "0.5rem" }}>
89
+ <Heading weight="medium" size="2" as="h6" style={{ marginTop: "0.5rem", marginBottom: "0.5rem" }}>
90
90
  {children}
91
91
  </Heading>
92
92
  ),
@@ -203,4 +203,3 @@ export function createMarkdownComponents(options: MarkdownComponentOptions = {})
203
203
  summary: ({ children }: MarkdownChildrenProps) => <summary style={{ cursor: "pointer", fontWeight: 500 }}>{children}</summary>,
204
204
  };
205
205
  }
206
-
@@ -1,8 +1,7 @@
1
- export { StreamingMarkdown } from "./StreamingMarkdown";
2
- export type { StreamingMarkdownOptions } from "./StreamingMarkdown";
1
+ export { StreamingMarkdown } from "./streaming-markdown";
2
+ export type { StreamingMarkdownOptions } from "./streaming-markdown";
3
3
 
4
- export { createMarkdownComponents } from "./createMarkdownComponents";
4
+ export { createMarkdownComponents } from "./create-markdown-components";
5
5
  export type { MarkdownComponentOptions, MarkdownChildrenProps } from "./types";
6
6
 
7
- export { completeUnterminatedMarkdown, parseMarkdownIntoBlocks } from "./utils/markdownStreaming";
8
-
7
+ export { completeUnterminatedMarkdown, parseMarkdownIntoBlocks } from "./utils/markdown-streaming";
@@ -6,8 +6,8 @@ import remarkGfm from "remark-gfm";
6
6
  import rehypeRaw from "rehype-raw";
7
7
  import hardenReactMarkdown from "harden-react-markdown";
8
8
  import { Box, Flex } from "@kushagradhawan/kookie-ui";
9
- import { createMarkdownComponents } from "./createMarkdownComponents";
10
- import { completeUnterminatedMarkdown, parseMarkdownIntoBlocks } from "./utils/markdownStreaming";
9
+ import { createMarkdownComponents } from "./create-markdown-components";
10
+ import { completeUnterminatedMarkdown, parseMarkdownIntoBlocks } from "./utils/markdown-streaming";
11
11
  import type { MarkdownComponentOptions } from "./types";
12
12
 
13
13
  const HardenedMarkdown = hardenReactMarkdown(ReactMarkdown);
@@ -1 +0,0 @@
1
- {"version":3,"file":"CodeBlock.d.ts","sourceRoot":"","sources":["../../../../src/components/code/CodeBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwF,MAAM,OAAO,CAAC;AAK7G,OAAO,KAAK,EAAE,cAAc,EAAuC,MAAM,SAAS,CAAC;AA2RnF,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,QAAe,EACf,YAAmB,EACnB,eAAsB,EACtB,WAAW,EACX,UAAU,EACV,eAAe,EACf,WAAkB,EAClB,eAA0C,EAC1C,IAAI,GACL,EAAE,cAAc,qBA2ChB;AAED,wBAAgB,mBAAmB,YAElC"}
@@ -1,2 +0,0 @@
1
- "use strict";var I=Object.create;var y=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var _=Object.getOwnPropertyNames;var z=Object.getPrototypeOf,D=Object.prototype.hasOwnProperty;var $=(r,o)=>{for(var t in o)y(r,t,{get:o[t],enumerable:!0})},S=(r,o,t,s)=>{if(o&&typeof o=="object"||typeof o=="function")for(let l of _(o))!D.call(r,l)&&l!==t&&y(r,l,{get:()=>o[l],enumerable:!(s=A(o,l))||s.enumerable});return r};var M=(r,o,t)=>(t=r!=null?I(z(r)):{},S(o||!r||!r.__esModule?y(t,"default",{value:r,enumerable:!0}):t,r)),W=r=>S(y({},"__esModule",{value:!0}),r);var X={};$(X,{CodeBlock:()=>J,useCodeBlockContext:()=>Q});module.exports=W(X);var e=M(require("react")),n=require("@kushagradhawan/kookie-ui"),w=require("@hugeicons/react"),f=require("@hugeicons/core-free-icons"),B=require("shiki"),x=require("./types"),v=require("./useCodeCard"),T=require("./LanguageBadge");const L=(0,e.createContext)(!1),O=360,U="one-light",j="one-dark-pro";function G({children:r,background:o="none",backgroundProps:t={}}){const{dotSize:s=24,color:l="var(--gray-10)",backgroundColor:c="var(--gray-2)",height:i,width:u="100%",radius:d="3"}=t,a=(0,e.useMemo)(()=>{if(o!=="none")return o==="dots"?{backgroundImage:`radial-gradient(circle, ${l} 1px, transparent 1px)`,borderRadius:`var(--radius-${d})`,backgroundSize:`${s}px ${s}px`,backgroundPosition:"center",backgroundColor:c,width:u,...i&&{height:i}}:{backgroundImage:`url(${o})`,backgroundSize:"cover",backgroundPosition:"center",backgroundRepeat:"no-repeat",borderRadius:`var(--radius-${d})`,width:u,...i&&{height:i}}},[o,l,c,s,i,u,d]);return e.default.createElement(n.Card,{size:"1",variant:"soft"},e.default.createElement(n.Flex,{justify:"center",align:"center",py:"4",style:a},e.default.createElement(n.Theme,{fontFamily:"sans"},r)))}function K(){return e.default.createElement(n.Box,{className:"code-skeleton"},["85%","70%","90%","60%","75%","80%"].map((o,t)=>e.default.createElement(n.Box,{key:t,className:"code-skeleton-line",style:{width:o}})))}const P=(0,e.memo)(function({code:o,language:t,showCopy:s,showLanguage:l,showLineNumbers:c,collapsible:i,collapsedHeight:u,file:d,isLoading:a=!1,children:p}){const{isExpanded:g,shouldShowToggle:h,copied:C,contentRef:m,contentMaxHeight:b,handleToggle:N,handleCopy:H}=(0,v.useCodeCard)({code:o,collapsedHeight:u}),k=i&&h,E=g?"rotate(180deg)":"rotate(0deg)",F=c?"code-content":"code-content hide-line-numbers";return e.default.createElement(n.Box,{position:"relative"},e.default.createElement(n.Card,{size:"1",variant:"soft"},e.default.createElement(n.Flex,{direction:"column"},e.default.createElement(n.Flex,{justify:"between",align:"start",gap:"2"},e.default.createElement(n.Flex,{align:"center",gap:"2"},l&&e.default.createElement(T.LanguageBadge,{language:t}),d&&e.default.createElement(n.Text,{size:"1",color:"gray",highContrast:!0},d)),e.default.createElement(n.Flex,{align:"center",className:"code-action-buttons"},k&&e.default.createElement(n.IconButton,{size:"2",variant:"ghost",color:"gray",onClick:N,tooltip:g?"Collapse":"Expand","aria-label":g?"Collapse code":"Expand code"},e.default.createElement(w.HugeiconsIcon,{icon:f.ArrowDown01Icon,style:{transform:E},className:"code-chevron",strokeWidth:1.75})),s&&e.default.createElement(n.Button,{size:"2",variant:"ghost",color:"gray",onClick:H,tooltip:C?"Copied!":"Copy","aria-label":C?"Copied!":"Copy code"},e.default.createElement(w.HugeiconsIcon,{icon:C?f.Tick01Icon:f.Copy01Icon,strokeWidth:1.75})," Copy"))),e.default.createElement(n.Box,{ref:m,style:{maxHeight:i?`${b}px`:void 0},className:F},e.default.createElement(n.ScrollArea,{type:"auto",scrollbars:"horizontal"},a?e.default.createElement(K,null):p)),k&&!g&&e.default.createElement(n.Box,{className:"code-scroll-shadow visible"}))))}),V=(0,e.memo)(function({code:o,language:t,showCopy:s,showLanguage:l,showLineNumbers:c,collapsible:i,collapsedHeight:u,file:d,shikiConfig:a}){const[p,g]=(0,e.useState)(null),h=(0,e.useMemo)(()=>{const m=a?.themes?.light||U,b=a?.themes?.dark||j;return{lang:t,themes:{light:m,dark:b},defaultColor:!1,langAlias:a?.langAlias,transformers:a?.transformers,meta:a?.meta?{__raw:a.meta}:void 0}},[t,a?.themes?.light,a?.themes?.dark,a?.langAlias,a?.transformers,a?.meta]);return(0,e.useEffect)(()=>{let m=!1;return(0,B.codeToHtml)(o,h).then(b=>{m||g(b)}).catch(b=>{}),()=>{m=!0}},[o,h]),e.default.createElement(P,{code:o,language:t,showCopy:s,showLanguage:l,showLineNumbers:c,collapsible:i,collapsedHeight:u,file:d,isLoading:p===null},p?e.default.createElement(n.Box,{dangerouslySetInnerHTML:{__html:p}}):null)}),q=(0,e.memo)(function({children:o,showCopy:t,showLanguage:s,showLineNumbers:l,collapsible:c,collapsedHeight:i,file:u}){const d=(0,x.extractTextFromChildren)(o),a=(0,x.extractLanguageFromChildren)(o);return e.default.createElement(P,{code:d,language:a,showCopy:t,showLanguage:s,showLineNumbers:l,collapsible:c,collapsedHeight:i,file:u},o)});function J({children:r,code:o,language:t,preview:s,showCopy:l=!0,showLanguage:c=!0,showLineNumbers:i=!0,shikiConfig:u,background:d,backgroundProps:a,collapsible:p=!0,collapsedHeight:g=O,file:h}){const C=t||(0,x.extractLanguageFromChildren)(r)||"text";return e.default.createElement(L.Provider,{value:!0},e.default.createElement(n.Box,{className:"docs-code-block",mt:"6",mb:"8"},e.default.createElement(n.Flex,{direction:"column",gap:"2"},s&&e.default.createElement(G,{background:d,backgroundProps:a},s),o&&e.default.createElement(V,{code:o,language:C,showCopy:l,showLanguage:c,showLineNumbers:i,collapsible:p,collapsedHeight:g,file:h,shikiConfig:u}),r&&!o&&e.default.createElement(q,{showCopy:l,showLanguage:c,showLineNumbers:i,collapsible:p,collapsedHeight:g,file:h},r))))}function Q(){return(0,e.useContext)(L)}
2
- //# sourceMappingURL=CodeBlock.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/components/code/CodeBlock.tsx"],
4
- "sourcesContent": ["import React, { useState, useEffect, useMemo, memo, createContext, useContext, type ReactNode } from \"react\";\nimport { Box, Card, Code, Flex, Button, Text, Theme, ScrollArea, IconButton } from \"@kushagradhawan/kookie-ui\";\nimport { HugeiconsIcon } from \"@hugeicons/react\";\nimport { Copy01Icon, Tick01Icon, ArrowDown01Icon } from \"@hugeicons/core-free-icons\";\nimport { codeToHtml, type BundledLanguage, type BundledTheme } from \"shiki\";\nimport type { CodeBlockProps, ShikiConfig, PreviewBackgroundProps } from \"./types\";\nimport { extractTextFromChildren, extractLanguageFromChildren } from \"./types\";\nimport { useCodeCard } from \"./useCodeCard\";\nimport { LanguageBadge } from \"./LanguageBadge\";\n\nconst CodeBlockContext = createContext<boolean>(false);\n\nconst DEFAULT_COLLAPSED_HEIGHT = 360;\nconst DEFAULT_LIGHT_THEME = \"one-light\";\nconst DEFAULT_DARK_THEME = \"one-dark-pro\";\n\ninterface PreviewSectionProps {\n children: ReactNode;\n background?: \"none\" | \"dots\" | string;\n backgroundProps?: PreviewBackgroundProps;\n}\n\nfunction PreviewSection({ children, background = \"none\", backgroundProps = {} }: PreviewSectionProps) {\n const { dotSize = 24, color = \"var(--gray-10)\", backgroundColor = \"var(--gray-2)\", height, width = \"100%\", radius = \"3\" } = backgroundProps;\n\n const backgroundStyle = useMemo((): React.CSSProperties | undefined => {\n if (background === \"none\") return undefined;\n\n if (background === \"dots\") {\n return {\n backgroundImage: `radial-gradient(circle, ${color} 1px, transparent 1px)`,\n borderRadius: `var(--radius-${radius})`,\n backgroundSize: `${dotSize}px ${dotSize}px`,\n backgroundPosition: \"center\",\n backgroundColor,\n width,\n ...(height && { height }),\n };\n }\n\n // Image background\n return {\n backgroundImage: `url(${background})`,\n backgroundSize: \"cover\",\n backgroundPosition: \"center\",\n backgroundRepeat: \"no-repeat\",\n borderRadius: `var(--radius-${radius})`,\n width,\n ...(height && { height }),\n };\n }, [background, color, backgroundColor, dotSize, height, width, radius]);\n\n return (\n <Card size=\"1\" variant=\"soft\">\n <Flex justify=\"center\" align=\"center\" py=\"4\" style={backgroundStyle}>\n <Theme fontFamily=\"sans\">{children}</Theme>\n </Flex>\n </Card>\n );\n}\n\ninterface CodeCardProps {\n code: string;\n language: string;\n showCopy: boolean;\n showLanguage: boolean;\n showLineNumbers: boolean;\n collapsible: boolean;\n collapsedHeight: number;\n file?: string;\n isLoading?: boolean;\n children: ReactNode;\n}\n\nfunction CodeSkeleton() {\n // Generate varied line widths for visual interest\n const lineWidths = [\"85%\", \"70%\", \"90%\", \"60%\", \"75%\", \"80%\"];\n\n return (\n <Box className=\"code-skeleton\">\n {lineWidths.map((width, index) => (\n <Box key={index} className=\"code-skeleton-line\" style={{ width }} />\n ))}\n </Box>\n );\n}\n\nconst CodeCard = memo(function CodeCard({\n code,\n language,\n showCopy,\n showLanguage,\n showLineNumbers,\n collapsible,\n collapsedHeight,\n file,\n isLoading = false,\n children,\n}: CodeCardProps) {\n const { isExpanded, shouldShowToggle, copied, contentRef, contentMaxHeight, handleToggle, handleCopy } = useCodeCard({\n code,\n collapsedHeight,\n });\n\n const showToggle = collapsible && shouldShowToggle;\n const chevronRotation = isExpanded ? \"rotate(180deg)\" : \"rotate(0deg)\";\n const contentClassName = showLineNumbers ? \"code-content\" : \"code-content hide-line-numbers\";\n\n return (\n <Box position=\"relative\">\n <Card size=\"1\" variant=\"soft\">\n <Flex direction=\"column\">\n <Flex justify=\"between\" align=\"start\" gap=\"2\">\n <Flex align=\"center\" gap=\"2\">\n {showLanguage && <LanguageBadge language={language} />}\n {file && (\n <Text size=\"1\" color=\"gray\" highContrast>\n {file}\n </Text>\n )}\n </Flex>\n\n <Flex align=\"center\" className=\"code-action-buttons\">\n {showToggle && (\n <IconButton\n size=\"2\"\n variant=\"ghost\"\n color=\"gray\"\n onClick={handleToggle}\n tooltip={isExpanded ? \"Collapse\" : \"Expand\"}\n aria-label={isExpanded ? \"Collapse code\" : \"Expand code\"}\n >\n <HugeiconsIcon icon={ArrowDown01Icon} style={{ transform: chevronRotation }} className=\"code-chevron\" strokeWidth={1.75} />\n </IconButton>\n )}\n {showCopy && (\n <Button\n size=\"2\"\n variant=\"ghost\"\n color=\"gray\"\n onClick={handleCopy}\n tooltip={copied ? \"Copied!\" : \"Copy\"}\n aria-label={copied ? \"Copied!\" : \"Copy code\"}\n >\n <HugeiconsIcon icon={copied ? Tick01Icon : Copy01Icon} strokeWidth={1.75} /> Copy\n </Button>\n )}\n </Flex>\n </Flex>\n\n <Box ref={contentRef} style={{ maxHeight: collapsible ? `${contentMaxHeight}px` : undefined }} className={contentClassName}>\n <ScrollArea type=\"auto\" scrollbars=\"horizontal\">\n {isLoading ? <CodeSkeleton /> : children}\n </ScrollArea>\n </Box>\n\n {showToggle && !isExpanded && <Box className=\"code-scroll-shadow visible\" />}\n </Flex>\n </Card>\n </Box>\n );\n});\n\ninterface RuntimeCodeSectionProps {\n code: string;\n language: string;\n showCopy: boolean;\n showLanguage: boolean;\n showLineNumbers: boolean;\n collapsible: boolean;\n collapsedHeight: number;\n file?: string;\n shikiConfig?: ShikiConfig;\n}\n\nconst RuntimeCodeSection = memo(function RuntimeCodeSection({\n code,\n language,\n showCopy,\n showLanguage,\n showLineNumbers,\n collapsible,\n collapsedHeight,\n file,\n shikiConfig,\n}: RuntimeCodeSectionProps) {\n const [highlighted, setHighlighted] = useState<string | null>(null);\n\n // Memoize Shiki config to prevent unnecessary re-highlights\n const shikiOptions = useMemo(() => {\n const lightTheme = shikiConfig?.themes?.light || DEFAULT_LIGHT_THEME;\n const darkTheme = shikiConfig?.themes?.dark || DEFAULT_DARK_THEME;\n\n return {\n lang: language as BundledLanguage,\n themes: {\n light: lightTheme as BundledTheme,\n dark: darkTheme as BundledTheme,\n },\n defaultColor: false as const,\n langAlias: shikiConfig?.langAlias,\n transformers: shikiConfig?.transformers,\n meta: shikiConfig?.meta ? { __raw: shikiConfig.meta } : undefined,\n };\n }, [language, shikiConfig?.themes?.light, shikiConfig?.themes?.dark, shikiConfig?.langAlias, shikiConfig?.transformers, shikiConfig?.meta]);\n\n useEffect(() => {\n let cancelled = false;\n\n codeToHtml(code, shikiOptions)\n .then((html) => {\n if (!cancelled) {\n setHighlighted(html);\n }\n })\n .catch((error) => {\n if (!cancelled) {\n // Keep previous highlighted content on error (stale while revalidate)\n if (process.env.NODE_ENV === \"development\") {\n console.error(\"[CodeBlock] Shiki highlighting failed:\", error);\n }\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [code, shikiOptions]);\n\n // Only show loading skeleton on initial render (no highlighted content yet)\n // During updates, keep showing previous highlighted content (stale while revalidate)\n const isInitialLoading = highlighted === null;\n\n return (\n <CodeCard\n code={code}\n language={language}\n showCopy={showCopy}\n showLanguage={showLanguage}\n showLineNumbers={showLineNumbers}\n collapsible={collapsible}\n collapsedHeight={collapsedHeight}\n file={file}\n isLoading={isInitialLoading}\n >\n {highlighted ? <Box dangerouslySetInnerHTML={{ __html: highlighted }} /> : null}\n </CodeCard>\n );\n});\n\ninterface ChildrenCodeSectionProps {\n children: ReactNode;\n showCopy: boolean;\n showLanguage: boolean;\n showLineNumbers: boolean;\n collapsible: boolean;\n collapsedHeight: number;\n file?: string;\n}\n\nconst ChildrenCodeSection = memo(function ChildrenCodeSection({\n children,\n showCopy,\n showLanguage,\n showLineNumbers,\n collapsible,\n collapsedHeight,\n file,\n}: ChildrenCodeSectionProps) {\n const code = extractTextFromChildren(children);\n const language = extractLanguageFromChildren(children);\n\n return (\n <CodeCard\n code={code}\n language={language}\n showCopy={showCopy}\n showLanguage={showLanguage}\n showLineNumbers={showLineNumbers}\n collapsible={collapsible}\n collapsedHeight={collapsedHeight}\n file={file}\n >\n {children}\n </CodeCard>\n );\n});\n\nexport function CodeBlock({\n children,\n code,\n language,\n preview,\n showCopy = true,\n showLanguage = true,\n showLineNumbers = true,\n shikiConfig,\n background,\n backgroundProps,\n collapsible = true,\n collapsedHeight = DEFAULT_COLLAPSED_HEIGHT,\n file,\n}: CodeBlockProps) {\n const displayLanguage = language || extractLanguageFromChildren(children) || \"text\";\n\n return (\n <CodeBlockContext.Provider value={true}>\n <Box className=\"docs-code-block\" mt=\"6\" mb=\"8\">\n <Flex direction=\"column\" gap=\"2\">\n {preview && (\n <PreviewSection background={background} backgroundProps={backgroundProps}>\n {preview}\n </PreviewSection>\n )}\n\n {code && (\n <RuntimeCodeSection\n code={code}\n language={displayLanguage}\n showCopy={showCopy}\n showLanguage={showLanguage}\n showLineNumbers={showLineNumbers}\n collapsible={collapsible}\n collapsedHeight={collapsedHeight}\n file={file}\n shikiConfig={shikiConfig}\n />\n )}\n\n {children && !code && (\n <ChildrenCodeSection\n showCopy={showCopy}\n showLanguage={showLanguage}\n showLineNumbers={showLineNumbers}\n collapsible={collapsible}\n collapsedHeight={collapsedHeight}\n file={file}\n >\n {children}\n </ChildrenCodeSection>\n )}\n </Flex>\n </Box>\n </CodeBlockContext.Provider>\n );\n}\n\nexport function useCodeBlockContext() {\n return useContext(CodeBlockContext);\n}\n"],
5
- "mappings": "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",
6
- "names": ["CodeBlock_exports", "__export", "CodeBlock", "useCodeBlockContext", "__toCommonJS", "import_react", "import_kookie_ui", "import_core_free_icons", "import_shiki", "import_types", "import_useCodeCard", "import_LanguageBadge", "CodeBlockContext", "DEFAULT_COLLAPSED_HEIGHT", "DEFAULT_LIGHT_THEME", "DEFAULT_DARK_THEME", "PreviewSection", "children", "background", "backgroundProps", "dotSize", "color", "backgroundColor", "height", "width", "radius", "backgroundStyle", "React", "CodeSkeleton", "index", "CodeCard", "code", "language", "showCopy", "showLanguage", "showLineNumbers", "collapsible", "collapsedHeight", "file", "isLoading", "isExpanded", "shouldShowToggle", "copied", "contentRef", "contentMaxHeight", "handleToggle", "handleCopy", "showToggle", "chevronRotation", "contentClassName", "RuntimeCodeSection", "shikiConfig", "highlighted", "setHighlighted", "shikiOptions", "lightTheme", "darkTheme", "cancelled", "html", "error", "ChildrenCodeSection", "preview", "displayLanguage"]
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"CopyButton.d.ts","sourceRoot":"","sources":["../../../../src/components/code/CopyButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAKxE,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,EAAE,eAAe,qBAoCnD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"LanguageBadge.d.ts","sourceRoot":"","sources":["../../../../src/components/code/LanguageBadge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAsD1B;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7D;AAED,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE,kBAAkB,qBAQ7D"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"PreviewSection.d.ts","sourceRoot":"","sources":["../../../../src/components/code/PreviewSection.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG9C,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,SAAS,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACtC,eAAe,CAAC,EAAE;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,UAAmB,EAAE,eAAoB,EAAE,EAAE,mBAAmB,qBAqD1G"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"SyntaxHighlighter.d.ts","sourceRoot":"","sources":["../../../../src/components/code/SyntaxHighlighter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAInD,UAAU,sBAAsB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAKD,wBAAgB,iBAAiB,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAgC,EAAE,SAA8B,EAAE,EAAE,sBAAsB,qBAuC7I"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"useCodeCard.d.ts","sourceRoot":"","sources":["../../../../src/components/code/useCodeCard.ts"],"names":[],"mappings":"AAIA,UAAU,kBAAkB;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,iBAAiB;IACzB,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACnD,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,kBAAkB,GAAG,iBAAiB,CA0D5F"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"StreamingMarkdown.d.ts","sourceRoot":"","sources":["../../../../src/components/markdown/StreamingMarkdown.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAwC,MAAM,OAAO,CAAC;AAC7D,OAAsB,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAOhE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AASxD;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG,wBAAwB,GAAG;IAChE;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,KAAK,CAAC;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAE3D;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;CAClC,CAAC;AAEF,KAAK,sBAAsB,GAAG;IAC5B;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,OAAO,CAAC,EAAE,wBAAwB,CAAC;CACpC,CAAC;AA6CF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,OAAY,EAAE,EAAE,sBAAsB,4BA2CtF"}
@@ -1,2 +0,0 @@
1
- "use strict";"use client";var B=Object.create;var m=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var E=Object.getPrototypeOf,x=Object.prototype.hasOwnProperty;var L=(o,n)=>{for(var t in n)m(o,t,{get:n[t],enumerable:!0})},M=(o,n,t,i)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of S(n))!x.call(o,r)&&r!==t&&m(o,r,{get:()=>n[r],enumerable:!(i=I(n,r))||i.enumerable});return o};var s=(o,n,t)=>(t=o!=null?B(E(o)):{},M(n||!o||!o.__esModule?m(t,"default",{value:o,enumerable:!0}):t,o)),A=o=>M(m({},"__esModule",{value:!0}),o);var H={};L(H,{StreamingMarkdown:()=>z});module.exports=A(H);var e=s(require("react")),O=s(require("react-markdown")),P=s(require("remark-gfm")),h=s(require("rehype-raw")),y=s(require("harden-react-markdown")),l=require("@kushagradhawan/kookie-ui"),C=require("./createMarkdownComponents"),d=require("./utils/markdownStreaming");const F=(0,y.default)(O.default),_=["https://","http://","/"],D=["https://","http://","/","data:"],N=["mailto:","tel:","data:","http:","https:"],R=typeof window<"u"&&window.location?.origin?window.location.origin:"https://app.kookie.ai";function G(o){return o||R}const k=(0,e.memo)(({content:o,defaultOrigin:n,components:t})=>e.default.createElement(l.Box,{width:"100%"},e.default.createElement(F,{defaultOrigin:n,allowedLinkPrefixes:_,allowedImagePrefixes:D,allowedProtocols:N,allowDataImages:!0,components:t,remarkPlugins:[P.default],rehypePlugins:[h.default]},o)),(o,n)=>o.content===n.content&&o.defaultOrigin===n.defaultOrigin&&o.components===n.components);k.displayName="MarkdownBlock";function z({content:o,id:n,options:t={}}){const{defaultOrigin:i,enableBlockMemoization:r=!0,blockParser:c,components:g={},...w}=t,f=(0,e.useMemo)(()=>G(i),[i]),u=(0,e.useMemo)(()=>({...(0,C.createMarkdownComponents)(w),...g}),[w,g]),p=(0,e.useMemo)(()=>{if(!r||!c){const a=(0,d.completeUnterminatedMarkdown)(o);return a.trim()?[a]:[]}return(0,d.parseMarkdownIntoBlocks)(o,c)},[o,r,c]);return p.length?p.length===1?e.default.createElement(k,{content:p[0],defaultOrigin:f,components:u}):e.default.createElement(l.Flex,{direction:"column",gap:"2",width:"100%"},p.map((a,b)=>e.default.createElement(k,{key:`${n}-block-${b}`,content:a,defaultOrigin:f,components:u}))):null}
2
- //# sourceMappingURL=StreamingMarkdown.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/components/markdown/StreamingMarkdown.tsx"],
4
- "sourcesContent": ["\"use client\";\n\nimport React, { memo, useMemo, type ReactNode } from \"react\";\nimport ReactMarkdown, { type Components } from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport rehypeRaw from \"rehype-raw\";\nimport hardenReactMarkdown from \"harden-react-markdown\";\nimport { Box, Flex } from \"@kushagradhawan/kookie-ui\";\nimport { createMarkdownComponents } from \"./createMarkdownComponents\";\nimport { completeUnterminatedMarkdown, parseMarkdownIntoBlocks } from \"./utils/markdownStreaming\";\nimport type { MarkdownComponentOptions } from \"./types\";\n\nconst HardenedMarkdown = hardenReactMarkdown(ReactMarkdown);\n\nconst LINK_PREFIXES = [\"https://\", \"http://\", \"/\"];\nconst IMAGE_PREFIXES = [\"https://\", \"http://\", \"/\", \"data:\"];\nconst ALLOWED_PROTOCOLS = [\"mailto:\", \"tel:\", \"data:\", \"http:\", \"https:\"];\nconst DEFAULT_APP_ORIGIN = typeof window !== \"undefined\" && window.location?.origin ? window.location.origin : \"https://app.kookie.ai\";\n\n/**\n * Options for StreamingMarkdown component\n */\nexport type StreamingMarkdownOptions = MarkdownComponentOptions & {\n /**\n * Security origin for link/image validation\n * @default window.location.origin or \"https://app.kookie.ai\"\n */\n defaultOrigin?: string;\n\n /**\n * Whether to enable block-level memoization for performance\n * Recommended for streaming scenarios where content updates frequently\n * @default true\n */\n enableBlockMemoization?: boolean;\n\n /**\n * Custom parser for splitting content into blocks\n * If not provided, content will be rendered as a single block\n * For optimal streaming performance, use marked.lexer with GFM enabled\n */\n blockParser?: (content: string) => Array<{ raw?: string }>;\n\n /**\n * Override default component mappings\n */\n components?: Partial<Components>;\n};\n\ntype StreamingMarkdownProps = {\n /**\n * Markdown content to render (supports streaming/incomplete markdown)\n */\n content: string;\n\n /**\n * Unique identifier for this markdown instance (used for keys)\n */\n id: string;\n\n /**\n * Optional configuration\n */\n options?: StreamingMarkdownOptions;\n};\n\ntype MarkdownBlockProps = {\n content: string;\n defaultOrigin: string;\n components: Components;\n};\n\n/**\n * Resolves the default origin for security validation\n */\nfunction resolveDefaultOrigin(customOrigin?: string): string {\n if (customOrigin) {\n return customOrigin;\n }\n return DEFAULT_APP_ORIGIN;\n}\n\n/**\n * Memoized markdown block component for efficient streaming rendering\n */\nconst MarkdownBlock = memo(\n ({ content, defaultOrigin, components }: MarkdownBlockProps) => {\n return (\n <Box width=\"100%\">\n <HardenedMarkdown\n defaultOrigin={defaultOrigin}\n allowedLinkPrefixes={LINK_PREFIXES}\n allowedImagePrefixes={IMAGE_PREFIXES}\n allowedProtocols={ALLOWED_PROTOCOLS}\n allowDataImages\n components={components}\n remarkPlugins={[remarkGfm]}\n rehypePlugins={[rehypeRaw]}\n >\n {content}\n </HardenedMarkdown>\n </Box>\n );\n },\n (previous, next) => previous.content === next.content && previous.defaultOrigin === next.defaultOrigin && previous.components === next.components\n);\n\nMarkdownBlock.displayName = \"MarkdownBlock\";\n\n/**\n * StreamingMarkdown - A drop-in markdown renderer designed for AI streaming.\n *\n * Features:\n * - Unterminated block parsing (handles incomplete markdown during streaming)\n * - Block-level memoization for performance\n * - Security hardening (validates links/images)\n * - GitHub Flavored Markdown support\n * - KookieUI component integration\n * - Code syntax highlighting via CodeBlock\n *\n * @example\n * ```tsx\n * import { StreamingMarkdown } from '@kushagradhawan/kookie-blocks';\n * import { marked } from 'marked';\n *\n * function ChatMessage({ message }) {\n * return (\n * <StreamingMarkdown\n * content={message.content}\n * id={message.id}\n * options={{\n * blockParser: (content) => marked.lexer(content, { gfm: true }),\n * enableBlockMemoization: true,\n * }}\n * />\n * );\n * }\n * ```\n */\nexport function StreamingMarkdown({ content, id, options = {} }: StreamingMarkdownProps) {\n const { defaultOrigin: customOrigin, enableBlockMemoization = true, blockParser, components: customComponents = {}, ...componentOptions } = options;\n\n // Resolve security origin\n const defaultOrigin = useMemo(() => resolveDefaultOrigin(customOrigin), [customOrigin]);\n\n // Create component mappings with custom overrides\n const markdownComponents = useMemo(() => {\n const baseComponents = createMarkdownComponents(componentOptions);\n return {\n ...baseComponents,\n ...customComponents,\n };\n }, [componentOptions, customComponents]);\n\n // Parse content into blocks for memoization (if enabled and parser provided)\n const blocks = useMemo(() => {\n if (!enableBlockMemoization || !blockParser) {\n // No block splitting - just complete unterminated markdown\n const completed = completeUnterminatedMarkdown(content);\n return completed.trim() ? [completed] : [];\n }\n\n return parseMarkdownIntoBlocks(content, blockParser);\n }, [content, enableBlockMemoization, blockParser]);\n\n if (!blocks.length) {\n return null;\n }\n\n // Single block - no need for wrapper\n if (blocks.length === 1) {\n return <MarkdownBlock content={blocks[0]} defaultOrigin={defaultOrigin} components={markdownComponents} />;\n }\n\n // Multiple blocks - render with flex wrapper\n return (\n <Flex direction=\"column\" gap=\"2\" width=\"100%\">\n {blocks.map((block, index) => (\n <MarkdownBlock key={`${id}-block-${index}`} content={block} defaultOrigin={defaultOrigin} components={markdownComponents} />\n ))}\n </Flex>\n );\n}\n"],
5
- "mappings": "ukBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,uBAAAE,IAAA,eAAAC,EAAAH,GAEA,IAAAI,EAAqD,oBACrDC,EAA+C,6BAC/CC,EAAsB,yBACtBC,EAAsB,yBACtBC,EAAgC,oCAChCC,EAA0B,qCAC1BC,EAAyC,sCACzCC,EAAsE,qCAGtE,MAAMC,KAAmB,EAAAC,SAAoB,EAAAC,OAAa,EAEpDC,EAAgB,CAAC,WAAY,UAAW,GAAG,EAC3CC,EAAiB,CAAC,WAAY,UAAW,IAAK,OAAO,EACrDC,EAAoB,CAAC,UAAW,OAAQ,QAAS,QAAS,QAAQ,EAClEC,EAAqB,OAAO,OAAW,KAAe,OAAO,UAAU,OAAS,OAAO,SAAS,OAAS,wBA0D/G,SAASC,EAAqBC,EAA+B,CAC3D,OAAIA,GAGGF,CACT,CAKA,MAAMG,KAAgB,QACpB,CAAC,CAAE,QAAAC,EAAS,cAAAC,EAAe,WAAAC,CAAW,IAElC,EAAAC,QAAA,cAAC,OAAI,MAAM,QACT,EAAAA,QAAA,cAACb,EAAA,CACC,cAAeW,EACf,oBAAqBR,EACrB,qBAAsBC,EACtB,iBAAkBC,EAClB,gBAAe,GACf,WAAYO,EACZ,cAAe,CAAC,EAAAE,OAAS,EACzB,cAAe,CAAC,EAAAC,OAAS,GAExBL,CACH,CACF,EAGJ,CAACM,EAAUC,IAASD,EAAS,UAAYC,EAAK,SAAWD,EAAS,gBAAkBC,EAAK,eAAiBD,EAAS,aAAeC,EAAK,UACzI,EAEAR,EAAc,YAAc,gBAgCrB,SAASnB,EAAkB,CAAE,QAAAoB,EAAS,GAAAQ,EAAI,QAAAC,EAAU,CAAC,CAAE,EAA2B,CACvF,KAAM,CAAE,cAAeX,EAAc,uBAAAY,EAAyB,GAAM,YAAAC,EAAa,WAAYC,EAAmB,CAAC,EAAG,GAAGC,CAAiB,EAAIJ,EAGtIR,KAAgB,WAAQ,IAAMJ,EAAqBC,CAAY,EAAG,CAACA,CAAY,CAAC,EAGhFgB,KAAqB,WAAQ,KAE1B,CACL,MAFqB,4BAAyBD,CAAgB,EAG9D,GAAGD,CACL,GACC,CAACC,EAAkBD,CAAgB,CAAC,EAGjCG,KAAS,WAAQ,IAAM,CAC3B,GAAI,CAACL,GAA0B,CAACC,EAAa,CAE3C,MAAMK,KAAY,gCAA6BhB,CAAO,EACtD,OAAOgB,EAAU,KAAK,EAAI,CAACA,CAAS,EAAI,CAAC,CAC3C,CAEA,SAAO,2BAAwBhB,EAASW,CAAW,CACrD,EAAG,CAACX,EAASU,EAAwBC,CAAW,CAAC,EAEjD,OAAKI,EAAO,OAKRA,EAAO,SAAW,EACb,EAAAZ,QAAA,cAACJ,EAAA,CAAc,QAASgB,EAAO,CAAC,EAAG,cAAed,EAAe,WAAYa,EAAoB,EAKxG,EAAAX,QAAA,cAAC,QAAK,UAAU,SAAS,IAAI,IAAI,MAAM,QACpCY,EAAO,IAAI,CAACE,EAAOC,IAClB,EAAAf,QAAA,cAACJ,EAAA,CAAc,IAAK,GAAGS,CAAE,UAAUU,CAAK,GAAI,QAASD,EAAO,cAAehB,EAAe,WAAYa,EAAoB,CAC3H,CACH,EAdO,IAgBX",
6
- "names": ["StreamingMarkdown_exports", "__export", "StreamingMarkdown", "__toCommonJS", "import_react", "import_react_markdown", "import_remark_gfm", "import_rehype_raw", "import_harden_react_markdown", "import_kookie_ui", "import_createMarkdownComponents", "import_markdownStreaming", "HardenedMarkdown", "hardenReactMarkdown", "ReactMarkdown", "LINK_PREFIXES", "IMAGE_PREFIXES", "ALLOWED_PROTOCOLS", "DEFAULT_APP_ORIGIN", "resolveDefaultOrigin", "customOrigin", "MarkdownBlock", "content", "defaultOrigin", "components", "React", "remarkGfm", "rehypeRaw", "previous", "next", "id", "options", "enableBlockMemoization", "blockParser", "customComponents", "componentOptions", "markdownComponents", "blocks", "completed", "block", "index"]
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"createMarkdownComponents.d.ts","sourceRoot":"","sources":["../../../../src/components/markdown/createMarkdownComponents.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGjD,OAAO,KAAK,EAAE,wBAAwB,EAAyB,MAAM,SAAS,CAAC;AA8B/E;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,GAAE,wBAA6B,GAAG,UAAU,CAmJ3F"}
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/components/markdown/createMarkdownComponents.tsx"],
4
- "sourcesContent": ["import React, { type ReactNode } from \"react\";\nimport type { Components } from \"react-markdown\";\nimport { Blockquote, Box, Code, Flex, Heading, Text, Table } from \"@kushagradhawan/kookie-ui\";\nimport { CodeBlock } from \"../code\";\nimport type { MarkdownComponentOptions, MarkdownChildrenProps } from \"./types\";\n\n/**\n * Extracts language from className (e.g., \"language-typescript\" -> \"typescript\")\n */\nfunction extractLanguage(className?: string): string {\n if (!className) {\n return \"text\";\n }\n const match = className.match(/language-([\\w-]+)/i);\n return match?.[1] ?? \"text\";\n}\n\n/**\n * Extracts code string from ReactNode children\n */\nfunction extractCode(children?: ReactNode): string {\n let code = \"\";\n if (!children) {\n return code;\n }\n if (typeof children === \"string\") {\n code = children;\n } else if (Array.isArray(children)) {\n code = children.map((child) => (typeof child === \"string\" ? child : \"\")).join(\"\");\n }\n // Trim trailing newlines but preserve internal whitespace\n return code.replace(/^\\n+|\\n+$/g, \"\");\n}\n\n/**\n * Creates markdown component mappings that work with both react-markdown and MDX.\n * Uses KookieUI components for consistent styling across all projects.\n *\n * @param options - Optional configuration for component behavior\n * @returns Component mappings for markdown/MDX renderers\n *\n * @example\n * ```tsx\n * // In react-markdown\n * <ReactMarkdown components={createMarkdownComponents()}>\n * {content}\n * </ReactMarkdown>\n *\n * // In MDX\n * export function useMDXComponents(components: MDXComponents) {\n * return {\n * ...createMarkdownComponents(),\n * ...components,\n * };\n * }\n * ```\n */\nexport function createMarkdownComponents(options: MarkdownComponentOptions = {}): Components {\n const { codeBlockCollapsible = false, imageComponent, inlineCodeHighContrast = true } = options;\n\n return {\n // Headings with consistent visual hierarchy\n h1: ({ children }: MarkdownChildrenProps) => (\n <Heading size=\"8\" weight=\"medium\" as=\"h1\" style={{ marginTop: \"1rem\", marginBottom: \"0.5rem\" }}>\n {children}\n </Heading>\n ),\n h2: ({ children }: MarkdownChildrenProps) => (\n <Heading weight=\"medium\" size=\"5\" as=\"h2\" style={{ marginTop: \"0.875rem\", marginBottom: \"0.5rem\" }}>\n {children}\n </Heading>\n ),\n h3: ({ children }: MarkdownChildrenProps) => (\n <Heading weight=\"medium\" size=\"4\" as=\"h3\" style={{ marginTop: \"0.75rem\", marginBottom: \"0.5rem\" }}>\n {children}\n </Heading>\n ),\n h4: ({ children }: MarkdownChildrenProps) => (\n <Heading weight=\"medium\" size=\"3\" as=\"h4\" style={{ marginTop: \"0.625rem\", marginBottom: \"0.5rem\" }}>\n {children}\n </Heading>\n ),\n h5: ({ children }: MarkdownChildrenProps) => (\n <Heading weight=\"medium\" size=\"3\" as=\"h5\" style={{ marginTop: \"0.5rem\", marginBottom: \"0.5rem\" }}>\n {children}\n </Heading>\n ),\n h6: ({ children }: MarkdownChildrenProps) => (\n <Heading weight=\"medium\" size=\"3\" as=\"h6\" style={{ marginTop: \"0.5rem\", marginBottom: \"0.5rem\" }}>\n {children}\n </Heading>\n ),\n\n // Paragraph text\n p: ({ children }: MarkdownChildrenProps) => (\n <Text size=\"3\" as=\"p\" style={{ lineHeight: \"1.6\" }}>\n {children}\n </Text>\n ),\n\n // Code - inline vs block\n code: ({ className, children, inline }: { className?: string; children?: ReactNode; inline?: boolean }) => {\n const code = extractCode(children);\n\n // Block code: has className (language) OR is not marked as inline\n // Inline code: explicitly marked as inline=true, or no className and short single-line content\n const isInlineCode = inline === true || (inline === undefined && !className && !code.includes(\"\\n\") && code.length < 100);\n\n if (isInlineCode) {\n return (\n <Code highContrast={inlineCodeHighContrast} size=\"3\">\n {code}\n </Code>\n );\n }\n\n return (\n <Box my=\"2\" style={{ minWidth: 0 }}>\n <CodeBlock code={code} language={extractLanguage(className)} collapsible={codeBlockCollapsible} />\n </Box>\n );\n },\n\n // Lists\n ul: ({ children }: MarkdownChildrenProps) => (\n <ul style={{ marginTop: \"0.5rem\", marginBottom: \"0.5rem\", lineHeight: \"1.6\", paddingLeft: \"1.5rem\", listStyleType: \"disc\" }}>{children}</ul>\n ),\n ol: ({ children }: MarkdownChildrenProps) => (\n <ol style={{ marginTop: \"0.5rem\", marginBottom: \"0.5rem\", lineHeight: \"1.6\", paddingLeft: \"1.5rem\", listStyleType: \"decimal\" }}>{children}</ol>\n ),\n li: ({ children }: MarkdownChildrenProps) => <li style={{ marginBottom: \"0.25rem\", lineHeight: \"1.6\" }}>{children}</li>,\n\n // Blockquote\n blockquote: ({ children }: MarkdownChildrenProps) => <Blockquote>{children}</Blockquote>,\n\n // Links\n a: ({ href, children }: { href?: string; children?: ReactNode }) => (\n <a href={href} style={{ color: \"var(--accent-9)\", textDecoration: \"underline\" }}>\n {children}\n </a>\n ),\n\n // Text styling\n strong: ({ children }: MarkdownChildrenProps) => (\n <Text weight=\"medium\" style={{ lineHeight: \"1.6\" }}>\n {children}\n </Text>\n ),\n em: ({ children }: MarkdownChildrenProps) => <Text style={{ lineHeight: \"1.6\", fontStyle: \"italic\" }}>{children}</Text>,\n\n // Horizontal rule\n hr: () => (\n <hr\n style={{\n color: \"var(--gray-6)\",\n marginTop: \"0.5rem\",\n marginBottom: \"0.5rem\",\n height: \"1px\",\n width: \"100%\",\n opacity: 0.5,\n }}\n />\n ),\n\n // Pre wrapper (pass through to let code handle it)\n pre: ({ children }: MarkdownChildrenProps) => <>{children}</>,\n\n // Tables using KookieUI\n table: ({ children }: MarkdownChildrenProps) => (\n <Box my=\"2\" style={{ overflowX: \"auto\" }}>\n <Table.Root size=\"2\" variant=\"ghost\">\n {children}\n </Table.Root>\n </Box>\n ),\n thead: ({ children }: MarkdownChildrenProps) => <Table.Header>{children}</Table.Header>,\n tbody: ({ children }: MarkdownChildrenProps) => <Table.Body>{children}</Table.Body>,\n tr: ({ children }: MarkdownChildrenProps) => <Table.Row>{children}</Table.Row>,\n th: ({ children }: MarkdownChildrenProps) => <Table.ColumnHeaderCell>{children}</Table.ColumnHeaderCell>,\n td: ({ children }: MarkdownChildrenProps) => <Table.Cell>{children}</Table.Cell>,\n\n // HTML elements for raw HTML support\n sub: ({ children }: MarkdownChildrenProps) => <sub>{children}</sub>,\n sup: ({ children }: MarkdownChildrenProps) => <sup>{children}</sup>,\n br: () => <br />,\n\n // Images - use custom component if provided\n img: imageComponent\n ? (props: React.ImgHTMLAttributes<HTMLImageElement>) => {\n const { src, alt, width, height } = props;\n if (!src || typeof src !== \"string\") return null;\n return imageComponent({\n src,\n alt: alt ?? \"Image\",\n width: width ? String(width) : undefined,\n height: height ? String(height) : undefined,\n });\n }\n : undefined,\n\n // Details/Summary for expandable sections\n details: ({ children }: MarkdownChildrenProps) => <details style={{ padding: \"0.5rem 0\" }}>{children}</details>,\n summary: ({ children }: MarkdownChildrenProps) => <summary style={{ cursor: \"pointer\", fontWeight: 500 }}>{children}</summary>,\n };\n}\n\n"],
5
- "mappings": "0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,8BAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAsC,oBAEtCC,EAAkE,qCAClEC,EAA0B,mBAM1B,SAASC,EAAgBC,EAA4B,CACnD,OAAKA,EAGSA,EAAU,MAAM,oBAAoB,IACnC,CAAC,GAAK,OAHZ,MAIX,CAKA,SAASC,EAAYC,EAA8B,CACjD,IAAIC,EAAO,GACX,OAAKD,GAGD,OAAOA,GAAa,SACtBC,EAAOD,EACE,MAAM,QAAQA,CAAQ,IAC/BC,EAAOD,EAAS,IAAKE,GAAW,OAAOA,GAAU,SAAWA,EAAQ,EAAG,EAAE,KAAK,EAAE,GAG3ED,EAAK,QAAQ,aAAc,EAAE,GAR3BA,CASX,CAyBO,SAAST,EAAyBW,EAAoC,CAAC,EAAe,CAC3F,KAAM,CAAE,qBAAAC,EAAuB,GAAO,eAAAC,EAAgB,uBAAAC,EAAyB,EAAK,EAAIH,EAExF,MAAO,CAEL,GAAI,CAAC,CAAE,SAAAH,CAAS,IACd,EAAAO,QAAA,cAAC,WAAQ,KAAK,IAAI,OAAO,SAAS,GAAG,KAAK,MAAO,CAAE,UAAW,OAAQ,aAAc,QAAS,GAC1FP,CACH,EAEF,GAAI,CAAC,CAAE,SAAAA,CAAS,IACd,EAAAO,QAAA,cAAC,WAAQ,OAAO,SAAS,KAAK,IAAI,GAAG,KAAK,MAAO,CAAE,UAAW,WAAY,aAAc,QAAS,GAC9FP,CACH,EAEF,GAAI,CAAC,CAAE,SAAAA,CAAS,IACd,EAAAO,QAAA,cAAC,WAAQ,OAAO,SAAS,KAAK,IAAI,GAAG,KAAK,MAAO,CAAE,UAAW,UAAW,aAAc,QAAS,GAC7FP,CACH,EAEF,GAAI,CAAC,CAAE,SAAAA,CAAS,IACd,EAAAO,QAAA,cAAC,WAAQ,OAAO,SAAS,KAAK,IAAI,GAAG,KAAK,MAAO,CAAE,UAAW,WAAY,aAAc,QAAS,GAC9FP,CACH,EAEF,GAAI,CAAC,CAAE,SAAAA,CAAS,IACd,EAAAO,QAAA,cAAC,WAAQ,OAAO,SAAS,KAAK,IAAI,GAAG,KAAK,MAAO,CAAE,UAAW,SAAU,aAAc,QAAS,GAC5FP,CACH,EAEF,GAAI,CAAC,CAAE,SAAAA,CAAS,IACd,EAAAO,QAAA,cAAC,WAAQ,OAAO,SAAS,KAAK,IAAI,GAAG,KAAK,MAAO,CAAE,UAAW,SAAU,aAAc,QAAS,GAC5FP,CACH,EAIF,EAAG,CAAC,CAAE,SAAAA,CAAS,IACb,EAAAO,QAAA,cAAC,QAAK,KAAK,IAAI,GAAG,IAAI,MAAO,CAAE,WAAY,KAAM,GAC9CP,CACH,EAIF,KAAM,CAAC,CAAE,UAAAF,EAAW,SAAAE,EAAU,OAAAQ,CAAO,IAAsE,CACzG,MAAMP,EAAOF,EAAYC,CAAQ,EAMjC,OAFqBQ,IAAW,IAASA,IAAW,QAAa,CAACV,GAAa,CAACG,EAAK,SAAS;AAAA,CAAI,GAAKA,EAAK,OAAS,IAIjH,EAAAM,QAAA,cAAC,QAAK,aAAcD,EAAwB,KAAK,KAC9CL,CACH,EAKF,EAAAM,QAAA,cAAC,OAAI,GAAG,IAAI,MAAO,CAAE,SAAU,CAAE,GAC/B,EAAAA,QAAA,cAAC,aAAU,KAAMN,EAAM,SAAUJ,EAAgBC,CAAS,EAAG,YAAaM,EAAsB,CAClG,CAEJ,EAGA,GAAI,CAAC,CAAE,SAAAJ,CAAS,IACd,EAAAO,QAAA,cAAC,MAAG,MAAO,CAAE,UAAW,SAAU,aAAc,SAAU,WAAY,MAAO,YAAa,SAAU,cAAe,MAAO,GAAIP,CAAS,EAEzI,GAAI,CAAC,CAAE,SAAAA,CAAS,IACd,EAAAO,QAAA,cAAC,MAAG,MAAO,CAAE,UAAW,SAAU,aAAc,SAAU,WAAY,MAAO,YAAa,SAAU,cAAe,SAAU,GAAIP,CAAS,EAE5I,GAAI,CAAC,CAAE,SAAAA,CAAS,IAA6B,EAAAO,QAAA,cAAC,MAAG,MAAO,CAAE,aAAc,UAAW,WAAY,KAAM,GAAIP,CAAS,EAGlH,WAAY,CAAC,CAAE,SAAAA,CAAS,IAA6B,EAAAO,QAAA,cAAC,kBAAYP,CAAS,EAG3E,EAAG,CAAC,CAAE,KAAAS,EAAM,SAAAT,CAAS,IACnB,EAAAO,QAAA,cAAC,KAAE,KAAME,EAAM,MAAO,CAAE,MAAO,kBAAmB,eAAgB,WAAY,GAC3ET,CACH,EAIF,OAAQ,CAAC,CAAE,SAAAA,CAAS,IAClB,EAAAO,QAAA,cAAC,QAAK,OAAO,SAAS,MAAO,CAAE,WAAY,KAAM,GAC9CP,CACH,EAEF,GAAI,CAAC,CAAE,SAAAA,CAAS,IAA6B,EAAAO,QAAA,cAAC,QAAK,MAAO,CAAE,WAAY,MAAO,UAAW,QAAS,GAAIP,CAAS,EAGhH,GAAI,IACF,EAAAO,QAAA,cAAC,MACC,MAAO,CACL,MAAO,gBACP,UAAW,SACX,aAAc,SACd,OAAQ,MACR,MAAO,OACP,QAAS,EACX,EACF,EAIF,IAAK,CAAC,CAAE,SAAAP,CAAS,IAA6B,EAAAO,QAAA,gBAAAA,QAAA,cAAGP,CAAS,EAG1D,MAAO,CAAC,CAAE,SAAAA,CAAS,IACjB,EAAAO,QAAA,cAAC,OAAI,GAAG,IAAI,MAAO,CAAE,UAAW,MAAO,GACrC,EAAAA,QAAA,cAAC,QAAM,KAAN,CAAW,KAAK,IAAI,QAAQ,SAC1BP,CACH,CACF,EAEF,MAAO,CAAC,CAAE,SAAAA,CAAS,IAA6B,EAAAO,QAAA,cAAC,QAAM,OAAN,KAAcP,CAAS,EACxE,MAAO,CAAC,CAAE,SAAAA,CAAS,IAA6B,EAAAO,QAAA,cAAC,QAAM,KAAN,KAAYP,CAAS,EACtE,GAAI,CAAC,CAAE,SAAAA,CAAS,IAA6B,EAAAO,QAAA,cAAC,QAAM,IAAN,KAAWP,CAAS,EAClE,GAAI,CAAC,CAAE,SAAAA,CAAS,IAA6B,EAAAO,QAAA,cAAC,QAAM,iBAAN,KAAwBP,CAAS,EAC/E,GAAI,CAAC,CAAE,SAAAA,CAAS,IAA6B,EAAAO,QAAA,cAAC,QAAM,KAAN,KAAYP,CAAS,EAGnE,IAAK,CAAC,CAAE,SAAAA,CAAS,IAA6B,EAAAO,QAAA,cAAC,WAAKP,CAAS,EAC7D,IAAK,CAAC,CAAE,SAAAA,CAAS,IAA6B,EAAAO,QAAA,cAAC,WAAKP,CAAS,EAC7D,GAAI,IAAM,EAAAO,QAAA,cAAC,SAAG,EAGd,IAAKF,EACAK,GAAqD,CACpD,KAAM,CAAE,IAAAC,EAAK,IAAAC,EAAK,MAAAC,EAAO,OAAAC,CAAO,EAAIJ,EACpC,MAAI,CAACC,GAAO,OAAOA,GAAQ,SAAiB,KACrCN,EAAe,CACpB,IAAAM,EACA,IAAKC,GAAO,QACZ,MAAOC,EAAQ,OAAOA,CAAK,EAAI,OAC/B,OAAQC,EAAS,OAAOA,CAAM,EAAI,MACpC,CAAC,CACH,EACA,OAGJ,QAAS,CAAC,CAAE,SAAAd,CAAS,IAA6B,EAAAO,QAAA,cAAC,WAAQ,MAAO,CAAE,QAAS,UAAW,GAAIP,CAAS,EACrG,QAAS,CAAC,CAAE,SAAAA,CAAS,IAA6B,EAAAO,QAAA,cAAC,WAAQ,MAAO,CAAE,OAAQ,UAAW,WAAY,GAAI,GAAIP,CAAS,CACtH,CACF",
6
- "names": ["createMarkdownComponents_exports", "__export", "createMarkdownComponents", "__toCommonJS", "import_react", "import_kookie_ui", "import_code", "extractLanguage", "className", "extractCode", "children", "code", "child", "options", "codeBlockCollapsible", "imageComponent", "inlineCodeHighContrast", "React", "inline", "href", "props", "src", "alt", "width", "height"]
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"markdownStreaming.d.ts","sourceRoot":"","sources":["../../../../../src/components/markdown/utils/markdownStreaming.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA2IH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAsGpE;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,KAAK,CAAC;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GACpD,MAAM,EAAE,CAuBV"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"CodeBlock.d.ts","sourceRoot":"","sources":["../../../../src/components/code/CodeBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwF,MAAM,OAAO,CAAC;AAK7G,OAAO,KAAK,EAAE,cAAc,EAAuC,MAAM,SAAS,CAAC;AA2RnF,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,QAAe,EACf,YAAmB,EACnB,eAAsB,EACtB,WAAW,EACX,UAAU,EACV,eAAe,EACf,WAAkB,EAClB,eAA0C,EAC1C,IAAI,GACL,EAAE,cAAc,qBA2ChB;AAED,wBAAgB,mBAAmB,YAElC"}
@@ -1,2 +0,0 @@
1
- import e,{useState as E,useEffect as F,useMemo as w,memo as x,createContext as I,useContext as A}from"react";import{Box as m,Card as k,Flex as f,Button as _,Text as z,Theme as D,ScrollArea as $,IconButton as M}from"@kushagradhawan/kookie-ui";import{HugeiconsIcon as S}from"@hugeicons/react";import{Copy01Icon as W,Tick01Icon as O,ArrowDown01Icon as U}from"@hugeicons/core-free-icons";import{codeToHtml as j}from"shiki";import{extractTextFromChildren as G,extractLanguageFromChildren as L}from"./types";import{useCodeCard as K}from"./useCodeCard";import{LanguageBadge as V}from"./LanguageBadge";const P=I(!1),q=360,J="one-light",Q="one-dark-pro";function X({children:c,background:o="none",backgroundProps:t={}}){const{dotSize:a=24,color:s="var(--gray-10)",backgroundColor:i="var(--gray-2)",height:r,width:d="100%",radius:l="3"}=t,n=w(()=>{if(o!=="none")return o==="dots"?{backgroundImage:`radial-gradient(circle, ${s} 1px, transparent 1px)`,borderRadius:`var(--radius-${l})`,backgroundSize:`${a}px ${a}px`,backgroundPosition:"center",backgroundColor:i,width:d,...r&&{height:r}}:{backgroundImage:`url(${o})`,backgroundSize:"cover",backgroundPosition:"center",backgroundRepeat:"no-repeat",borderRadius:`var(--radius-${l})`,width:d,...r&&{height:r}}},[o,s,i,a,r,d,l]);return e.createElement(k,{size:"1",variant:"soft"},e.createElement(f,{justify:"center",align:"center",py:"4",style:n},e.createElement(D,{fontFamily:"sans"},c)))}function Y(){return e.createElement(m,{className:"code-skeleton"},["85%","70%","90%","60%","75%","80%"].map((o,t)=>e.createElement(m,{key:t,className:"code-skeleton-line",style:{width:o}})))}const B=x(function({code:o,language:t,showCopy:a,showLanguage:s,showLineNumbers:i,collapsible:r,collapsedHeight:d,file:l,isLoading:n=!1,children:g}){const{isExpanded:u,shouldShowToggle:p,copied:C,contentRef:h,contentMaxHeight:b,handleToggle:v,handleCopy:T}=K({code:o,collapsedHeight:d}),y=r&&p,N=u?"rotate(180deg)":"rotate(0deg)",H=i?"code-content":"code-content hide-line-numbers";return e.createElement(m,{position:"relative"},e.createElement(k,{size:"1",variant:"soft"},e.createElement(f,{direction:"column"},e.createElement(f,{justify:"between",align:"start",gap:"2"},e.createElement(f,{align:"center",gap:"2"},s&&e.createElement(V,{language:t}),l&&e.createElement(z,{size:"1",color:"gray",highContrast:!0},l)),e.createElement(f,{align:"center",className:"code-action-buttons"},y&&e.createElement(M,{size:"2",variant:"ghost",color:"gray",onClick:v,tooltip:u?"Collapse":"Expand","aria-label":u?"Collapse code":"Expand code"},e.createElement(S,{icon:U,style:{transform:N},className:"code-chevron",strokeWidth:1.75})),a&&e.createElement(_,{size:"2",variant:"ghost",color:"gray",onClick:T,tooltip:C?"Copied!":"Copy","aria-label":C?"Copied!":"Copy code"},e.createElement(S,{icon:C?O:W,strokeWidth:1.75})," Copy"))),e.createElement(m,{ref:h,style:{maxHeight:r?`${b}px`:void 0},className:H},e.createElement($,{type:"auto",scrollbars:"horizontal"},n?e.createElement(Y,null):g)),y&&!u&&e.createElement(m,{className:"code-scroll-shadow visible"}))))}),Z=x(function({code:o,language:t,showCopy:a,showLanguage:s,showLineNumbers:i,collapsible:r,collapsedHeight:d,file:l,shikiConfig:n}){const[g,u]=E(null),p=w(()=>{const h=n?.themes?.light||J,b=n?.themes?.dark||Q;return{lang:t,themes:{light:h,dark:b},defaultColor:!1,langAlias:n?.langAlias,transformers:n?.transformers,meta:n?.meta?{__raw:n.meta}:void 0}},[t,n?.themes?.light,n?.themes?.dark,n?.langAlias,n?.transformers,n?.meta]);return F(()=>{let h=!1;return j(o,p).then(b=>{h||u(b)}).catch(b=>{}),()=>{h=!0}},[o,p]),e.createElement(B,{code:o,language:t,showCopy:a,showLanguage:s,showLineNumbers:i,collapsible:r,collapsedHeight:d,file:l,isLoading:g===null},g?e.createElement(m,{dangerouslySetInnerHTML:{__html:g}}):null)}),R=x(function({children:o,showCopy:t,showLanguage:a,showLineNumbers:s,collapsible:i,collapsedHeight:r,file:d}){const l=G(o),n=L(o);return e.createElement(B,{code:l,language:n,showCopy:t,showLanguage:a,showLineNumbers:s,collapsible:i,collapsedHeight:r,file:d},o)});function de({children:c,code:o,language:t,preview:a,showCopy:s=!0,showLanguage:i=!0,showLineNumbers:r=!0,shikiConfig:d,background:l,backgroundProps:n,collapsible:g=!0,collapsedHeight:u=q,file:p}){const C=t||L(c)||"text";return e.createElement(P.Provider,{value:!0},e.createElement(m,{className:"docs-code-block",mt:"6",mb:"8"},e.createElement(f,{direction:"column",gap:"2"},a&&e.createElement(X,{background:l,backgroundProps:n},a),o&&e.createElement(Z,{code:o,language:C,showCopy:s,showLanguage:i,showLineNumbers:r,collapsible:g,collapsedHeight:u,file:p,shikiConfig:d}),c&&!o&&e.createElement(R,{showCopy:s,showLanguage:i,showLineNumbers:r,collapsible:g,collapsedHeight:u,file:p},c))))}function ce(){return A(P)}export{de as CodeBlock,ce as useCodeBlockContext};
2
- //# sourceMappingURL=CodeBlock.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/components/code/CodeBlock.tsx"],
4
- "sourcesContent": ["import React, { useState, useEffect, useMemo, memo, createContext, useContext, type ReactNode } from \"react\";\nimport { Box, Card, Code, Flex, Button, Text, Theme, ScrollArea, IconButton } from \"@kushagradhawan/kookie-ui\";\nimport { HugeiconsIcon } from \"@hugeicons/react\";\nimport { Copy01Icon, Tick01Icon, ArrowDown01Icon } from \"@hugeicons/core-free-icons\";\nimport { codeToHtml, type BundledLanguage, type BundledTheme } from \"shiki\";\nimport type { CodeBlockProps, ShikiConfig, PreviewBackgroundProps } from \"./types\";\nimport { extractTextFromChildren, extractLanguageFromChildren } from \"./types\";\nimport { useCodeCard } from \"./useCodeCard\";\nimport { LanguageBadge } from \"./LanguageBadge\";\n\nconst CodeBlockContext = createContext<boolean>(false);\n\nconst DEFAULT_COLLAPSED_HEIGHT = 360;\nconst DEFAULT_LIGHT_THEME = \"one-light\";\nconst DEFAULT_DARK_THEME = \"one-dark-pro\";\n\ninterface PreviewSectionProps {\n children: ReactNode;\n background?: \"none\" | \"dots\" | string;\n backgroundProps?: PreviewBackgroundProps;\n}\n\nfunction PreviewSection({ children, background = \"none\", backgroundProps = {} }: PreviewSectionProps) {\n const { dotSize = 24, color = \"var(--gray-10)\", backgroundColor = \"var(--gray-2)\", height, width = \"100%\", radius = \"3\" } = backgroundProps;\n\n const backgroundStyle = useMemo((): React.CSSProperties | undefined => {\n if (background === \"none\") return undefined;\n\n if (background === \"dots\") {\n return {\n backgroundImage: `radial-gradient(circle, ${color} 1px, transparent 1px)`,\n borderRadius: `var(--radius-${radius})`,\n backgroundSize: `${dotSize}px ${dotSize}px`,\n backgroundPosition: \"center\",\n backgroundColor,\n width,\n ...(height && { height }),\n };\n }\n\n // Image background\n return {\n backgroundImage: `url(${background})`,\n backgroundSize: \"cover\",\n backgroundPosition: \"center\",\n backgroundRepeat: \"no-repeat\",\n borderRadius: `var(--radius-${radius})`,\n width,\n ...(height && { height }),\n };\n }, [background, color, backgroundColor, dotSize, height, width, radius]);\n\n return (\n <Card size=\"1\" variant=\"soft\">\n <Flex justify=\"center\" align=\"center\" py=\"4\" style={backgroundStyle}>\n <Theme fontFamily=\"sans\">{children}</Theme>\n </Flex>\n </Card>\n );\n}\n\ninterface CodeCardProps {\n code: string;\n language: string;\n showCopy: boolean;\n showLanguage: boolean;\n showLineNumbers: boolean;\n collapsible: boolean;\n collapsedHeight: number;\n file?: string;\n isLoading?: boolean;\n children: ReactNode;\n}\n\nfunction CodeSkeleton() {\n // Generate varied line widths for visual interest\n const lineWidths = [\"85%\", \"70%\", \"90%\", \"60%\", \"75%\", \"80%\"];\n\n return (\n <Box className=\"code-skeleton\">\n {lineWidths.map((width, index) => (\n <Box key={index} className=\"code-skeleton-line\" style={{ width }} />\n ))}\n </Box>\n );\n}\n\nconst CodeCard = memo(function CodeCard({\n code,\n language,\n showCopy,\n showLanguage,\n showLineNumbers,\n collapsible,\n collapsedHeight,\n file,\n isLoading = false,\n children,\n}: CodeCardProps) {\n const { isExpanded, shouldShowToggle, copied, contentRef, contentMaxHeight, handleToggle, handleCopy } = useCodeCard({\n code,\n collapsedHeight,\n });\n\n const showToggle = collapsible && shouldShowToggle;\n const chevronRotation = isExpanded ? \"rotate(180deg)\" : \"rotate(0deg)\";\n const contentClassName = showLineNumbers ? \"code-content\" : \"code-content hide-line-numbers\";\n\n return (\n <Box position=\"relative\">\n <Card size=\"1\" variant=\"soft\">\n <Flex direction=\"column\">\n <Flex justify=\"between\" align=\"start\" gap=\"2\">\n <Flex align=\"center\" gap=\"2\">\n {showLanguage && <LanguageBadge language={language} />}\n {file && (\n <Text size=\"1\" color=\"gray\" highContrast>\n {file}\n </Text>\n )}\n </Flex>\n\n <Flex align=\"center\" className=\"code-action-buttons\">\n {showToggle && (\n <IconButton\n size=\"2\"\n variant=\"ghost\"\n color=\"gray\"\n onClick={handleToggle}\n tooltip={isExpanded ? \"Collapse\" : \"Expand\"}\n aria-label={isExpanded ? \"Collapse code\" : \"Expand code\"}\n >\n <HugeiconsIcon icon={ArrowDown01Icon} style={{ transform: chevronRotation }} className=\"code-chevron\" strokeWidth={1.75} />\n </IconButton>\n )}\n {showCopy && (\n <Button\n size=\"2\"\n variant=\"ghost\"\n color=\"gray\"\n onClick={handleCopy}\n tooltip={copied ? \"Copied!\" : \"Copy\"}\n aria-label={copied ? \"Copied!\" : \"Copy code\"}\n >\n <HugeiconsIcon icon={copied ? Tick01Icon : Copy01Icon} strokeWidth={1.75} /> Copy\n </Button>\n )}\n </Flex>\n </Flex>\n\n <Box ref={contentRef} style={{ maxHeight: collapsible ? `${contentMaxHeight}px` : undefined }} className={contentClassName}>\n <ScrollArea type=\"auto\" scrollbars=\"horizontal\">\n {isLoading ? <CodeSkeleton /> : children}\n </ScrollArea>\n </Box>\n\n {showToggle && !isExpanded && <Box className=\"code-scroll-shadow visible\" />}\n </Flex>\n </Card>\n </Box>\n );\n});\n\ninterface RuntimeCodeSectionProps {\n code: string;\n language: string;\n showCopy: boolean;\n showLanguage: boolean;\n showLineNumbers: boolean;\n collapsible: boolean;\n collapsedHeight: number;\n file?: string;\n shikiConfig?: ShikiConfig;\n}\n\nconst RuntimeCodeSection = memo(function RuntimeCodeSection({\n code,\n language,\n showCopy,\n showLanguage,\n showLineNumbers,\n collapsible,\n collapsedHeight,\n file,\n shikiConfig,\n}: RuntimeCodeSectionProps) {\n const [highlighted, setHighlighted] = useState<string | null>(null);\n\n // Memoize Shiki config to prevent unnecessary re-highlights\n const shikiOptions = useMemo(() => {\n const lightTheme = shikiConfig?.themes?.light || DEFAULT_LIGHT_THEME;\n const darkTheme = shikiConfig?.themes?.dark || DEFAULT_DARK_THEME;\n\n return {\n lang: language as BundledLanguage,\n themes: {\n light: lightTheme as BundledTheme,\n dark: darkTheme as BundledTheme,\n },\n defaultColor: false as const,\n langAlias: shikiConfig?.langAlias,\n transformers: shikiConfig?.transformers,\n meta: shikiConfig?.meta ? { __raw: shikiConfig.meta } : undefined,\n };\n }, [language, shikiConfig?.themes?.light, shikiConfig?.themes?.dark, shikiConfig?.langAlias, shikiConfig?.transformers, shikiConfig?.meta]);\n\n useEffect(() => {\n let cancelled = false;\n\n codeToHtml(code, shikiOptions)\n .then((html) => {\n if (!cancelled) {\n setHighlighted(html);\n }\n })\n .catch((error) => {\n if (!cancelled) {\n // Keep previous highlighted content on error (stale while revalidate)\n if (process.env.NODE_ENV === \"development\") {\n console.error(\"[CodeBlock] Shiki highlighting failed:\", error);\n }\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [code, shikiOptions]);\n\n // Only show loading skeleton on initial render (no highlighted content yet)\n // During updates, keep showing previous highlighted content (stale while revalidate)\n const isInitialLoading = highlighted === null;\n\n return (\n <CodeCard\n code={code}\n language={language}\n showCopy={showCopy}\n showLanguage={showLanguage}\n showLineNumbers={showLineNumbers}\n collapsible={collapsible}\n collapsedHeight={collapsedHeight}\n file={file}\n isLoading={isInitialLoading}\n >\n {highlighted ? <Box dangerouslySetInnerHTML={{ __html: highlighted }} /> : null}\n </CodeCard>\n );\n});\n\ninterface ChildrenCodeSectionProps {\n children: ReactNode;\n showCopy: boolean;\n showLanguage: boolean;\n showLineNumbers: boolean;\n collapsible: boolean;\n collapsedHeight: number;\n file?: string;\n}\n\nconst ChildrenCodeSection = memo(function ChildrenCodeSection({\n children,\n showCopy,\n showLanguage,\n showLineNumbers,\n collapsible,\n collapsedHeight,\n file,\n}: ChildrenCodeSectionProps) {\n const code = extractTextFromChildren(children);\n const language = extractLanguageFromChildren(children);\n\n return (\n <CodeCard\n code={code}\n language={language}\n showCopy={showCopy}\n showLanguage={showLanguage}\n showLineNumbers={showLineNumbers}\n collapsible={collapsible}\n collapsedHeight={collapsedHeight}\n file={file}\n >\n {children}\n </CodeCard>\n );\n});\n\nexport function CodeBlock({\n children,\n code,\n language,\n preview,\n showCopy = true,\n showLanguage = true,\n showLineNumbers = true,\n shikiConfig,\n background,\n backgroundProps,\n collapsible = true,\n collapsedHeight = DEFAULT_COLLAPSED_HEIGHT,\n file,\n}: CodeBlockProps) {\n const displayLanguage = language || extractLanguageFromChildren(children) || \"text\";\n\n return (\n <CodeBlockContext.Provider value={true}>\n <Box className=\"docs-code-block\" mt=\"6\" mb=\"8\">\n <Flex direction=\"column\" gap=\"2\">\n {preview && (\n <PreviewSection background={background} backgroundProps={backgroundProps}>\n {preview}\n </PreviewSection>\n )}\n\n {code && (\n <RuntimeCodeSection\n code={code}\n language={displayLanguage}\n showCopy={showCopy}\n showLanguage={showLanguage}\n showLineNumbers={showLineNumbers}\n collapsible={collapsible}\n collapsedHeight={collapsedHeight}\n file={file}\n shikiConfig={shikiConfig}\n />\n )}\n\n {children && !code && (\n <ChildrenCodeSection\n showCopy={showCopy}\n showLanguage={showLanguage}\n showLineNumbers={showLineNumbers}\n collapsible={collapsible}\n collapsedHeight={collapsedHeight}\n file={file}\n >\n {children}\n </ChildrenCodeSection>\n )}\n </Flex>\n </Box>\n </CodeBlockContext.Provider>\n );\n}\n\nexport function useCodeBlockContext() {\n return useContext(CodeBlockContext);\n}\n"],
5
- "mappings": "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",
6
- "names": ["React", "useState", "useEffect", "useMemo", "memo", "createContext", "useContext", "Box", "Card", "Flex", "Button", "Text", "Theme", "ScrollArea", "IconButton", "HugeiconsIcon", "Copy01Icon", "Tick01Icon", "ArrowDown01Icon", "codeToHtml", "extractTextFromChildren", "extractLanguageFromChildren", "useCodeCard", "LanguageBadge", "CodeBlockContext", "DEFAULT_COLLAPSED_HEIGHT", "DEFAULT_LIGHT_THEME", "DEFAULT_DARK_THEME", "PreviewSection", "children", "background", "backgroundProps", "dotSize", "color", "backgroundColor", "height", "width", "radius", "backgroundStyle", "CodeSkeleton", "index", "CodeCard", "code", "language", "showCopy", "showLanguage", "showLineNumbers", "collapsible", "collapsedHeight", "file", "isLoading", "isExpanded", "shouldShowToggle", "copied", "contentRef", "contentMaxHeight", "handleToggle", "handleCopy", "showToggle", "chevronRotation", "contentClassName", "RuntimeCodeSection", "shikiConfig", "highlighted", "setHighlighted", "shikiOptions", "lightTheme", "darkTheme", "cancelled", "html", "error", "ChildrenCodeSection", "CodeBlock", "preview", "displayLanguage", "useCodeBlockContext"]
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"CopyButton.d.ts","sourceRoot":"","sources":["../../../../src/components/code/CopyButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAKxE,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,EAAE,eAAe,qBAoCnD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"LanguageBadge.d.ts","sourceRoot":"","sources":["../../../../src/components/code/LanguageBadge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAsD1B;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7D;AAED,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE,kBAAkB,qBAQ7D"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"PreviewSection.d.ts","sourceRoot":"","sources":["../../../../src/components/code/PreviewSection.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG9C,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,SAAS,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACtC,eAAe,CAAC,EAAE;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,UAAmB,EAAE,eAAoB,EAAE,EAAE,mBAAmB,qBAqD1G"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"SyntaxHighlighter.d.ts","sourceRoot":"","sources":["../../../../src/components/code/SyntaxHighlighter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAInD,UAAU,sBAAsB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAKD,wBAAgB,iBAAiB,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAgC,EAAE,SAA8B,EAAE,EAAE,sBAAsB,qBAuC7I"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"useCodeCard.d.ts","sourceRoot":"","sources":["../../../../src/components/code/useCodeCard.ts"],"names":[],"mappings":"AAIA,UAAU,kBAAkB;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,iBAAiB;IACzB,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACnD,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,kBAAkB,GAAG,iBAAiB,CA0D5F"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"StreamingMarkdown.d.ts","sourceRoot":"","sources":["../../../../src/components/markdown/StreamingMarkdown.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAwC,MAAM,OAAO,CAAC;AAC7D,OAAsB,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAOhE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AASxD;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG,wBAAwB,GAAG;IAChE;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,KAAK,CAAC;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAE3D;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;CAClC,CAAC;AAEF,KAAK,sBAAsB,GAAG;IAC5B;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,OAAO,CAAC,EAAE,wBAAwB,CAAC;CACpC,CAAC;AA6CF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,OAAY,EAAE,EAAE,sBAAsB,4BA2CtF"}
@@ -1,2 +0,0 @@
1
- "use client";import e,{memo as f,useMemo as s}from"react";import u from"react-markdown";import M from"remark-gfm";import O from"rehype-raw";import P from"harden-react-markdown";import{Box as h,Flex as y}from"@kushagradhawan/kookie-ui";import{createMarkdownComponents as C}from"./createMarkdownComponents";import{completeUnterminatedMarkdown as b,parseMarkdownIntoBlocks as B}from"./utils/markdownStreaming";const I=P(u),S=["https://","http://","/"],E=["https://","http://","/","data:"],x=["mailto:","tel:","data:","http:","https:"],L=typeof window<"u"&&window.location?.origin?window.location.origin:"https://app.kookie.ai";function A(o){return o||L}const p=f(({content:o,defaultOrigin:n,components:i})=>e.createElement(h,{width:"100%"},e.createElement(I,{defaultOrigin:n,allowedLinkPrefixes:S,allowedImagePrefixes:E,allowedProtocols:x,allowDataImages:!0,components:i,remarkPlugins:[M],rehypePlugins:[O]},o)),(o,n)=>o.content===n.content&&o.defaultOrigin===n.defaultOrigin&&o.components===n.components);p.displayName="MarkdownBlock";function T({content:o,id:n,options:i={}}){const{defaultOrigin:m,enableBlockMemoization:l=!0,blockParser:a,components:d={},...c}=i,k=s(()=>A(m),[m]),g=s(()=>({...C(c),...d}),[c,d]),r=s(()=>{if(!l||!a){const t=b(o);return t.trim()?[t]:[]}return B(o,a)},[o,l,a]);return r.length?r.length===1?e.createElement(p,{content:r[0],defaultOrigin:k,components:g}):e.createElement(y,{direction:"column",gap:"2",width:"100%"},r.map((t,w)=>e.createElement(p,{key:`${n}-block-${w}`,content:t,defaultOrigin:k,components:g}))):null}export{T as StreamingMarkdown};
2
- //# sourceMappingURL=StreamingMarkdown.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/components/markdown/StreamingMarkdown.tsx"],
4
- "sourcesContent": ["\"use client\";\n\nimport React, { memo, useMemo, type ReactNode } from \"react\";\nimport ReactMarkdown, { type Components } from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport rehypeRaw from \"rehype-raw\";\nimport hardenReactMarkdown from \"harden-react-markdown\";\nimport { Box, Flex } from \"@kushagradhawan/kookie-ui\";\nimport { createMarkdownComponents } from \"./createMarkdownComponents\";\nimport { completeUnterminatedMarkdown, parseMarkdownIntoBlocks } from \"./utils/markdownStreaming\";\nimport type { MarkdownComponentOptions } from \"./types\";\n\nconst HardenedMarkdown = hardenReactMarkdown(ReactMarkdown);\n\nconst LINK_PREFIXES = [\"https://\", \"http://\", \"/\"];\nconst IMAGE_PREFIXES = [\"https://\", \"http://\", \"/\", \"data:\"];\nconst ALLOWED_PROTOCOLS = [\"mailto:\", \"tel:\", \"data:\", \"http:\", \"https:\"];\nconst DEFAULT_APP_ORIGIN = typeof window !== \"undefined\" && window.location?.origin ? window.location.origin : \"https://app.kookie.ai\";\n\n/**\n * Options for StreamingMarkdown component\n */\nexport type StreamingMarkdownOptions = MarkdownComponentOptions & {\n /**\n * Security origin for link/image validation\n * @default window.location.origin or \"https://app.kookie.ai\"\n */\n defaultOrigin?: string;\n\n /**\n * Whether to enable block-level memoization for performance\n * Recommended for streaming scenarios where content updates frequently\n * @default true\n */\n enableBlockMemoization?: boolean;\n\n /**\n * Custom parser for splitting content into blocks\n * If not provided, content will be rendered as a single block\n * For optimal streaming performance, use marked.lexer with GFM enabled\n */\n blockParser?: (content: string) => Array<{ raw?: string }>;\n\n /**\n * Override default component mappings\n */\n components?: Partial<Components>;\n};\n\ntype StreamingMarkdownProps = {\n /**\n * Markdown content to render (supports streaming/incomplete markdown)\n */\n content: string;\n\n /**\n * Unique identifier for this markdown instance (used for keys)\n */\n id: string;\n\n /**\n * Optional configuration\n */\n options?: StreamingMarkdownOptions;\n};\n\ntype MarkdownBlockProps = {\n content: string;\n defaultOrigin: string;\n components: Components;\n};\n\n/**\n * Resolves the default origin for security validation\n */\nfunction resolveDefaultOrigin(customOrigin?: string): string {\n if (customOrigin) {\n return customOrigin;\n }\n return DEFAULT_APP_ORIGIN;\n}\n\n/**\n * Memoized markdown block component for efficient streaming rendering\n */\nconst MarkdownBlock = memo(\n ({ content, defaultOrigin, components }: MarkdownBlockProps) => {\n return (\n <Box width=\"100%\">\n <HardenedMarkdown\n defaultOrigin={defaultOrigin}\n allowedLinkPrefixes={LINK_PREFIXES}\n allowedImagePrefixes={IMAGE_PREFIXES}\n allowedProtocols={ALLOWED_PROTOCOLS}\n allowDataImages\n components={components}\n remarkPlugins={[remarkGfm]}\n rehypePlugins={[rehypeRaw]}\n >\n {content}\n </HardenedMarkdown>\n </Box>\n );\n },\n (previous, next) => previous.content === next.content && previous.defaultOrigin === next.defaultOrigin && previous.components === next.components\n);\n\nMarkdownBlock.displayName = \"MarkdownBlock\";\n\n/**\n * StreamingMarkdown - A drop-in markdown renderer designed for AI streaming.\n *\n * Features:\n * - Unterminated block parsing (handles incomplete markdown during streaming)\n * - Block-level memoization for performance\n * - Security hardening (validates links/images)\n * - GitHub Flavored Markdown support\n * - KookieUI component integration\n * - Code syntax highlighting via CodeBlock\n *\n * @example\n * ```tsx\n * import { StreamingMarkdown } from '@kushagradhawan/kookie-blocks';\n * import { marked } from 'marked';\n *\n * function ChatMessage({ message }) {\n * return (\n * <StreamingMarkdown\n * content={message.content}\n * id={message.id}\n * options={{\n * blockParser: (content) => marked.lexer(content, { gfm: true }),\n * enableBlockMemoization: true,\n * }}\n * />\n * );\n * }\n * ```\n */\nexport function StreamingMarkdown({ content, id, options = {} }: StreamingMarkdownProps) {\n const { defaultOrigin: customOrigin, enableBlockMemoization = true, blockParser, components: customComponents = {}, ...componentOptions } = options;\n\n // Resolve security origin\n const defaultOrigin = useMemo(() => resolveDefaultOrigin(customOrigin), [customOrigin]);\n\n // Create component mappings with custom overrides\n const markdownComponents = useMemo(() => {\n const baseComponents = createMarkdownComponents(componentOptions);\n return {\n ...baseComponents,\n ...customComponents,\n };\n }, [componentOptions, customComponents]);\n\n // Parse content into blocks for memoization (if enabled and parser provided)\n const blocks = useMemo(() => {\n if (!enableBlockMemoization || !blockParser) {\n // No block splitting - just complete unterminated markdown\n const completed = completeUnterminatedMarkdown(content);\n return completed.trim() ? [completed] : [];\n }\n\n return parseMarkdownIntoBlocks(content, blockParser);\n }, [content, enableBlockMemoization, blockParser]);\n\n if (!blocks.length) {\n return null;\n }\n\n // Single block - no need for wrapper\n if (blocks.length === 1) {\n return <MarkdownBlock content={blocks[0]} defaultOrigin={defaultOrigin} components={markdownComponents} />;\n }\n\n // Multiple blocks - render with flex wrapper\n return (\n <Flex direction=\"column\" gap=\"2\" width=\"100%\">\n {blocks.map((block, index) => (\n <MarkdownBlock key={`${id}-block-${index}`} content={block} defaultOrigin={defaultOrigin} components={markdownComponents} />\n ))}\n </Flex>\n );\n}\n"],
5
- "mappings": "aAEA,OAAOA,GAAS,QAAAC,EAAM,WAAAC,MAA+B,QACrD,OAAOC,MAAwC,iBAC/C,OAAOC,MAAe,aACtB,OAAOC,MAAe,aACtB,OAAOC,MAAyB,wBAChC,OAAS,OAAAC,EAAK,QAAAC,MAAY,4BAC1B,OAAS,4BAAAC,MAAgC,6BACzC,OAAS,gCAAAC,EAA8B,2BAAAC,MAA+B,4BAGtE,MAAMC,EAAmBN,EAAoBH,CAAa,EAEpDU,EAAgB,CAAC,WAAY,UAAW,GAAG,EAC3CC,EAAiB,CAAC,WAAY,UAAW,IAAK,OAAO,EACrDC,EAAoB,CAAC,UAAW,OAAQ,QAAS,QAAS,QAAQ,EAClEC,EAAqB,OAAO,OAAW,KAAe,OAAO,UAAU,OAAS,OAAO,SAAS,OAAS,wBA0D/G,SAASC,EAAqBC,EAA+B,CAC3D,OAAIA,GAGGF,CACT,CAKA,MAAMG,EAAgBlB,EACpB,CAAC,CAAE,QAAAmB,EAAS,cAAAC,EAAe,WAAAC,CAAW,IAElCtB,EAAA,cAACO,EAAA,CAAI,MAAM,QACTP,EAAA,cAACY,EAAA,CACC,cAAeS,EACf,oBAAqBR,EACrB,qBAAsBC,EACtB,iBAAkBC,EAClB,gBAAe,GACf,WAAYO,EACZ,cAAe,CAAClB,CAAS,EACzB,cAAe,CAACC,CAAS,GAExBe,CACH,CACF,EAGJ,CAACG,EAAUC,IAASD,EAAS,UAAYC,EAAK,SAAWD,EAAS,gBAAkBC,EAAK,eAAiBD,EAAS,aAAeC,EAAK,UACzI,EAEAL,EAAc,YAAc,gBAgCrB,SAASM,EAAkB,CAAE,QAAAL,EAAS,GAAAM,EAAI,QAAAC,EAAU,CAAC,CAAE,EAA2B,CACvF,KAAM,CAAE,cAAeT,EAAc,uBAAAU,EAAyB,GAAM,YAAAC,EAAa,WAAYC,EAAmB,CAAC,EAAG,GAAGC,CAAiB,EAAIJ,EAGtIN,EAAgBnB,EAAQ,IAAMe,EAAqBC,CAAY,EAAG,CAACA,CAAY,CAAC,EAGhFc,EAAqB9B,EAAQ,KAE1B,CACL,GAFqBO,EAAyBsB,CAAgB,EAG9D,GAAGD,CACL,GACC,CAACC,EAAkBD,CAAgB,CAAC,EAGjCG,EAAS/B,EAAQ,IAAM,CAC3B,GAAI,CAAC0B,GAA0B,CAACC,EAAa,CAE3C,MAAMK,EAAYxB,EAA6BU,CAAO,EACtD,OAAOc,EAAU,KAAK,EAAI,CAACA,CAAS,EAAI,CAAC,CAC3C,CAEA,OAAOvB,EAAwBS,EAASS,CAAW,CACrD,EAAG,CAACT,EAASQ,EAAwBC,CAAW,CAAC,EAEjD,OAAKI,EAAO,OAKRA,EAAO,SAAW,EACbjC,EAAA,cAACmB,EAAA,CAAc,QAASc,EAAO,CAAC,EAAG,cAAeZ,EAAe,WAAYW,EAAoB,EAKxGhC,EAAA,cAACQ,EAAA,CAAK,UAAU,SAAS,IAAI,IAAI,MAAM,QACpCyB,EAAO,IAAI,CAACE,EAAOC,IAClBpC,EAAA,cAACmB,EAAA,CAAc,IAAK,GAAGO,CAAE,UAAUU,CAAK,GAAI,QAASD,EAAO,cAAed,EAAe,WAAYW,EAAoB,CAC3H,CACH,EAdO,IAgBX",
6
- "names": ["React", "memo", "useMemo", "ReactMarkdown", "remarkGfm", "rehypeRaw", "hardenReactMarkdown", "Box", "Flex", "createMarkdownComponents", "completeUnterminatedMarkdown", "parseMarkdownIntoBlocks", "HardenedMarkdown", "LINK_PREFIXES", "IMAGE_PREFIXES", "ALLOWED_PROTOCOLS", "DEFAULT_APP_ORIGIN", "resolveDefaultOrigin", "customOrigin", "MarkdownBlock", "content", "defaultOrigin", "components", "previous", "next", "StreamingMarkdown", "id", "options", "enableBlockMemoization", "blockParser", "customComponents", "componentOptions", "markdownComponents", "blocks", "completed", "block", "index"]
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"createMarkdownComponents.d.ts","sourceRoot":"","sources":["../../../../src/components/markdown/createMarkdownComponents.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGjD,OAAO,KAAK,EAAE,wBAAwB,EAAyB,MAAM,SAAS,CAAC;AA8B/E;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,GAAE,wBAA6B,GAAG,UAAU,CAmJ3F"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"markdownStreaming.d.ts","sourceRoot":"","sources":["../../../../../src/components/markdown/utils/markdownStreaming.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA2IH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAsGpE;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,KAAK,CAAC;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GACpD,MAAM,EAAE,CAuBV"}
File without changes