@kushagradhawan/kookie-blocks 0.1.39 → 0.1.41

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 (47) hide show
  1. package/components.css +20 -0
  2. package/dist/cjs/components/empty-state/empty-state.d.ts +21 -0
  3. package/dist/cjs/components/empty-state/empty-state.d.ts.map +1 -0
  4. package/dist/cjs/components/empty-state/empty-state.js +2 -0
  5. package/dist/cjs/components/empty-state/empty-state.js.map +7 -0
  6. package/dist/cjs/components/empty-state/index.d.ts +2 -0
  7. package/dist/cjs/components/empty-state/index.d.ts.map +1 -0
  8. package/dist/cjs/components/empty-state/index.js +2 -0
  9. package/dist/cjs/components/empty-state/index.js.map +7 -0
  10. package/dist/cjs/components/index.d.ts +1 -0
  11. package/dist/cjs/components/index.d.ts.map +1 -1
  12. package/dist/cjs/components/index.js +1 -1
  13. package/dist/cjs/components/index.js.map +2 -2
  14. package/dist/cjs/components/markdown/streaming-markdown.d.ts.map +1 -1
  15. package/dist/cjs/components/markdown/streaming-markdown.js +1 -1
  16. package/dist/cjs/components/markdown/streaming-markdown.js.map +3 -3
  17. package/dist/cjs/components/section-header/section-header.d.ts +4 -0
  18. package/dist/cjs/components/section-header/section-header.d.ts.map +1 -1
  19. package/dist/cjs/components/section-header/section-header.js +1 -1
  20. package/dist/cjs/components/section-header/section-header.js.map +3 -3
  21. package/dist/esm/components/empty-state/empty-state.d.ts +21 -0
  22. package/dist/esm/components/empty-state/empty-state.d.ts.map +1 -0
  23. package/dist/esm/components/empty-state/empty-state.js +2 -0
  24. package/dist/esm/components/empty-state/empty-state.js.map +7 -0
  25. package/dist/esm/components/empty-state/index.d.ts +2 -0
  26. package/dist/esm/components/empty-state/index.d.ts.map +1 -0
  27. package/dist/esm/components/empty-state/index.js +2 -0
  28. package/dist/esm/components/empty-state/index.js.map +7 -0
  29. package/dist/esm/components/index.d.ts +1 -0
  30. package/dist/esm/components/index.d.ts.map +1 -1
  31. package/dist/esm/components/index.js +1 -1
  32. package/dist/esm/components/index.js.map +2 -2
  33. package/dist/esm/components/markdown/streaming-markdown.d.ts.map +1 -1
  34. package/dist/esm/components/markdown/streaming-markdown.js +1 -1
  35. package/dist/esm/components/markdown/streaming-markdown.js.map +3 -3
  36. package/dist/esm/components/section-header/section-header.d.ts +4 -0
  37. package/dist/esm/components/section-header/section-header.d.ts.map +1 -1
  38. package/dist/esm/components/section-header/section-header.js +1 -1
  39. package/dist/esm/components/section-header/section-header.js.map +3 -3
  40. package/package.json +2 -2
  41. package/src/components/empty-state/empty-state.tsx +92 -0
  42. package/src/components/empty-state/index.ts +1 -0
  43. package/src/components/index.css +19 -0
  44. package/src/components/index.ts +1 -0
  45. package/src/components/markdown/streaming-markdown.tsx +19 -3
  46. package/src/components/section-header/section-header.tsx +5 -3
  47. package/styles.css +16 -0
package/components.css CHANGED
@@ -181,3 +181,23 @@ pre[data-theme] code span {
181
181
  -webkit-text-decoration: var(--shiki-dark-text-decoration);
182
182
  text-decoration: var(--shiki-dark-text-decoration);
183
183
  }
184
+
185
+ /* ============================================
186
+ Empty State Component Styles
187
+ ============================================ */
188
+
189
+ /*
190
+ * EmptyState.Icon default sizing
191
+ * Sets a consistent default size for icons/illustrations in empty states
192
+ * Can be overridden via inline styles or custom CSS
193
+ */
194
+
195
+ .kb-empty-state-icon {
196
+ --empty-state-icon-size: var(--space-6);
197
+ color: var(--gray-a9);
198
+ }
199
+
200
+ .kb-empty-state-icon :where(svg) {
201
+ width: var(--empty-state-icon-size);
202
+ height: var(--empty-state-icon-size);
203
+ }
@@ -0,0 +1,21 @@
1
+ import * as React from "react";
2
+ import type { FlexProps } from "@kushagradhawan/kookie-ui/components/flex";
3
+ import type { HeadingProps } from "@kushagradhawan/kookie-ui/components/heading";
4
+ import type { TextProps } from "@kushagradhawan/kookie-ui/components/text";
5
+ import type { BoxProps } from "@kushagradhawan/kookie-ui/components/box";
6
+ declare const EmptyState: React.ForwardRefExoticComponent<Omit<FlexProps, "direction"> & {
7
+ /** Content alignment. Defaults to center. */
8
+ align?: "start" | "center";
9
+ } & React.RefAttributes<HTMLDivElement>> & {
10
+ Root: React.ForwardRefExoticComponent<Omit<FlexProps, "direction"> & {
11
+ /** Content alignment. Defaults to center. */
12
+ align?: "start" | "center";
13
+ } & React.RefAttributes<HTMLDivElement>>;
14
+ Icon: React.ForwardRefExoticComponent<BoxProps & React.RefAttributes<HTMLDivElement>>;
15
+ Content: React.ForwardRefExoticComponent<FlexProps & React.RefAttributes<HTMLDivElement>>;
16
+ Title: React.ForwardRefExoticComponent<HeadingProps & React.RefAttributes<HTMLHeadingElement>>;
17
+ Description: React.ForwardRefExoticComponent<TextProps & React.RefAttributes<HTMLParagraphElement>>;
18
+ Actions: React.ForwardRefExoticComponent<FlexProps & React.RefAttributes<HTMLDivElement>>;
19
+ };
20
+ export { EmptyState };
21
+ //# sourceMappingURL=empty-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"empty-state.d.ts","sourceRoot":"","sources":["../../../../src/components/empty-state/empty-state.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2CAA2C,CAAC;AAC3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8CAA8C,CAAC;AACjF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2CAA2C,CAAC;AAC3E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0CAA0C,CAAC;AA6EzE,QAAA,MAAM,UAAU;IAzEd,6CAA6C;YACrC,OAAO,GAAG,QAAQ;;;QAD1B,6CAA6C;gBACrC,OAAO,GAAG,QAAQ;;;;;;;CA+E1B,CAAC;AAEH,OAAO,EAAE,UAAU,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ "use strict";var P=Object.create;var i=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var x=Object.getPrototypeOf,T=Object.prototype.hasOwnProperty;var k=(t,e)=>{for(var o in e)i(t,o,{get:e[o],enumerable:!0})},m=(t,e,o,p)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of u(e))!T.call(t,r)&&r!==o&&i(t,r,{get:()=>e[r],enumerable:!(p=g(e,r))||p.enumerable});return t};var h=(t,e,o)=>(o=t!=null?P(x(t)):{},m(e||!t||!t.__esModule?i(o,"default",{value:t,enumerable:!0}):o,t)),w=t=>m(i({},"__esModule",{value:!0}),t);var H={};k(H,{EmptyState:()=>d});module.exports=w(H);var n=h(require("react")),a=require("@kushagradhawan/kookie-ui");const s=n.forwardRef(({align:t="center",gap:e="4",children:o,...p},r)=>n.createElement(a.Flex,{ref:r,direction:"column",align:t,gap:e,...p},o));s.displayName="EmptyState.Root";const y=n.forwardRef(({className:t,...e},o)=>n.createElement(a.Box,{ref:o,className:`kb-empty-state-icon${t?` ${t}`:""}`,...e}));y.displayName="EmptyState.Icon";const c=n.forwardRef(({direction:t="column",gap:e="1",...o},p)=>n.createElement(a.Flex,{ref:p,direction:t,gap:e,...o}));c.displayName="EmptyState.Content";const l=n.forwardRef(({as:t="h3",size:e="5",weight:o="medium",align:p="center",...r},S)=>n.createElement(a.Heading,{ref:S,as:t,size:e,weight:o,align:p,...r}));l.displayName="EmptyState.Title";const E=n.forwardRef(({size:t="2",color:e="gray",align:o="center",...p},r)=>n.createElement(a.Text,{ref:r,size:t,color:e,align:o,...p}));E.displayName="EmptyState.Description";const f=n.forwardRef(({gap:t="2",align:e="center",justify:o="center",...p},r)=>n.createElement(a.Flex,{ref:r,gap:t,align:e,justify:o,...p}));f.displayName="EmptyState.Actions";const d=Object.assign(s,{Root:s,Icon:y,Content:c,Title:l,Description:E,Actions:f});
2
+ //# sourceMappingURL=empty-state.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/components/empty-state/empty-state.tsx"],
4
+ "sourcesContent": ["import * as React from \"react\";\nimport { Flex, Heading, Text, Box } from \"@kushagradhawan/kookie-ui\";\nimport type { FlexProps } from \"@kushagradhawan/kookie-ui/components/flex\";\nimport type { HeadingProps } from \"@kushagradhawan/kookie-ui/components/heading\";\nimport type { TextProps } from \"@kushagradhawan/kookie-ui/components/text\";\nimport type { BoxProps } from \"@kushagradhawan/kookie-ui/components/box\";\n\n// EmptyState.Root Props\ntype EmptyStateRootProps = Omit<FlexProps, 'direction'> & {\n /** Content alignment. Defaults to center. */\n align?: \"start\" | \"center\";\n};\n\nconst EmptyStateRoot = React.forwardRef<HTMLDivElement, EmptyStateRootProps>(\n ({ align = \"center\", gap = \"4\", children, ...props }, ref) => {\n return (\n <Flex\n ref={ref}\n direction=\"column\"\n align={align}\n gap={gap}\n {...props}\n >\n {children}\n </Flex>\n );\n }\n);\nEmptyStateRoot.displayName = \"EmptyState.Root\";\n\n// EmptyState.Icon - Container for the icon/illustration\ntype EmptyStateIconProps = BoxProps;\nconst EmptyStateIcon = React.forwardRef<HTMLDivElement, EmptyStateIconProps>(\n ({ className, ...props }, ref) => {\n return (\n <Box\n ref={ref}\n className={`kb-empty-state-icon${className ? ` ${className}` : \"\"}`}\n {...props}\n />\n );\n }\n);\nEmptyStateIcon.displayName = \"EmptyState.Icon\";\n\n// EmptyState.Content - Groups title and description with tighter gap\ntype EmptyStateContentProps = FlexProps;\nconst EmptyStateContent = React.forwardRef<HTMLDivElement, EmptyStateContentProps>(\n ({ direction = \"column\", gap = \"1\", ...props }, ref) => {\n return <Flex ref={ref} direction={direction} gap={gap} {...props} />;\n }\n);\nEmptyStateContent.displayName = \"EmptyState.Content\";\n\n// EmptyState.Title - Passes through to Heading with sensible defaults\ntype EmptyStateTitleProps = HeadingProps;\nconst EmptyStateTitle = React.forwardRef<HTMLHeadingElement, EmptyStateTitleProps>(\n ({ as = \"h3\", size = \"5\", weight = \"medium\", align = \"center\", ...props }, ref) => {\n return <Heading ref={ref} as={as} size={size} weight={weight} align={align} {...props} />;\n }\n);\nEmptyStateTitle.displayName = \"EmptyState.Title\";\n\n// EmptyState.Description - Passes through to Text with sensible defaults\ntype EmptyStateDescriptionProps = TextProps;\nconst EmptyStateDescription = React.forwardRef<HTMLParagraphElement, EmptyStateDescriptionProps>(\n ({ size = \"2\", color = \"gray\", align = \"center\", ...props }, ref) => {\n return <Text ref={ref} size={size} color={color} align={align} {...props} />;\n }\n);\nEmptyStateDescription.displayName = \"EmptyState.Description\";\n\n// EmptyState.Actions - Container for action buttons\ntype EmptyStateActionsProps = FlexProps;\nconst EmptyStateActions = React.forwardRef<HTMLDivElement, EmptyStateActionsProps>(\n ({ gap = \"2\", align = \"center\", justify = \"center\", ...props }, ref) => {\n return <Flex ref={ref} gap={gap} align={align} justify={justify} {...props} />;\n }\n);\nEmptyStateActions.displayName = \"EmptyState.Actions\";\n\n// Compose the EmptyState object\nconst EmptyState = Object.assign(EmptyStateRoot, {\n Root: EmptyStateRoot,\n Icon: EmptyStateIcon,\n Content: EmptyStateContent,\n Title: EmptyStateTitle,\n Description: EmptyStateDescription,\n Actions: EmptyStateActions,\n});\n\nexport { EmptyState };\n"],
5
+ "mappings": "0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,gBAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAuB,oBACvBC,EAAyC,qCAYzC,MAAMC,EAAiBF,EAAM,WAC3B,CAAC,CAAE,MAAAG,EAAQ,SAAU,IAAAC,EAAM,IAAK,SAAAC,EAAU,GAAGC,CAAM,EAAGC,IAElDP,EAAA,cAAC,QACC,IAAKO,EACL,UAAU,SACV,MAAOJ,EACP,IAAKC,EACJ,GAAGE,GAEHD,CACH,CAGN,EACAH,EAAe,YAAc,kBAI7B,MAAMM,EAAiBR,EAAM,WAC3B,CAAC,CAAE,UAAAS,EAAW,GAAGH,CAAM,EAAGC,IAEtBP,EAAA,cAAC,OACC,IAAKO,EACL,UAAW,sBAAsBE,EAAY,IAAIA,CAAS,GAAK,EAAE,GAChE,GAAGH,EACN,CAGN,EACAE,EAAe,YAAc,kBAI7B,MAAME,EAAoBV,EAAM,WAC9B,CAAC,CAAE,UAAAW,EAAY,SAAU,IAAAP,EAAM,IAAK,GAAGE,CAAM,EAAGC,IACvCP,EAAA,cAAC,QAAK,IAAKO,EAAK,UAAWI,EAAW,IAAKP,EAAM,GAAGE,EAAO,CAEtE,EACAI,EAAkB,YAAc,qBAIhC,MAAME,EAAkBZ,EAAM,WAC5B,CAAC,CAAE,GAAAa,EAAK,KAAM,KAAAC,EAAO,IAAK,OAAAC,EAAS,SAAU,MAAAZ,EAAQ,SAAU,GAAGG,CAAM,EAAGC,IAClEP,EAAA,cAAC,WAAQ,IAAKO,EAAK,GAAIM,EAAI,KAAMC,EAAM,OAAQC,EAAQ,MAAOZ,EAAQ,GAAGG,EAAO,CAE3F,EACAM,EAAgB,YAAc,mBAI9B,MAAMI,EAAwBhB,EAAM,WAClC,CAAC,CAAE,KAAAc,EAAO,IAAK,MAAAG,EAAQ,OAAQ,MAAAd,EAAQ,SAAU,GAAGG,CAAM,EAAGC,IACpDP,EAAA,cAAC,QAAK,IAAKO,EAAK,KAAMO,EAAM,MAAOG,EAAO,MAAOd,EAAQ,GAAGG,EAAO,CAE9E,EACAU,EAAsB,YAAc,yBAIpC,MAAME,EAAoBlB,EAAM,WAC9B,CAAC,CAAE,IAAAI,EAAM,IAAK,MAAAD,EAAQ,SAAU,QAAAgB,EAAU,SAAU,GAAGb,CAAM,EAAGC,IACvDP,EAAA,cAAC,QAAK,IAAKO,EAAK,IAAKH,EAAK,MAAOD,EAAO,QAASgB,EAAU,GAAGb,EAAO,CAEhF,EACAY,EAAkB,YAAc,qBAGhC,MAAMpB,EAAa,OAAO,OAAOI,EAAgB,CAC/C,KAAMA,EACN,KAAMM,EACN,QAASE,EACT,MAAOE,EACP,YAAaI,EACb,QAASE,CACX,CAAC",
6
+ "names": ["empty_state_exports", "__export", "EmptyState", "__toCommonJS", "React", "import_kookie_ui", "EmptyStateRoot", "align", "gap", "children", "props", "ref", "EmptyStateIcon", "className", "EmptyStateContent", "direction", "EmptyStateTitle", "as", "size", "weight", "EmptyStateDescription", "color", "EmptyStateActions", "justify"]
7
+ }
@@ -0,0 +1,2 @@
1
+ export { EmptyState } from './empty-state.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/empty-state/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,2 @@
1
+ "use strict";var p=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var E=(e,t)=>{for(var o in t)p(e,o,{get:t[o],enumerable:!0})},S=(e,t,o,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let m of x(t))!y.call(e,m)&&m!==o&&p(e,m,{get:()=>t[m],enumerable:!(r=f(t,m))||r.enumerable});return e};var b=e=>S(p({},"__esModule",{value:!0}),e);var c={};E(c,{EmptyState:()=>a.EmptyState});module.exports=b(c);var a=require("./empty-state.js");
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/components/empty-state/index.ts"],
4
+ "sourcesContent": ["export { EmptyState } from './empty-state.js';\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,8CAAAE,EAAAF,GAAA,IAAAG,EAA2B",
6
+ "names": ["empty_state_exports", "__export", "__toCommonJS", "import_empty_state"]
7
+ }
@@ -1,5 +1,6 @@
1
1
  export * from './code/index.js';
2
2
  export * from './docs/index.js';
3
+ export * from './empty-state/index.js';
3
4
  export * from './footer/index.js';
4
5
  export * from './hero/index.js';
5
6
  export * from './markdown/index.js';
@@ -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,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,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,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC"}
@@ -1,2 +1,2 @@
1
- "use strict";var a=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var t=(f,e,p,x)=>{if(e&&typeof e=="object"||typeof e=="function")for(let m of c(e))!d.call(f,m)&&m!==p&&a(f,m,{get:()=>e[m],enumerable:!(x=b(e,m))||x.enumerable});return f},r=(f,e,p)=>(t(f,e,"default"),p&&t(p,e,"default"));var g=f=>t(a({},"__esModule",{value:!0}),f);var o={};module.exports=g(o);r(o,require("./code/index.js"),module.exports);r(o,require("./docs/index.js"),module.exports);r(o,require("./footer/index.js"),module.exports);r(o,require("./hero/index.js"),module.exports);r(o,require("./markdown/index.js"),module.exports);r(o,require("./page-header/index.js"),module.exports);r(o,require("./section-header/index.js"),module.exports);
1
+ "use strict";var a=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var t=(f,e,p,x)=>{if(e&&typeof e=="object"||typeof e=="function")for(let m of c(e))!d.call(f,m)&&m!==p&&a(f,m,{get:()=>e[m],enumerable:!(x=b(e,m))||x.enumerable});return f},r=(f,e,p)=>(t(f,e,"default"),p&&t(p,e,"default"));var g=f=>t(a({},"__esModule",{value:!0}),f);var o={};module.exports=g(o);r(o,require("./code/index.js"),module.exports);r(o,require("./docs/index.js"),module.exports);r(o,require("./empty-state/index.js"),module.exports);r(o,require("./footer/index.js"),module.exports);r(o,require("./hero/index.js"),module.exports);r(o,require("./markdown/index.js"),module.exports);r(o,require("./page-header/index.js"),module.exports);r(o,require("./section-header/index.js"),module.exports);
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 './docs/index.js';\nexport * from './footer/index.js';\nexport * from './hero/index.js';\nexport * from './markdown/index.js';\nexport * from './page-header/index.js';\nexport * from './section-header/index.js';\n"],
5
- "mappings": "iaAAA,IAAAA,EAAA,kBAAAC,EAAAD,GAAAE,EAAAF,EAAc,2BAAd,gBACAE,EAAAF,EAAc,2BADd,gBAEAE,EAAAF,EAAc,6BAFd,gBAGAE,EAAAF,EAAc,2BAHd,gBAIAE,EAAAF,EAAc,+BAJd,gBAKAE,EAAAF,EAAc,kCALd,gBAMAE,EAAAF,EAAc,qCANd",
4
+ "sourcesContent": ["export * from './code/index.js';\nexport * from './docs/index.js';\nexport * from './empty-state/index.js';\nexport * from './footer/index.js';\nexport * from './hero/index.js';\nexport * from './markdown/index.js';\nexport * from './page-header/index.js';\nexport * from './section-header/index.js';\n"],
5
+ "mappings": "iaAAA,IAAAA,EAAA,kBAAAC,EAAAD,GAAAE,EAAAF,EAAc,2BAAd,gBACAE,EAAAF,EAAc,2BADd,gBAEAE,EAAAF,EAAc,kCAFd,gBAGAE,EAAAF,EAAc,6BAHd,gBAIAE,EAAAF,EAAc,2BAJd,gBAKAE,EAAAF,EAAc,+BALd,gBAMAE,EAAAF,EAAc,kCANd,gBAOAE,EAAAF,EAAc,qCAPd",
6
6
  "names": ["components_exports", "__toCommonJS", "__reExport"]
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,YAAY,CAAC;AAa3D;;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,YAAY,CAAC;AAa3D;;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,4BA2DtF"}
@@ -1,2 +1,2 @@
1
- "use strict";"use client";var B=Object.create;var d=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)d(o,t,{get:n[t],enumerable:!0})},O=(o,n,t,i)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of S(n))!x.call(o,r)&&r!==t&&d(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)):{},O(n||!o||!o.__esModule?d(t,"default",{value:o,enumerable:!0}):t,o)),A=o=>O(d({},"__esModule",{value:!0}),o);var T={};L(T,{StreamingMarkdown:()=>H});module.exports=A(T);var e=s(require("react")),P=s(require("react-markdown")),h=s(require("remark-gfm")),y=s(require("rehype-raw")),p=s(require("harden-react-markdown")),l=require("@kushagradhawan/kookie-ui"),C=require("./create-markdown-components.js"),c=require("./utils/markdown-streaming.js");const F=typeof p.default=="function"?p.default:p.default.default||p.default,R=F(P.default),_=["https://","http://","/"],D=["https://","http://","/","data:"],N=["mailto:","tel:","data:","http:","https:"],G=typeof window<"u"&&window.location?.origin?window.location.origin:"https://app.kookie.ai";function z(o){return o||G}const w=(0,e.memo)(({content:o,defaultOrigin:n,components:t})=>e.default.createElement(l.Box,{width:"100%"},e.default.createElement(R,{defaultOrigin:n,allowedLinkPrefixes:_,allowedImagePrefixes:D,allowedProtocols:N,allowDataImages:!0,components:t,remarkPlugins:[h.default],rehypePlugins:[y.default]},o)),(o,n)=>o.content===n.content&&o.defaultOrigin===n.defaultOrigin&&o.components===n.components);w.displayName="MarkdownBlock";function H({content:o,id:n,options:t={}}){const{defaultOrigin:i,enableBlockMemoization:r=!0,blockParser:k,components:f={},...g}=t,u=(0,e.useMemo)(()=>z(i),[i]),M=(0,e.useMemo)(()=>({...(0,C.createMarkdownComponents)(g),...f}),[g,f]),m=(0,e.useMemo)(()=>{if(!r||!k){const a=(0,c.completeUnterminatedMarkdown)(o);return a.trim()?[a]:[]}return(0,c.parseMarkdownIntoBlocks)(o,k)},[o,r,k]);return m.length?m.length===1?e.default.createElement(w,{content:m[0],defaultOrigin:u,components:M}):e.default.createElement(l.Flex,{direction:"column",gap:"2",width:"100%"},m.map((a,b)=>e.default.createElement(w,{key:`${n}-block-${b}`,content:a,defaultOrigin:u,components:M}))):null}
1
+ "use strict";"use client";var E=Object.create;var l=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var A=Object.getPrototypeOf,F=Object.prototype.hasOwnProperty;var R=(o,n)=>{for(var t in n)l(o,t,{get:n[t],enumerable:!0})},y=(o,n,t,i)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of L(n))!F.call(o,r)&&r!==t&&l(o,r,{get:()=>n[r],enumerable:!(i=x(n,r))||i.enumerable});return o};var s=(o,n,t)=>(t=o!=null?E(A(o)):{},y(n||!o||!o.__esModule?l(t,"default",{value:o,enumerable:!0}):t,o)),_=o=>y(l({},"__esModule",{value:!0}),o);var $={};R($,{StreamingMarkdown:()=>X});module.exports=_($);var e=s(require("react")),C=s(require("react-markdown")),b=s(require("remark-gfm")),B=s(require("rehype-raw")),p=s(require("harden-react-markdown")),d=require("@kushagradhawan/kookie-ui"),I=require("./create-markdown-components.js"),c=require("./utils/markdown-streaming.js");const D=typeof p.default=="function"?p.default:p.default.default||p.default,N=D(C.default),G=["https://","http://","/"],H=["https://","http://","/","data:"],z=["mailto:","tel:","data:","http:","https:"],T=typeof window<"u"&&window.location?.origin?window.location.origin:"https://app.kookie.ai";function U(o){return o||T}const g=(0,e.memo)(({content:o,defaultOrigin:n,components:t})=>e.default.createElement(d.Box,{width:"100%"},e.default.createElement(N,{defaultOrigin:n,allowedLinkPrefixes:G,allowedImagePrefixes:H,allowedProtocols:z,allowDataImages:!0,components:t,remarkPlugins:[b.default],rehypePlugins:[B.default]},o)),(o,n)=>o.content===n.content&&o.defaultOrigin===n.defaultOrigin&&o.components===n.components);g.displayName="MarkdownBlock";function X({content:o,id:n,options:t={}}){const{defaultOrigin:i,enableBlockMemoization:r=!0,blockParser:k,components:f,codeBlockCollapsible:w=!1,imageComponent:u,inlineCodeHighContrast:M=!0,spacing:O="spacious"}=t,P=(0,e.useMemo)(()=>U(i),[i]),h=(0,e.useMemo)(()=>({...(0,I.createMarkdownComponents)({codeBlockCollapsible:w,imageComponent:u,inlineCodeHighContrast:M,spacing:O}),...f}),[w,u,M,O,f]),m=(0,e.useMemo)(()=>{if(!r||!k){const a=(0,c.completeUnterminatedMarkdown)(o);return a.trim()?[a]:[]}return(0,c.parseMarkdownIntoBlocks)(o,k)},[o,r,k]);return m.length?m.length===1?e.default.createElement(g,{content:m[0],defaultOrigin:P,components:h}):e.default.createElement(d.Flex,{direction:"column",gap:"2",width:"100%"},m.map((a,S)=>e.default.createElement(g,{key:`${n}-block-${S}`,content:a,defaultOrigin:P,components:h}))):null}
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 hardenReactMarkdownModule from \"harden-react-markdown\";\nimport { Box, Flex } from \"@kushagradhawan/kookie-ui\";\nimport { createMarkdownComponents } from \"./create-markdown-components.js\";\nimport { completeUnterminatedMarkdown, parseMarkdownIntoBlocks } from \"./utils/markdown-streaming.js\";\nimport type { MarkdownComponentOptions } from \"./types.js\";\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": "ukBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,uBAAAE,IAAA,eAAAC,EAAAH,GAEA,IAAAI,EAAqD,oBACrDC,EAA+C,6BAC/CC,EAAsB,yBACtBC,EAAsB,yBACtBC,EAAsC,oCACtCC,EAA0B,qCAC1BC,EAAyC,2CACzCC,EAAsE,yCAItE,MAAMC,EACJ,OAAO,EAAAC,SAA8B,WAAa,EAAAA,QAA6B,EAAAA,QAAkC,SAAW,EAAAA,QAExHC,EAAmBF,EAAoB,EAAAG,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,cAACZ,EAAA,CACC,cAAeU,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,SAASpB,EAAkB,CAAE,QAAAqB,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": ["streaming_markdown_exports", "__export", "StreamingMarkdown", "__toCommonJS", "import_react", "import_react_markdown", "import_remark_gfm", "import_rehype_raw", "import_harden_react_markdown", "import_kookie_ui", "import_create_markdown_components", "import_markdown_streaming", "hardenReactMarkdown", "hardenReactMarkdownModule", "HardenedMarkdown", "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"]
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.js\";\nimport { completeUnterminatedMarkdown, parseMarkdownIntoBlocks } from \"./utils/markdown-streaming.js\";\nimport type { MarkdownComponentOptions } from \"./types.js\";\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 {\n defaultOrigin: customOrigin,\n enableBlockMemoization = true,\n blockParser,\n components: customComponents,\n // Extract individual options as primitives for stable useMemo deps\n codeBlockCollapsible = false,\n imageComponent,\n inlineCodeHighContrast = true,\n spacing = \"spacious\",\n } = options;\n\n // Resolve security origin\n const defaultOrigin = useMemo(() => resolveDefaultOrigin(customOrigin), [customOrigin]);\n\n // Create component mappings with custom overrides\n // Uses primitive deps to avoid recreating on every render\n const markdownComponents = useMemo(() => {\n const baseComponents = createMarkdownComponents({\n codeBlockCollapsible,\n imageComponent,\n inlineCodeHighContrast,\n spacing,\n });\n return {\n ...baseComponents,\n ...customComponents,\n };\n }, [codeBlockCollapsible, imageComponent, inlineCodeHighContrast, spacing, 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,EAAsC,oCACtCC,EAA0B,qCAC1BC,EAAyC,2CACzCC,EAAsE,yCAItE,MAAMC,EACJ,OAAO,EAAAC,SAA8B,WAAa,EAAAA,QAA6B,EAAAA,QAAkC,SAAW,EAAAA,QAExHC,EAAmBF,EAAoB,EAAAG,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,cAACZ,EAAA,CACC,cAAeU,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,SAASpB,EAAkB,CAAE,QAAAqB,EAAS,GAAAQ,EAAI,QAAAC,EAAU,CAAC,CAAE,EAA2B,CACvF,KAAM,CACJ,cAAeX,EACf,uBAAAY,EAAyB,GACzB,YAAAC,EACA,WAAYC,EAEZ,qBAAAC,EAAuB,GACvB,eAAAC,EACA,uBAAAC,EAAyB,GACzB,QAAAC,EAAU,UACZ,EAAIP,EAGER,KAAgB,WAAQ,IAAMJ,EAAqBC,CAAY,EAAG,CAACA,CAAY,CAAC,EAIhFmB,KAAqB,WAAQ,KAO1B,CACL,MAPqB,4BAAyB,CAC9C,qBAAAJ,EACA,eAAAC,EACA,uBAAAC,EACA,QAAAC,CACF,CAAC,EAGC,GAAGJ,CACL,GACC,CAACC,EAAsBC,EAAgBC,EAAwBC,EAASJ,CAAgB,CAAC,EAGtFM,KAAS,WAAQ,IAAM,CAC3B,GAAI,CAACR,GAA0B,CAACC,EAAa,CAE3C,MAAMQ,KAAY,gCAA6BnB,CAAO,EACtD,OAAOmB,EAAU,KAAK,EAAI,CAACA,CAAS,EAAI,CAAC,CAC3C,CAEA,SAAO,2BAAwBnB,EAASW,CAAW,CACrD,EAAG,CAACX,EAASU,EAAwBC,CAAW,CAAC,EAEjD,OAAKO,EAAO,OAKRA,EAAO,SAAW,EACb,EAAAf,QAAA,cAACJ,EAAA,CAAc,QAASmB,EAAO,CAAC,EAAG,cAAejB,EAAe,WAAYgB,EAAoB,EAKxG,EAAAd,QAAA,cAAC,QAAK,UAAU,SAAS,IAAI,IAAI,MAAM,QACpCe,EAAO,IAAI,CAACE,EAAOC,IAClB,EAAAlB,QAAA,cAACJ,EAAA,CAAc,IAAK,GAAGS,CAAE,UAAUa,CAAK,GAAI,QAASD,EAAO,cAAenB,EAAe,WAAYgB,EAAoB,CAC3H,CACH,EAdO,IAgBX",
6
+ "names": ["streaming_markdown_exports", "__export", "StreamingMarkdown", "__toCommonJS", "import_react", "import_react_markdown", "import_remark_gfm", "import_rehype_raw", "import_harden_react_markdown", "import_kookie_ui", "import_create_markdown_components", "import_markdown_streaming", "hardenReactMarkdown", "hardenReactMarkdownModule", "HardenedMarkdown", "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", "codeBlockCollapsible", "imageComponent", "inlineCodeHighContrast", "spacing", "markdownComponents", "blocks", "completed", "block", "index"]
7
7
  }
@@ -6,6 +6,8 @@ type Responsive<T> = T | Partial<Record<'initial' | 'xs' | 'sm' | 'md' | 'lg' |
6
6
  declare const SectionHeader: React.ForwardRefExoticComponent<Omit<FlexProps, "direction"> & {
7
7
  /** Layout mode: stacked (vertical) or inline (horizontal with actions on right) */
8
8
  layout?: Responsive<"stacked" | "inline">;
9
+ /** Content alignment. Overrides the default alignment derived from layout. */
10
+ align?: Responsive<"start" | "center">;
9
11
  /** Show separator at bottom. Use when no tabs are present. */
10
12
  separator?: boolean;
11
13
  /** Allow explicit direction override if needed */
@@ -14,6 +16,8 @@ declare const SectionHeader: React.ForwardRefExoticComponent<Omit<FlexProps, "di
14
16
  Root: React.ForwardRefExoticComponent<Omit<FlexProps, "direction"> & {
15
17
  /** Layout mode: stacked (vertical) or inline (horizontal with actions on right) */
16
18
  layout?: Responsive<"stacked" | "inline">;
19
+ /** Content alignment. Overrides the default alignment derived from layout. */
20
+ align?: Responsive<"start" | "center">;
17
21
  /** Show separator at bottom. Use when no tabs are present. */
18
22
  separator?: boolean;
19
23
  /** Allow explicit direction override if needed */
@@ -1 +1 @@
1
- {"version":3,"file":"section-header.d.ts","sourceRoot":"","sources":["../../../../src/components/section-header/section-header.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2CAA2C,CAAC;AAC3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8CAA8C,CAAC;AACjF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2CAA2C,CAAC;AAG3E,KAAK,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AA4J1F,QAAA,MAAM,aAAa;IA/EjB,mFAAmF;aAC1E,UAAU,CAAC,SAAS,GAAG,QAAQ,CAAC;IACzC,8DAA8D;gBAClD,OAAO;IACnB,kDAAkD;gBACtC,SAAS,CAAC,WAAW,CAAC;;;QALlC,mFAAmF;iBAC1E,UAAU,CAAC,SAAS,GAAG,QAAQ,CAAC;QACzC,8DAA8D;oBAClD,OAAO;QACnB,kDAAkD;oBACtC,SAAS,CAAC,WAAW,CAAC;;;;;;;CAiFlC,CAAC;AAEH,OAAO,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"section-header.d.ts","sourceRoot":"","sources":["../../../../src/components/section-header/section-header.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2CAA2C,CAAC;AAC3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8CAA8C,CAAC;AACjF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2CAA2C,CAAC;AAG3E,KAAK,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AA8J1F,QAAA,MAAM,aAAa;IAjFjB,mFAAmF;aAC1E,UAAU,CAAC,SAAS,GAAG,QAAQ,CAAC;IACzC,8EAA8E;YACtE,UAAU,CAAC,OAAO,GAAG,QAAQ,CAAC;IACtC,8DAA8D;gBAClD,OAAO;IACnB,kDAAkD;gBACtC,SAAS,CAAC,WAAW,CAAC;;;QAPlC,mFAAmF;iBAC1E,UAAU,CAAC,SAAS,GAAG,QAAQ,CAAC;QACzC,8EAA8E;gBACtE,UAAU,CAAC,OAAO,GAAG,QAAQ,CAAC;QACtC,8DAA8D;oBAClD,OAAO;QACnB,kDAAkD;oBACtC,SAAS,CAAC,WAAW,CAAC;;;;;;;CAiFlC,CAAC;AAEH,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -1,2 +1,2 @@
1
- "use strict";var b=Object.create;var a=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var R=Object.getOwnPropertyNames;var D=Object.getPrototypeOf,h=Object.prototype.hasOwnProperty;var F=(e,t)=>{for(var n in t)a(e,n,{get:t[n],enumerable:!0})},d=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of R(t))!h.call(e,s)&&s!==n&&a(e,s,{get:()=>t[s],enumerable:!(o=v(t,s))||o.enumerable});return e};var L=(e,t,n)=>(n=e!=null?b(D(e)):{},d(t||!e||!e.__esModule?a(n,"default",{value:e,enumerable:!0}):n,e)),A=e=>d(a({},"__esModule",{value:!0}),e);var j={};F(j,{SectionHeader:()=>P});module.exports=A(j);var r=L(require("react")),i=require("@kushagradhawan/kookie-ui");function p(e){return e==="inline"?"row":"column"}function E(e){if(!e)return;if(typeof e=="string")return p(e);const t={};for(const[n,o]of Object.entries(e))o&&(t[n]=p(o));return t}function l(e){return e==="inline"?"between":"start"}function M(e){if(!e)return;if(typeof e=="string")return l(e);const t={};for(const[n,o]of Object.entries(e))o&&(t[n]=l(o));return t}function f(e){return e==="inline"?"center":"start"}function N(e){if(!e)return;if(typeof e=="string")return f(e);const t={};for(const[n,o]of Object.entries(e))o&&(t[n]=f(o));return t}const c=r.forwardRef(({layout:e="inline",separator:t=!1,gap:n="4",direction:o,children:s,...y},S)=>{const w=o||E(e)||"row",x=M(e)||"between",k=N(e)||"center";return r.createElement(i.Flex,{ref:S,direction:"column",gap:n,...y},r.createElement(i.Flex,{direction:w,justify:x,align:k,gap:n,wrap:"wrap"},s),t&&r.createElement(i.Separator,{size:"4"}))});c.displayName="SectionHeader.Root";const u=r.forwardRef(({direction:e="column",gap:t="1",...n},o)=>r.createElement(i.Flex,{ref:o,direction:e,gap:t,...n}));u.displayName="SectionHeader.Content";const m=r.forwardRef(({as:e="h2",size:t="6",weight:n="medium",...o},s)=>r.createElement(i.Heading,{ref:s,as:e,size:t,weight:n,...o}));m.displayName="SectionHeader.Title";const H=r.forwardRef(({size:e="3",color:t="gray",...n},o)=>r.createElement(i.Text,{ref:o,size:e,color:t,...n}));H.displayName="SectionHeader.Description";const T=r.forwardRef(({gap:e="2",align:t="center",...n},o)=>r.createElement(i.Flex,{ref:o,gap:e,align:t,...n}));T.displayName="SectionHeader.Actions";const g=r.forwardRef(({width:e="100%",...t},n)=>r.createElement(i.Flex,{ref:n,width:e,...t}));g.displayName="SectionHeader.Tabs";const P=Object.assign(c,{Root:c,Content:u,Title:m,Description:H,Actions:T,Tabs:g});
1
+ "use strict";var b=Object.create;var a=Object.defineProperty;var R=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var h=Object.getPrototypeOf,F=Object.prototype.hasOwnProperty;var L=(e,t)=>{for(var n in t)a(e,n,{get:t[n],enumerable:!0})},d=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of D(t))!F.call(e,s)&&s!==n&&a(e,s,{get:()=>t[s],enumerable:!(r=R(t,s))||r.enumerable});return e};var A=(e,t,n)=>(n=e!=null?b(h(e)):{},d(t||!e||!e.__esModule?a(n,"default",{value:e,enumerable:!0}):n,e)),E=e=>d(a({},"__esModule",{value:!0}),e);var C={};L(C,{SectionHeader:()=>P});module.exports=E(C);var o=A(require("react")),i=require("@kushagradhawan/kookie-ui");function p(e){return e==="inline"?"row":"column"}function M(e){if(!e)return;if(typeof e=="string")return p(e);const t={};for(const[n,r]of Object.entries(e))r&&(t[n]=p(r));return t}function l(e){return e==="inline"?"between":"start"}function N(e){if(!e)return;if(typeof e=="string")return l(e);const t={};for(const[n,r]of Object.entries(e))r&&(t[n]=l(r));return t}function f(e){return e==="inline"?"center":"start"}function j(e){if(!e)return;if(typeof e=="string")return f(e);const t={};for(const[n,r]of Object.entries(e))r&&(t[n]=f(r));return t}const c=o.forwardRef(({layout:e="inline",align:t,separator:n=!1,gap:r="4",direction:s,children:y,...S},w)=>{const x=s||M(e)||"row",k=N(e)||"between",v=t??j(e)??"center";return o.createElement(i.Flex,{ref:w,direction:"column",gap:r,...S},o.createElement(i.Flex,{direction:x,justify:k,align:v,gap:r,wrap:"wrap"},y),n&&o.createElement(i.Separator,{size:"4"}))});c.displayName="SectionHeader.Root";const u=o.forwardRef(({direction:e="column",gap:t="1",...n},r)=>o.createElement(i.Flex,{ref:r,direction:e,gap:t,...n}));u.displayName="SectionHeader.Content";const m=o.forwardRef(({as:e="h2",size:t="6",weight:n="medium",...r},s)=>o.createElement(i.Heading,{ref:s,as:e,size:t,weight:n,...r}));m.displayName="SectionHeader.Title";const H=o.forwardRef(({size:e="3",color:t="gray",...n},r)=>o.createElement(i.Text,{ref:r,size:e,color:t,...n}));H.displayName="SectionHeader.Description";const g=o.forwardRef(({gap:e="2",align:t="center",...n},r)=>o.createElement(i.Flex,{ref:r,gap:e,align:t,...n}));g.displayName="SectionHeader.Actions";const T=o.forwardRef(({width:e="100%",...t},n)=>o.createElement(i.Flex,{ref:n,width:e,...t}));T.displayName="SectionHeader.Tabs";const P=Object.assign(c,{Root:c,Content:u,Title:m,Description:H,Actions:g,Tabs:T});
2
2
  //# sourceMappingURL=section-header.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/section-header/section-header.tsx"],
4
- "sourcesContent": ["import * as React from \"react\";\nimport { Flex, Heading, Text, Separator } from \"@kushagradhawan/kookie-ui\";\nimport type { FlexProps } from \"@kushagradhawan/kookie-ui/components/flex\";\nimport type { HeadingProps } from \"@kushagradhawan/kookie-ui/components/heading\";\nimport type { TextProps } from \"@kushagradhawan/kookie-ui/components/text\";\n\n// Responsive type matching Kookie UI's pattern\ntype Responsive<T> = T | Partial<Record<'initial' | 'xs' | 'sm' | 'md' | 'lg' | 'xl', T>>;\n\n// Helper to convert layout to direction\nfunction layoutToDirection(layout: \"stacked\" | \"inline\"): \"column\" | \"row\" {\n return layout === \"inline\" ? \"row\" : \"column\";\n}\n\n// Helper to convert responsive layout to responsive direction\nfunction convertLayoutToDirection(\n layout?: Responsive<\"stacked\" | \"inline\">\n): Responsive<\"column\" | \"row\"> | undefined {\n if (!layout) return undefined;\n\n if (typeof layout === \"string\") {\n return layoutToDirection(layout);\n }\n\n // Handle responsive object\n const result: Partial<Record<'initial' | 'xs' | 'sm' | 'md' | 'lg' | 'xl', \"column\" | \"row\">> = {};\n for (const [breakpoint, value] of Object.entries(layout)) {\n if (value) {\n result[breakpoint as keyof typeof result] = layoutToDirection(value);\n }\n }\n return result;\n}\n\n// Helper to convert layout to justify\nfunction layoutToJustify(layout: \"stacked\" | \"inline\"): \"start\" | \"between\" {\n return layout === \"inline\" ? \"between\" : \"start\";\n}\n\n// Helper to convert responsive layout to responsive justify\nfunction convertLayoutToJustify(\n layout?: Responsive<\"stacked\" | \"inline\">\n): Responsive<\"start\" | \"between\"> | undefined {\n if (!layout) return undefined;\n\n if (typeof layout === \"string\") {\n return layoutToJustify(layout);\n }\n\n const result: Partial<Record<'initial' | 'xs' | 'sm' | 'md' | 'lg' | 'xl', \"start\" | \"between\">> = {};\n for (const [breakpoint, value] of Object.entries(layout)) {\n if (value) {\n result[breakpoint as keyof typeof result] = layoutToJustify(value);\n }\n }\n return result;\n}\n\n// Helper to convert layout to align\nfunction layoutToAlign(layout: \"stacked\" | \"inline\"): \"start\" | \"center\" {\n return layout === \"inline\" ? \"center\" : \"start\";\n}\n\n// Helper to convert responsive layout to responsive align\nfunction convertLayoutToAlign(\n layout?: Responsive<\"stacked\" | \"inline\">\n): Responsive<\"start\" | \"center\"> | undefined {\n if (!layout) return undefined;\n\n if (typeof layout === \"string\") {\n return layoutToAlign(layout);\n }\n\n const result: Partial<Record<'initial' | 'xs' | 'sm' | 'md' | 'lg' | 'xl', \"start\" | \"center\">> = {};\n for (const [breakpoint, value] of Object.entries(layout)) {\n if (value) {\n result[breakpoint as keyof typeof result] = layoutToAlign(value);\n }\n }\n return result;\n}\n\n// SectionHeader.Root Props\ntype SectionHeaderRootProps = Omit<FlexProps, 'direction'> & {\n /** Layout mode: stacked (vertical) or inline (horizontal with actions on right) */\n layout?: Responsive<\"stacked\" | \"inline\">;\n /** Show separator at bottom. Use when no tabs are present. */\n separator?: boolean;\n /** Allow explicit direction override if needed */\n direction?: FlexProps['direction'];\n};\n\nconst SectionHeaderRoot = React.forwardRef<HTMLDivElement, SectionHeaderRootProps>(\n ({ layout = \"inline\", separator = false, gap = \"4\", direction, children, ...props }, ref) => {\n // Convert layout to direction/justify/align, but allow explicit direction override\n const computedDirection = direction || convertLayoutToDirection(layout) || \"row\";\n const computedJustify = convertLayoutToJustify(layout) || \"between\";\n const computedAlign = convertLayoutToAlign(layout) || \"center\";\n\n return (\n <Flex ref={ref} direction=\"column\" gap={gap} {...props}>\n <Flex\n direction={computedDirection}\n justify={computedJustify}\n align={computedAlign}\n gap={gap}\n wrap=\"wrap\"\n >\n {children}\n </Flex>\n {separator && <Separator size=\"4\" />}\n </Flex>\n );\n }\n);\nSectionHeaderRoot.displayName = \"SectionHeader.Root\";\n\n// SectionHeader.Content - Groups title and description\ntype SectionHeaderContentProps = FlexProps;\nconst SectionHeaderContent = React.forwardRef<HTMLDivElement, SectionHeaderContentProps>(\n ({ direction = \"column\", gap = \"1\", ...props }, ref) => {\n return <Flex ref={ref} direction={direction} gap={gap} {...props} />;\n }\n);\nSectionHeaderContent.displayName = \"SectionHeader.Content\";\n\n// SectionHeader.Title - Passes through to Heading with sensible defaults\ntype SectionHeaderTitleProps = HeadingProps;\nconst SectionHeaderTitle = React.forwardRef<HTMLHeadingElement, SectionHeaderTitleProps>(\n ({ as = \"h2\", size = \"6\", weight = \"medium\", ...props }, ref) => {\n return <Heading ref={ref} as={as} size={size} weight={weight} {...props} />;\n }\n);\nSectionHeaderTitle.displayName = \"SectionHeader.Title\";\n\n// SectionHeader.Description - Passes through to Text with sensible defaults\ntype SectionHeaderDescriptionProps = TextProps;\nconst SectionHeaderDescription = React.forwardRef<HTMLParagraphElement, SectionHeaderDescriptionProps>(\n ({ size = \"3\", color = \"gray\", ...props }, ref) => {\n return <Text ref={ref} size={size} color={color} {...props} />;\n }\n);\nSectionHeaderDescription.displayName = \"SectionHeader.Description\";\n\n// SectionHeader.Actions - Container for action buttons (right side in inline layout)\ntype SectionHeaderActionsProps = FlexProps;\nconst SectionHeaderActions = React.forwardRef<HTMLDivElement, SectionHeaderActionsProps>(\n ({ gap = \"2\", align = \"center\", ...props }, ref) => {\n return <Flex ref={ref} gap={gap} align={align} {...props} />;\n }\n);\nSectionHeaderActions.displayName = \"SectionHeader.Actions\";\n\n// SectionHeader.Tabs - Container for tabs (renders below the header row)\ntype SectionHeaderTabsProps = FlexProps;\nconst SectionHeaderTabs = React.forwardRef<HTMLDivElement, SectionHeaderTabsProps>(\n ({ width = \"100%\", ...props }, ref) => {\n return <Flex ref={ref} width={width} {...props} />;\n }\n);\nSectionHeaderTabs.displayName = \"SectionHeader.Tabs\";\n\n// Compose the SectionHeader object\nconst SectionHeader = Object.assign(SectionHeaderRoot, {\n Root: SectionHeaderRoot,\n Content: SectionHeaderContent,\n Title: SectionHeaderTitle,\n Description: SectionHeaderDescription,\n Actions: SectionHeaderActions,\n Tabs: SectionHeaderTabs,\n});\n\nexport { SectionHeader };\n"],
5
- "mappings": "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",
6
- "names": ["section_header_exports", "__export", "SectionHeader", "__toCommonJS", "React", "import_kookie_ui", "layoutToDirection", "layout", "convertLayoutToDirection", "result", "breakpoint", "value", "layoutToJustify", "convertLayoutToJustify", "layoutToAlign", "convertLayoutToAlign", "SectionHeaderRoot", "separator", "gap", "direction", "children", "props", "ref", "computedDirection", "computedJustify", "computedAlign", "SectionHeaderContent", "SectionHeaderTitle", "as", "size", "weight", "SectionHeaderDescription", "color", "SectionHeaderActions", "align", "SectionHeaderTabs", "width"]
4
+ "sourcesContent": ["import * as React from \"react\";\nimport { Flex, Heading, Text, Separator } from \"@kushagradhawan/kookie-ui\";\nimport type { FlexProps } from \"@kushagradhawan/kookie-ui/components/flex\";\nimport type { HeadingProps } from \"@kushagradhawan/kookie-ui/components/heading\";\nimport type { TextProps } from \"@kushagradhawan/kookie-ui/components/text\";\n\n// Responsive type matching Kookie UI's pattern\ntype Responsive<T> = T | Partial<Record<'initial' | 'xs' | 'sm' | 'md' | 'lg' | 'xl', T>>;\n\n// Helper to convert layout to direction\nfunction layoutToDirection(layout: \"stacked\" | \"inline\"): \"column\" | \"row\" {\n return layout === \"inline\" ? \"row\" : \"column\";\n}\n\n// Helper to convert responsive layout to responsive direction\nfunction convertLayoutToDirection(\n layout?: Responsive<\"stacked\" | \"inline\">\n): Responsive<\"column\" | \"row\"> | undefined {\n if (!layout) return undefined;\n\n if (typeof layout === \"string\") {\n return layoutToDirection(layout);\n }\n\n // Handle responsive object\n const result: Partial<Record<'initial' | 'xs' | 'sm' | 'md' | 'lg' | 'xl', \"column\" | \"row\">> = {};\n for (const [breakpoint, value] of Object.entries(layout)) {\n if (value) {\n result[breakpoint as keyof typeof result] = layoutToDirection(value);\n }\n }\n return result;\n}\n\n// Helper to convert layout to justify\nfunction layoutToJustify(layout: \"stacked\" | \"inline\"): \"start\" | \"between\" {\n return layout === \"inline\" ? \"between\" : \"start\";\n}\n\n// Helper to convert responsive layout to responsive justify\nfunction convertLayoutToJustify(\n layout?: Responsive<\"stacked\" | \"inline\">\n): Responsive<\"start\" | \"between\"> | undefined {\n if (!layout) return undefined;\n\n if (typeof layout === \"string\") {\n return layoutToJustify(layout);\n }\n\n const result: Partial<Record<'initial' | 'xs' | 'sm' | 'md' | 'lg' | 'xl', \"start\" | \"between\">> = {};\n for (const [breakpoint, value] of Object.entries(layout)) {\n if (value) {\n result[breakpoint as keyof typeof result] = layoutToJustify(value);\n }\n }\n return result;\n}\n\n// Helper to convert layout to align\nfunction layoutToAlign(layout: \"stacked\" | \"inline\"): \"start\" | \"center\" {\n return layout === \"inline\" ? \"center\" : \"start\";\n}\n\n// Helper to convert responsive layout to responsive align\nfunction convertLayoutToAlign(\n layout?: Responsive<\"stacked\" | \"inline\">\n): Responsive<\"start\" | \"center\"> | undefined {\n if (!layout) return undefined;\n\n if (typeof layout === \"string\") {\n return layoutToAlign(layout);\n }\n\n const result: Partial<Record<'initial' | 'xs' | 'sm' | 'md' | 'lg' | 'xl', \"start\" | \"center\">> = {};\n for (const [breakpoint, value] of Object.entries(layout)) {\n if (value) {\n result[breakpoint as keyof typeof result] = layoutToAlign(value);\n }\n }\n return result;\n}\n\n// SectionHeader.Root Props\ntype SectionHeaderRootProps = Omit<FlexProps, 'direction'> & {\n /** Layout mode: stacked (vertical) or inline (horizontal with actions on right) */\n layout?: Responsive<\"stacked\" | \"inline\">;\n /** Content alignment. Overrides the default alignment derived from layout. */\n align?: Responsive<\"start\" | \"center\">;\n /** Show separator at bottom. Use when no tabs are present. */\n separator?: boolean;\n /** Allow explicit direction override if needed */\n direction?: FlexProps['direction'];\n};\n\nconst SectionHeaderRoot = React.forwardRef<HTMLDivElement, SectionHeaderRootProps>(\n ({ layout = \"inline\", align, separator = false, gap = \"4\", direction, children, ...props }, ref) => {\n // Convert layout to direction/justify/align, but allow explicit overrides\n const computedDirection = direction || convertLayoutToDirection(layout) || \"row\";\n const computedJustify = convertLayoutToJustify(layout) || \"between\";\n const computedAlign = align ?? convertLayoutToAlign(layout) ?? \"center\";\n\n return (\n <Flex ref={ref} direction=\"column\" gap={gap} {...props}>\n <Flex\n direction={computedDirection}\n justify={computedJustify}\n align={computedAlign}\n gap={gap}\n wrap=\"wrap\"\n >\n {children}\n </Flex>\n {separator && <Separator size=\"4\" />}\n </Flex>\n );\n }\n);\nSectionHeaderRoot.displayName = \"SectionHeader.Root\";\n\n// SectionHeader.Content - Groups title and description\ntype SectionHeaderContentProps = FlexProps;\nconst SectionHeaderContent = React.forwardRef<HTMLDivElement, SectionHeaderContentProps>(\n ({ direction = \"column\", gap = \"1\", ...props }, ref) => {\n return <Flex ref={ref} direction={direction} gap={gap} {...props} />;\n }\n);\nSectionHeaderContent.displayName = \"SectionHeader.Content\";\n\n// SectionHeader.Title - Passes through to Heading with sensible defaults\ntype SectionHeaderTitleProps = HeadingProps;\nconst SectionHeaderTitle = React.forwardRef<HTMLHeadingElement, SectionHeaderTitleProps>(\n ({ as = \"h2\", size = \"6\", weight = \"medium\", ...props }, ref) => {\n return <Heading ref={ref} as={as} size={size} weight={weight} {...props} />;\n }\n);\nSectionHeaderTitle.displayName = \"SectionHeader.Title\";\n\n// SectionHeader.Description - Passes through to Text with sensible defaults\ntype SectionHeaderDescriptionProps = TextProps;\nconst SectionHeaderDescription = React.forwardRef<HTMLParagraphElement, SectionHeaderDescriptionProps>(\n ({ size = \"3\", color = \"gray\", ...props }, ref) => {\n return <Text ref={ref} size={size} color={color} {...props} />;\n }\n);\nSectionHeaderDescription.displayName = \"SectionHeader.Description\";\n\n// SectionHeader.Actions - Container for action buttons (right side in inline layout)\ntype SectionHeaderActionsProps = FlexProps;\nconst SectionHeaderActions = React.forwardRef<HTMLDivElement, SectionHeaderActionsProps>(\n ({ gap = \"2\", align = \"center\", ...props }, ref) => {\n return <Flex ref={ref} gap={gap} align={align} {...props} />;\n }\n);\nSectionHeaderActions.displayName = \"SectionHeader.Actions\";\n\n// SectionHeader.Tabs - Container for tabs (renders below the header row)\ntype SectionHeaderTabsProps = FlexProps;\nconst SectionHeaderTabs = React.forwardRef<HTMLDivElement, SectionHeaderTabsProps>(\n ({ width = \"100%\", ...props }, ref) => {\n return <Flex ref={ref} width={width} {...props} />;\n }\n);\nSectionHeaderTabs.displayName = \"SectionHeader.Tabs\";\n\n// Compose the SectionHeader object\nconst SectionHeader = Object.assign(SectionHeaderRoot, {\n Root: SectionHeaderRoot,\n Content: SectionHeaderContent,\n Title: SectionHeaderTitle,\n Description: SectionHeaderDescription,\n Actions: SectionHeaderActions,\n Tabs: SectionHeaderTabs,\n});\n\nexport { SectionHeader };\n"],
5
+ "mappings": "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",
6
+ "names": ["section_header_exports", "__export", "SectionHeader", "__toCommonJS", "React", "import_kookie_ui", "layoutToDirection", "layout", "convertLayoutToDirection", "result", "breakpoint", "value", "layoutToJustify", "convertLayoutToJustify", "layoutToAlign", "convertLayoutToAlign", "SectionHeaderRoot", "align", "separator", "gap", "direction", "children", "props", "ref", "computedDirection", "computedJustify", "computedAlign", "SectionHeaderContent", "SectionHeaderTitle", "as", "size", "weight", "SectionHeaderDescription", "color", "SectionHeaderActions", "SectionHeaderTabs", "width"]
7
7
  }
@@ -0,0 +1,21 @@
1
+ import * as React from "react";
2
+ import type { FlexProps } from "@kushagradhawan/kookie-ui/components/flex";
3
+ import type { HeadingProps } from "@kushagradhawan/kookie-ui/components/heading";
4
+ import type { TextProps } from "@kushagradhawan/kookie-ui/components/text";
5
+ import type { BoxProps } from "@kushagradhawan/kookie-ui/components/box";
6
+ declare const EmptyState: React.ForwardRefExoticComponent<Omit<FlexProps, "direction"> & {
7
+ /** Content alignment. Defaults to center. */
8
+ align?: "start" | "center";
9
+ } & React.RefAttributes<HTMLDivElement>> & {
10
+ Root: React.ForwardRefExoticComponent<Omit<FlexProps, "direction"> & {
11
+ /** Content alignment. Defaults to center. */
12
+ align?: "start" | "center";
13
+ } & React.RefAttributes<HTMLDivElement>>;
14
+ Icon: React.ForwardRefExoticComponent<BoxProps & React.RefAttributes<HTMLDivElement>>;
15
+ Content: React.ForwardRefExoticComponent<FlexProps & React.RefAttributes<HTMLDivElement>>;
16
+ Title: React.ForwardRefExoticComponent<HeadingProps & React.RefAttributes<HTMLHeadingElement>>;
17
+ Description: React.ForwardRefExoticComponent<TextProps & React.RefAttributes<HTMLParagraphElement>>;
18
+ Actions: React.ForwardRefExoticComponent<FlexProps & React.RefAttributes<HTMLDivElement>>;
19
+ };
20
+ export { EmptyState };
21
+ //# sourceMappingURL=empty-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"empty-state.d.ts","sourceRoot":"","sources":["../../../../src/components/empty-state/empty-state.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2CAA2C,CAAC;AAC3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8CAA8C,CAAC;AACjF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2CAA2C,CAAC;AAC3E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0CAA0C,CAAC;AA6EzE,QAAA,MAAM,UAAU;IAzEd,6CAA6C;YACrC,OAAO,GAAG,QAAQ;;;QAD1B,6CAA6C;gBACrC,OAAO,GAAG,QAAQ;;;;;;;CA+E1B,CAAC;AAEH,OAAO,EAAE,UAAU,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ import*as e from"react";import{Flex as a,Heading as f,Text as d,Box as S}from"@kushagradhawan/kookie-ui";const i=e.forwardRef(({align:t="center",gap:o="4",children:r,...p},n)=>e.createElement(a,{ref:n,direction:"column",align:t,gap:o,...p},r));i.displayName="EmptyState.Root";const s=e.forwardRef(({className:t,...o},r)=>e.createElement(S,{ref:r,className:`kb-empty-state-icon${t?` ${t}`:""}`,...o}));s.displayName="EmptyState.Icon";const m=e.forwardRef(({direction:t="column",gap:o="1",...r},p)=>e.createElement(a,{ref:p,direction:t,gap:o,...r}));m.displayName="EmptyState.Content";const y=e.forwardRef(({as:t="h3",size:o="5",weight:r="medium",align:p="center",...n},E)=>e.createElement(f,{ref:E,as:t,size:o,weight:r,align:p,...n}));y.displayName="EmptyState.Title";const c=e.forwardRef(({size:t="2",color:o="gray",align:r="center",...p},n)=>e.createElement(d,{ref:n,size:t,color:o,align:r,...p}));c.displayName="EmptyState.Description";const l=e.forwardRef(({gap:t="2",align:o="center",justify:r="center",...p},n)=>e.createElement(a,{ref:n,gap:t,align:o,justify:r,...p}));l.displayName="EmptyState.Actions";const P=Object.assign(i,{Root:i,Icon:s,Content:m,Title:y,Description:c,Actions:l});export{P as EmptyState};
2
+ //# sourceMappingURL=empty-state.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/components/empty-state/empty-state.tsx"],
4
+ "sourcesContent": ["import * as React from \"react\";\nimport { Flex, Heading, Text, Box } from \"@kushagradhawan/kookie-ui\";\nimport type { FlexProps } from \"@kushagradhawan/kookie-ui/components/flex\";\nimport type { HeadingProps } from \"@kushagradhawan/kookie-ui/components/heading\";\nimport type { TextProps } from \"@kushagradhawan/kookie-ui/components/text\";\nimport type { BoxProps } from \"@kushagradhawan/kookie-ui/components/box\";\n\n// EmptyState.Root Props\ntype EmptyStateRootProps = Omit<FlexProps, 'direction'> & {\n /** Content alignment. Defaults to center. */\n align?: \"start\" | \"center\";\n};\n\nconst EmptyStateRoot = React.forwardRef<HTMLDivElement, EmptyStateRootProps>(\n ({ align = \"center\", gap = \"4\", children, ...props }, ref) => {\n return (\n <Flex\n ref={ref}\n direction=\"column\"\n align={align}\n gap={gap}\n {...props}\n >\n {children}\n </Flex>\n );\n }\n);\nEmptyStateRoot.displayName = \"EmptyState.Root\";\n\n// EmptyState.Icon - Container for the icon/illustration\ntype EmptyStateIconProps = BoxProps;\nconst EmptyStateIcon = React.forwardRef<HTMLDivElement, EmptyStateIconProps>(\n ({ className, ...props }, ref) => {\n return (\n <Box\n ref={ref}\n className={`kb-empty-state-icon${className ? ` ${className}` : \"\"}`}\n {...props}\n />\n );\n }\n);\nEmptyStateIcon.displayName = \"EmptyState.Icon\";\n\n// EmptyState.Content - Groups title and description with tighter gap\ntype EmptyStateContentProps = FlexProps;\nconst EmptyStateContent = React.forwardRef<HTMLDivElement, EmptyStateContentProps>(\n ({ direction = \"column\", gap = \"1\", ...props }, ref) => {\n return <Flex ref={ref} direction={direction} gap={gap} {...props} />;\n }\n);\nEmptyStateContent.displayName = \"EmptyState.Content\";\n\n// EmptyState.Title - Passes through to Heading with sensible defaults\ntype EmptyStateTitleProps = HeadingProps;\nconst EmptyStateTitle = React.forwardRef<HTMLHeadingElement, EmptyStateTitleProps>(\n ({ as = \"h3\", size = \"5\", weight = \"medium\", align = \"center\", ...props }, ref) => {\n return <Heading ref={ref} as={as} size={size} weight={weight} align={align} {...props} />;\n }\n);\nEmptyStateTitle.displayName = \"EmptyState.Title\";\n\n// EmptyState.Description - Passes through to Text with sensible defaults\ntype EmptyStateDescriptionProps = TextProps;\nconst EmptyStateDescription = React.forwardRef<HTMLParagraphElement, EmptyStateDescriptionProps>(\n ({ size = \"2\", color = \"gray\", align = \"center\", ...props }, ref) => {\n return <Text ref={ref} size={size} color={color} align={align} {...props} />;\n }\n);\nEmptyStateDescription.displayName = \"EmptyState.Description\";\n\n// EmptyState.Actions - Container for action buttons\ntype EmptyStateActionsProps = FlexProps;\nconst EmptyStateActions = React.forwardRef<HTMLDivElement, EmptyStateActionsProps>(\n ({ gap = \"2\", align = \"center\", justify = \"center\", ...props }, ref) => {\n return <Flex ref={ref} gap={gap} align={align} justify={justify} {...props} />;\n }\n);\nEmptyStateActions.displayName = \"EmptyState.Actions\";\n\n// Compose the EmptyState object\nconst EmptyState = Object.assign(EmptyStateRoot, {\n Root: EmptyStateRoot,\n Icon: EmptyStateIcon,\n Content: EmptyStateContent,\n Title: EmptyStateTitle,\n Description: EmptyStateDescription,\n Actions: EmptyStateActions,\n});\n\nexport { EmptyState };\n"],
5
+ "mappings": "AAAA,UAAYA,MAAW,QACvB,OAAS,QAAAC,EAAM,WAAAC,EAAS,QAAAC,EAAM,OAAAC,MAAW,4BAYzC,MAAMC,EAAiBL,EAAM,WAC3B,CAAC,CAAE,MAAAM,EAAQ,SAAU,IAAAC,EAAM,IAAK,SAAAC,EAAU,GAAGC,CAAM,EAAGC,IAElDV,EAAA,cAACC,EAAA,CACC,IAAKS,EACL,UAAU,SACV,MAAOJ,EACP,IAAKC,EACJ,GAAGE,GAEHD,CACH,CAGN,EACAH,EAAe,YAAc,kBAI7B,MAAMM,EAAiBX,EAAM,WAC3B,CAAC,CAAE,UAAAY,EAAW,GAAGH,CAAM,EAAGC,IAEtBV,EAAA,cAACI,EAAA,CACC,IAAKM,EACL,UAAW,sBAAsBE,EAAY,IAAIA,CAAS,GAAK,EAAE,GAChE,GAAGH,EACN,CAGN,EACAE,EAAe,YAAc,kBAI7B,MAAME,EAAoBb,EAAM,WAC9B,CAAC,CAAE,UAAAc,EAAY,SAAU,IAAAP,EAAM,IAAK,GAAGE,CAAM,EAAGC,IACvCV,EAAA,cAACC,EAAA,CAAK,IAAKS,EAAK,UAAWI,EAAW,IAAKP,EAAM,GAAGE,EAAO,CAEtE,EACAI,EAAkB,YAAc,qBAIhC,MAAME,EAAkBf,EAAM,WAC5B,CAAC,CAAE,GAAAgB,EAAK,KAAM,KAAAC,EAAO,IAAK,OAAAC,EAAS,SAAU,MAAAZ,EAAQ,SAAU,GAAGG,CAAM,EAAGC,IAClEV,EAAA,cAACE,EAAA,CAAQ,IAAKQ,EAAK,GAAIM,EAAI,KAAMC,EAAM,OAAQC,EAAQ,MAAOZ,EAAQ,GAAGG,EAAO,CAE3F,EACAM,EAAgB,YAAc,mBAI9B,MAAMI,EAAwBnB,EAAM,WAClC,CAAC,CAAE,KAAAiB,EAAO,IAAK,MAAAG,EAAQ,OAAQ,MAAAd,EAAQ,SAAU,GAAGG,CAAM,EAAGC,IACpDV,EAAA,cAACG,EAAA,CAAK,IAAKO,EAAK,KAAMO,EAAM,MAAOG,EAAO,MAAOd,EAAQ,GAAGG,EAAO,CAE9E,EACAU,EAAsB,YAAc,yBAIpC,MAAME,EAAoBrB,EAAM,WAC9B,CAAC,CAAE,IAAAO,EAAM,IAAK,MAAAD,EAAQ,SAAU,QAAAgB,EAAU,SAAU,GAAGb,CAAM,EAAGC,IACvDV,EAAA,cAACC,EAAA,CAAK,IAAKS,EAAK,IAAKH,EAAK,MAAOD,EAAO,QAASgB,EAAU,GAAGb,EAAO,CAEhF,EACAY,EAAkB,YAAc,qBAGhC,MAAME,EAAa,OAAO,OAAOlB,EAAgB,CAC/C,KAAMA,EACN,KAAMM,EACN,QAASE,EACT,MAAOE,EACP,YAAaI,EACb,QAASE,CACX,CAAC",
6
+ "names": ["React", "Flex", "Heading", "Text", "Box", "EmptyStateRoot", "align", "gap", "children", "props", "ref", "EmptyStateIcon", "className", "EmptyStateContent", "direction", "EmptyStateTitle", "as", "size", "weight", "EmptyStateDescription", "color", "EmptyStateActions", "justify", "EmptyState"]
7
+ }
@@ -0,0 +1,2 @@
1
+ export { EmptyState } from './empty-state.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/empty-state/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{EmptyState as m}from"./empty-state.js";export{m as EmptyState};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/components/empty-state/index.ts"],
4
+ "sourcesContent": ["export { EmptyState } from './empty-state.js';\n"],
5
+ "mappings": "AAAA,OAAS,cAAAA,MAAkB",
6
+ "names": ["EmptyState"]
7
+ }
@@ -1,5 +1,6 @@
1
1
  export * from './code/index.js';
2
2
  export * from './docs/index.js';
3
+ export * from './empty-state/index.js';
3
4
  export * from './footer/index.js';
4
5
  export * from './hero/index.js';
5
6
  export * from './markdown/index.js';
@@ -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,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,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,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC"}
@@ -1,2 +1,2 @@
1
- export*from"./code/index.js";export*from"./docs/index.js";export*from"./footer/index.js";export*from"./hero/index.js";export*from"./markdown/index.js";export*from"./page-header/index.js";export*from"./section-header/index.js";
1
+ export*from"./code/index.js";export*from"./docs/index.js";export*from"./empty-state/index.js";export*from"./footer/index.js";export*from"./hero/index.js";export*from"./markdown/index.js";export*from"./page-header/index.js";export*from"./section-header/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 './docs/index.js';\nexport * from './footer/index.js';\nexport * from './hero/index.js';\nexport * from './markdown/index.js';\nexport * from './page-header/index.js';\nexport * from './section-header/index.js';\n"],
5
- "mappings": "AAAA,WAAc,kBACd,WAAc,kBACd,WAAc,oBACd,WAAc,kBACd,WAAc,sBACd,WAAc,yBACd,WAAc",
4
+ "sourcesContent": ["export * from './code/index.js';\nexport * from './docs/index.js';\nexport * from './empty-state/index.js';\nexport * from './footer/index.js';\nexport * from './hero/index.js';\nexport * from './markdown/index.js';\nexport * from './page-header/index.js';\nexport * from './section-header/index.js';\n"],
5
+ "mappings": "AAAA,WAAc,kBACd,WAAc,kBACd,WAAc,yBACd,WAAc,oBACd,WAAc,kBACd,WAAc,sBACd,WAAc,yBACd,WAAc",
6
6
  "names": []
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,YAAY,CAAC;AAa3D;;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,YAAY,CAAC;AAa3D;;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,4BA2DtF"}
@@ -1,2 +1,2 @@
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.js";import{completeUnterminatedMarkdown as b,parseMarkdownIntoBlocks as B}from"./utils/markdown-streaming.js";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};
1
+ "use client";import e,{memo as P,useMemo as p}from"react";import h from"react-markdown";import y from"remark-gfm";import C from"rehype-raw";import i from"harden-react-markdown";import{Box as b,Flex as B}from"@kushagradhawan/kookie-ui";import{createMarkdownComponents as I}from"./create-markdown-components.js";import{completeUnterminatedMarkdown as S,parseMarkdownIntoBlocks as E}from"./utils/markdown-streaming.js";const x=typeof i=="function"?i:i.default||i,L=x(h),A=["https://","http://","/"],F=["https://","http://","/","data:"],R=["mailto:","tel:","data:","http:","https:"],_=typeof window<"u"&&window.location?.origin?window.location.origin:"https://app.kookie.ai";function D(o){return o||_}const m=P(({content:o,defaultOrigin:n,components:a})=>e.createElement(b,{width:"100%"},e.createElement(L,{defaultOrigin:n,allowedLinkPrefixes:A,allowedImagePrefixes:F,allowedProtocols:R,allowDataImages:!0,components:a,remarkPlugins:[y],rehypePlugins:[C]},o)),(o,n)=>o.content===n.content&&o.defaultOrigin===n.defaultOrigin&&o.components===n.components);m.displayName="MarkdownBlock";function j({content:o,id:n,options:a={}}){const{defaultOrigin:l,enableBlockMemoization:d=!0,blockParser:s,components:c,codeBlockCollapsible:k=!1,imageComponent:g,inlineCodeHighContrast:f=!0,spacing:w="spacious"}=a,u=p(()=>D(l),[l]),M=p(()=>({...I({codeBlockCollapsible:k,imageComponent:g,inlineCodeHighContrast:f,spacing:w}),...c}),[k,g,f,w,c]),r=p(()=>{if(!d||!s){const t=S(o);return t.trim()?[t]:[]}return E(o,s)},[o,d,s]);return r.length?r.length===1?e.createElement(m,{content:r[0],defaultOrigin:u,components:M}):e.createElement(B,{direction:"column",gap:"2",width:"100%"},r.map((t,O)=>e.createElement(m,{key:`${n}-block-${O}`,content:t,defaultOrigin:u,components:M}))):null}export{j 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 hardenReactMarkdownModule from \"harden-react-markdown\";\nimport { Box, Flex } from \"@kushagradhawan/kookie-ui\";\nimport { createMarkdownComponents } from \"./create-markdown-components.js\";\nimport { completeUnterminatedMarkdown, parseMarkdownIntoBlocks } from \"./utils/markdown-streaming.js\";\nimport type { MarkdownComponentOptions } from \"./types.js\";\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,kCACzC,OAAS,gCAAAC,EAA8B,2BAAAC,MAA+B,gCAItE,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"]
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.js\";\nimport { completeUnterminatedMarkdown, parseMarkdownIntoBlocks } from \"./utils/markdown-streaming.js\";\nimport type { MarkdownComponentOptions } from \"./types.js\";\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 {\n defaultOrigin: customOrigin,\n enableBlockMemoization = true,\n blockParser,\n components: customComponents,\n // Extract individual options as primitives for stable useMemo deps\n codeBlockCollapsible = false,\n imageComponent,\n inlineCodeHighContrast = true,\n spacing = \"spacious\",\n } = options;\n\n // Resolve security origin\n const defaultOrigin = useMemo(() => resolveDefaultOrigin(customOrigin), [customOrigin]);\n\n // Create component mappings with custom overrides\n // Uses primitive deps to avoid recreating on every render\n const markdownComponents = useMemo(() => {\n const baseComponents = createMarkdownComponents({\n codeBlockCollapsible,\n imageComponent,\n inlineCodeHighContrast,\n spacing,\n });\n return {\n ...baseComponents,\n ...customComponents,\n };\n }, [codeBlockCollapsible, imageComponent, inlineCodeHighContrast, spacing, 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,kCACzC,OAAS,gCAAAC,EAA8B,2BAAAC,MAA+B,gCAItE,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,CACJ,cAAeT,EACf,uBAAAU,EAAyB,GACzB,YAAAC,EACA,WAAYC,EAEZ,qBAAAC,EAAuB,GACvB,eAAAC,EACA,uBAAAC,EAAyB,GACzB,QAAAC,EAAU,UACZ,EAAIP,EAGEN,EAAgBpB,EAAQ,IAAMgB,EAAqBC,CAAY,EAAG,CAACA,CAAY,CAAC,EAIhFiB,EAAqBlC,EAAQ,KAO1B,CACL,GAPqBO,EAAyB,CAC9C,qBAAAuB,EACA,eAAAC,EACA,uBAAAC,EACA,QAAAC,CACF,CAAC,EAGC,GAAGJ,CACL,GACC,CAACC,EAAsBC,EAAgBC,EAAwBC,EAASJ,CAAgB,CAAC,EAGtFM,EAASnC,EAAQ,IAAM,CAC3B,GAAI,CAAC2B,GAA0B,CAACC,EAAa,CAE3C,MAAMQ,EAAY5B,EAA6BW,CAAO,EACtD,OAAOiB,EAAU,KAAK,EAAI,CAACA,CAAS,EAAI,CAAC,CAC3C,CAEA,OAAO3B,EAAwBU,EAASS,CAAW,CACrD,EAAG,CAACT,EAASQ,EAAwBC,CAAW,CAAC,EAEjD,OAAKO,EAAO,OAKRA,EAAO,SAAW,EACbrC,EAAA,cAACoB,EAAA,CAAc,QAASiB,EAAO,CAAC,EAAG,cAAef,EAAe,WAAYc,EAAoB,EAKxGpC,EAAA,cAACQ,EAAA,CAAK,UAAU,SAAS,IAAI,IAAI,MAAM,QACpC6B,EAAO,IAAI,CAACE,EAAOC,IAClBxC,EAAA,cAACoB,EAAA,CAAc,IAAK,GAAGO,CAAE,UAAUa,CAAK,GAAI,QAASD,EAAO,cAAejB,EAAe,WAAYc,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", "codeBlockCollapsible", "imageComponent", "inlineCodeHighContrast", "spacing", "markdownComponents", "blocks", "completed", "block", "index"]
7
7
  }
@@ -6,6 +6,8 @@ type Responsive<T> = T | Partial<Record<'initial' | 'xs' | 'sm' | 'md' | 'lg' |
6
6
  declare const SectionHeader: React.ForwardRefExoticComponent<Omit<FlexProps, "direction"> & {
7
7
  /** Layout mode: stacked (vertical) or inline (horizontal with actions on right) */
8
8
  layout?: Responsive<"stacked" | "inline">;
9
+ /** Content alignment. Overrides the default alignment derived from layout. */
10
+ align?: Responsive<"start" | "center">;
9
11
  /** Show separator at bottom. Use when no tabs are present. */
10
12
  separator?: boolean;
11
13
  /** Allow explicit direction override if needed */
@@ -14,6 +16,8 @@ declare const SectionHeader: React.ForwardRefExoticComponent<Omit<FlexProps, "di
14
16
  Root: React.ForwardRefExoticComponent<Omit<FlexProps, "direction"> & {
15
17
  /** Layout mode: stacked (vertical) or inline (horizontal with actions on right) */
16
18
  layout?: Responsive<"stacked" | "inline">;
19
+ /** Content alignment. Overrides the default alignment derived from layout. */
20
+ align?: Responsive<"start" | "center">;
17
21
  /** Show separator at bottom. Use when no tabs are present. */
18
22
  separator?: boolean;
19
23
  /** Allow explicit direction override if needed */
@@ -1 +1 @@
1
- {"version":3,"file":"section-header.d.ts","sourceRoot":"","sources":["../../../../src/components/section-header/section-header.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2CAA2C,CAAC;AAC3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8CAA8C,CAAC;AACjF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2CAA2C,CAAC;AAG3E,KAAK,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AA4J1F,QAAA,MAAM,aAAa;IA/EjB,mFAAmF;aAC1E,UAAU,CAAC,SAAS,GAAG,QAAQ,CAAC;IACzC,8DAA8D;gBAClD,OAAO;IACnB,kDAAkD;gBACtC,SAAS,CAAC,WAAW,CAAC;;;QALlC,mFAAmF;iBAC1E,UAAU,CAAC,SAAS,GAAG,QAAQ,CAAC;QACzC,8DAA8D;oBAClD,OAAO;QACnB,kDAAkD;oBACtC,SAAS,CAAC,WAAW,CAAC;;;;;;;CAiFlC,CAAC;AAEH,OAAO,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"section-header.d.ts","sourceRoot":"","sources":["../../../../src/components/section-header/section-header.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2CAA2C,CAAC;AAC3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8CAA8C,CAAC;AACjF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2CAA2C,CAAC;AAG3E,KAAK,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AA8J1F,QAAA,MAAM,aAAa;IAjFjB,mFAAmF;aAC1E,UAAU,CAAC,SAAS,GAAG,QAAQ,CAAC;IACzC,8EAA8E;YACtE,UAAU,CAAC,OAAO,GAAG,QAAQ,CAAC;IACtC,8DAA8D;gBAClD,OAAO;IACnB,kDAAkD;gBACtC,SAAS,CAAC,WAAW,CAAC;;;QAPlC,mFAAmF;iBAC1E,UAAU,CAAC,SAAS,GAAG,QAAQ,CAAC;QACzC,8EAA8E;gBACtE,UAAU,CAAC,OAAO,GAAG,QAAQ,CAAC;QACtC,8DAA8D;oBAClD,OAAO;QACnB,kDAAkD;oBACtC,SAAS,CAAC,WAAW,CAAC;;;;;;;CAiFlC,CAAC;AAEH,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -1,2 +1,2 @@
1
- import*as r from"react";import{Flex as i,Heading as w,Text as x,Separator as k}from"@kushagradhawan/kookie-ui";function c(e){return e==="inline"?"row":"column"}function b(e){if(!e)return;if(typeof e=="string")return c(e);const t={};for(const[n,o]of Object.entries(e))o&&(t[n]=c(o));return t}function d(e){return e==="inline"?"between":"start"}function v(e){if(!e)return;if(typeof e=="string")return d(e);const t={};for(const[n,o]of Object.entries(e))o&&(t[n]=d(o));return t}function p(e){return e==="inline"?"center":"start"}function R(e){if(!e)return;if(typeof e=="string")return p(e);const t={};for(const[n,o]of Object.entries(e))o&&(t[n]=p(o));return t}const a=r.forwardRef(({layout:e="inline",separator:t=!1,gap:n="4",direction:o,children:s,...T},g)=>{const P=o||b(e)||"row",y=v(e)||"between",S=R(e)||"center";return r.createElement(i,{ref:g,direction:"column",gap:n,...T},r.createElement(i,{direction:P,justify:y,align:S,gap:n,wrap:"wrap"},s),t&&r.createElement(k,{size:"4"}))});a.displayName="SectionHeader.Root";const l=r.forwardRef(({direction:e="column",gap:t="1",...n},o)=>r.createElement(i,{ref:o,direction:e,gap:t,...n}));l.displayName="SectionHeader.Content";const f=r.forwardRef(({as:e="h2",size:t="6",weight:n="medium",...o},s)=>r.createElement(w,{ref:s,as:e,size:t,weight:n,...o}));f.displayName="SectionHeader.Title";const u=r.forwardRef(({size:e="3",color:t="gray",...n},o)=>r.createElement(x,{ref:o,size:e,color:t,...n}));u.displayName="SectionHeader.Description";const m=r.forwardRef(({gap:e="2",align:t="center",...n},o)=>r.createElement(i,{ref:o,gap:e,align:t,...n}));m.displayName="SectionHeader.Actions";const H=r.forwardRef(({width:e="100%",...t},n)=>r.createElement(i,{ref:n,width:e,...t}));H.displayName="SectionHeader.Tabs";const D=Object.assign(a,{Root:a,Content:l,Title:f,Description:u,Actions:m,Tabs:H});export{D as SectionHeader};
1
+ import*as o from"react";import{Flex as i,Heading as x,Text as k,Separator as v}from"@kushagradhawan/kookie-ui";function c(e){return e==="inline"?"row":"column"}function b(e){if(!e)return;if(typeof e=="string")return c(e);const t={};for(const[r,n]of Object.entries(e))n&&(t[r]=c(n));return t}function d(e){return e==="inline"?"between":"start"}function R(e){if(!e)return;if(typeof e=="string")return d(e);const t={};for(const[r,n]of Object.entries(e))n&&(t[r]=d(n));return t}function p(e){return e==="inline"?"center":"start"}function D(e){if(!e)return;if(typeof e=="string")return p(e);const t={};for(const[r,n]of Object.entries(e))n&&(t[r]=p(n));return t}const a=o.forwardRef(({layout:e="inline",align:t,separator:r=!1,gap:n="4",direction:s,children:g,...T},P)=>{const y=s||b(e)||"row",S=R(e)||"between",w=t??D(e)??"center";return o.createElement(i,{ref:P,direction:"column",gap:n,...T},o.createElement(i,{direction:y,justify:S,align:w,gap:n,wrap:"wrap"},g),r&&o.createElement(v,{size:"4"}))});a.displayName="SectionHeader.Root";const l=o.forwardRef(({direction:e="column",gap:t="1",...r},n)=>o.createElement(i,{ref:n,direction:e,gap:t,...r}));l.displayName="SectionHeader.Content";const f=o.forwardRef(({as:e="h2",size:t="6",weight:r="medium",...n},s)=>o.createElement(x,{ref:s,as:e,size:t,weight:r,...n}));f.displayName="SectionHeader.Title";const u=o.forwardRef(({size:e="3",color:t="gray",...r},n)=>o.createElement(k,{ref:n,size:e,color:t,...r}));u.displayName="SectionHeader.Description";const m=o.forwardRef(({gap:e="2",align:t="center",...r},n)=>o.createElement(i,{ref:n,gap:e,align:t,...r}));m.displayName="SectionHeader.Actions";const H=o.forwardRef(({width:e="100%",...t},r)=>o.createElement(i,{ref:r,width:e,...t}));H.displayName="SectionHeader.Tabs";const h=Object.assign(a,{Root:a,Content:l,Title:f,Description:u,Actions:m,Tabs:H});export{h as SectionHeader};
2
2
  //# sourceMappingURL=section-header.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/section-header/section-header.tsx"],
4
- "sourcesContent": ["import * as React from \"react\";\nimport { Flex, Heading, Text, Separator } from \"@kushagradhawan/kookie-ui\";\nimport type { FlexProps } from \"@kushagradhawan/kookie-ui/components/flex\";\nimport type { HeadingProps } from \"@kushagradhawan/kookie-ui/components/heading\";\nimport type { TextProps } from \"@kushagradhawan/kookie-ui/components/text\";\n\n// Responsive type matching Kookie UI's pattern\ntype Responsive<T> = T | Partial<Record<'initial' | 'xs' | 'sm' | 'md' | 'lg' | 'xl', T>>;\n\n// Helper to convert layout to direction\nfunction layoutToDirection(layout: \"stacked\" | \"inline\"): \"column\" | \"row\" {\n return layout === \"inline\" ? \"row\" : \"column\";\n}\n\n// Helper to convert responsive layout to responsive direction\nfunction convertLayoutToDirection(\n layout?: Responsive<\"stacked\" | \"inline\">\n): Responsive<\"column\" | \"row\"> | undefined {\n if (!layout) return undefined;\n\n if (typeof layout === \"string\") {\n return layoutToDirection(layout);\n }\n\n // Handle responsive object\n const result: Partial<Record<'initial' | 'xs' | 'sm' | 'md' | 'lg' | 'xl', \"column\" | \"row\">> = {};\n for (const [breakpoint, value] of Object.entries(layout)) {\n if (value) {\n result[breakpoint as keyof typeof result] = layoutToDirection(value);\n }\n }\n return result;\n}\n\n// Helper to convert layout to justify\nfunction layoutToJustify(layout: \"stacked\" | \"inline\"): \"start\" | \"between\" {\n return layout === \"inline\" ? \"between\" : \"start\";\n}\n\n// Helper to convert responsive layout to responsive justify\nfunction convertLayoutToJustify(\n layout?: Responsive<\"stacked\" | \"inline\">\n): Responsive<\"start\" | \"between\"> | undefined {\n if (!layout) return undefined;\n\n if (typeof layout === \"string\") {\n return layoutToJustify(layout);\n }\n\n const result: Partial<Record<'initial' | 'xs' | 'sm' | 'md' | 'lg' | 'xl', \"start\" | \"between\">> = {};\n for (const [breakpoint, value] of Object.entries(layout)) {\n if (value) {\n result[breakpoint as keyof typeof result] = layoutToJustify(value);\n }\n }\n return result;\n}\n\n// Helper to convert layout to align\nfunction layoutToAlign(layout: \"stacked\" | \"inline\"): \"start\" | \"center\" {\n return layout === \"inline\" ? \"center\" : \"start\";\n}\n\n// Helper to convert responsive layout to responsive align\nfunction convertLayoutToAlign(\n layout?: Responsive<\"stacked\" | \"inline\">\n): Responsive<\"start\" | \"center\"> | undefined {\n if (!layout) return undefined;\n\n if (typeof layout === \"string\") {\n return layoutToAlign(layout);\n }\n\n const result: Partial<Record<'initial' | 'xs' | 'sm' | 'md' | 'lg' | 'xl', \"start\" | \"center\">> = {};\n for (const [breakpoint, value] of Object.entries(layout)) {\n if (value) {\n result[breakpoint as keyof typeof result] = layoutToAlign(value);\n }\n }\n return result;\n}\n\n// SectionHeader.Root Props\ntype SectionHeaderRootProps = Omit<FlexProps, 'direction'> & {\n /** Layout mode: stacked (vertical) or inline (horizontal with actions on right) */\n layout?: Responsive<\"stacked\" | \"inline\">;\n /** Show separator at bottom. Use when no tabs are present. */\n separator?: boolean;\n /** Allow explicit direction override if needed */\n direction?: FlexProps['direction'];\n};\n\nconst SectionHeaderRoot = React.forwardRef<HTMLDivElement, SectionHeaderRootProps>(\n ({ layout = \"inline\", separator = false, gap = \"4\", direction, children, ...props }, ref) => {\n // Convert layout to direction/justify/align, but allow explicit direction override\n const computedDirection = direction || convertLayoutToDirection(layout) || \"row\";\n const computedJustify = convertLayoutToJustify(layout) || \"between\";\n const computedAlign = convertLayoutToAlign(layout) || \"center\";\n\n return (\n <Flex ref={ref} direction=\"column\" gap={gap} {...props}>\n <Flex\n direction={computedDirection}\n justify={computedJustify}\n align={computedAlign}\n gap={gap}\n wrap=\"wrap\"\n >\n {children}\n </Flex>\n {separator && <Separator size=\"4\" />}\n </Flex>\n );\n }\n);\nSectionHeaderRoot.displayName = \"SectionHeader.Root\";\n\n// SectionHeader.Content - Groups title and description\ntype SectionHeaderContentProps = FlexProps;\nconst SectionHeaderContent = React.forwardRef<HTMLDivElement, SectionHeaderContentProps>(\n ({ direction = \"column\", gap = \"1\", ...props }, ref) => {\n return <Flex ref={ref} direction={direction} gap={gap} {...props} />;\n }\n);\nSectionHeaderContent.displayName = \"SectionHeader.Content\";\n\n// SectionHeader.Title - Passes through to Heading with sensible defaults\ntype SectionHeaderTitleProps = HeadingProps;\nconst SectionHeaderTitle = React.forwardRef<HTMLHeadingElement, SectionHeaderTitleProps>(\n ({ as = \"h2\", size = \"6\", weight = \"medium\", ...props }, ref) => {\n return <Heading ref={ref} as={as} size={size} weight={weight} {...props} />;\n }\n);\nSectionHeaderTitle.displayName = \"SectionHeader.Title\";\n\n// SectionHeader.Description - Passes through to Text with sensible defaults\ntype SectionHeaderDescriptionProps = TextProps;\nconst SectionHeaderDescription = React.forwardRef<HTMLParagraphElement, SectionHeaderDescriptionProps>(\n ({ size = \"3\", color = \"gray\", ...props }, ref) => {\n return <Text ref={ref} size={size} color={color} {...props} />;\n }\n);\nSectionHeaderDescription.displayName = \"SectionHeader.Description\";\n\n// SectionHeader.Actions - Container for action buttons (right side in inline layout)\ntype SectionHeaderActionsProps = FlexProps;\nconst SectionHeaderActions = React.forwardRef<HTMLDivElement, SectionHeaderActionsProps>(\n ({ gap = \"2\", align = \"center\", ...props }, ref) => {\n return <Flex ref={ref} gap={gap} align={align} {...props} />;\n }\n);\nSectionHeaderActions.displayName = \"SectionHeader.Actions\";\n\n// SectionHeader.Tabs - Container for tabs (renders below the header row)\ntype SectionHeaderTabsProps = FlexProps;\nconst SectionHeaderTabs = React.forwardRef<HTMLDivElement, SectionHeaderTabsProps>(\n ({ width = \"100%\", ...props }, ref) => {\n return <Flex ref={ref} width={width} {...props} />;\n }\n);\nSectionHeaderTabs.displayName = \"SectionHeader.Tabs\";\n\n// Compose the SectionHeader object\nconst SectionHeader = Object.assign(SectionHeaderRoot, {\n Root: SectionHeaderRoot,\n Content: SectionHeaderContent,\n Title: SectionHeaderTitle,\n Description: SectionHeaderDescription,\n Actions: SectionHeaderActions,\n Tabs: SectionHeaderTabs,\n});\n\nexport { SectionHeader };\n"],
5
- "mappings": "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",
6
- "names": ["React", "Flex", "Heading", "Text", "Separator", "layoutToDirection", "layout", "convertLayoutToDirection", "result", "breakpoint", "value", "layoutToJustify", "convertLayoutToJustify", "layoutToAlign", "convertLayoutToAlign", "SectionHeaderRoot", "separator", "gap", "direction", "children", "props", "ref", "computedDirection", "computedJustify", "computedAlign", "SectionHeaderContent", "SectionHeaderTitle", "as", "size", "weight", "SectionHeaderDescription", "color", "SectionHeaderActions", "align", "SectionHeaderTabs", "width", "SectionHeader"]
4
+ "sourcesContent": ["import * as React from \"react\";\nimport { Flex, Heading, Text, Separator } from \"@kushagradhawan/kookie-ui\";\nimport type { FlexProps } from \"@kushagradhawan/kookie-ui/components/flex\";\nimport type { HeadingProps } from \"@kushagradhawan/kookie-ui/components/heading\";\nimport type { TextProps } from \"@kushagradhawan/kookie-ui/components/text\";\n\n// Responsive type matching Kookie UI's pattern\ntype Responsive<T> = T | Partial<Record<'initial' | 'xs' | 'sm' | 'md' | 'lg' | 'xl', T>>;\n\n// Helper to convert layout to direction\nfunction layoutToDirection(layout: \"stacked\" | \"inline\"): \"column\" | \"row\" {\n return layout === \"inline\" ? \"row\" : \"column\";\n}\n\n// Helper to convert responsive layout to responsive direction\nfunction convertLayoutToDirection(\n layout?: Responsive<\"stacked\" | \"inline\">\n): Responsive<\"column\" | \"row\"> | undefined {\n if (!layout) return undefined;\n\n if (typeof layout === \"string\") {\n return layoutToDirection(layout);\n }\n\n // Handle responsive object\n const result: Partial<Record<'initial' | 'xs' | 'sm' | 'md' | 'lg' | 'xl', \"column\" | \"row\">> = {};\n for (const [breakpoint, value] of Object.entries(layout)) {\n if (value) {\n result[breakpoint as keyof typeof result] = layoutToDirection(value);\n }\n }\n return result;\n}\n\n// Helper to convert layout to justify\nfunction layoutToJustify(layout: \"stacked\" | \"inline\"): \"start\" | \"between\" {\n return layout === \"inline\" ? \"between\" : \"start\";\n}\n\n// Helper to convert responsive layout to responsive justify\nfunction convertLayoutToJustify(\n layout?: Responsive<\"stacked\" | \"inline\">\n): Responsive<\"start\" | \"between\"> | undefined {\n if (!layout) return undefined;\n\n if (typeof layout === \"string\") {\n return layoutToJustify(layout);\n }\n\n const result: Partial<Record<'initial' | 'xs' | 'sm' | 'md' | 'lg' | 'xl', \"start\" | \"between\">> = {};\n for (const [breakpoint, value] of Object.entries(layout)) {\n if (value) {\n result[breakpoint as keyof typeof result] = layoutToJustify(value);\n }\n }\n return result;\n}\n\n// Helper to convert layout to align\nfunction layoutToAlign(layout: \"stacked\" | \"inline\"): \"start\" | \"center\" {\n return layout === \"inline\" ? \"center\" : \"start\";\n}\n\n// Helper to convert responsive layout to responsive align\nfunction convertLayoutToAlign(\n layout?: Responsive<\"stacked\" | \"inline\">\n): Responsive<\"start\" | \"center\"> | undefined {\n if (!layout) return undefined;\n\n if (typeof layout === \"string\") {\n return layoutToAlign(layout);\n }\n\n const result: Partial<Record<'initial' | 'xs' | 'sm' | 'md' | 'lg' | 'xl', \"start\" | \"center\">> = {};\n for (const [breakpoint, value] of Object.entries(layout)) {\n if (value) {\n result[breakpoint as keyof typeof result] = layoutToAlign(value);\n }\n }\n return result;\n}\n\n// SectionHeader.Root Props\ntype SectionHeaderRootProps = Omit<FlexProps, 'direction'> & {\n /** Layout mode: stacked (vertical) or inline (horizontal with actions on right) */\n layout?: Responsive<\"stacked\" | \"inline\">;\n /** Content alignment. Overrides the default alignment derived from layout. */\n align?: Responsive<\"start\" | \"center\">;\n /** Show separator at bottom. Use when no tabs are present. */\n separator?: boolean;\n /** Allow explicit direction override if needed */\n direction?: FlexProps['direction'];\n};\n\nconst SectionHeaderRoot = React.forwardRef<HTMLDivElement, SectionHeaderRootProps>(\n ({ layout = \"inline\", align, separator = false, gap = \"4\", direction, children, ...props }, ref) => {\n // Convert layout to direction/justify/align, but allow explicit overrides\n const computedDirection = direction || convertLayoutToDirection(layout) || \"row\";\n const computedJustify = convertLayoutToJustify(layout) || \"between\";\n const computedAlign = align ?? convertLayoutToAlign(layout) ?? \"center\";\n\n return (\n <Flex ref={ref} direction=\"column\" gap={gap} {...props}>\n <Flex\n direction={computedDirection}\n justify={computedJustify}\n align={computedAlign}\n gap={gap}\n wrap=\"wrap\"\n >\n {children}\n </Flex>\n {separator && <Separator size=\"4\" />}\n </Flex>\n );\n }\n);\nSectionHeaderRoot.displayName = \"SectionHeader.Root\";\n\n// SectionHeader.Content - Groups title and description\ntype SectionHeaderContentProps = FlexProps;\nconst SectionHeaderContent = React.forwardRef<HTMLDivElement, SectionHeaderContentProps>(\n ({ direction = \"column\", gap = \"1\", ...props }, ref) => {\n return <Flex ref={ref} direction={direction} gap={gap} {...props} />;\n }\n);\nSectionHeaderContent.displayName = \"SectionHeader.Content\";\n\n// SectionHeader.Title - Passes through to Heading with sensible defaults\ntype SectionHeaderTitleProps = HeadingProps;\nconst SectionHeaderTitle = React.forwardRef<HTMLHeadingElement, SectionHeaderTitleProps>(\n ({ as = \"h2\", size = \"6\", weight = \"medium\", ...props }, ref) => {\n return <Heading ref={ref} as={as} size={size} weight={weight} {...props} />;\n }\n);\nSectionHeaderTitle.displayName = \"SectionHeader.Title\";\n\n// SectionHeader.Description - Passes through to Text with sensible defaults\ntype SectionHeaderDescriptionProps = TextProps;\nconst SectionHeaderDescription = React.forwardRef<HTMLParagraphElement, SectionHeaderDescriptionProps>(\n ({ size = \"3\", color = \"gray\", ...props }, ref) => {\n return <Text ref={ref} size={size} color={color} {...props} />;\n }\n);\nSectionHeaderDescription.displayName = \"SectionHeader.Description\";\n\n// SectionHeader.Actions - Container for action buttons (right side in inline layout)\ntype SectionHeaderActionsProps = FlexProps;\nconst SectionHeaderActions = React.forwardRef<HTMLDivElement, SectionHeaderActionsProps>(\n ({ gap = \"2\", align = \"center\", ...props }, ref) => {\n return <Flex ref={ref} gap={gap} align={align} {...props} />;\n }\n);\nSectionHeaderActions.displayName = \"SectionHeader.Actions\";\n\n// SectionHeader.Tabs - Container for tabs (renders below the header row)\ntype SectionHeaderTabsProps = FlexProps;\nconst SectionHeaderTabs = React.forwardRef<HTMLDivElement, SectionHeaderTabsProps>(\n ({ width = \"100%\", ...props }, ref) => {\n return <Flex ref={ref} width={width} {...props} />;\n }\n);\nSectionHeaderTabs.displayName = \"SectionHeader.Tabs\";\n\n// Compose the SectionHeader object\nconst SectionHeader = Object.assign(SectionHeaderRoot, {\n Root: SectionHeaderRoot,\n Content: SectionHeaderContent,\n Title: SectionHeaderTitle,\n Description: SectionHeaderDescription,\n Actions: SectionHeaderActions,\n Tabs: SectionHeaderTabs,\n});\n\nexport { SectionHeader };\n"],
5
+ "mappings": "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",
6
+ "names": ["React", "Flex", "Heading", "Text", "Separator", "layoutToDirection", "layout", "convertLayoutToDirection", "result", "breakpoint", "value", "layoutToJustify", "convertLayoutToJustify", "layoutToAlign", "convertLayoutToAlign", "SectionHeaderRoot", "align", "separator", "gap", "direction", "children", "props", "ref", "computedDirection", "computedJustify", "computedAlign", "SectionHeaderContent", "SectionHeaderTitle", "as", "size", "weight", "SectionHeaderDescription", "color", "SectionHeaderActions", "SectionHeaderTabs", "width", "SectionHeader"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kushagradhawan/kookie-blocks",
3
- "version": "0.1.39",
3
+ "version": "0.1.41",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/KushagraDhawan1997/kookie-blocks.git"
@@ -102,7 +102,7 @@
102
102
  "shiki": "^1.24.2"
103
103
  },
104
104
  "peerDependencies": {
105
- "@kushagradhawan/kookie-ui": ">=0.1.107",
105
+ "@kushagradhawan/kookie-ui": ">=0.1.111",
106
106
  "react": "^18.0.0 || ^19.0.0",
107
107
  "react-dom": "^18.0.0 || ^19.0.0"
108
108
  },
@@ -0,0 +1,92 @@
1
+ import * as React from "react";
2
+ import { Flex, Heading, Text, Box } from "@kushagradhawan/kookie-ui";
3
+ import type { FlexProps } from "@kushagradhawan/kookie-ui/components/flex";
4
+ import type { HeadingProps } from "@kushagradhawan/kookie-ui/components/heading";
5
+ import type { TextProps } from "@kushagradhawan/kookie-ui/components/text";
6
+ import type { BoxProps } from "@kushagradhawan/kookie-ui/components/box";
7
+
8
+ // EmptyState.Root Props
9
+ type EmptyStateRootProps = Omit<FlexProps, 'direction'> & {
10
+ /** Content alignment. Defaults to center. */
11
+ align?: "start" | "center";
12
+ };
13
+
14
+ const EmptyStateRoot = React.forwardRef<HTMLDivElement, EmptyStateRootProps>(
15
+ ({ align = "center", gap = "4", children, ...props }, ref) => {
16
+ return (
17
+ <Flex
18
+ ref={ref}
19
+ direction="column"
20
+ align={align}
21
+ gap={gap}
22
+ {...props}
23
+ >
24
+ {children}
25
+ </Flex>
26
+ );
27
+ }
28
+ );
29
+ EmptyStateRoot.displayName = "EmptyState.Root";
30
+
31
+ // EmptyState.Icon - Container for the icon/illustration
32
+ type EmptyStateIconProps = BoxProps;
33
+ const EmptyStateIcon = React.forwardRef<HTMLDivElement, EmptyStateIconProps>(
34
+ ({ className, ...props }, ref) => {
35
+ return (
36
+ <Box
37
+ ref={ref}
38
+ className={`kb-empty-state-icon${className ? ` ${className}` : ""}`}
39
+ {...props}
40
+ />
41
+ );
42
+ }
43
+ );
44
+ EmptyStateIcon.displayName = "EmptyState.Icon";
45
+
46
+ // EmptyState.Content - Groups title and description with tighter gap
47
+ type EmptyStateContentProps = FlexProps;
48
+ const EmptyStateContent = React.forwardRef<HTMLDivElement, EmptyStateContentProps>(
49
+ ({ direction = "column", gap = "1", ...props }, ref) => {
50
+ return <Flex ref={ref} direction={direction} gap={gap} {...props} />;
51
+ }
52
+ );
53
+ EmptyStateContent.displayName = "EmptyState.Content";
54
+
55
+ // EmptyState.Title - Passes through to Heading with sensible defaults
56
+ type EmptyStateTitleProps = HeadingProps;
57
+ const EmptyStateTitle = React.forwardRef<HTMLHeadingElement, EmptyStateTitleProps>(
58
+ ({ as = "h3", size = "5", weight = "medium", align = "center", ...props }, ref) => {
59
+ return <Heading ref={ref} as={as} size={size} weight={weight} align={align} {...props} />;
60
+ }
61
+ );
62
+ EmptyStateTitle.displayName = "EmptyState.Title";
63
+
64
+ // EmptyState.Description - Passes through to Text with sensible defaults
65
+ type EmptyStateDescriptionProps = TextProps;
66
+ const EmptyStateDescription = React.forwardRef<HTMLParagraphElement, EmptyStateDescriptionProps>(
67
+ ({ size = "2", color = "gray", align = "center", ...props }, ref) => {
68
+ return <Text ref={ref} size={size} color={color} align={align} {...props} />;
69
+ }
70
+ );
71
+ EmptyStateDescription.displayName = "EmptyState.Description";
72
+
73
+ // EmptyState.Actions - Container for action buttons
74
+ type EmptyStateActionsProps = FlexProps;
75
+ const EmptyStateActions = React.forwardRef<HTMLDivElement, EmptyStateActionsProps>(
76
+ ({ gap = "2", align = "center", justify = "center", ...props }, ref) => {
77
+ return <Flex ref={ref} gap={gap} align={align} justify={justify} {...props} />;
78
+ }
79
+ );
80
+ EmptyStateActions.displayName = "EmptyState.Actions";
81
+
82
+ // Compose the EmptyState object
83
+ const EmptyState = Object.assign(EmptyStateRoot, {
84
+ Root: EmptyStateRoot,
85
+ Icon: EmptyStateIcon,
86
+ Content: EmptyStateContent,
87
+ Title: EmptyStateTitle,
88
+ Description: EmptyStateDescription,
89
+ Actions: EmptyStateActions,
90
+ });
91
+
92
+ export { EmptyState };
@@ -0,0 +1 @@
1
+ export { EmptyState } from './empty-state.js';
@@ -160,3 +160,22 @@ pre[data-theme] code span {
160
160
  font-weight: var(--shiki-dark-font-weight);
161
161
  text-decoration: var(--shiki-dark-text-decoration);
162
162
  }
163
+
164
+ /* ============================================
165
+ Empty State Component Styles
166
+ ============================================ */
167
+
168
+ /*
169
+ * EmptyState.Icon default sizing
170
+ * Sets a consistent default size for icons/illustrations in empty states
171
+ * Can be overridden via inline styles or custom CSS
172
+ */
173
+ .kb-empty-state-icon {
174
+ --empty-state-icon-size: var(--space-6);
175
+ color: var(--gray-a9);
176
+ }
177
+
178
+ .kb-empty-state-icon :where(svg) {
179
+ width: var(--empty-state-icon-size);
180
+ height: var(--empty-state-icon-size);
181
+ }
@@ -1,5 +1,6 @@
1
1
  export * from './code/index.js';
2
2
  export * from './docs/index.js';
3
+ export * from './empty-state/index.js';
3
4
  export * from './footer/index.js';
4
5
  export * from './hero/index.js';
5
6
  export * from './markdown/index.js';
@@ -142,19 +142,35 @@ MarkdownBlock.displayName = "MarkdownBlock";
142
142
  * ```
143
143
  */
144
144
  export function StreamingMarkdown({ content, id, options = {} }: StreamingMarkdownProps) {
145
- const { defaultOrigin: customOrigin, enableBlockMemoization = true, blockParser, components: customComponents = {}, ...componentOptions } = options;
145
+ const {
146
+ defaultOrigin: customOrigin,
147
+ enableBlockMemoization = true,
148
+ blockParser,
149
+ components: customComponents,
150
+ // Extract individual options as primitives for stable useMemo deps
151
+ codeBlockCollapsible = false,
152
+ imageComponent,
153
+ inlineCodeHighContrast = true,
154
+ spacing = "spacious",
155
+ } = options;
146
156
 
147
157
  // Resolve security origin
148
158
  const defaultOrigin = useMemo(() => resolveDefaultOrigin(customOrigin), [customOrigin]);
149
159
 
150
160
  // Create component mappings with custom overrides
161
+ // Uses primitive deps to avoid recreating on every render
151
162
  const markdownComponents = useMemo(() => {
152
- const baseComponents = createMarkdownComponents(componentOptions);
163
+ const baseComponents = createMarkdownComponents({
164
+ codeBlockCollapsible,
165
+ imageComponent,
166
+ inlineCodeHighContrast,
167
+ spacing,
168
+ });
153
169
  return {
154
170
  ...baseComponents,
155
171
  ...customComponents,
156
172
  };
157
- }, [componentOptions, customComponents]);
173
+ }, [codeBlockCollapsible, imageComponent, inlineCodeHighContrast, spacing, customComponents]);
158
174
 
159
175
  // Parse content into blocks for memoization (if enabled and parser provided)
160
176
  const blocks = useMemo(() => {
@@ -84,6 +84,8 @@ function convertLayoutToAlign(
84
84
  type SectionHeaderRootProps = Omit<FlexProps, 'direction'> & {
85
85
  /** Layout mode: stacked (vertical) or inline (horizontal with actions on right) */
86
86
  layout?: Responsive<"stacked" | "inline">;
87
+ /** Content alignment. Overrides the default alignment derived from layout. */
88
+ align?: Responsive<"start" | "center">;
87
89
  /** Show separator at bottom. Use when no tabs are present. */
88
90
  separator?: boolean;
89
91
  /** Allow explicit direction override if needed */
@@ -91,11 +93,11 @@ type SectionHeaderRootProps = Omit<FlexProps, 'direction'> & {
91
93
  };
92
94
 
93
95
  const SectionHeaderRoot = React.forwardRef<HTMLDivElement, SectionHeaderRootProps>(
94
- ({ layout = "inline", separator = false, gap = "4", direction, children, ...props }, ref) => {
95
- // Convert layout to direction/justify/align, but allow explicit direction override
96
+ ({ layout = "inline", align, separator = false, gap = "4", direction, children, ...props }, ref) => {
97
+ // Convert layout to direction/justify/align, but allow explicit overrides
96
98
  const computedDirection = direction || convertLayoutToDirection(layout) || "row";
97
99
  const computedJustify = convertLayoutToJustify(layout) || "between";
98
- const computedAlign = convertLayoutToAlign(layout) || "center";
100
+ const computedAlign = align ?? convertLayoutToAlign(layout) ?? "center";
99
101
 
100
102
  return (
101
103
  <Flex ref={ref} direction="column" gap={gap} {...props}>
package/styles.css CHANGED
@@ -148,3 +148,19 @@ pre[data-theme] code span {
148
148
  -webkit-text-decoration: var(--shiki-dark-text-decoration);
149
149
  text-decoration: var(--shiki-dark-text-decoration);
150
150
  }
151
+ /* ============================================
152
+ Empty State Component Styles
153
+ ============================================ */
154
+ /*
155
+ * EmptyState.Icon default sizing
156
+ * Sets a consistent default size for icons/illustrations in empty states
157
+ * Can be overridden via inline styles or custom CSS
158
+ */
159
+ .kb-empty-state-icon {
160
+ --empty-state-icon-size: var(--space-6);
161
+ color: var(--gray-a9);
162
+ }
163
+ .kb-empty-state-icon :where(svg) {
164
+ width: var(--empty-state-icon-size);
165
+ height: var(--empty-state-icon-size);
166
+ }