@kushagradhawan/kookie-blocks 0.1.16 → 0.1.18

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 (99) hide show
  1. package/dist/cjs/components/code/code-block.js +1 -1
  2. package/dist/cjs/components/code/code-block.js.map +2 -2
  3. package/dist/cjs/components/docs/docs-page-header.d.ts +12 -0
  4. package/dist/cjs/components/docs/docs-page-header.d.ts.map +1 -0
  5. package/dist/cjs/components/docs/docs-page-header.js +10 -0
  6. package/dist/cjs/components/docs/docs-page-header.js.map +7 -0
  7. package/dist/cjs/components/docs/docs-page.d.ts +28 -0
  8. package/dist/cjs/components/docs/docs-page.d.ts.map +1 -0
  9. package/dist/cjs/components/docs/docs-page.js +2 -0
  10. package/dist/cjs/components/docs/docs-page.js.map +7 -0
  11. package/dist/cjs/components/docs/docs-shell.d.ts +32 -0
  12. package/dist/cjs/components/docs/docs-shell.d.ts.map +1 -0
  13. package/dist/cjs/components/docs/docs-shell.js +2 -0
  14. package/dist/cjs/components/docs/docs-shell.js.map +7 -0
  15. package/dist/cjs/components/docs/docs-sidebar.d.ts +33 -0
  16. package/dist/cjs/components/docs/docs-sidebar.d.ts.map +1 -0
  17. package/dist/cjs/components/docs/docs-sidebar.js +2 -0
  18. package/dist/cjs/components/docs/docs-sidebar.js.map +7 -0
  19. package/dist/cjs/components/docs/index.d.ts +7 -0
  20. package/dist/cjs/components/docs/index.d.ts.map +1 -0
  21. package/dist/cjs/components/docs/index.js +2 -0
  22. package/dist/cjs/components/docs/index.js.map +7 -0
  23. package/dist/cjs/components/docs/table-of-contents.d.ts +12 -0
  24. package/dist/cjs/components/docs/table-of-contents.d.ts.map +1 -0
  25. package/dist/cjs/components/docs/table-of-contents.js +2 -0
  26. package/dist/cjs/components/docs/table-of-contents.js.map +7 -0
  27. package/dist/cjs/components/docs/types.d.ts +38 -0
  28. package/dist/cjs/components/docs/types.d.ts.map +1 -0
  29. package/dist/cjs/components/docs/types.js +2 -0
  30. package/dist/cjs/components/docs/types.js.map +7 -0
  31. package/dist/cjs/components/index.d.ts +1 -0
  32. package/dist/cjs/components/index.d.ts.map +1 -1
  33. package/dist/cjs/components/index.js +1 -1
  34. package/dist/cjs/components/index.js.map +2 -2
  35. package/dist/cjs/components/markdown/create-markdown-components.d.ts.map +1 -1
  36. package/dist/cjs/components/markdown/create-markdown-components.js +2 -2
  37. package/dist/cjs/components/markdown/create-markdown-components.js.map +3 -3
  38. package/dist/cjs/components/markdown/streaming-markdown.d.ts.map +1 -1
  39. package/dist/cjs/components/markdown/streaming-markdown.js +1 -1
  40. package/dist/cjs/components/markdown/streaming-markdown.js.map +3 -3
  41. package/dist/cjs/components/markdown/types.d.ts +7 -0
  42. package/dist/cjs/components/markdown/types.d.ts.map +1 -1
  43. package/dist/cjs/components/markdown/types.js +1 -1
  44. package/dist/cjs/components/markdown/types.js.map +1 -1
  45. package/dist/esm/components/code/code-block.js +1 -1
  46. package/dist/esm/components/code/code-block.js.map +2 -2
  47. package/dist/esm/components/docs/docs-page-header.d.ts +12 -0
  48. package/dist/esm/components/docs/docs-page-header.d.ts.map +1 -0
  49. package/dist/esm/components/docs/docs-page-header.js +10 -0
  50. package/dist/esm/components/docs/docs-page-header.js.map +7 -0
  51. package/dist/esm/components/docs/docs-page.d.ts +28 -0
  52. package/dist/esm/components/docs/docs-page.d.ts.map +1 -0
  53. package/dist/esm/components/docs/docs-page.js +2 -0
  54. package/dist/esm/components/docs/docs-page.js.map +7 -0
  55. package/dist/esm/components/docs/docs-shell.d.ts +32 -0
  56. package/dist/esm/components/docs/docs-shell.d.ts.map +1 -0
  57. package/dist/esm/components/docs/docs-shell.js +2 -0
  58. package/dist/esm/components/docs/docs-shell.js.map +7 -0
  59. package/dist/esm/components/docs/docs-sidebar.d.ts +33 -0
  60. package/dist/esm/components/docs/docs-sidebar.d.ts.map +1 -0
  61. package/dist/esm/components/docs/docs-sidebar.js +2 -0
  62. package/dist/esm/components/docs/docs-sidebar.js.map +7 -0
  63. package/dist/esm/components/docs/index.d.ts +7 -0
  64. package/dist/esm/components/docs/index.d.ts.map +1 -0
  65. package/dist/esm/components/docs/index.js +2 -0
  66. package/dist/esm/components/docs/index.js.map +7 -0
  67. package/dist/esm/components/docs/table-of-contents.d.ts +12 -0
  68. package/dist/esm/components/docs/table-of-contents.d.ts.map +1 -0
  69. package/dist/esm/components/docs/table-of-contents.js +2 -0
  70. package/dist/esm/components/docs/table-of-contents.js.map +7 -0
  71. package/dist/esm/components/docs/types.d.ts +38 -0
  72. package/dist/esm/components/docs/types.d.ts.map +1 -0
  73. package/dist/esm/components/docs/types.js +1 -0
  74. package/dist/esm/components/docs/types.js.map +7 -0
  75. package/dist/esm/components/index.d.ts +1 -0
  76. package/dist/esm/components/index.d.ts.map +1 -1
  77. package/dist/esm/components/index.js +1 -1
  78. package/dist/esm/components/index.js.map +2 -2
  79. package/dist/esm/components/markdown/create-markdown-components.d.ts.map +1 -1
  80. package/dist/esm/components/markdown/create-markdown-components.js +2 -2
  81. package/dist/esm/components/markdown/create-markdown-components.js.map +3 -3
  82. package/dist/esm/components/markdown/streaming-markdown.d.ts.map +1 -1
  83. package/dist/esm/components/markdown/streaming-markdown.js +1 -1
  84. package/dist/esm/components/markdown/streaming-markdown.js.map +3 -3
  85. package/dist/esm/components/markdown/types.d.ts +7 -0
  86. package/dist/esm/components/markdown/types.d.ts.map +1 -1
  87. package/package.json +5 -1
  88. package/src/components/code/code-block.tsx +1 -1
  89. package/src/components/docs/docs-page-header.tsx +92 -0
  90. package/src/components/docs/docs-page.tsx +99 -0
  91. package/src/components/docs/docs-shell.tsx +114 -0
  92. package/src/components/docs/docs-sidebar.tsx +180 -0
  93. package/src/components/docs/index.ts +16 -0
  94. package/src/components/docs/table-of-contents.tsx +157 -0
  95. package/src/components/docs/types.ts +45 -0
  96. package/src/components/index.ts +1 -0
  97. package/src/components/markdown/create-markdown-components.tsx +38 -24
  98. package/src/components/markdown/streaming-markdown.tsx +5 -1
  99. package/src/components/markdown/types.ts +8 -0
@@ -0,0 +1,33 @@
1
+ import React from 'react';
2
+ import type { DocsNavigationConfig, DocsLogoConfig } from './types.js';
3
+ type AccentColor = 'gray' | 'gold' | 'bronze' | 'brown' | 'yellow' | 'amber' | 'orange' | 'tomato' | 'red' | 'ruby' | 'crimson' | 'pink' | 'plum' | 'purple' | 'violet' | 'iris' | 'indigo' | 'blue' | 'cyan' | 'teal' | 'jade' | 'green' | 'grass' | 'lime' | 'mint' | 'sky';
4
+ export interface DocsSidebarProps {
5
+ /** Navigation configuration */
6
+ navigation: DocsNavigationConfig;
7
+ /** Logo configuration */
8
+ logo?: DocsLogoConfig;
9
+ /** Presentation mode from parent Shell */
10
+ presentation?: 'thin' | 'expanded';
11
+ /** Footer content */
12
+ footer?: React.ReactNode;
13
+ /** Sidebar size */
14
+ size?: '1' | '2';
15
+ /** Sidebar variant */
16
+ variant?: 'soft' | 'outline' | 'surface' | 'ghost';
17
+ /** Menu item variant */
18
+ menuVariant?: 'solid' | 'soft';
19
+ /** Accent color */
20
+ color?: AccentColor;
21
+ /** Current pathname for active state detection */
22
+ pathname?: string;
23
+ /** Link component to use (defaults to 'a') */
24
+ linkComponent?: React.ComponentType<{
25
+ href: string;
26
+ children: React.ReactNode;
27
+ prefetch?: boolean;
28
+ 'aria-label'?: string;
29
+ }>;
30
+ }
31
+ export declare function DocsSidebar({ navigation, logo, presentation, footer, size, variant, menuVariant, color, pathname, linkComponent: LinkComponent, }: DocsSidebarProps): React.JSX.Element;
32
+ export {};
33
+ //# sourceMappingURL=docs-sidebar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docs-sidebar.d.ts","sourceRoot":"","sources":["../../../../src/components/docs/docs-sidebar.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAyB,MAAM,OAAO,CAAC;AAG9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAKvE,KAAK,WAAW,GACZ,MAAM,GACN,MAAM,GACN,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,KAAK,GACL,MAAM,GACN,SAAS,GACT,MAAM,GACN,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,OAAO,GACP,OAAO,GACP,MAAM,GACN,MAAM,GACN,KAAK,CAAC;AAEV,MAAM,WAAW,gBAAgB;IAC/B,+BAA+B;IAC/B,UAAU,EAAE,oBAAoB,CAAC;IACjC,yBAAyB;IACzB,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IACnC,qBAAqB;IACrB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,mBAAmB;IACnB,IAAI,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;IACjB,sBAAsB;IACtB,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IACnD,wBAAwB;IACxB,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC/B,mBAAmB;IACnB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,aAAa,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC7H;AAED,wBAAgB,WAAW,CAAC,EAC1B,UAAU,EACV,IAAI,EACJ,YAAyB,EACzB,MAAM,EACN,IAAU,EACV,OAAgB,EAChB,WAAoB,EACpB,KAAc,EACd,QAAa,EACb,aAAa,EAAE,aAA0B,GAC1C,EAAE,gBAAgB,qBA2GlB"}
@@ -0,0 +1,2 @@
1
+ "use client";import e,{isValidElement as C}from"react";import{Sidebar as r,Flex as b,Avatar as M}from"@kushagradhawan/kookie-ui";import{HugeiconsIcon as v}from"@hugeicons/react";function I({navigation:p,logo:i,presentation:f="expanded",footer:u,size:g="2",variant:c="soft",menuVariant:S="soft",color:m="gray",pathname:a="",linkComponent:s="a"}){const y=n=>Array.isArray(n)&&n.length>0&&Array.isArray(n[0]),l=n=>n?C(n)?n:y(n)?e.createElement(v,{icon:n,size:16}):typeof n=="function"?e.createElement(n,null):null:null;return e.createElement(r.Root,{size:g,variant:c,color:m,menuVariant:S,presentation:f},i&&e.createElement(r.Header,null,e.createElement(b,{justify:"between",align:"center",width:"100%"},e.createElement(s,{href:i.href||"/","aria-label":i.alt||"Home"},e.createElement(b,{align:"center",gap:"2"},e.createElement(M,{fallback:i.alt?.[0]||"K",size:"2",src:i.src}))))),e.createElement(r.Content,null,e.createElement(r.Menu,null,p.groups.map(n=>e.createElement(r.Group,{key:n.label},e.createElement(r.GroupLabel,null,n.label),e.createElement(r.GroupContent,null,n.items.map(o=>{const d=o.items&&o.items.length>0,h=d?o.items.some(t=>a===t.href):!1;return d?e.createElement(r.MenuItem,{key:o.href},e.createElement(r.MenuSub,{defaultOpen:h},e.createElement(r.MenuSubTrigger,null,l(o.icon),o.title),e.createElement(r.MenuSubContent,null,o.items.map(t=>e.createElement(r.MenuButton,{asChild:!0,key:t.href,isActive:a===t.href},e.createElement(s,{href:t.href},l(t.icon),e.createElement("span",{className:"rt-SidebarMenuLabel"},t.title))))))):e.createElement(r.MenuItem,{key:o.href},e.createElement(r.MenuButton,{asChild:!0,isActive:a===o.href,badge:o.badge},e.createElement(s,{href:o.href},l(o.icon),e.createElement("span",{className:"rt-SidebarMenuLabel"},o.title))))})))))),u&&e.createElement(r.Footer,null,u))}export{I as DocsSidebar};
2
+ //# sourceMappingURL=docs-sidebar.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/components/docs/docs-sidebar.tsx"],
4
+ "sourcesContent": ["'use client';\n\nimport React, { isValidElement } from 'react';\nimport { Sidebar, Flex, Avatar } from '@kushagradhawan/kookie-ui';\nimport { HugeiconsIcon } from '@hugeicons/react';\nimport type { DocsNavigationConfig, DocsLogoConfig } from './types.js';\n\n// HugeIcons IconSvgObject type - readonly array of tuples with tag name and attributes\ntype IconSvgObject = readonly (readonly [string, { readonly [key: string]: string | number }])[];\n\ntype AccentColor =\n | 'gray'\n | 'gold'\n | 'bronze'\n | 'brown'\n | 'yellow'\n | 'amber'\n | 'orange'\n | 'tomato'\n | 'red'\n | 'ruby'\n | 'crimson'\n | 'pink'\n | 'plum'\n | 'purple'\n | 'violet'\n | 'iris'\n | 'indigo'\n | 'blue'\n | 'cyan'\n | 'teal'\n | 'jade'\n | 'green'\n | 'grass'\n | 'lime'\n | 'mint'\n | 'sky';\n\nexport interface DocsSidebarProps {\n /** Navigation configuration */\n navigation: DocsNavigationConfig;\n /** Logo configuration */\n logo?: DocsLogoConfig;\n /** Presentation mode from parent Shell */\n presentation?: 'thin' | 'expanded';\n /** Footer content */\n footer?: React.ReactNode;\n /** Sidebar size */\n size?: '1' | '2';\n /** Sidebar variant */\n variant?: 'soft' | 'outline' | 'surface' | 'ghost';\n /** Menu item variant */\n menuVariant?: 'solid' | 'soft';\n /** Accent color */\n color?: AccentColor;\n /** Current pathname for active state detection */\n pathname?: string;\n /** Link component to use (defaults to 'a') */\n linkComponent?: React.ComponentType<{ href: string; children: React.ReactNode; prefetch?: boolean; 'aria-label'?: string }>;\n}\n\nexport function DocsSidebar({\n navigation,\n logo,\n presentation = 'expanded',\n footer,\n size = '2',\n variant = 'soft',\n menuVariant = 'soft',\n color = 'gray',\n pathname = '',\n linkComponent: LinkComponent = 'a' as any,\n}: DocsSidebarProps) {\n\n // Helper to check if icon is HugeIcons IconSvgObject format\n const isIconSvgObject = (icon: unknown): icon is IconSvgObject => {\n return Array.isArray(icon) && icon.length > 0 && Array.isArray(icon[0]);\n };\n\n // Helper to render icon\n const renderIcon = (icon: React.ComponentType<{ className?: string }> | React.ReactNode | IconSvgObject) => {\n if (!icon) return null;\n if (isValidElement(icon)) return icon;\n // Handle HugeIcons IconSvgObject format\n if (isIconSvgObject(icon)) {\n return <HugeiconsIcon icon={icon} size={16} />;\n }\n if (typeof icon === 'function') {\n const IconComponent = icon as React.ComponentType<{ className?: string }>;\n return <IconComponent />;\n }\n return null;\n };\n\n return (\n <Sidebar.Root\n size={size}\n variant={variant}\n color={color}\n menuVariant={menuVariant}\n presentation={presentation}\n >\n {logo && (\n <Sidebar.Header>\n <Flex justify=\"between\" align=\"center\" width=\"100%\">\n <LinkComponent href={logo.href || '/'} aria-label={logo.alt || 'Home'}>\n <Flex align=\"center\" gap=\"2\">\n <Avatar fallback={logo.alt?.[0] || 'K'} size=\"2\" src={logo.src} />\n </Flex>\n </LinkComponent>\n </Flex>\n </Sidebar.Header>\n )}\n\n <Sidebar.Content>\n <Sidebar.Menu>\n {navigation.groups.map((group) => (\n <Sidebar.Group key={group.label}>\n <Sidebar.GroupLabel>{group.label}</Sidebar.GroupLabel>\n <Sidebar.GroupContent>\n {group.items.map((item) => {\n // Check if this item or any nested item is active\n const hasNestedItems = item.items && item.items.length > 0;\n const isNestedActive = hasNestedItems\n ? item.items!.some((subItem) => pathname === subItem.href)\n : false;\n\n if (hasNestedItems) {\n return (\n <Sidebar.MenuItem key={item.href}>\n <Sidebar.MenuSub defaultOpen={isNestedActive}>\n <Sidebar.MenuSubTrigger>\n {renderIcon(item.icon)}\n {item.title}\n </Sidebar.MenuSubTrigger>\n <Sidebar.MenuSubContent>\n {item.items!.map((subItem) => (\n <Sidebar.MenuButton\n asChild\n key={subItem.href}\n isActive={pathname === subItem.href}\n >\n <LinkComponent href={subItem.href}>\n {renderIcon(subItem.icon)}\n <span className=\"rt-SidebarMenuLabel\">{subItem.title}</span>\n </LinkComponent>\n </Sidebar.MenuButton>\n ))}\n </Sidebar.MenuSubContent>\n </Sidebar.MenuSub>\n </Sidebar.MenuItem>\n );\n }\n\n // Regular menu item\n return (\n <Sidebar.MenuItem key={item.href}>\n <Sidebar.MenuButton\n asChild\n isActive={pathname === item.href}\n badge={item.badge}\n >\n <LinkComponent href={item.href}>\n {renderIcon(item.icon)}\n <span className=\"rt-SidebarMenuLabel\">{item.title}</span>\n </LinkComponent>\n </Sidebar.MenuButton>\n </Sidebar.MenuItem>\n );\n })}\n </Sidebar.GroupContent>\n </Sidebar.Group>\n ))}\n </Sidebar.Menu>\n </Sidebar.Content>\n\n {footer && <Sidebar.Footer>{footer}</Sidebar.Footer>}\n </Sidebar.Root>\n );\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["React", "isValidElement", "Sidebar", "Flex", "Avatar", "HugeiconsIcon", "DocsSidebar", "navigation", "logo", "presentation", "footer", "size", "variant", "menuVariant", "color", "pathname", "LinkComponent", "isIconSvgObject", "icon", "renderIcon", "group", "item", "hasNestedItems", "isNestedActive", "subItem"]
7
+ }
@@ -0,0 +1,7 @@
1
+ export type { DocsNavigationItem, DocsNavigationGroup, DocsNavigationConfig, DocsPageMeta, DocsLogoConfig, TocItem, } from './types.js';
2
+ export { TableOfContents } from './table-of-contents.js';
3
+ export { DocsSidebar } from './docs-sidebar.js';
4
+ export { DocsPageHeader } from './docs-page-header.js';
5
+ export { DocsPage } from './docs-page.js';
6
+ export { DocsShell } from './docs-shell.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/docs/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,cAAc,EACd,OAAO,GACR,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{TableOfContents as t}from"./table-of-contents.js";import{DocsSidebar as a}from"./docs-sidebar.js";import{DocsPageHeader as c}from"./docs-page-header.js";import{DocsPage as g}from"./docs-page.js";import{DocsShell as p}from"./docs-shell.js";export{g as DocsPage,c as DocsPageHeader,p as DocsShell,a as DocsSidebar,t as TableOfContents};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/components/docs/index.ts"],
4
+ "sourcesContent": ["// Types\nexport type {\n DocsNavigationItem,\n DocsNavigationGroup,\n DocsNavigationConfig,\n DocsPageMeta,\n DocsLogoConfig,\n TocItem,\n} from './types.js';\n\n// Components\nexport { TableOfContents } from './table-of-contents.js';\nexport { DocsSidebar } from './docs-sidebar.js';\nexport { DocsPageHeader } from './docs-page-header.js';\nexport { DocsPage } from './docs-page.js';\nexport { DocsShell } from './docs-shell.js';\n"],
5
+ "mappings": "AAWA,OAAS,mBAAAA,MAAuB,yBAChC,OAAS,eAAAC,MAAmB,oBAC5B,OAAS,kBAAAC,MAAsB,wBAC/B,OAAS,YAAAC,MAAgB,iBACzB,OAAS,aAAAC,MAAiB",
6
+ "names": ["TableOfContents", "DocsSidebar", "DocsPageHeader", "DocsPage", "DocsShell"]
7
+ }
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ export interface TableOfContentsProps {
3
+ className?: string;
4
+ /** Heading levels to include (default: [2]) */
5
+ levels?: number[];
6
+ /** Title shown above TOC (default: "On this page") */
7
+ title?: string;
8
+ /** Optional wrapper for the TOC content */
9
+ renderContainer?: (tocContent: React.ReactNode) => React.ReactNode | null;
10
+ }
11
+ export declare const TableOfContents: React.NamedExoticComponent<TableOfContentsProps>;
12
+ //# sourceMappingURL=table-of-contents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-of-contents.d.ts","sourceRoot":"","sources":["../../../../src/components/docs/table-of-contents.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAyD,MAAM,OAAO,CAAC;AAa9E,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC;CAC3E;AAED,eAAO,MAAM,eAAe,kDAmI1B,CAAC"}
@@ -0,0 +1,2 @@
1
+ "use client";import l,{useEffect as S,useState as b,useCallback as x,useRef as u,memo as A}from"react";import{Text as k,Link as E,Flex as h}from"@kushagradhawan/kookie-ui";const R=a=>a.toLowerCase().replace(/[^\w\s-]/g,"").replace(/\s+/g,"-").trim(),P=A(function({className:y,levels:f=[2],title:C="On this page",renderContainer:m}){const[d,I]=b([]),[T,v]=b(""),r=u(null),c=u(null),s=u(null),g=x(()=>{c.current=requestAnimationFrame(()=>{const t=document.querySelector("[data-content-area]");if(!t)return;const O=f.map(e=>`h${e}`).join(", "),i=Array.from(t.querySelectorAll(O)).map(e=>{const o=e.textContent||"";let n=e.id;return!n&&o&&(n=R(o),e.id=n),{id:n,text:o,level:parseInt(e.tagName.charAt(1))}}).filter(e=>e.id&&e.text);if(I(i),r.current&&(r.current.disconnect(),r.current=null),i.length>0){const e=new IntersectionObserver(o=>{o.forEach(n=>{n.isIntersecting&&v(n.target.id)})},{rootMargin:"-20% 0% -35% 0%"});i.forEach(({id:o})=>{const n=document.getElementById(o);n&&e.observe(n)}),r.current=e}})},[f]);S(()=>(s.current=window.setTimeout(()=>{g()},100),()=>{s.current&&(clearTimeout(s.current),s.current=null),c.current&&(cancelAnimationFrame(c.current),c.current=null),r.current&&(r.current.disconnect(),r.current=null)}),[g]);const w=x(t=>({display:"block",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis",paddingLeft:t>2?`${(t-2)*12}px`:"0"}),[]);if(d.length===0)return null;const p=l.createElement(h,{direction:"column",gap:"3",className:y},l.createElement(k,{size:"1",weight:"medium",color:"gray"},C),l.createElement(h,{direction:"column",gap:"2"},d.map(t=>l.createElement(E,{key:t.id,color:"gray",highContrast:T===t.id,size:"1",href:`#${t.id}`,style:w(t.level)},t.text))));return m?m(p):p});export{P as TableOfContents};
2
+ //# sourceMappingURL=table-of-contents.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/components/docs/table-of-contents.tsx"],
4
+ "sourcesContent": ["'use client';\n\nimport React, { useEffect, useState, useCallback, useRef, memo } from 'react';\nimport { Box, Text, Link, Flex } from '@kushagradhawan/kookie-ui';\nimport type { TocItem } from './types.js';\n\n// Generate slug from heading text\nconst generateSlug = (text: string): string => {\n return text\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, '')\n .replace(/\\s+/g, '-')\n .trim();\n};\n\nexport interface TableOfContentsProps {\n className?: string;\n /** Heading levels to include (default: [2]) */\n levels?: number[];\n /** Title shown above TOC (default: \"On this page\") */\n title?: string;\n /** Optional wrapper for the TOC content */\n renderContainer?: (tocContent: React.ReactNode) => React.ReactNode | null;\n}\n\nexport const TableOfContents = memo(function TableOfContents({\n className,\n levels = [2],\n title = 'On this page',\n renderContainer,\n}: TableOfContentsProps) {\n const [toc, setToc] = useState<TocItem[]>([]);\n const [activeId, setActiveId] = useState<string>('');\n const observerRef = useRef<IntersectionObserver | null>(null);\n const rafIdRef = useRef<number | null>(null);\n const timeoutIdRef = useRef<number | null>(null);\n\n const extractHeadings = useCallback(() => {\n rafIdRef.current = requestAnimationFrame(() => {\n const contentArea = document.querySelector('[data-content-area]');\n if (!contentArea) return;\n\n // Build selector from levels\n const selector = levels.map((l) => `h${l}`).join(', ');\n const headingElements = Array.from(contentArea.querySelectorAll(selector));\n\n const headings = headingElements\n .map((heading) => {\n const text = heading.textContent || '';\n let id = heading.id;\n\n if (!id && text) {\n id = generateSlug(text);\n heading.id = id;\n }\n\n return {\n id,\n text,\n level: parseInt(heading.tagName.charAt(1)),\n };\n })\n .filter((item) => item.id && item.text);\n\n setToc(headings);\n\n // Disconnect any previous observer\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n\n if (headings.length > 0) {\n const observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n setActiveId(entry.target.id);\n }\n });\n },\n { rootMargin: '-20% 0% -35% 0%' }\n );\n\n headings.forEach(({ id }) => {\n const element = document.getElementById(id);\n if (element) observer.observe(element);\n });\n\n observerRef.current = observer;\n }\n });\n }, [levels]);\n\n useEffect(() => {\n // Initial extraction with delay for DOM readiness\n timeoutIdRef.current = window.setTimeout(() => {\n extractHeadings();\n }, 100);\n\n return () => {\n if (timeoutIdRef.current) {\n clearTimeout(timeoutIdRef.current);\n timeoutIdRef.current = null;\n }\n if (rafIdRef.current) {\n cancelAnimationFrame(rafIdRef.current);\n rafIdRef.current = null;\n }\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n };\n }, [extractHeadings]);\n\n const getLinkStyle = useCallback(\n (level: number): React.CSSProperties => ({\n display: 'block',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n paddingLeft: level > 2 ? `${(level - 2) * 12}px` : '0',\n }),\n []\n );\n\n if (toc.length === 0) return null;\n\n const tocContent = (\n <Flex direction=\"column\" gap=\"3\" className={className}>\n <Text size=\"1\" weight=\"medium\" color=\"gray\">\n {title}\n </Text>\n <Flex direction=\"column\" gap=\"2\">\n {toc.map((item) => (\n <Link\n key={item.id}\n color=\"gray\"\n highContrast={activeId === item.id}\n size=\"1\"\n href={`#${item.id}`}\n style={getLinkStyle(item.level)}\n >\n {item.text}\n </Link>\n ))}\n </Flex>\n </Flex>\n );\n\n if (renderContainer) {\n return renderContainer(tocContent);\n }\n\n return tocContent;\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["React", "useEffect", "useState", "useCallback", "useRef", "memo", "Text", "Link", "Flex", "generateSlug", "text", "TableOfContents", "className", "levels", "title", "renderContainer", "toc", "setToc", "activeId", "setActiveId", "observerRef", "rafIdRef", "timeoutIdRef", "extractHeadings", "contentArea", "selector", "l", "headings", "heading", "id", "item", "observer", "entries", "entry", "element", "getLinkStyle", "level", "tocContent"]
7
+ }
@@ -0,0 +1,38 @@
1
+ import type { ReactNode, ComponentType } from 'react';
2
+ type IconSvgObject = readonly (readonly [string, {
3
+ readonly [key: string]: string | number;
4
+ }])[];
5
+ export interface DocsNavigationItem {
6
+ href: string;
7
+ title: string;
8
+ icon?: ComponentType<{
9
+ className?: string;
10
+ }> | ReactNode | IconSvgObject;
11
+ badge?: string;
12
+ items?: DocsNavigationItem[];
13
+ }
14
+ export interface DocsNavigationGroup {
15
+ label: string;
16
+ items: DocsNavigationItem[];
17
+ }
18
+ export interface DocsNavigationConfig {
19
+ groups: DocsNavigationGroup[];
20
+ }
21
+ export interface DocsPageMeta {
22
+ title: string;
23
+ description?: string;
24
+ category?: string;
25
+ source?: string;
26
+ }
27
+ export interface DocsLogoConfig {
28
+ src: string;
29
+ alt?: string;
30
+ href?: string;
31
+ }
32
+ export interface TocItem {
33
+ id: string;
34
+ text: string;
35
+ level: number;
36
+ }
37
+ export {};
38
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/docs/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAGtD,KAAK,aAAa,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE;IAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC,CAAC,EAAE,CAAC;AAGjG,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IAEd,IAAI,CAAC,EAAE,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,SAAS,GAAG,aAAa,CAAC;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,kBAAkB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,kBAAkB,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,mBAAmB,EAAE,CAAC;CAC/B;AAGD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAGD,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAGD,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf"}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -1,4 +1,5 @@
1
1
  export * from './code/index.js';
2
+ export * from './docs/index.js';
2
3
  export * from './hero/index.js';
3
4
  export * from './markdown/index.js';
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC"}
@@ -1,2 +1,2 @@
1
- export*from"./code/index.js";export*from"./hero/index.js";export*from"./markdown/index.js";
1
+ export*from"./code/index.js";export*from"./docs/index.js";export*from"./hero/index.js";export*from"./markdown/index.js";
2
2
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/index.ts"],
4
- "sourcesContent": ["export * from './code/index.js';\nexport * from './hero/index.js';\nexport * from './markdown/index.js';\n"],
5
- "mappings": "AAAA,WAAc,kBACd,WAAc,kBACd,WAAc",
4
+ "sourcesContent": ["export * from './code/index.js';\nexport * from './docs/index.js';\nexport * from './hero/index.js';\nexport * from './markdown/index.js';\n"],
5
+ "mappings": "AAAA,WAAc,kBACd,WAAc,kBACd,WAAc,kBACd,WAAc",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"create-markdown-components.d.ts","sourceRoot":"","sources":["../../../../src/components/markdown/create-markdown-components.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
+ {"version":3,"file":"create-markdown-components.d.ts","sourceRoot":"","sources":["../../../../src/components/markdown/create-markdown-components.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,CAiK3F"}
@@ -1,3 +1,3 @@
1
- import r from"react";import{Blockquote as u,Box as p,Code as C,Heading as d,Text as g,Table as l}from"@kushagradhawan/kookie-ui";import{CodeBlock as w}from"../code";function y(o){return o?o.match(/language-([\w-]+)/i)?.[1]??"text":"text"}function k(o){let n="";return o?(typeof o=="string"?n=o:Array.isArray(o)&&(n=o.map(s=>typeof s=="string"?s:"").join("")),n.replace(/^\n+|\n+$/g,"")):n}function H(o={}){const{codeBlockCollapsible:n=!1,imageComponent:s,inlineCodeHighContrast:h=!0}=o;return{h1:({children:e})=>r.createElement(d,{size:"9",weight:"medium",as:"h1",style:{marginTop:"1rem",marginBottom:"0.5rem"}},e),h2:({children:e})=>r.createElement(d,{weight:"medium",size:"6",as:"h2",style:{marginTop:"0.875rem",marginBottom:"0.5rem"}},e),h3:({children:e})=>r.createElement(d,{weight:"medium",size:"5",as:"h3",style:{marginTop:"0.75rem",marginBottom:"0.5rem"}},e),h4:({children:e})=>r.createElement(d,{weight:"medium",size:"4",as:"h4",style:{marginTop:"0.625rem",marginBottom:"0.5rem"}},e),h5:({children:e})=>r.createElement(d,{weight:"medium",size:"3",as:"h5",style:{marginTop:"0.5rem",marginBottom:"0.5rem"}},e),h6:({children:e})=>r.createElement(d,{weight:"medium",size:"2",as:"h6",style:{marginTop:"0.5rem",marginBottom:"0.5rem"}},e),p:({children:e})=>r.createElement(g,{size:"3",as:"p",style:{lineHeight:"1.6"}},e),code:({className:e,children:i,inline:m})=>{const t=k(i);return m===!0||m===void 0&&!e&&!t.includes(`
2
- `)&&t.length<100?r.createElement(C,{highContrast:h,size:"3"},t):r.createElement(p,{my:"2",style:{minWidth:0}},r.createElement(w,{code:t,language:y(e),collapsible:n}))},ul:({children:e})=>r.createElement("ul",{style:{marginTop:"0.5rem",marginBottom:"0.5rem",lineHeight:"1.6",paddingLeft:"1.5rem",listStyleType:"disc"}},e),ol:({children:e})=>r.createElement("ol",{style:{marginTop:"0.5rem",marginBottom:"0.5rem",lineHeight:"1.6",paddingLeft:"1.5rem",listStyleType:"decimal"}},e),li:({children:e})=>r.createElement("li",{style:{marginBottom:"0.25rem",lineHeight:"1.6"}},e),blockquote:({children:e})=>r.createElement(u,null,e),a:({href:e,children:i})=>r.createElement("a",{href:e,style:{color:"var(--accent-9)",textDecoration:"underline"}},i),strong:({children:e})=>r.createElement(g,{weight:"medium",style:{lineHeight:"1.6"}},e),em:({children:e})=>r.createElement(g,{style:{lineHeight:"1.6",fontStyle:"italic"}},e),hr:()=>r.createElement("hr",{style:{color:"var(--gray-6)",marginTop:"0.5rem",marginBottom:"0.5rem",height:"1px",width:"100%",opacity:.5}}),pre:({children:e})=>r.createElement(r.Fragment,null,e),table:({children:e})=>r.createElement(p,{my:"2",style:{overflowX:"auto"}},r.createElement(l.Root,{size:"2",variant:"ghost"},e)),thead:({children:e})=>r.createElement(l.Header,null,e),tbody:({children:e})=>r.createElement(l.Body,null,e),tr:({children:e})=>r.createElement(l.Row,null,e),th:({children:e})=>r.createElement(l.ColumnHeaderCell,null,e),td:({children:e})=>r.createElement(l.Cell,null,e),sub:({children:e})=>r.createElement("sub",null,e),sup:({children:e})=>r.createElement("sup",null,e),br:()=>r.createElement("br",null),img:s?e=>{const{src:i,alt:m,width:t,height:a}=e;return!i||typeof i!="string"?null:s({src:i,alt:m??"Image",width:t?String(t):void 0,height:a?String(a):void 0})}:void 0,details:({children:e})=>r.createElement("details",{style:{padding:"0.5rem 0"}},e),summary:({children:e})=>r.createElement("summary",{style:{cursor:"pointer",fontWeight:500}},e)}}export{H as createMarkdownComponents};
1
+ import e from"react";import{Blockquote as T,Box as u,Code as c,Heading as l,Text as C,Table as d,Separator as B}from"@kushagradhawan/kookie-ui";import{CodeBlock as H}from"../code";function x(n){return n?n.match(/language-([\w-]+)/i)?.[1]??"text":"text"}function z(n){let i="";return n?(typeof n=="string"?i=n:Array.isArray(n)&&(i=n.map(a=>typeof a=="string"?a:"").join("")),i.replace(/^\n+|\n+$/g,"")):i}function v(n={}){const{codeBlockCollapsible:i=!1,imageComponent:a,inlineCodeHighContrast:M=!0,spacing:k="spacious"}=n,r=k==="compact",t={h1:{top:r?"1.5rem":"3rem",bottom:r?"1rem":"1.5rem"},h2:{top:r?"2rem":"3rem",bottom:r?"0.375rem":"0.5rem"},h3:{top:r?"1.5rem":"2rem",bottom:r?"0.375rem":"0.5rem"},h4:{top:r?"0.5rem":"0.625rem",bottom:r?"0.25rem":"0.5rem"},h5:{top:r?"0.375rem":"0.5rem",bottom:r?"0.25rem":"0.5rem"},h6:{top:r?"0.375rem":"0.5rem",bottom:r?"0.25rem":"0.5rem"}},h=r?"0.25rem":"0.5rem",b=r?"0.125rem":"0.25rem",f=r?"1":"2",w=r?"0.375rem":"0.5rem",y=r?"0":"0.5rem",P=r?"0.5rem":"1rem";return{h1:({children:o})=>e.createElement(l,{size:"9",weight:"medium",as:"h1",style:{marginTop:t.h1.top,marginBottom:t.h1.bottom}},o),h2:({children:o})=>e.createElement(l,{weight:"medium",size:"7",as:"h2",style:{marginTop:t.h2.top,marginBottom:t.h2.bottom}},o),h3:({children:o})=>e.createElement(l,{weight:"medium",size:"5",as:"h3",style:{marginTop:t.h3.top,marginBottom:t.h3.bottom}},o),h4:({children:o})=>e.createElement(l,{weight:"medium",size:"4",as:"h4",style:{marginTop:t.h4.top,marginBottom:t.h4.bottom}},o),h5:({children:o})=>e.createElement(l,{weight:"medium",size:"3",as:"h5",style:{marginTop:t.h5.top,marginBottom:t.h5.bottom}},o),h6:({children:o})=>e.createElement(l,{weight:"medium",size:"2",as:"h6",style:{marginTop:t.h6.top,marginBottom:t.h6.bottom}},o),p:({children:o})=>e.createElement(C,{size:"3",as:"p",style:{lineHeight:"1.6",marginTop:y,marginBottom:y}},o),code:({className:o,children:m,inline:p})=>{const s=z(m);return p===!0||p===void 0&&!o&&!s.includes(`
2
+ `)&&s.length<100?e.createElement(c,{highContrast:M,size:"3"},s):e.createElement(u,{my:f,style:{minWidth:0}},e.createElement(H,{code:s,language:x(o),collapsible:i}))},ul:({children:o})=>e.createElement("ul",{style:{marginTop:h,marginBottom:h,lineHeight:"1.6",paddingLeft:"1.5rem",listStyleType:"disc"}},o),ol:({children:o})=>e.createElement("ol",{style:{marginTop:h,marginBottom:h,lineHeight:"1.6",paddingLeft:"1.5rem",listStyleType:"decimal"}},o),li:({children:o})=>e.createElement("li",{style:{marginBottom:b,lineHeight:"1.6"}},o),blockquote:({children:o})=>e.createElement(T,{size:"1",my:P},o),a:({href:o,children:m})=>e.createElement("a",{href:o,style:{color:"var(--accent-9)",textDecoration:"underline"}},m),strong:({children:o})=>e.createElement(C,{weight:"medium",style:{lineHeight:"1.6"}},o),em:({children:o})=>e.createElement(C,{style:{lineHeight:"1.6",fontStyle:"italic"}},o),hr:()=>e.createElement(u,{style:{marginTop:w,marginBottom:w}},e.createElement(B,{orientation:"horizontal",light:!0})),pre:({children:o})=>e.createElement(e.Fragment,null,o),table:({children:o})=>e.createElement(u,{my:"2",style:{overflowX:"auto"}},e.createElement(d.Root,{size:"2",variant:"ghost"},o)),thead:({children:o})=>e.createElement(d.Header,null,o),tbody:({children:o})=>e.createElement(d.Body,null,o),tr:({children:o})=>e.createElement(d.Row,null,o),th:({children:o})=>e.createElement(d.ColumnHeaderCell,null,o),td:({children:o})=>e.createElement(d.Cell,null,o),sub:({children:o})=>e.createElement("sub",null,o),sup:({children:o})=>e.createElement("sup",null,o),br:()=>e.createElement("br",null),img:a?o=>{const{src:m,alt:p,width:s,height:g}=o;return!m||typeof m!="string"?null:a({src:m,alt:p??"Image",width:s?String(s):void 0,height:g?String(g):void 0})}:void 0,details:({children:o})=>e.createElement("details",{style:{padding:"0.5rem 0"}},o),summary:({children:o})=>e.createElement("summary",{style:{cursor:"pointer",fontWeight:500}},o)}}export{v as createMarkdownComponents};
3
3
  //# sourceMappingURL=create-markdown-components.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/markdown/create-markdown-components.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 (9-6-5-4-3-2)\n h1: ({ children }: MarkdownChildrenProps) => (\n <Heading size=\"9\" weight=\"medium\" as=\"h1\" style={{ marginTop: \"1rem\", marginBottom: \"0.5rem\" }}>\n {children}\n </Heading>\n ),\n h2: ({ children }: MarkdownChildrenProps) => (\n <Heading weight=\"medium\" size=\"6\" as=\"h2\" style={{ marginTop: \"0.875rem\", marginBottom: \"0.5rem\" }}>\n {children}\n </Heading>\n ),\n h3: ({ children }: MarkdownChildrenProps) => (\n <Heading weight=\"medium\" size=\"5\" as=\"h3\" style={{ marginTop: \"0.75rem\", marginBottom: \"0.5rem\" }}>\n {children}\n </Heading>\n ),\n h4: ({ children }: MarkdownChildrenProps) => (\n <Heading weight=\"medium\" size=\"4\" 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=\"2\" 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"],
5
- "mappings": "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",
6
- "names": ["React", "Blockquote", "Box", "Code", "Heading", "Text", "Table", "CodeBlock", "extractLanguage", "className", "extractCode", "children", "code", "child", "createMarkdownComponents", "options", "codeBlockCollapsible", "imageComponent", "inlineCodeHighContrast", "inline", "href", "props", "src", "alt", "width", "height"]
4
+ "sourcesContent": ["import React, { type ReactNode } from \"react\";\nimport type { Components } from \"react-markdown\";\nimport { Blockquote, Box, Code, Flex, Heading, Text, Table, Separator } 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, spacing = \"spacious\" } = options;\n\n // Spacing configuration\n const isCompact = spacing === \"compact\";\n const headingMargins = {\n h1: { top: isCompact ? \"1.5rem\" : \"3rem\", bottom: isCompact ? \"1rem\" : \"1.5rem\" },\n h2: { top: isCompact ? \"2rem\" : \"3rem\", bottom: isCompact ? \"0.375rem\" : \"0.5rem\" },\n h3: { top: isCompact ? \"1.5rem\" : \"2rem\", bottom: isCompact ? \"0.375rem\" : \"0.5rem\" },\n h4: { top: isCompact ? \"0.5rem\" : \"0.625rem\", bottom: isCompact ? \"0.25rem\" : \"0.5rem\" },\n h5: { top: isCompact ? \"0.375rem\" : \"0.5rem\", bottom: isCompact ? \"0.25rem\" : \"0.5rem\" },\n h6: { top: isCompact ? \"0.375rem\" : \"0.5rem\", bottom: isCompact ? \"0.25rem\" : \"0.5rem\" },\n };\n const listMargin = isCompact ? \"0.25rem\" : \"0.5rem\";\n const listItemMargin = isCompact ? \"0.125rem\" : \"0.25rem\";\n const codeBlockMargin = isCompact ? \"1\" : \"2\";\n const hrMargin = isCompact ? \"0.375rem\" : \"0.5rem\";\n const paragraphMargin = isCompact ? \"0\" : \"0.5rem\";\n const blockquoteMargin = isCompact ? \"0.5rem\" : \"1rem\";\n\n return {\n // Headings with consistent visual hierarchy (9-6-5-4-3-2)\n h1: ({ children }: MarkdownChildrenProps) => (\n <Heading size=\"9\" weight=\"medium\" as=\"h1\" style={{ marginTop: headingMargins.h1.top, marginBottom: headingMargins.h1.bottom }}>\n {children}\n </Heading>\n ),\n h2: ({ children }: MarkdownChildrenProps) => (\n <Heading weight=\"medium\" size=\"7\" as=\"h2\" style={{ marginTop: headingMargins.h2.top, marginBottom: headingMargins.h2.bottom }}>\n {children}\n </Heading>\n ),\n h3: ({ children }: MarkdownChildrenProps) => (\n <Heading weight=\"medium\" size=\"5\" as=\"h3\" style={{ marginTop: headingMargins.h3.top, marginBottom: headingMargins.h3.bottom }}>\n {children}\n </Heading>\n ),\n h4: ({ children }: MarkdownChildrenProps) => (\n <Heading weight=\"medium\" size=\"4\" as=\"h4\" style={{ marginTop: headingMargins.h4.top, marginBottom: headingMargins.h4.bottom }}>\n {children}\n </Heading>\n ),\n h5: ({ children }: MarkdownChildrenProps) => (\n <Heading weight=\"medium\" size=\"3\" as=\"h5\" style={{ marginTop: headingMargins.h5.top, marginBottom: headingMargins.h5.bottom }}>\n {children}\n </Heading>\n ),\n h6: ({ children }: MarkdownChildrenProps) => (\n <Heading weight=\"medium\" size=\"2\" as=\"h6\" style={{ marginTop: headingMargins.h6.top, marginBottom: headingMargins.h6.bottom }}>\n {children}\n </Heading>\n ),\n\n // Paragraph text\n p: ({ children }: MarkdownChildrenProps) => (\n <Text size=\"3\" as=\"p\" style={{ lineHeight: \"1.6\", marginTop: paragraphMargin, marginBottom: paragraphMargin }}>\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={codeBlockMargin} 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: listMargin, marginBottom: listMargin, lineHeight: \"1.6\", paddingLeft: \"1.5rem\", listStyleType: \"disc\" }}>{children}</ul>\n ),\n ol: ({ children }: MarkdownChildrenProps) => (\n <ol style={{ marginTop: listMargin, marginBottom: listMargin, lineHeight: \"1.6\", paddingLeft: \"1.5rem\", listStyleType: \"decimal\" }}>{children}</ol>\n ),\n li: ({ children }: MarkdownChildrenProps) => <li style={{ marginBottom: listItemMargin, lineHeight: \"1.6\" }}>{children}</li>,\n\n // Blockquote\n blockquote: ({ children }: MarkdownChildrenProps) => (\n <Blockquote size=\"1\" my={blockquoteMargin}>\n {children}\n </Blockquote>\n ),\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 <Box style={{ marginTop: hrMargin, marginBottom: hrMargin }}>\n <Separator orientation=\"horizontal\" light />\n </Box>\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"],
5
+ "mappings": "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",
6
+ "names": ["React", "Blockquote", "Box", "Code", "Heading", "Text", "Table", "Separator", "CodeBlock", "extractLanguage", "className", "extractCode", "children", "code", "child", "createMarkdownComponents", "options", "codeBlockCollapsible", "imageComponent", "inlineCodeHighContrast", "spacing", "isCompact", "headingMargins", "listMargin", "listItemMargin", "codeBlockMargin", "hrMargin", "paragraphMargin", "blockquoteMargin", "inline", "href", "props", "src", "alt", "width", "height"]
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"streaming-markdown.d.ts","sourceRoot":"","sources":["../../../../src/components/markdown/streaming-markdown.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
+ {"version":3,"file":"streaming-markdown.d.ts","sourceRoot":"","sources":["../../../../src/components/markdown/streaming-markdown.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;AAaxD;;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 +1,2 @@
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"./create-markdown-components";import{completeUnterminatedMarkdown as b,parseMarkdownIntoBlocks as B}from"./utils/markdown-streaming";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};
1
+ "use client";import e,{memo as u,useMemo as p}from"react";import M from"react-markdown";import O from"remark-gfm";import P from"rehype-raw";import i from"harden-react-markdown";import{Box as h,Flex as y}from"@kushagradhawan/kookie-ui";import{createMarkdownComponents as C}from"./create-markdown-components";import{completeUnterminatedMarkdown as b,parseMarkdownIntoBlocks as B}from"./utils/markdown-streaming";const I=typeof i=="function"?i:i.default||i,S=I(M),E=["https://","http://","/"],x=["https://","http://","/","data:"],L=["mailto:","tel:","data:","http:","https:"],A=typeof window<"u"&&window.location?.origin?window.location.origin:"https://app.kookie.ai";function F(o){return o||A}const m=u(({content:o,defaultOrigin:n,components:a})=>e.createElement(h,{width:"100%"},e.createElement(S,{defaultOrigin:n,allowedLinkPrefixes:E,allowedImagePrefixes:x,allowedProtocols:L,allowDataImages:!0,components:a,remarkPlugins:[O],rehypePlugins:[P]},o)),(o,n)=>o.content===n.content&&o.defaultOrigin===n.defaultOrigin&&o.components===n.components);m.displayName="MarkdownBlock";function U({content:o,id:n,options:a={}}){const{defaultOrigin:d,enableBlockMemoization:l=!0,blockParser:s,components:c={},...k}=a,w=p(()=>F(d),[d]),f=p(()=>({...C(k),...c}),[k,c]),r=p(()=>{if(!l||!s){const t=b(o);return t.trim()?[t]:[]}return B(o,s)},[o,l,s]);return r.length?r.length===1?e.createElement(m,{content:r[0],defaultOrigin:w,components:f}):e.createElement(y,{direction:"column",gap:"2",width:"100%"},r.map((t,g)=>e.createElement(m,{key:`${n}-block-${g}`,content:t,defaultOrigin:w,components:f}))):null}export{U as StreamingMarkdown};
2
2
  //# sourceMappingURL=streaming-markdown.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/markdown/streaming-markdown.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 \"./create-markdown-components\";\nimport { completeUnterminatedMarkdown, parseMarkdownIntoBlocks } from \"./utils/markdown-streaming\";\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,+BACzC,OAAS,gCAAAC,EAA8B,2BAAAC,MAA+B,6BAGtE,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"]
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 hardenReactMarkdownModule from \"harden-react-markdown\";\nimport { Box, Flex } from \"@kushagradhawan/kookie-ui\";\nimport { createMarkdownComponents } from \"./create-markdown-components\";\nimport { completeUnterminatedMarkdown, parseMarkdownIntoBlocks } from \"./utils/markdown-streaming\";\nimport type { MarkdownComponentOptions } from \"./types\";\n\n// Handle different export formats\nconst hardenReactMarkdown =\n typeof hardenReactMarkdownModule === \"function\" ? hardenReactMarkdownModule : (hardenReactMarkdownModule as any).default || hardenReactMarkdownModule;\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,MAA+B,wBACtC,OAAS,OAAAC,EAAK,QAAAC,MAAY,4BAC1B,OAAS,4BAAAC,MAAgC,+BACzC,OAAS,gCAAAC,EAA8B,2BAAAC,MAA+B,6BAItE,MAAMC,EACJ,OAAON,GAA8B,WAAaA,EAA6BA,EAAkC,SAAWA,EAExHO,EAAmBD,EAAoBT,CAAa,EAEpDW,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,EAAgBnB,EACpB,CAAC,CAAE,QAAAoB,EAAS,cAAAC,EAAe,WAAAC,CAAW,IAElCvB,EAAA,cAACO,EAAA,CAAI,MAAM,QACTP,EAAA,cAACa,EAAA,CACC,cAAeS,EACf,oBAAqBR,EACrB,qBAAsBC,EACtB,iBAAkBC,EAClB,gBAAe,GACf,WAAYO,EACZ,cAAe,CAACnB,CAAS,EACzB,cAAe,CAACC,CAAS,GAExBgB,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,EAAgBpB,EAAQ,IAAMgB,EAAqBC,CAAY,EAAG,CAACA,CAAY,CAAC,EAGhFc,EAAqB/B,EAAQ,KAE1B,CACL,GAFqBO,EAAyBuB,CAAgB,EAG9D,GAAGD,CACL,GACC,CAACC,EAAkBD,CAAgB,CAAC,EAGjCG,EAAShC,EAAQ,IAAM,CAC3B,GAAI,CAAC2B,GAA0B,CAACC,EAAa,CAE3C,MAAMK,EAAYzB,EAA6BW,CAAO,EACtD,OAAOc,EAAU,KAAK,EAAI,CAACA,CAAS,EAAI,CAAC,CAC3C,CAEA,OAAOxB,EAAwBU,EAASS,CAAW,CACrD,EAAG,CAACT,EAASQ,EAAwBC,CAAW,CAAC,EAEjD,OAAKI,EAAO,OAKRA,EAAO,SAAW,EACblC,EAAA,cAACoB,EAAA,CAAc,QAASc,EAAO,CAAC,EAAG,cAAeZ,EAAe,WAAYW,EAAoB,EAKxGjC,EAAA,cAACQ,EAAA,CAAK,UAAU,SAAS,IAAI,IAAI,MAAM,QACpC0B,EAAO,IAAI,CAACE,EAAOC,IAClBrC,EAAA,cAACoB,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", "hardenReactMarkdownModule", "Box", "Flex", "createMarkdownComponents", "completeUnterminatedMarkdown", "parseMarkdownIntoBlocks", "hardenReactMarkdown", "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
7
  }
@@ -22,6 +22,13 @@ export type MarkdownComponentOptions = {
22
22
  * @default true
23
23
  */
24
24
  inlineCodeHighContrast?: boolean;
25
+ /**
26
+ * Spacing density for markdown elements
27
+ * - "compact": Tighter spacing, ideal for chat/conversational interfaces
28
+ * - "spacious": More breathing room, ideal for documentation/articles
29
+ * @default "spacious"
30
+ */
31
+ spacing?: "compact" | "spacious";
25
32
  };
26
33
  /**
27
34
  * Common props for markdown child components
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/markdown/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,SAAS,CAAC;IAEvG;;;OAGG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/markdown/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,SAAS,CAAC;IAEvG;;;OAGG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;CAClC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kushagradhawan/kookie-blocks",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/KushagraDhawan1997/kookie-blocks.git"
@@ -113,12 +113,16 @@
113
113
  },
114
114
  "devDependencies": {
115
115
  "@eslint/js": "^9.18.0",
116
+ "@kushagradhawan/kookie-ui": "^0.1.89",
117
+ "@testing-library/jest-dom": "^6.9.1",
118
+ "@testing-library/react": "^16.3.1",
116
119
  "@types/react": "^19.0.2",
117
120
  "@types/react-dom": "^19.0.2",
118
121
  "autoprefixer": "10.4.19",
119
122
  "esbuild": "0.20.0",
120
123
  "eslint": "^9.18.0",
121
124
  "globals": "^15.14.0",
125
+ "jsdom": "^27.3.0",
122
126
  "postcss": "8.4.33",
123
127
  "postcss-cli": "11.0.0",
124
128
  "postcss-combine-duplicated-selectors": "10.0.3",
@@ -305,7 +305,7 @@ export function CodeBlock({
305
305
 
306
306
  return (
307
307
  <CodeBlockContext.Provider value={true}>
308
- <Box className="docs-code-block" mt="2" mb="4">
308
+ <Box className="docs-code-block" my="3">
309
309
  <Flex direction="column" gap="2">
310
310
  {preview && (
311
311
  <PreviewSection background={background} backgroundProps={backgroundProps}>
@@ -0,0 +1,92 @@
1
+ 'use client';
2
+
3
+ import React, { useCallback } from 'react';
4
+ import { Flex, Heading, Text, Link, Button } from '@kushagradhawan/kookie-ui';
5
+ import { HugeiconsIcon } from '@hugeicons/react';
6
+ import { Copy01Icon } from '@hugeicons/core-free-icons';
7
+ import type { DocsPageMeta } from './types.js';
8
+
9
+ export interface DocsPageHeaderProps {
10
+ /** Page metadata */
11
+ meta: DocsPageMeta;
12
+ /** Optional actions to render on the right side */
13
+ actions?: React.ReactNode;
14
+ /** Show copy page button */
15
+ showCopyButton?: boolean;
16
+ }
17
+
18
+ export function DocsPageHeader({ meta, actions, showCopyButton = true }: DocsPageHeaderProps) {
19
+ const handleCopyPage = useCallback(() => {
20
+ const contentArea = document.querySelector('[data-content-area]');
21
+ if (!contentArea) return;
22
+
23
+ let markdown = `# ${meta.title}\n\n`;
24
+
25
+ if (meta.description) {
26
+ markdown += `${meta.description}\n\n`;
27
+ }
28
+
29
+ if (meta.source) {
30
+ markdown += `[View source](${meta.source})\n\n`;
31
+ }
32
+
33
+ markdown += `---\n\n`;
34
+
35
+ const textContent = contentArea.textContent || '';
36
+ markdown += textContent.trim();
37
+
38
+ navigator.clipboard.writeText(markdown);
39
+ }, [meta.title, meta.description, meta.source]);
40
+
41
+ return (
42
+ <Flex direction="column" gap="4">
43
+ {meta.category && (
44
+ <Text size="2" weight="medium">
45
+ {meta.category}
46
+ </Text>
47
+ )}
48
+
49
+ <Flex align="center" justify="between" gap="4">
50
+ <Heading as="h1" size="9" weight="medium">
51
+ {meta.title}
52
+ </Heading>
53
+
54
+ <Flex align="center" gap="4">
55
+ {actions}
56
+ {showCopyButton && (
57
+ <Button
58
+ size="2"
59
+ variant="ghost"
60
+ color="gray"
61
+ highContrast
62
+ onClick={handleCopyPage}
63
+ aria-label="Copy page content"
64
+ >
65
+ <HugeiconsIcon icon={Copy01Icon} />
66
+ Copy page
67
+ </Button>
68
+ )}
69
+ </Flex>
70
+ </Flex>
71
+
72
+ {meta.description && (
73
+ <Text size="3" color="gray">
74
+ {meta.description}
75
+ </Text>
76
+ )}
77
+
78
+ {meta.source && (
79
+ <Link
80
+ size="3"
81
+ href={meta.source}
82
+ target="_blank"
83
+ color="gray"
84
+ highContrast
85
+ rel="noreferrer"
86
+ >
87
+ View source →
88
+ </Link>
89
+ )}
90
+ </Flex>
91
+ );
92
+ }