@kushagradhawan/kookie-blocks 0.1.5 → 0.1.7

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.
package/components.css CHANGED
@@ -18,74 +18,17 @@
18
18
  position: relative;
19
19
  }
20
20
 
21
- /* Code block content (the pre part, below the header) */
22
-
23
- .code-block-content {
24
- width: 100%;
25
- min-width: 0;
26
- overflow-x: auto;
27
- /* Hide scrollbars while keeping scroll functionality */
28
- scrollbar-width: none; /* Firefox */
29
- -ms-overflow-style: none; /* IE/Edge */
30
- }
31
-
32
- /* Hide scrollbars for webkit browsers */
33
-
34
- .code-block-content::-webkit-scrollbar,
35
- .code-block-content::-webkit-scrollbar-horizontal,
36
- .code-block-content::-webkit-scrollbar-vertical,
37
- .code-block-content::-webkit-scrollbar-track,
38
- .code-block-content::-webkit-scrollbar-thumb,
39
- .code-block-content::-webkit-scrollbar-corner {
40
- display: none !important;
41
- width: 0 !important;
42
- height: 0 !important;
43
- }
44
-
45
- /* Also hide scrollbars on any pre/code elements inside code content */
46
-
47
- .code-block-content pre::-webkit-scrollbar,
48
- .code-block-content pre::-webkit-scrollbar-horizontal,
49
- .code-block-content pre::-webkit-scrollbar-vertical,
50
- .code-block-content pre::-webkit-scrollbar-track,
51
- .code-block-content pre::-webkit-scrollbar-thumb,
52
- .code-block-content pre::-webkit-scrollbar-corner,
53
- .code-block-content code::-webkit-scrollbar,
54
- .code-block-content code::-webkit-scrollbar-horizontal,
55
- .code-block-content code::-webkit-scrollbar-vertical,
56
- .code-block-content code::-webkit-scrollbar-track,
57
- .code-block-content code::-webkit-scrollbar-thumb,
58
- .code-block-content code::-webkit-scrollbar-corner {
59
- display: none !important;
60
- width: 0 !important;
61
- height: 0 !important;
62
- }
63
-
64
21
  /* Pre elements inside code content */
65
22
 
66
- .code-content pre,
67
- .code-block-content pre {
68
- overflow-x: visible;
69
- max-width: 100%;
70
- min-width: 0;
23
+ .code-content pre {
71
24
  margin: 0;
72
25
  width: 100%;
73
26
  box-sizing: border-box;
74
- scrollbar-width: none;
75
- -ms-overflow-style: none;
76
- }
77
-
78
- /* Ensure Shiki-generated pre elements fill width */
79
-
80
- .code-block-content > pre {
81
- width: 100% !important;
82
- min-width: 0;
83
27
  }
84
28
 
85
29
  /* Code elements inside pre */
86
30
 
87
- .code-content pre code,
88
- .code-block-content pre code {
31
+ .code-content pre code {
89
32
  font-family: var(--font-mono);
90
33
  font-size: var(--font-size-2);
91
34
  line-height: 1.75;
@@ -98,8 +41,7 @@
98
41
 
99
42
  /* Shiki line spans */
100
43
 
101
- .code-content pre code .line,
102
- .code-block-content pre code .line {
44
+ .code-content pre code .line {
103
45
  display: flex;
104
46
  align-items: center;
105
47
  gap: 0;
@@ -107,8 +49,7 @@
107
49
 
108
50
  /* Line numbers */
109
51
 
110
- .code-content pre code .line::before,
111
- .code-block-content pre code .line::before {
52
+ .code-content pre code .line::before {
112
53
  counter-increment: line;
113
54
  content: counter(line);
114
55
  display: inline-block;
@@ -156,7 +97,6 @@
156
97
 
157
98
  /* Default to light theme for all tokens (codeToHtml with defaultColor: false) */
158
99
 
159
- .code-block-content pre.shiki span,
160
100
  .code-content pre.shiki span {
161
101
  color: var(--shiki-light) !important;
162
102
  font-style: var(--shiki-light-font-style);
@@ -167,9 +107,6 @@
167
107
 
168
108
  /* Override with dark theme colors when inside a dark context */
169
109
 
170
- .dark .code-block-content pre.shiki span,
171
- .dark-theme .code-block-content pre.shiki span,
172
- [data-appearance="dark"] .code-block-content pre.shiki span,
173
110
  .dark .code-content pre.shiki span,
174
111
  .dark-theme .code-content pre.shiki span,
175
112
  [data-appearance="dark"] .code-content pre.shiki span {
@@ -1 +1 @@
1
- {"version":3,"file":"CodeBlock.d.ts","sourceRoot":"","sources":["../../../../src/components/code/CodeBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyE,MAAM,OAAO,CAAC;AAK9F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAmV9C,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,QAAe,EACf,YAAmB,EACnB,UAAU,EACV,SAAS,EACT,UAAU,EACV,eAAe,GAChB,EAAE,cAAc,qBAyBhB"}
1
+ {"version":3,"file":"CodeBlock.d.ts","sourceRoot":"","sources":["../../../../src/components/code/CodeBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyE,MAAM,OAAO,CAAC;AAK9F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAiZ9C,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,QAAe,EACf,YAAmB,EACnB,UAAU,EACV,SAAS,EACT,UAAU,EACV,eAAe,GAChB,EAAE,cAAc,qBAyBhB"}
@@ -1,2 +1,2 @@
1
- "use strict";var z=Object.create;var b=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var B=Object.getOwnPropertyNames;var I=Object.getPrototypeOf,$=Object.prototype.hasOwnProperty;var M=(o,t)=>{for(var r in t)b(o,r,{get:t[r],enumerable:!0})},w=(o,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of B(t))!$.call(o,i)&&i!==r&&b(o,i,{get:()=>t[i],enumerable:!(s=j(t,i))||s.enumerable});return o};var _=(o,t,r)=>(r=o!=null?z(I(o)):{},w(t||!o||!o.__esModule?b(r,"default",{value:o,enumerable:!0}):r,o)),D=o=>w(b({},"__esModule",{value:!0}),o);var q={};M(q,{CodeBlock:()=>W});module.exports=D(q);var e=_(require("react")),n=require("@kushagradhawan/kookie-ui"),v=require("@hugeicons/react"),C=require("@hugeicons/core-free-icons"),H=require("shiki");const m=360,A="one-light",J="one-dark-pro";function G({children:o,background:t="none",backgroundProps:r={}}){const{dotSize:s=24,color:i="var(--gray-10)",backgroundColor:d="var(--gray-2)",height:a,width:l="100%",radius:c="3"}=r;if(t==="none")return e.default.createElement(n.Card,{size:"1",variant:"soft"},e.default.createElement(n.Flex,{justify:"center",align:"center",py:"4"},e.default.createElement(n.Theme,{fontFamily:"sans"},o)));if(t==="dots"){const g={backgroundImage:`radial-gradient(circle, ${i} 1px, transparent 1px)`,borderRadius:`var(--radius-${c})`,backgroundSize:`${s}px ${s}px`,backgroundPosition:"center",backgroundColor:d,width:l,...a&&{height:a}};return e.default.createElement(n.Card,{size:"1",variant:"soft"},e.default.createElement(n.Flex,{justify:"center",align:"center",py:"4",style:g},e.default.createElement(n.Theme,{fontFamily:"sans"},o)))}const p={backgroundImage:`url(${t})`,backgroundSize:"cover",backgroundPosition:"center",backgroundRepeat:"no-repeat",borderRadius:`var(--radius-${c})`,width:l,...a&&{height:a}};return e.default.createElement(n.Card,{size:"1",variant:"soft"},e.default.createElement(n.Flex,{justify:"center",align:"center",py:"4",style:p},e.default.createElement(n.Theme,{fontFamily:"sans"},o)))}const O=(0,e.memo)(function({code:t,language:r,showCopy:s=!0,showLanguage:i=!0,lightTheme:d=A,darkTheme:a=J}){const[l,c]=(0,e.useState)(null),[p,g]=(0,e.useState)(!1),[u,h]=(0,e.useState)(m),[y,x]=(0,e.useState)(!1),S=(0,e.useRef)(null),f=(0,e.useRef)(null),T=u>m;(0,e.useEffect)(()=>{let P=!1;return(0,H.codeToHtml)(t,{lang:r,themes:{light:d,dark:a},defaultColor:!1}).then(E=>{P||c(E)}).catch(()=>{P||c(null)}),()=>{P=!0}},[t,r,d,a]),(0,e.useEffect)(()=>{S.current&&h(S.current.scrollHeight)},[l]),(0,e.useEffect)(()=>()=>{f.current&&clearTimeout(f.current)},[]);const N=(0,e.useCallback)(async()=>{if(t.trim())try{await navigator.clipboard.writeText(t),x(!0),f.current&&clearTimeout(f.current),f.current=setTimeout(()=>x(!1),2e3)}catch{}},[t]),L=r==="text"?"plaintext":r,F={maxHeight:p?`${u}px`:`${m}px`};return e.default.createElement(n.Box,{position:"relative"},e.default.createElement(n.Card,{size:"1",variant:"soft"},e.default.createElement(n.Flex,{direction:"column",gap:"3"},e.default.createElement(n.Flex,{gap:"2",justify:"between",align:"start"},i&&e.default.createElement(n.Code,{size:"1",color:"gray",highContrast:!0},L),e.default.createElement(n.Flex,{align:"center",gap:"2",className:"code-action-buttons"},s&&e.default.createElement(n.Button,{size:"2",variant:"ghost",color:"gray",onClick:N,tooltip:y?"Copied!":"Copy","aria-label":y?"Copied!":"Copy code"},e.default.createElement(v.HugeiconsIcon,{icon:y?C.Tick01Icon:C.Copy01Icon})," Copy"))),e.default.createElement(n.Box,{ref:S,style:F,className:"code-content"},l?e.default.createElement(n.Box,{className:"code-block-content",width:"100%",style:{minWidth:0},dangerouslySetInnerHTML:{__html:l}}):e.default.createElement("pre",{className:"code-block-content"},e.default.createElement(n.Code,{size:"3"},t))),T&&!p&&e.default.createElement(n.Box,{className:"code-scroll-shadow visible"}))))});function U(o){if(!o)return"";if(typeof o=="object"&&o!==null&&"props"in o){const t=o.props;if(t?.children&&typeof t.children=="object"){const s=t.children.props?.children;if(typeof s=="string")return s}if(typeof t?.children=="string")return t.children}return typeof o=="string"?o:""}function k(o){if(!o)return"text";if(typeof o=="object"&&o!==null&&"props"in o){const t=o.props;if(t?.children&&typeof t.children=="object"){const a=(t.children.props?.className||"").match(/language-([\w-]+)/i);if(a)return a[1]}const s=(t?.className||"").match(/language-([\w-]+)/i);if(s)return s[1]}return"text"}function X(o){return{tsx:"TSX",ts:"TS",jsx:"JSX",js:"JS",javascript:"JS",typescript:"TS",css:"CSS",html:"HTML",json:"JSON",bash:"SH",sh:"SH",shell:"SH",text:"plaintext"}[o.toLowerCase()]||o.toLowerCase()}const K=(0,e.memo)(function({children:t,showCopy:r=!0,showLanguage:s=!0}){const[i,d]=(0,e.useState)(!1),[a,l]=(0,e.useState)(m),[c,p]=(0,e.useState)(!1),g=(0,e.useRef)(null),u=(0,e.useRef)(null),h=U(t),y=k(t),x=X(y),S=a>m;(0,e.useEffect)(()=>{g.current&&l(g.current.scrollHeight)},[t]),(0,e.useEffect)(()=>()=>{u.current&&clearTimeout(u.current)},[]);const f=(0,e.useCallback)(async()=>{if(h.trim())try{await navigator.clipboard.writeText(h),p(!0),u.current&&clearTimeout(u.current),u.current=setTimeout(()=>p(!1),2e3)}catch{}},[h]),T={maxHeight:i?`${a}px`:`${m}px`};return e.default.createElement(n.Box,{position:"relative"},e.default.createElement(n.Card,{size:"1",variant:"soft"},e.default.createElement(n.Flex,{direction:"column",gap:"3"},e.default.createElement(n.Flex,{gap:"2",justify:"between",align:"start"},s&&e.default.createElement(n.Code,{size:"1",color:"gray",highContrast:!0},x),e.default.createElement(n.Flex,{align:"center",gap:"2",className:"code-action-buttons"},r&&e.default.createElement(n.Button,{size:"2",variant:"ghost",color:"gray",onClick:f,tooltip:c?"Copied!":"Copy","aria-label":c?"Copied!":"Copy code"},e.default.createElement(v.HugeiconsIcon,{icon:c?C.Tick01Icon:C.Copy01Icon})," Copy"))),e.default.createElement(n.Box,{ref:g,style:T,className:"code-content"},e.default.createElement("div",{className:"code-block-content"},t)),S&&!i&&e.default.createElement(n.Box,{className:"code-scroll-shadow visible"}))))});function W({children:o,code:t,language:r,preview:s,showCopy:i=!0,showLanguage:d=!0,lightTheme:a,darkTheme:l,background:c,backgroundProps:p}){const g=t||o&&e.default.Children.count(o)>0,u=r||k(o)||"text";return e.default.createElement(n.Box,{className:"docs-code-block",mt:"6",mb:"8"},e.default.createElement(n.Flex,{direction:"column",gap:"2"},s&&e.default.createElement(G,{background:c,backgroundProps:p},s),t&&e.default.createElement(O,{code:t,language:u,showCopy:i,showLanguage:d,lightTheme:a,darkTheme:l}),o&&!t&&e.default.createElement(K,{showCopy:i,showLanguage:d},o)))}
1
+ "use strict";var B=Object.create;var w=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var I=Object.getPrototypeOf,$=Object.prototype.hasOwnProperty;var M=(n,o)=>{for(var r in o)w(n,r,{get:o[r],enumerable:!0})},L=(n,o,r,i)=>{if(o&&typeof o=="object"||typeof o=="function")for(let s of A(o))!$.call(n,s)&&s!==r&&w(n,s,{get:()=>o[s],enumerable:!(i=j(o,s))||i.enumerable});return n};var D=(n,o,r)=>(r=n!=null?B(I(n)):{},L(o||!n||!n.__esModule?w(r,"default",{value:n,enumerable:!0}):r,n)),_=n=>L(w({},"__esModule",{value:!0}),n);var V={};M(V,{CodeBlock:()=>Q});module.exports=_(V);var e=D(require("react")),t=require("@kushagradhawan/kookie-ui"),b=require("@hugeicons/react"),d=require("@hugeicons/core-free-icons"),z=require("shiki");const y=360,J="one-light",G="one-dark-pro";function O({children:n,background:o="none",backgroundProps:r={}}){const{dotSize:i=24,color:s="var(--gray-10)",backgroundColor:l="var(--gray-2)",height:a,width:g="100%",radius:u="3"}=r;if(o==="none")return e.default.createElement(t.Card,{size:"1",variant:"soft"},e.default.createElement(t.Flex,{justify:"center",align:"center",py:"4"},e.default.createElement(t.Theme,{fontFamily:"sans"},n)));if(o==="dots"){const f={backgroundImage:`radial-gradient(circle, ${s} 1px, transparent 1px)`,borderRadius:`var(--radius-${u})`,backgroundSize:`${i}px ${i}px`,backgroundPosition:"center",backgroundColor:l,width:g,...a&&{height:a}};return e.default.createElement(t.Card,{size:"1",variant:"soft"},e.default.createElement(t.Flex,{justify:"center",align:"center",py:"4",style:f},e.default.createElement(t.Theme,{fontFamily:"sans"},n)))}const c={backgroundImage:`url(${o})`,backgroundSize:"cover",backgroundPosition:"center",backgroundRepeat:"no-repeat",borderRadius:`var(--radius-${u})`,width:g,...a&&{height:a}};return e.default.createElement(t.Card,{size:"1",variant:"soft"},e.default.createElement(t.Flex,{justify:"center",align:"center",py:"4",style:c},e.default.createElement(t.Theme,{fontFamily:"sans"},n)))}const U=(0,e.memo)(function({code:o,language:r,showCopy:i=!0,showLanguage:s=!0,lightTheme:l=J,darkTheme:a=G}){const[g,u]=(0,e.useState)(null),[c,f]=(0,e.useState)(!1),[p,m]=(0,e.useState)(y),[S,T]=(0,e.useState)(!1),C=(0,e.useRef)(null),h=(0,e.useRef)(null),v=p>y;(0,e.useEffect)(()=>{let x=!1;return(0,z.codeToHtml)(o,{lang:r,themes:{light:l,dark:a},defaultColor:!1}).then(N=>{x||u(N)}).catch(()=>{x||u(null)}),()=>{x=!0}},[o,r,l,a]),(0,e.useEffect)(()=>{C.current&&m(C.current.scrollHeight)},[g]),(0,e.useEffect)(()=>()=>{h.current&&clearTimeout(h.current)},[]);const k=(0,e.useCallback)(async()=>{if(o.trim())try{await navigator.clipboard.writeText(o),T(!0),h.current&&clearTimeout(h.current),h.current=setTimeout(()=>T(!1),2e3)}catch{}},[o]),P=r==="text"?"plaintext":r,H=(0,e.useCallback)(()=>{f(x=>!x)},[]),F={maxHeight:c?`${p}px`:`${y}px`};return e.default.createElement(t.Box,{position:"relative"},e.default.createElement(t.Card,{size:"1",variant:"soft"},e.default.createElement(t.Flex,{direction:"column",gap:"3"},e.default.createElement(t.Flex,{gap:"2",justify:"between",align:"start"},s&&e.default.createElement(t.Code,{size:"1",color:"gray",highContrast:!0},P),e.default.createElement(t.Flex,{align:"center",gap:"2",className:"code-action-buttons"},v&&e.default.createElement(t.Button,{size:"2",variant:"ghost",color:"gray",onClick:H,tooltip:c?"Collapse":"Expand","aria-label":c?"Collapse code":"Expand code"},e.default.createElement(b.HugeiconsIcon,{icon:d.ArrowDown01Icon,style:{transform:c?"rotate(180deg)":"rotate(0deg)"},className:"code-chevron"})),i&&e.default.createElement(t.Button,{size:"2",variant:"ghost",color:"gray",onClick:k,tooltip:S?"Copied!":"Copy","aria-label":S?"Copied!":"Copy code"},e.default.createElement(b.HugeiconsIcon,{icon:S?d.Tick01Icon:d.Copy01Icon})," Copy"))),e.default.createElement(t.Box,{ref:C,style:F,className:"code-content"},e.default.createElement(t.ScrollArea,{type:"auto",scrollbars:"horizontal"},g?e.default.createElement(t.Box,{dangerouslySetInnerHTML:{__html:g}}):e.default.createElement("pre",null,e.default.createElement(t.Code,{size:"3"},o)))),v&&!c&&e.default.createElement(t.Box,{className:"code-scroll-shadow visible"}))))});function X(n){const o=r=>{if(typeof r=="string")return r;if(typeof r=="number")return String(r);if(!r)return"";if(Array.isArray(r))return r.map(o).join("");if(typeof r=="object"&&"props"in r){const i=r.props;if(i?.children)return o(i.children)}return""};return o(n)}function E(n){const o=r=>{if(!r)return null;if(typeof r=="object"&&"props"in r){const i=r.props;if(i?.["data-language"])return i["data-language"];const s=i?.className||i?.class||"";if(typeof s=="string"){const l=s.match(/language-([\w-]+)/i);if(l)return l[1]}if(i?.children)if(Array.isArray(i.children))for(const l of i.children){const a=o(l);if(a)return a}else return o(i.children)}return null};return o(n)||"text"}function K(n){return{tsx:"TSX",ts:"TS",jsx:"JSX",js:"JS",javascript:"JS",typescript:"TS",css:"CSS",html:"HTML",json:"JSON",bash:"SH",sh:"SH",shell:"SH",text:"plaintext"}[n.toLowerCase()]||n.toLowerCase()}const q=(0,e.memo)(function({children:o,showCopy:r=!0,showLanguage:i=!0}){const[s,l]=(0,e.useState)(!1),[a,g]=(0,e.useState)(y),[u,c]=(0,e.useState)(!1),f=(0,e.useRef)(null),p=(0,e.useRef)(null),m=X(o),S=E(o),T=K(S),C=a>y;(0,e.useEffect)(()=>{f.current&&g(f.current.scrollHeight)},[o]),(0,e.useEffect)(()=>()=>{p.current&&clearTimeout(p.current)},[]);const h=(0,e.useCallback)(async()=>{if(m.trim())try{await navigator.clipboard.writeText(m),c(!0),p.current&&clearTimeout(p.current),p.current=setTimeout(()=>c(!1),2e3)}catch{}},[m]),v={maxHeight:s?`${a}px`:`${y}px`},k=(0,e.useCallback)(()=>{l(H=>!H)},[]);return e.default.createElement(t.Box,{position:"relative"},e.default.createElement(t.Card,{size:"1",variant:"soft"},e.default.createElement(t.Flex,{direction:"column",gap:"3"},e.default.createElement(t.Flex,{gap:"2",justify:"between",align:"start"},i&&e.default.createElement(t.Code,{size:"1",color:"gray",highContrast:!0},T),e.default.createElement(t.Flex,{align:"center",gap:"2",className:"code-action-buttons"},C&&e.default.createElement(t.Button,{size:"2",variant:"ghost",color:"gray",onClick:k,tooltip:s?"Collapse":"Expand","aria-label":s?"Collapse code":"Expand code"},e.default.createElement(b.HugeiconsIcon,{icon:d.ArrowDown01Icon,style:{transform:s?"rotate(180deg)":"rotate(0deg)"},className:"code-chevron"})),r&&e.default.createElement(t.Button,{size:"2",variant:"ghost",color:"gray",onClick:h,tooltip:u?"Copied!":"Copy","aria-label":u?"Copied!":"Copy code"},e.default.createElement(b.HugeiconsIcon,{icon:u?d.Tick01Icon:d.Copy01Icon})," Copy"))),e.default.createElement(t.Box,{ref:f,style:v,className:"code-content"},e.default.createElement(t.ScrollArea,{type:"auto",scrollbars:"horizontal"},o)),C&&!s&&e.default.createElement(t.Box,{className:"code-scroll-shadow visible"}))))});function Q({children:n,code:o,language:r,preview:i,showCopy:s=!0,showLanguage:l=!0,lightTheme:a,darkTheme:g,background:u,backgroundProps:c}){const f=o||n&&e.default.Children.count(n)>0,p=r||E(n)||"text";return e.default.createElement(t.Box,{className:"docs-code-block",mt:"6",mb:"8"},e.default.createElement(t.Flex,{direction:"column",gap:"2"},i&&e.default.createElement(O,{background:u,backgroundProps:c},i),o&&e.default.createElement(U,{code:o,language:p,showCopy:s,showLanguage:l,lightTheme:a,darkTheme:g}),n&&!o&&e.default.createElement(q,{showCopy:s,showLanguage:l},n)))}
2
2
  //# sourceMappingURL=CodeBlock.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/code/CodeBlock.tsx"],
4
- "sourcesContent": ["import React, { useState, useRef, useEffect, useCallback, memo, type ReactNode } from \"react\";\nimport { Box, Card, Flex, Button, Code, Theme } from \"@kushagradhawan/kookie-ui\";\nimport { HugeiconsIcon } from \"@hugeicons/react\";\nimport { Copy01Icon, Tick01Icon } from \"@hugeicons/core-free-icons\";\nimport { codeToHtml } from \"shiki\";\nimport type { CodeBlockProps } from \"./types\";\n\nconst COLLAPSED_HEIGHT = 360;\nconst DEFAULT_LIGHT_THEME = \"one-light\";\nconst DEFAULT_DARK_THEME = \"one-dark-pro\";\n\n// ============================================\n// Preview Section\n// ============================================\n\ninterface PreviewSectionProps {\n children: ReactNode;\n background?: \"none\" | \"dots\" | string;\n backgroundProps?: {\n dotSize?: number;\n color?: string;\n backgroundColor?: string;\n height?: string;\n width?: string;\n radius?: string;\n };\n}\n\nfunction PreviewSection({ children, background = \"none\", backgroundProps = {} }: PreviewSectionProps) {\n const { dotSize = 24, color = \"var(--gray-10)\", backgroundColor = \"var(--gray-2)\", height, width = \"100%\", radius = \"3\" } = backgroundProps;\n\n if (background === \"none\") {\n return (\n <Card size=\"1\" variant=\"soft\">\n <Flex justify=\"center\" align=\"center\" py=\"4\">\n <Theme fontFamily=\"sans\">{children}</Theme>\n </Flex>\n </Card>\n );\n }\n\n if (background === \"dots\") {\n const dotsStyle: React.CSSProperties = {\n backgroundImage: `radial-gradient(circle, ${color} 1px, transparent 1px)`,\n borderRadius: `var(--radius-${radius})`,\n backgroundSize: `${dotSize}px ${dotSize}px`,\n backgroundPosition: \"center\",\n backgroundColor,\n width,\n ...(height && { height }),\n };\n\n return (\n <Card size=\"1\" variant=\"soft\">\n <Flex justify=\"center\" align=\"center\" py=\"4\" style={dotsStyle}>\n <Theme fontFamily=\"sans\">{children}</Theme>\n </Flex>\n </Card>\n );\n }\n\n const imageStyle: React.CSSProperties = {\n backgroundImage: `url(${background})`,\n backgroundSize: \"cover\",\n backgroundPosition: \"center\",\n backgroundRepeat: \"no-repeat\",\n borderRadius: `var(--radius-${radius})`,\n width,\n ...(height && { height }),\n };\n\n return (\n <Card size=\"1\" variant=\"soft\">\n <Flex justify=\"center\" align=\"center\" py=\"4\" style={imageStyle}>\n <Theme fontFamily=\"sans\">{children}</Theme>\n </Flex>\n </Card>\n );\n}\n\n// ============================================\n// Code Section (for runtime highlighting)\n// ============================================\n\ninterface CodeSectionProps {\n code: string;\n language: string;\n showCopy?: boolean;\n showLanguage?: boolean;\n lightTheme?: string;\n darkTheme?: string;\n}\n\nconst CodeSection = memo(function CodeSection({\n code,\n language,\n showCopy = true,\n showLanguage = true,\n lightTheme = DEFAULT_LIGHT_THEME,\n darkTheme = DEFAULT_DARK_THEME,\n}: CodeSectionProps) {\n const [highlighted, setHighlighted] = useState<string | null>(null);\n const [isExpanded, setIsExpanded] = useState(false);\n const [contentHeight, setContentHeight] = useState(COLLAPSED_HEIGHT);\n const [copied, setCopied] = useState(false);\n const contentRef = useRef<HTMLDivElement>(null);\n const resetTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const shouldShowToggle = contentHeight > COLLAPSED_HEIGHT;\n\n useEffect(() => {\n let cancelled = false;\n codeToHtml(code, {\n lang: language,\n themes: { light: lightTheme, dark: darkTheme },\n defaultColor: false,\n })\n .then((html) => {\n if (!cancelled) setHighlighted(html);\n })\n .catch(() => {\n if (!cancelled) setHighlighted(null);\n });\n return () => {\n cancelled = true;\n };\n }, [code, language, lightTheme, darkTheme]);\n\n useEffect(() => {\n if (contentRef.current) {\n setContentHeight(contentRef.current.scrollHeight);\n }\n }, [highlighted]);\n\n useEffect(() => {\n return () => {\n if (resetTimeoutRef.current) clearTimeout(resetTimeoutRef.current);\n };\n }, []);\n\n const handleCopy = useCallback(async () => {\n if (!code.trim()) return;\n try {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n if (resetTimeoutRef.current) clearTimeout(resetTimeoutRef.current);\n resetTimeoutRef.current = setTimeout(() => setCopied(false), 2000);\n } catch {\n // Silently fail\n }\n }, [code]);\n\n const displayLanguage = language === \"text\" ? \"plaintext\" : language;\n\n const contentStyle: React.CSSProperties = {\n maxHeight: isExpanded ? `${contentHeight}px` : `${COLLAPSED_HEIGHT}px`,\n };\n\n return (\n <Box position=\"relative\">\n <Card size=\"1\" variant=\"soft\">\n <Flex direction=\"column\" gap=\"3\">\n <Flex gap=\"2\" justify=\"between\" align=\"start\">\n {showLanguage && (\n <Code size=\"1\" color=\"gray\" highContrast>\n {displayLanguage}\n </Code>\n )}\n <Flex align=\"center\" gap=\"2\" className=\"code-action-buttons\">\n {showCopy && (\n <Button\n size=\"2\"\n variant=\"ghost\"\n color=\"gray\"\n onClick={handleCopy}\n tooltip={copied ? \"Copied!\" : \"Copy\"}\n aria-label={copied ? \"Copied!\" : \"Copy code\"}\n >\n <HugeiconsIcon icon={copied ? Tick01Icon : Copy01Icon} /> Copy\n </Button>\n )}\n </Flex>\n </Flex>\n\n <Box ref={contentRef} style={contentStyle} className=\"code-content\">\n {highlighted ? (\n <Box className=\"code-block-content\" width=\"100%\" style={{ minWidth: 0 }} dangerouslySetInnerHTML={{ __html: highlighted }} />\n ) : (\n <pre className=\"code-block-content\">\n <Code size=\"3\">{code}</Code>\n </pre>\n )}\n </Box>\n\n {shouldShowToggle && !isExpanded && <Box className=\"code-scroll-shadow visible\" />}\n </Flex>\n </Card>\n </Box>\n );\n});\n\n// ============================================\n// Children Code Section (for pre-highlighted MDX)\n// ============================================\n\ninterface ChildrenCodeSectionProps {\n children: ReactNode;\n showCopy?: boolean;\n showLanguage?: boolean;\n}\n\nfunction extractCodeFromChildren(children?: ReactNode): string {\n if (!children) return \"\";\n if (typeof children === \"object\" && children !== null && \"props\" in children) {\n const childProps = (children as any).props;\n if (childProps?.children && typeof childProps.children === \"object\") {\n const codeProps = (childProps.children as any).props;\n const codeChildren = codeProps?.children;\n if (typeof codeChildren === \"string\") return codeChildren;\n }\n if (typeof childProps?.children === \"string\") return childProps.children;\n }\n if (typeof children === \"string\") return children;\n return \"\";\n}\n\nfunction extractLanguageFromChildren(children?: ReactNode): string {\n if (!children) return \"text\";\n if (typeof children === \"object\" && children !== null && \"props\" in children) {\n const childProps = (children as any).props;\n if (childProps?.children && typeof childProps.children === \"object\") {\n const codeProps = (childProps.children as any).props;\n const className = codeProps?.className || \"\";\n const match = className.match(/language-([\\w-]+)/i);\n if (match) return match[1];\n }\n const className = childProps?.className || \"\";\n const match = className.match(/language-([\\w-]+)/i);\n if (match) return match[1];\n }\n return \"text\";\n}\n\nfunction formatLanguageLabel(lang: string): string {\n const aliasMap: Record<string, string> = {\n tsx: \"TSX\",\n ts: \"TS\",\n jsx: \"JSX\",\n js: \"JS\",\n javascript: \"JS\",\n typescript: \"TS\",\n css: \"CSS\",\n html: \"HTML\",\n json: \"JSON\",\n bash: \"SH\",\n sh: \"SH\",\n shell: \"SH\",\n text: \"plaintext\",\n };\n return aliasMap[lang.toLowerCase()] || lang.toLowerCase();\n}\n\nconst ChildrenCodeSection = memo(function ChildrenCodeSection({ children, showCopy = true, showLanguage = true }: ChildrenCodeSectionProps) {\n const [isExpanded, setIsExpanded] = useState(false);\n const [contentHeight, setContentHeight] = useState(COLLAPSED_HEIGHT);\n const [copied, setCopied] = useState(false);\n const contentRef = useRef<HTMLDivElement>(null);\n const resetTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const code = extractCodeFromChildren(children);\n const language = extractLanguageFromChildren(children);\n const displayLanguage = formatLanguageLabel(language);\n\n const shouldShowToggle = contentHeight > COLLAPSED_HEIGHT;\n\n useEffect(() => {\n if (contentRef.current) {\n setContentHeight(contentRef.current.scrollHeight);\n }\n }, [children]);\n\n useEffect(() => {\n return () => {\n if (resetTimeoutRef.current) clearTimeout(resetTimeoutRef.current);\n };\n }, []);\n\n const handleCopy = useCallback(async () => {\n if (!code.trim()) return;\n try {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n if (resetTimeoutRef.current) clearTimeout(resetTimeoutRef.current);\n resetTimeoutRef.current = setTimeout(() => setCopied(false), 2000);\n } catch {\n // Silently fail\n }\n }, [code]);\n\n const contentStyle: React.CSSProperties = {\n maxHeight: isExpanded ? `${contentHeight}px` : `${COLLAPSED_HEIGHT}px`,\n };\n\n return (\n <Box position=\"relative\">\n <Card size=\"1\" variant=\"soft\">\n <Flex direction=\"column\" gap=\"3\">\n <Flex gap=\"2\" justify=\"between\" align=\"start\">\n {showLanguage && (\n <Code size=\"1\" color=\"gray\" highContrast>\n {displayLanguage}\n </Code>\n )}\n <Flex align=\"center\" gap=\"2\" className=\"code-action-buttons\">\n {showCopy && (\n <Button\n size=\"2\"\n variant=\"ghost\"\n color=\"gray\"\n onClick={handleCopy}\n tooltip={copied ? \"Copied!\" : \"Copy\"}\n aria-label={copied ? \"Copied!\" : \"Copy code\"}\n >\n <HugeiconsIcon icon={copied ? Tick01Icon : Copy01Icon} /> Copy\n </Button>\n )}\n </Flex>\n </Flex>\n\n <Box ref={contentRef} style={contentStyle} className=\"code-content\">\n <div className=\"code-block-content\">{children}</div>\n </Box>\n\n {shouldShowToggle && !isExpanded && <Box className=\"code-scroll-shadow visible\" />}\n </Flex>\n </Card>\n </Box>\n );\n});\n\n// ============================================\n// Main CodeBlock Component\n// ============================================\n\nexport function CodeBlock({\n children,\n code,\n language,\n preview,\n showCopy = true,\n showLanguage = true,\n lightTheme,\n darkTheme,\n background,\n backgroundProps,\n}: CodeBlockProps) {\n const hasCode = code || (children && React.Children.count(children) > 0);\n const displayLanguage = language || extractLanguageFromChildren(children) || \"text\";\n\n return (\n <Box className=\"docs-code-block\" mt=\"6\" mb=\"8\">\n <Flex direction=\"column\" gap=\"2\">\n {preview && (\n <PreviewSection background={background} backgroundProps={backgroundProps}>\n {preview}\n </PreviewSection>\n )}\n\n {code && (\n <CodeSection code={code} language={displayLanguage} showCopy={showCopy} showLanguage={showLanguage} lightTheme={lightTheme} darkTheme={darkTheme} />\n )}\n\n {children && !code && (\n <ChildrenCodeSection showCopy={showCopy} showLanguage={showLanguage}>\n {children}\n </ChildrenCodeSection>\n )}\n </Flex>\n </Box>\n );\n}\n"],
5
- "mappings": "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",
6
- "names": ["CodeBlock_exports", "__export", "CodeBlock", "__toCommonJS", "import_react", "import_kookie_ui", "import_core_free_icons", "import_shiki", "COLLAPSED_HEIGHT", "DEFAULT_LIGHT_THEME", "DEFAULT_DARK_THEME", "PreviewSection", "children", "background", "backgroundProps", "dotSize", "color", "backgroundColor", "height", "width", "radius", "React", "dotsStyle", "imageStyle", "CodeSection", "code", "language", "showCopy", "showLanguage", "lightTheme", "darkTheme", "highlighted", "setHighlighted", "isExpanded", "setIsExpanded", "contentHeight", "setContentHeight", "copied", "setCopied", "contentRef", "resetTimeoutRef", "shouldShowToggle", "cancelled", "html", "handleCopy", "displayLanguage", "contentStyle", "extractCodeFromChildren", "childProps", "codeChildren", "extractLanguageFromChildren", "match", "formatLanguageLabel", "lang", "ChildrenCodeSection", "preview", "hasCode"]
4
+ "sourcesContent": ["import React, { useState, useRef, useEffect, useCallback, memo, type ReactNode } from \"react\";\nimport { Box, Card, Flex, Button, Code, Theme, ScrollArea } from \"@kushagradhawan/kookie-ui\";\nimport { HugeiconsIcon } from \"@hugeicons/react\";\nimport { Copy01Icon, Tick01Icon, ArrowDown01Icon } from \"@hugeicons/core-free-icons\";\nimport { codeToHtml } from \"shiki\";\nimport type { CodeBlockProps } from \"./types\";\n\nconst COLLAPSED_HEIGHT = 360;\nconst DEFAULT_LIGHT_THEME = \"one-light\";\nconst DEFAULT_DARK_THEME = \"one-dark-pro\";\n\n// ============================================\n// Preview Section\n// ============================================\n\ninterface PreviewSectionProps {\n children: ReactNode;\n background?: \"none\" | \"dots\" | string;\n backgroundProps?: {\n dotSize?: number;\n color?: string;\n backgroundColor?: string;\n height?: string;\n width?: string;\n radius?: string;\n };\n}\n\nfunction PreviewSection({ children, background = \"none\", backgroundProps = {} }: PreviewSectionProps) {\n const { dotSize = 24, color = \"var(--gray-10)\", backgroundColor = \"var(--gray-2)\", height, width = \"100%\", radius = \"3\" } = backgroundProps;\n\n if (background === \"none\") {\n return (\n <Card size=\"1\" variant=\"soft\">\n <Flex justify=\"center\" align=\"center\" py=\"4\">\n <Theme fontFamily=\"sans\">{children}</Theme>\n </Flex>\n </Card>\n );\n }\n\n if (background === \"dots\") {\n const dotsStyle: React.CSSProperties = {\n backgroundImage: `radial-gradient(circle, ${color} 1px, transparent 1px)`,\n borderRadius: `var(--radius-${radius})`,\n backgroundSize: `${dotSize}px ${dotSize}px`,\n backgroundPosition: \"center\",\n backgroundColor,\n width,\n ...(height && { height }),\n };\n\n return (\n <Card size=\"1\" variant=\"soft\">\n <Flex justify=\"center\" align=\"center\" py=\"4\" style={dotsStyle}>\n <Theme fontFamily=\"sans\">{children}</Theme>\n </Flex>\n </Card>\n );\n }\n\n const imageStyle: React.CSSProperties = {\n backgroundImage: `url(${background})`,\n backgroundSize: \"cover\",\n backgroundPosition: \"center\",\n backgroundRepeat: \"no-repeat\",\n borderRadius: `var(--radius-${radius})`,\n width,\n ...(height && { height }),\n };\n\n return (\n <Card size=\"1\" variant=\"soft\">\n <Flex justify=\"center\" align=\"center\" py=\"4\" style={imageStyle}>\n <Theme fontFamily=\"sans\">{children}</Theme>\n </Flex>\n </Card>\n );\n}\n\n// ============================================\n// Code Section (for runtime highlighting)\n// ============================================\n\ninterface CodeSectionProps {\n code: string;\n language: string;\n showCopy?: boolean;\n showLanguage?: boolean;\n lightTheme?: string;\n darkTheme?: string;\n}\n\nconst CodeSection = memo(function CodeSection({\n code,\n language,\n showCopy = true,\n showLanguage = true,\n lightTheme = DEFAULT_LIGHT_THEME,\n darkTheme = DEFAULT_DARK_THEME,\n}: CodeSectionProps) {\n const [highlighted, setHighlighted] = useState<string | null>(null);\n const [isExpanded, setIsExpanded] = useState(false);\n const [contentHeight, setContentHeight] = useState(COLLAPSED_HEIGHT);\n const [copied, setCopied] = useState(false);\n const contentRef = useRef<HTMLDivElement>(null);\n const resetTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const shouldShowToggle = contentHeight > COLLAPSED_HEIGHT;\n\n useEffect(() => {\n let cancelled = false;\n codeToHtml(code, {\n lang: language,\n themes: { light: lightTheme, dark: darkTheme },\n defaultColor: false,\n })\n .then((html) => {\n if (!cancelled) setHighlighted(html);\n })\n .catch(() => {\n if (!cancelled) setHighlighted(null);\n });\n return () => {\n cancelled = true;\n };\n }, [code, language, lightTheme, darkTheme]);\n\n useEffect(() => {\n if (contentRef.current) {\n setContentHeight(contentRef.current.scrollHeight);\n }\n }, [highlighted]);\n\n useEffect(() => {\n return () => {\n if (resetTimeoutRef.current) clearTimeout(resetTimeoutRef.current);\n };\n }, []);\n\n const handleCopy = useCallback(async () => {\n if (!code.trim()) return;\n try {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n if (resetTimeoutRef.current) clearTimeout(resetTimeoutRef.current);\n resetTimeoutRef.current = setTimeout(() => setCopied(false), 2000);\n } catch {\n // Silently fail\n }\n }, [code]);\n\n const displayLanguage = language === \"text\" ? \"plaintext\" : language;\n\n const handleToggle = useCallback(() => {\n setIsExpanded((prev) => !prev);\n }, []);\n\n const contentStyle: React.CSSProperties = {\n maxHeight: isExpanded ? `${contentHeight}px` : `${COLLAPSED_HEIGHT}px`,\n };\n\n const chevronStyle: React.CSSProperties = {\n transform: isExpanded ? \"rotate(180deg)\" : \"rotate(0deg)\",\n };\n\n return (\n <Box position=\"relative\">\n <Card size=\"1\" variant=\"soft\">\n <Flex direction=\"column\" gap=\"3\">\n <Flex gap=\"2\" justify=\"between\" align=\"start\">\n {showLanguage && (\n <Code size=\"1\" color=\"gray\" highContrast>\n {displayLanguage}\n </Code>\n )}\n <Flex align=\"center\" gap=\"2\" className=\"code-action-buttons\">\n {shouldShowToggle && (\n <Button\n size=\"2\"\n variant=\"ghost\"\n color=\"gray\"\n onClick={handleToggle}\n tooltip={isExpanded ? \"Collapse\" : \"Expand\"}\n aria-label={isExpanded ? \"Collapse code\" : \"Expand code\"}\n >\n <HugeiconsIcon icon={ArrowDown01Icon} style={chevronStyle} className=\"code-chevron\" />\n </Button>\n )}\n {showCopy && (\n <Button\n size=\"2\"\n variant=\"ghost\"\n color=\"gray\"\n onClick={handleCopy}\n tooltip={copied ? \"Copied!\" : \"Copy\"}\n aria-label={copied ? \"Copied!\" : \"Copy code\"}\n >\n <HugeiconsIcon icon={copied ? Tick01Icon : Copy01Icon} /> Copy\n </Button>\n )}\n </Flex>\n </Flex>\n\n <Box ref={contentRef} style={contentStyle} className=\"code-content\">\n <ScrollArea type=\"auto\" scrollbars=\"horizontal\">\n {highlighted ? (\n <Box dangerouslySetInnerHTML={{ __html: highlighted }} />\n ) : (\n <pre>\n <Code size=\"3\">{code}</Code>\n </pre>\n )}\n </ScrollArea>\n </Box>\n\n {shouldShowToggle && !isExpanded && <Box className=\"code-scroll-shadow visible\" />}\n </Flex>\n </Card>\n </Box>\n );\n});\n\n// ============================================\n// Children Code Section (for pre-highlighted MDX)\n// ============================================\n\ninterface ChildrenCodeSectionProps {\n children: ReactNode;\n showCopy?: boolean;\n showLanguage?: boolean;\n}\n\nfunction extractCodeFromChildren(children?: ReactNode): string {\n const extractText = (node: any): string => {\n if (typeof node === \"string\") return node;\n if (typeof node === \"number\") return String(node);\n if (!node) return \"\";\n if (Array.isArray(node)) return node.map(extractText).join(\"\");\n if (typeof node === \"object\" && \"props\" in node) {\n const props = node.props;\n if (props?.children) return extractText(props.children);\n }\n return \"\";\n };\n return extractText(children);\n}\n\nfunction extractLanguageFromChildren(children?: ReactNode): string {\n const findLanguage = (node: any): string | null => {\n if (!node) return null;\n if (typeof node === \"object\" && \"props\" in node) {\n const props = node.props;\n\n // Check data-language attribute (rehype-pretty-code)\n if (props?.[\"data-language\"]) {\n return props[\"data-language\"];\n }\n\n // Check className for language-xxx\n const className = props?.className || props?.class || \"\";\n if (typeof className === \"string\") {\n const match = className.match(/language-([\\w-]+)/i);\n if (match) return match[1];\n }\n\n // Recursively check children\n if (props?.children) {\n if (Array.isArray(props.children)) {\n for (const child of props.children) {\n const lang = findLanguage(child);\n if (lang) return lang;\n }\n } else {\n return findLanguage(props.children);\n }\n }\n }\n return null;\n };\n return findLanguage(children) || \"text\";\n}\n\nfunction formatLanguageLabel(lang: string): string {\n const aliasMap: Record<string, string> = {\n tsx: \"TSX\",\n ts: \"TS\",\n jsx: \"JSX\",\n js: \"JS\",\n javascript: \"JS\",\n typescript: \"TS\",\n css: \"CSS\",\n html: \"HTML\",\n json: \"JSON\",\n bash: \"SH\",\n sh: \"SH\",\n shell: \"SH\",\n text: \"plaintext\",\n };\n return aliasMap[lang.toLowerCase()] || lang.toLowerCase();\n}\n\nconst ChildrenCodeSection = memo(function ChildrenCodeSection({ children, showCopy = true, showLanguage = true }: ChildrenCodeSectionProps) {\n const [isExpanded, setIsExpanded] = useState(false);\n const [contentHeight, setContentHeight] = useState(COLLAPSED_HEIGHT);\n const [copied, setCopied] = useState(false);\n const contentRef = useRef<HTMLDivElement>(null);\n const resetTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const code = extractCodeFromChildren(children);\n const language = extractLanguageFromChildren(children);\n const displayLanguage = formatLanguageLabel(language);\n\n const shouldShowToggle = contentHeight > COLLAPSED_HEIGHT;\n\n useEffect(() => {\n if (contentRef.current) {\n setContentHeight(contentRef.current.scrollHeight);\n }\n }, [children]);\n\n useEffect(() => {\n return () => {\n if (resetTimeoutRef.current) clearTimeout(resetTimeoutRef.current);\n };\n }, []);\n\n const handleCopy = useCallback(async () => {\n if (!code.trim()) return;\n try {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n if (resetTimeoutRef.current) clearTimeout(resetTimeoutRef.current);\n resetTimeoutRef.current = setTimeout(() => setCopied(false), 2000);\n } catch {\n // Silently fail\n }\n }, [code]);\n\n const contentStyle: React.CSSProperties = {\n maxHeight: isExpanded ? `${contentHeight}px` : `${COLLAPSED_HEIGHT}px`,\n };\n\n const handleToggle = useCallback(() => {\n setIsExpanded((prev) => !prev);\n }, []);\n\n const chevronStyle: React.CSSProperties = {\n transform: isExpanded ? \"rotate(180deg)\" : \"rotate(0deg)\",\n };\n\n return (\n <Box position=\"relative\">\n <Card size=\"1\" variant=\"soft\">\n <Flex direction=\"column\" gap=\"3\">\n <Flex gap=\"2\" justify=\"between\" align=\"start\">\n {showLanguage && (\n <Code size=\"1\" color=\"gray\" highContrast>\n {displayLanguage}\n </Code>\n )}\n <Flex align=\"center\" gap=\"2\" className=\"code-action-buttons\">\n {shouldShowToggle && (\n <Button\n size=\"2\"\n variant=\"ghost\"\n color=\"gray\"\n onClick={handleToggle}\n tooltip={isExpanded ? \"Collapse\" : \"Expand\"}\n aria-label={isExpanded ? \"Collapse code\" : \"Expand code\"}\n >\n <HugeiconsIcon icon={ArrowDown01Icon} style={chevronStyle} className=\"code-chevron\" />\n </Button>\n )}\n {showCopy && (\n <Button\n size=\"2\"\n variant=\"ghost\"\n color=\"gray\"\n onClick={handleCopy}\n tooltip={copied ? \"Copied!\" : \"Copy\"}\n aria-label={copied ? \"Copied!\" : \"Copy code\"}\n >\n <HugeiconsIcon icon={copied ? Tick01Icon : Copy01Icon} /> Copy\n </Button>\n )}\n </Flex>\n </Flex>\n\n <Box ref={contentRef} style={contentStyle} className=\"code-content\">\n <ScrollArea type=\"auto\" scrollbars=\"horizontal\">\n {children}\n </ScrollArea>\n </Box>\n\n {shouldShowToggle && !isExpanded && <Box className=\"code-scroll-shadow visible\" />}\n </Flex>\n </Card>\n </Box>\n );\n});\n\n// ============================================\n// Main CodeBlock Component\n// ============================================\n\nexport function CodeBlock({\n children,\n code,\n language,\n preview,\n showCopy = true,\n showLanguage = true,\n lightTheme,\n darkTheme,\n background,\n backgroundProps,\n}: CodeBlockProps) {\n const hasCode = code || (children && React.Children.count(children) > 0);\n const displayLanguage = language || extractLanguageFromChildren(children) || \"text\";\n\n return (\n <Box className=\"docs-code-block\" mt=\"6\" mb=\"8\">\n <Flex direction=\"column\" gap=\"2\">\n {preview && (\n <PreviewSection background={background} backgroundProps={backgroundProps}>\n {preview}\n </PreviewSection>\n )}\n\n {code && (\n <CodeSection code={code} language={displayLanguage} showCopy={showCopy} showLanguage={showLanguage} lightTheme={lightTheme} darkTheme={darkTheme} />\n )}\n\n {children && !code && (\n <ChildrenCodeSection showCopy={showCopy} showLanguage={showLanguage}>\n {children}\n </ChildrenCodeSection>\n )}\n </Flex>\n </Box>\n );\n}\n"],
5
+ "mappings": "0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,eAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAsF,oBACtFC,EAAiE,qCACjED,EAA8B,4BAC9BE,EAAwD,sCACxDC,EAA2B,iBAG3B,MAAMC,EAAmB,IACnBC,EAAsB,YACtBC,EAAqB,eAmB3B,SAASC,EAAe,CAAE,SAAAC,EAAU,WAAAC,EAAa,OAAQ,gBAAAC,EAAkB,CAAC,CAAE,EAAwB,CACpG,KAAM,CAAE,QAAAC,EAAU,GAAI,MAAAC,EAAQ,iBAAkB,gBAAAC,EAAkB,gBAAiB,OAAAC,EAAQ,MAAAC,EAAQ,OAAQ,OAAAC,EAAS,GAAI,EAAIN,EAE5H,GAAID,IAAe,OACjB,OACE,EAAAQ,QAAA,cAAC,QAAK,KAAK,IAAI,QAAQ,QACrB,EAAAA,QAAA,cAAC,QAAK,QAAQ,SAAS,MAAM,SAAS,GAAG,KACvC,EAAAA,QAAA,cAAC,SAAM,WAAW,QAAQT,CAAS,CACrC,CACF,EAIJ,GAAIC,IAAe,OAAQ,CACzB,MAAMS,EAAiC,CACrC,gBAAiB,2BAA2BN,CAAK,yBACjD,aAAc,gBAAgBI,CAAM,IACpC,eAAgB,GAAGL,CAAO,MAAMA,CAAO,KACvC,mBAAoB,SACpB,gBAAAE,EACA,MAAAE,EACA,GAAID,GAAU,CAAE,OAAAA,CAAO,CACzB,EAEA,OACE,EAAAG,QAAA,cAAC,QAAK,KAAK,IAAI,QAAQ,QACrB,EAAAA,QAAA,cAAC,QAAK,QAAQ,SAAS,MAAM,SAAS,GAAG,IAAI,MAAOC,GAClD,EAAAD,QAAA,cAAC,SAAM,WAAW,QAAQT,CAAS,CACrC,CACF,CAEJ,CAEA,MAAMW,EAAkC,CACtC,gBAAiB,OAAOV,CAAU,IAClC,eAAgB,QAChB,mBAAoB,SACpB,iBAAkB,YAClB,aAAc,gBAAgBO,CAAM,IACpC,MAAAD,EACA,GAAID,GAAU,CAAE,OAAAA,CAAO,CACzB,EAEA,OACE,EAAAG,QAAA,cAAC,QAAK,KAAK,IAAI,QAAQ,QACrB,EAAAA,QAAA,cAAC,QAAK,QAAQ,SAAS,MAAM,SAAS,GAAG,IAAI,MAAOE,GAClD,EAAAF,QAAA,cAAC,SAAM,WAAW,QAAQT,CAAS,CACrC,CACF,CAEJ,CAeA,MAAMY,KAAc,QAAK,SAAqB,CAC5C,KAAAC,EACA,SAAAC,EACA,SAAAC,EAAW,GACX,aAAAC,EAAe,GACf,WAAAC,EAAapB,EACb,UAAAqB,EAAYpB,CACd,EAAqB,CACnB,KAAM,CAACqB,EAAaC,CAAc,KAAI,YAAwB,IAAI,EAC5D,CAACC,EAAYC,CAAa,KAAI,YAAS,EAAK,EAC5C,CAACC,EAAeC,CAAgB,KAAI,YAAS5B,CAAgB,EAC7D,CAAC6B,EAAQC,CAAS,KAAI,YAAS,EAAK,EACpCC,KAAa,UAAuB,IAAI,EACxCC,KAAkB,UAA6C,IAAI,EAEnEC,EAAmBN,EAAgB3B,KAEzC,aAAU,IAAM,CACd,IAAIkC,EAAY,GAChB,uBAAWjB,EAAM,CACf,KAAMC,EACN,OAAQ,CAAE,MAAOG,EAAY,KAAMC,CAAU,EAC7C,aAAc,EAChB,CAAC,EACE,KAAMa,GAAS,CACTD,GAAWV,EAAeW,CAAI,CACrC,CAAC,EACA,MAAM,IAAM,CACND,GAAWV,EAAe,IAAI,CACrC,CAAC,EACI,IAAM,CACXU,EAAY,EACd,CACF,EAAG,CAACjB,EAAMC,EAAUG,EAAYC,CAAS,CAAC,KAE1C,aAAU,IAAM,CACVS,EAAW,SACbH,EAAiBG,EAAW,QAAQ,YAAY,CAEpD,EAAG,CAACR,CAAW,CAAC,KAEhB,aAAU,IACD,IAAM,CACPS,EAAgB,SAAS,aAAaA,EAAgB,OAAO,CACnE,EACC,CAAC,CAAC,EAEL,MAAMI,KAAa,eAAY,SAAY,CACzC,GAAKnB,EAAK,KAAK,EACf,GAAI,CACF,MAAM,UAAU,UAAU,UAAUA,CAAI,EACxCa,EAAU,EAAI,EACVE,EAAgB,SAAS,aAAaA,EAAgB,OAAO,EACjEA,EAAgB,QAAU,WAAW,IAAMF,EAAU,EAAK,EAAG,GAAI,CACnE,MAAQ,CAER,CACF,EAAG,CAACb,CAAI,CAAC,EAEHoB,EAAkBnB,IAAa,OAAS,YAAcA,EAEtDoB,KAAe,eAAY,IAAM,CACrCZ,EAAea,GAAS,CAACA,CAAI,CAC/B,EAAG,CAAC,CAAC,EAECC,EAAoC,CACxC,UAAWf,EAAa,GAAGE,CAAa,KAAO,GAAG3B,CAAgB,IACpE,EAMA,OACE,EAAAa,QAAA,cAAC,OAAI,SAAS,YACZ,EAAAA,QAAA,cAAC,QAAK,KAAK,IAAI,QAAQ,QACrB,EAAAA,QAAA,cAAC,QAAK,UAAU,SAAS,IAAI,KAC3B,EAAAA,QAAA,cAAC,QAAK,IAAI,IAAI,QAAQ,UAAU,MAAM,SACnCO,GACC,EAAAP,QAAA,cAAC,QAAK,KAAK,IAAI,MAAM,OAAO,aAAY,IACrCwB,CACH,EAEF,EAAAxB,QAAA,cAAC,QAAK,MAAM,SAAS,IAAI,IAAI,UAAU,uBACpCoB,GACC,EAAApB,QAAA,cAAC,UACC,KAAK,IACL,QAAQ,QACR,MAAM,OACN,QAASyB,EACT,QAASb,EAAa,WAAa,SACnC,aAAYA,EAAa,gBAAkB,eAE3C,EAAAZ,QAAA,cAAC,iBAAc,KAAM,kBAAiB,MAxBZ,CACxC,UAAWY,EAAa,iBAAmB,cAC7C,EAsB2E,UAAU,eAAe,CACtF,EAEDN,GACC,EAAAN,QAAA,cAAC,UACC,KAAK,IACL,QAAQ,QACR,MAAM,OACN,QAASuB,EACT,QAASP,EAAS,UAAY,OAC9B,aAAYA,EAAS,UAAY,aAEjC,EAAAhB,QAAA,cAAC,iBAAc,KAAMgB,EAAS,aAAa,aAAY,EAAE,OAC3D,CAEJ,CACF,EAEA,EAAAhB,QAAA,cAAC,OAAI,IAAKkB,EAAY,MAAOS,EAAc,UAAU,gBACnD,EAAA3B,QAAA,cAAC,cAAW,KAAK,OAAO,WAAW,cAChCU,EACC,EAAAV,QAAA,cAAC,OAAI,wBAAyB,CAAE,OAAQU,CAAY,EAAG,EAEvD,EAAAV,QAAA,cAAC,WACC,EAAAA,QAAA,cAAC,QAAK,KAAK,KAAKI,CAAK,CACvB,CAEJ,CACF,EAECgB,GAAoB,CAACR,GAAc,EAAAZ,QAAA,cAAC,OAAI,UAAU,6BAA6B,CAClF,CACF,CACF,CAEJ,CAAC,EAYD,SAAS4B,EAAwBrC,EAA8B,CAC7D,MAAMsC,EAAeC,GAAsB,CACzC,GAAI,OAAOA,GAAS,SAAU,OAAOA,EACrC,GAAI,OAAOA,GAAS,SAAU,OAAO,OAAOA,CAAI,EAChD,GAAI,CAACA,EAAM,MAAO,GAClB,GAAI,MAAM,QAAQA,CAAI,EAAG,OAAOA,EAAK,IAAID,CAAW,EAAE,KAAK,EAAE,EAC7D,GAAI,OAAOC,GAAS,UAAY,UAAWA,EAAM,CAC/C,MAAMC,EAAQD,EAAK,MACnB,GAAIC,GAAO,SAAU,OAAOF,EAAYE,EAAM,QAAQ,CACxD,CACA,MAAO,EACT,EACA,OAAOF,EAAYtC,CAAQ,CAC7B,CAEA,SAASyC,EAA4BzC,EAA8B,CACjE,MAAM0C,EAAgBH,GAA6B,CACjD,GAAI,CAACA,EAAM,OAAO,KAClB,GAAI,OAAOA,GAAS,UAAY,UAAWA,EAAM,CAC/C,MAAMC,EAAQD,EAAK,MAGnB,GAAIC,IAAQ,eAAe,EACzB,OAAOA,EAAM,eAAe,EAI9B,MAAMG,EAAYH,GAAO,WAAaA,GAAO,OAAS,GACtD,GAAI,OAAOG,GAAc,SAAU,CACjC,MAAMC,EAAQD,EAAU,MAAM,oBAAoB,EAClD,GAAIC,EAAO,OAAOA,EAAM,CAAC,CAC3B,CAGA,GAAIJ,GAAO,SACT,GAAI,MAAM,QAAQA,EAAM,QAAQ,EAC9B,UAAWK,KAASL,EAAM,SAAU,CAClC,MAAMM,EAAOJ,EAAaG,CAAK,EAC/B,GAAIC,EAAM,OAAOA,CACnB,KAEA,QAAOJ,EAAaF,EAAM,QAAQ,CAGxC,CACA,OAAO,IACT,EACA,OAAOE,EAAa1C,CAAQ,GAAK,MACnC,CAEA,SAAS+C,EAAoBD,EAAsB,CAgBjD,MAfyC,CACvC,IAAK,MACL,GAAI,KACJ,IAAK,MACL,GAAI,KACJ,WAAY,KACZ,WAAY,KACZ,IAAK,MACL,KAAM,OACN,KAAM,OACN,KAAM,KACN,GAAI,KACJ,MAAO,KACP,KAAM,WACR,EACgBA,EAAK,YAAY,CAAC,GAAKA,EAAK,YAAY,CAC1D,CAEA,MAAME,KAAsB,QAAK,SAA6B,CAAE,SAAAhD,EAAU,SAAAe,EAAW,GAAM,aAAAC,EAAe,EAAK,EAA6B,CAC1I,KAAM,CAACK,EAAYC,CAAa,KAAI,YAAS,EAAK,EAC5C,CAACC,EAAeC,CAAgB,KAAI,YAAS5B,CAAgB,EAC7D,CAAC6B,EAAQC,CAAS,KAAI,YAAS,EAAK,EACpCC,KAAa,UAAuB,IAAI,EACxCC,KAAkB,UAA6C,IAAI,EAEnEf,EAAOwB,EAAwBrC,CAAQ,EACvCc,EAAW2B,EAA4BzC,CAAQ,EAC/CiC,EAAkBc,EAAoBjC,CAAQ,EAE9Ce,EAAmBN,EAAgB3B,KAEzC,aAAU,IAAM,CACV+B,EAAW,SACbH,EAAiBG,EAAW,QAAQ,YAAY,CAEpD,EAAG,CAAC3B,CAAQ,CAAC,KAEb,aAAU,IACD,IAAM,CACP4B,EAAgB,SAAS,aAAaA,EAAgB,OAAO,CACnE,EACC,CAAC,CAAC,EAEL,MAAMI,KAAa,eAAY,SAAY,CACzC,GAAKnB,EAAK,KAAK,EACf,GAAI,CACF,MAAM,UAAU,UAAU,UAAUA,CAAI,EACxCa,EAAU,EAAI,EACVE,EAAgB,SAAS,aAAaA,EAAgB,OAAO,EACjEA,EAAgB,QAAU,WAAW,IAAMF,EAAU,EAAK,EAAG,GAAI,CACnE,MAAQ,CAER,CACF,EAAG,CAACb,CAAI,CAAC,EAEHuB,EAAoC,CACxC,UAAWf,EAAa,GAAGE,CAAa,KAAO,GAAG3B,CAAgB,IACpE,EAEMsC,KAAe,eAAY,IAAM,CACrCZ,EAAea,GAAS,CAACA,CAAI,CAC/B,EAAG,CAAC,CAAC,EAML,OACE,EAAA1B,QAAA,cAAC,OAAI,SAAS,YACZ,EAAAA,QAAA,cAAC,QAAK,KAAK,IAAI,QAAQ,QACrB,EAAAA,QAAA,cAAC,QAAK,UAAU,SAAS,IAAI,KAC3B,EAAAA,QAAA,cAAC,QAAK,IAAI,IAAI,QAAQ,UAAU,MAAM,SACnCO,GACC,EAAAP,QAAA,cAAC,QAAK,KAAK,IAAI,MAAM,OAAO,aAAY,IACrCwB,CACH,EAEF,EAAAxB,QAAA,cAAC,QAAK,MAAM,SAAS,IAAI,IAAI,UAAU,uBACpCoB,GACC,EAAApB,QAAA,cAAC,UACC,KAAK,IACL,QAAQ,QACR,MAAM,OACN,QAASyB,EACT,QAASb,EAAa,WAAa,SACnC,aAAYA,EAAa,gBAAkB,eAE3C,EAAAZ,QAAA,cAAC,iBAAc,KAAM,kBAAiB,MAxBZ,CACxC,UAAWY,EAAa,iBAAmB,cAC7C,EAsB2E,UAAU,eAAe,CACtF,EAEDN,GACC,EAAAN,QAAA,cAAC,UACC,KAAK,IACL,QAAQ,QACR,MAAM,OACN,QAASuB,EACT,QAASP,EAAS,UAAY,OAC9B,aAAYA,EAAS,UAAY,aAEjC,EAAAhB,QAAA,cAAC,iBAAc,KAAMgB,EAAS,aAAa,aAAY,EAAE,OAC3D,CAEJ,CACF,EAEA,EAAAhB,QAAA,cAAC,OAAI,IAAKkB,EAAY,MAAOS,EAAc,UAAU,gBACnD,EAAA3B,QAAA,cAAC,cAAW,KAAK,OAAO,WAAW,cAChCT,CACH,CACF,EAEC6B,GAAoB,CAACR,GAAc,EAAAZ,QAAA,cAAC,OAAI,UAAU,6BAA6B,CAClF,CACF,CACF,CAEJ,CAAC,EAMM,SAASnB,EAAU,CACxB,SAAAU,EACA,KAAAa,EACA,SAAAC,EACA,QAAAmC,EACA,SAAAlC,EAAW,GACX,aAAAC,EAAe,GACf,WAAAC,EACA,UAAAC,EACA,WAAAjB,EACA,gBAAAC,CACF,EAAmB,CACjB,MAAMgD,EAAUrC,GAASb,GAAY,EAAAS,QAAM,SAAS,MAAMT,CAAQ,EAAI,EAChEiC,EAAkBnB,GAAY2B,EAA4BzC,CAAQ,GAAK,OAE7E,OACE,EAAAS,QAAA,cAAC,OAAI,UAAU,kBAAkB,GAAG,IAAI,GAAG,KACzC,EAAAA,QAAA,cAAC,QAAK,UAAU,SAAS,IAAI,KAC1BwC,GACC,EAAAxC,QAAA,cAACV,EAAA,CAAe,WAAYE,EAAY,gBAAiBC,GACtD+C,CACH,EAGDpC,GACC,EAAAJ,QAAA,cAACG,EAAA,CAAY,KAAMC,EAAM,SAAUoB,EAAiB,SAAUlB,EAAU,aAAcC,EAAc,WAAYC,EAAY,UAAWC,EAAW,EAGnJlB,GAAY,CAACa,GACZ,EAAAJ,QAAA,cAACuC,EAAA,CAAoB,SAAUjC,EAAU,aAAcC,GACpDhB,CACH,CAEJ,CACF,CAEJ",
6
+ "names": ["CodeBlock_exports", "__export", "CodeBlock", "__toCommonJS", "import_react", "import_kookie_ui", "import_core_free_icons", "import_shiki", "COLLAPSED_HEIGHT", "DEFAULT_LIGHT_THEME", "DEFAULT_DARK_THEME", "PreviewSection", "children", "background", "backgroundProps", "dotSize", "color", "backgroundColor", "height", "width", "radius", "React", "dotsStyle", "imageStyle", "CodeSection", "code", "language", "showCopy", "showLanguage", "lightTheme", "darkTheme", "highlighted", "setHighlighted", "isExpanded", "setIsExpanded", "contentHeight", "setContentHeight", "copied", "setCopied", "contentRef", "resetTimeoutRef", "shouldShowToggle", "cancelled", "html", "handleCopy", "displayLanguage", "handleToggle", "prev", "contentStyle", "extractCodeFromChildren", "extractText", "node", "props", "extractLanguageFromChildren", "findLanguage", "className", "match", "child", "lang", "formatLanguageLabel", "ChildrenCodeSection", "preview", "hasCode"]
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CodeBlock.d.ts","sourceRoot":"","sources":["../../../../src/components/code/CodeBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyE,MAAM,OAAO,CAAC;AAK9F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAmV9C,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,QAAe,EACf,YAAmB,EACnB,UAAU,EACV,SAAS,EACT,UAAU,EACV,eAAe,GAChB,EAAE,cAAc,qBAyBhB"}
1
+ {"version":3,"file":"CodeBlock.d.ts","sourceRoot":"","sources":["../../../../src/components/code/CodeBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyE,MAAM,OAAO,CAAC;AAK9F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAiZ9C,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,QAAe,EACf,YAAmB,EACnB,UAAU,EACV,SAAS,EACT,UAAU,EACV,eAAe,GAChB,EAAE,cAAc,qBAyBhB"}
@@ -1,2 +1,2 @@
1
- import e,{useState as C,useRef as v,useEffect as b,useCallback as L,memo as F}from"react";import{Box as g,Card as T,Flex as u,Button as E,Code as H,Theme as N}from"@kushagradhawan/kookie-ui";import{HugeiconsIcon as z}from"@hugeicons/react";import{Copy01Icon as j,Tick01Icon as B}from"@hugeicons/core-free-icons";import{codeToHtml as A}from"shiki";const h=360,J="one-light",G="one-dark-pro";function O({children:o,background:t="none",backgroundProps:s={}}){const{dotSize:n=24,color:a="var(--gray-10)",backgroundColor:d="var(--gray-2)",height:r,width:c="100%",radius:i="3"}=s;if(t==="none")return e.createElement(T,{size:"1",variant:"soft"},e.createElement(u,{justify:"center",align:"center",py:"4"},e.createElement(N,{fontFamily:"sans"},o)));if(t==="dots"){const f={backgroundImage:`radial-gradient(circle, ${a} 1px, transparent 1px)`,borderRadius:`var(--radius-${i})`,backgroundSize:`${n}px ${n}px`,backgroundPosition:"center",backgroundColor:d,width:c,...r&&{height:r}};return e.createElement(T,{size:"1",variant:"soft"},e.createElement(u,{justify:"center",align:"center",py:"4",style:f},e.createElement(N,{fontFamily:"sans"},o)))}const p={backgroundImage:`url(${t})`,backgroundSize:"cover",backgroundPosition:"center",backgroundRepeat:"no-repeat",borderRadius:`var(--radius-${i})`,width:c,...r&&{height:r}};return e.createElement(T,{size:"1",variant:"soft"},e.createElement(u,{justify:"center",align:"center",py:"4",style:p},e.createElement(N,{fontFamily:"sans"},o)))}const U=F(function({code:t,language:s,showCopy:n=!0,showLanguage:a=!0,lightTheme:d=J,darkTheme:r=G}){const[c,i]=C(null),[p,f]=C(!1),[l,y]=C(h),[S,P]=C(!1),x=v(null),m=v(null),w=l>h;b(()=>{let k=!1;return A(t,{lang:s,themes:{light:d,dark:r},defaultColor:!1}).then(D=>{k||i(D)}).catch(()=>{k||i(null)}),()=>{k=!0}},[t,s,d,r]),b(()=>{x.current&&y(x.current.scrollHeight)},[c]),b(()=>()=>{m.current&&clearTimeout(m.current)},[]);const $=L(async()=>{if(t.trim())try{await navigator.clipboard.writeText(t),P(!0),m.current&&clearTimeout(m.current),m.current=setTimeout(()=>P(!1),2e3)}catch{}},[t]),M=s==="text"?"plaintext":s,_={maxHeight:p?`${l}px`:`${h}px`};return e.createElement(g,{position:"relative"},e.createElement(T,{size:"1",variant:"soft"},e.createElement(u,{direction:"column",gap:"3"},e.createElement(u,{gap:"2",justify:"between",align:"start"},a&&e.createElement(H,{size:"1",color:"gray",highContrast:!0},M),e.createElement(u,{align:"center",gap:"2",className:"code-action-buttons"},n&&e.createElement(E,{size:"2",variant:"ghost",color:"gray",onClick:$,tooltip:S?"Copied!":"Copy","aria-label":S?"Copied!":"Copy code"},e.createElement(z,{icon:S?B:j})," Copy"))),e.createElement(g,{ref:x,style:_,className:"code-content"},c?e.createElement(g,{className:"code-block-content",width:"100%",style:{minWidth:0},dangerouslySetInnerHTML:{__html:c}}):e.createElement("pre",{className:"code-block-content"},e.createElement(H,{size:"3"},t))),w&&!p&&e.createElement(g,{className:"code-scroll-shadow visible"}))))});function X(o){if(!o)return"";if(typeof o=="object"&&o!==null&&"props"in o){const t=o.props;if(t?.children&&typeof t.children=="object"){const n=t.children.props?.children;if(typeof n=="string")return n}if(typeof t?.children=="string")return t.children}return typeof o=="string"?o:""}function I(o){if(!o)return"text";if(typeof o=="object"&&o!==null&&"props"in o){const t=o.props;if(t?.children&&typeof t.children=="object"){const r=(t.children.props?.className||"").match(/language-([\w-]+)/i);if(r)return r[1]}const n=(t?.className||"").match(/language-([\w-]+)/i);if(n)return n[1]}return"text"}function K(o){return{tsx:"TSX",ts:"TS",jsx:"JSX",js:"JS",javascript:"JS",typescript:"TS",css:"CSS",html:"HTML",json:"JSON",bash:"SH",sh:"SH",shell:"SH",text:"plaintext"}[o.toLowerCase()]||o.toLowerCase()}const W=F(function({children:t,showCopy:s=!0,showLanguage:n=!0}){const[a,d]=C(!1),[r,c]=C(h),[i,p]=C(!1),f=v(null),l=v(null),y=X(t),S=I(t),P=K(S),x=r>h;b(()=>{f.current&&c(f.current.scrollHeight)},[t]),b(()=>()=>{l.current&&clearTimeout(l.current)},[]);const m=L(async()=>{if(y.trim())try{await navigator.clipboard.writeText(y),p(!0),l.current&&clearTimeout(l.current),l.current=setTimeout(()=>p(!1),2e3)}catch{}},[y]),w={maxHeight:a?`${r}px`:`${h}px`};return e.createElement(g,{position:"relative"},e.createElement(T,{size:"1",variant:"soft"},e.createElement(u,{direction:"column",gap:"3"},e.createElement(u,{gap:"2",justify:"between",align:"start"},n&&e.createElement(H,{size:"1",color:"gray",highContrast:!0},P),e.createElement(u,{align:"center",gap:"2",className:"code-action-buttons"},s&&e.createElement(E,{size:"2",variant:"ghost",color:"gray",onClick:m,tooltip:i?"Copied!":"Copy","aria-label":i?"Copied!":"Copy code"},e.createElement(z,{icon:i?B:j})," Copy"))),e.createElement(g,{ref:f,style:w,className:"code-content"},e.createElement("div",{className:"code-block-content"},t)),x&&!a&&e.createElement(g,{className:"code-scroll-shadow visible"}))))});function R({children:o,code:t,language:s,preview:n,showCopy:a=!0,showLanguage:d=!0,lightTheme:r,darkTheme:c,background:i,backgroundProps:p}){const f=t||o&&e.Children.count(o)>0,l=s||I(o)||"text";return e.createElement(g,{className:"docs-code-block",mt:"6",mb:"8"},e.createElement(u,{direction:"column",gap:"2"},n&&e.createElement(O,{background:i,backgroundProps:p},n),t&&e.createElement(U,{code:t,language:l,showCopy:a,showLanguage:d,lightTheme:r,darkTheme:c}),o&&!t&&e.createElement(W,{showCopy:a,showLanguage:d},o)))}export{R as CodeBlock};
1
+ import e,{useState as C,useRef as H,useEffect as T,useCallback as P,memo as A}from"react";import{Box as f,Card as v,Flex as p,Button as L,Code as N,Theme as B,ScrollArea as I}from"@kushagradhawan/kookie-ui";import{HugeiconsIcon as E}from"@hugeicons/react";import{Copy01Icon as $,Tick01Icon as M,ArrowDown01Icon as D}from"@hugeicons/core-free-icons";import{codeToHtml as O}from"shiki";const m=360,U="one-light",X="one-dark-pro";function K({children:n,background:t="none",backgroundProps:o={}}){const{dotSize:r=24,color:i="var(--gray-10)",backgroundColor:a="var(--gray-2)",height:s,width:u="100%",radius:c="3"}=o;if(t==="none")return e.createElement(v,{size:"1",variant:"soft"},e.createElement(p,{justify:"center",align:"center",py:"4"},e.createElement(B,{fontFamily:"sans"},n)));if(t==="dots"){const d={backgroundImage:`radial-gradient(circle, ${i} 1px, transparent 1px)`,borderRadius:`var(--radius-${c})`,backgroundSize:`${r}px ${r}px`,backgroundPosition:"center",backgroundColor:a,width:u,...s&&{height:s}};return e.createElement(v,{size:"1",variant:"soft"},e.createElement(p,{justify:"center",align:"center",py:"4",style:d},e.createElement(B,{fontFamily:"sans"},n)))}const l={backgroundImage:`url(${t})`,backgroundSize:"cover",backgroundPosition:"center",backgroundRepeat:"no-repeat",borderRadius:`var(--radius-${c})`,width:u,...s&&{height:s}};return e.createElement(v,{size:"1",variant:"soft"},e.createElement(p,{justify:"center",align:"center",py:"4",style:l},e.createElement(B,{fontFamily:"sans"},n)))}const q=A(function({code:t,language:o,showCopy:r=!0,showLanguage:i=!0,lightTheme:a=U,darkTheme:s=X}){const[u,c]=C(null),[l,d]=C(!1),[g,S]=C(m),[x,w]=C(!1),y=H(null),h=H(null),k=g>m;T(()=>{let b=!1;return O(t,{lang:o,themes:{light:a,dark:s},defaultColor:!1}).then(G=>{b||c(G)}).catch(()=>{b||c(null)}),()=>{b=!0}},[t,o,a,s]),T(()=>{y.current&&S(y.current.scrollHeight)},[u]),T(()=>()=>{h.current&&clearTimeout(h.current)},[]);const z=P(async()=>{if(t.trim())try{await navigator.clipboard.writeText(t),w(!0),h.current&&clearTimeout(h.current),h.current=setTimeout(()=>w(!1),2e3)}catch{}},[t]),j=o==="text"?"plaintext":o,F=P(()=>{d(b=>!b)},[]),J={maxHeight:l?`${g}px`:`${m}px`};return e.createElement(f,{position:"relative"},e.createElement(v,{size:"1",variant:"soft"},e.createElement(p,{direction:"column",gap:"3"},e.createElement(p,{gap:"2",justify:"between",align:"start"},i&&e.createElement(N,{size:"1",color:"gray",highContrast:!0},j),e.createElement(p,{align:"center",gap:"2",className:"code-action-buttons"},k&&e.createElement(L,{size:"2",variant:"ghost",color:"gray",onClick:F,tooltip:l?"Collapse":"Expand","aria-label":l?"Collapse code":"Expand code"},e.createElement(E,{icon:D,style:{transform:l?"rotate(180deg)":"rotate(0deg)"},className:"code-chevron"})),r&&e.createElement(L,{size:"2",variant:"ghost",color:"gray",onClick:z,tooltip:x?"Copied!":"Copy","aria-label":x?"Copied!":"Copy code"},e.createElement(E,{icon:x?M:$})," Copy"))),e.createElement(f,{ref:y,style:J,className:"code-content"},e.createElement(I,{type:"auto",scrollbars:"horizontal"},u?e.createElement(f,{dangerouslySetInnerHTML:{__html:u}}):e.createElement("pre",null,e.createElement(N,{size:"3"},t)))),k&&!l&&e.createElement(f,{className:"code-scroll-shadow visible"}))))});function Q(n){const t=o=>{if(typeof o=="string")return o;if(typeof o=="number")return String(o);if(!o)return"";if(Array.isArray(o))return o.map(t).join("");if(typeof o=="object"&&"props"in o){const r=o.props;if(r?.children)return t(r.children)}return""};return t(n)}function _(n){const t=o=>{if(!o)return null;if(typeof o=="object"&&"props"in o){const r=o.props;if(r?.["data-language"])return r["data-language"];const i=r?.className||r?.class||"";if(typeof i=="string"){const a=i.match(/language-([\w-]+)/i);if(a)return a[1]}if(r?.children)if(Array.isArray(r.children))for(const a of r.children){const s=t(a);if(s)return s}else return t(r.children)}return null};return t(n)||"text"}function V(n){return{tsx:"TSX",ts:"TS",jsx:"JSX",js:"JS",javascript:"JS",typescript:"TS",css:"CSS",html:"HTML",json:"JSON",bash:"SH",sh:"SH",shell:"SH",text:"plaintext"}[n.toLowerCase()]||n.toLowerCase()}const W=A(function({children:t,showCopy:o=!0,showLanguage:r=!0}){const[i,a]=C(!1),[s,u]=C(m),[c,l]=C(!1),d=H(null),g=H(null),S=Q(t),x=_(t),w=V(x),y=s>m;T(()=>{d.current&&u(d.current.scrollHeight)},[t]),T(()=>()=>{g.current&&clearTimeout(g.current)},[]);const h=P(async()=>{if(S.trim())try{await navigator.clipboard.writeText(S),l(!0),g.current&&clearTimeout(g.current),g.current=setTimeout(()=>l(!1),2e3)}catch{}},[S]),k={maxHeight:i?`${s}px`:`${m}px`},z=P(()=>{a(F=>!F)},[]);return e.createElement(f,{position:"relative"},e.createElement(v,{size:"1",variant:"soft"},e.createElement(p,{direction:"column",gap:"3"},e.createElement(p,{gap:"2",justify:"between",align:"start"},r&&e.createElement(N,{size:"1",color:"gray",highContrast:!0},w),e.createElement(p,{align:"center",gap:"2",className:"code-action-buttons"},y&&e.createElement(L,{size:"2",variant:"ghost",color:"gray",onClick:z,tooltip:i?"Collapse":"Expand","aria-label":i?"Collapse code":"Expand code"},e.createElement(E,{icon:D,style:{transform:i?"rotate(180deg)":"rotate(0deg)"},className:"code-chevron"})),o&&e.createElement(L,{size:"2",variant:"ghost",color:"gray",onClick:h,tooltip:c?"Copied!":"Copy","aria-label":c?"Copied!":"Copy code"},e.createElement(E,{icon:c?M:$})," Copy"))),e.createElement(f,{ref:d,style:k,className:"code-content"},e.createElement(I,{type:"auto",scrollbars:"horizontal"},t)),y&&!i&&e.createElement(f,{className:"code-scroll-shadow visible"}))))});function re({children:n,code:t,language:o,preview:r,showCopy:i=!0,showLanguage:a=!0,lightTheme:s,darkTheme:u,background:c,backgroundProps:l}){const d=t||n&&e.Children.count(n)>0,g=o||_(n)||"text";return e.createElement(f,{className:"docs-code-block",mt:"6",mb:"8"},e.createElement(p,{direction:"column",gap:"2"},r&&e.createElement(K,{background:c,backgroundProps:l},r),t&&e.createElement(q,{code:t,language:g,showCopy:i,showLanguage:a,lightTheme:s,darkTheme:u}),n&&!t&&e.createElement(W,{showCopy:i,showLanguage:a},n)))}export{re as CodeBlock};
2
2
  //# sourceMappingURL=CodeBlock.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/code/CodeBlock.tsx"],
4
- "sourcesContent": ["import React, { useState, useRef, useEffect, useCallback, memo, type ReactNode } from \"react\";\nimport { Box, Card, Flex, Button, Code, Theme } from \"@kushagradhawan/kookie-ui\";\nimport { HugeiconsIcon } from \"@hugeicons/react\";\nimport { Copy01Icon, Tick01Icon } from \"@hugeicons/core-free-icons\";\nimport { codeToHtml } from \"shiki\";\nimport type { CodeBlockProps } from \"./types\";\n\nconst COLLAPSED_HEIGHT = 360;\nconst DEFAULT_LIGHT_THEME = \"one-light\";\nconst DEFAULT_DARK_THEME = \"one-dark-pro\";\n\n// ============================================\n// Preview Section\n// ============================================\n\ninterface PreviewSectionProps {\n children: ReactNode;\n background?: \"none\" | \"dots\" | string;\n backgroundProps?: {\n dotSize?: number;\n color?: string;\n backgroundColor?: string;\n height?: string;\n width?: string;\n radius?: string;\n };\n}\n\nfunction PreviewSection({ children, background = \"none\", backgroundProps = {} }: PreviewSectionProps) {\n const { dotSize = 24, color = \"var(--gray-10)\", backgroundColor = \"var(--gray-2)\", height, width = \"100%\", radius = \"3\" } = backgroundProps;\n\n if (background === \"none\") {\n return (\n <Card size=\"1\" variant=\"soft\">\n <Flex justify=\"center\" align=\"center\" py=\"4\">\n <Theme fontFamily=\"sans\">{children}</Theme>\n </Flex>\n </Card>\n );\n }\n\n if (background === \"dots\") {\n const dotsStyle: React.CSSProperties = {\n backgroundImage: `radial-gradient(circle, ${color} 1px, transparent 1px)`,\n borderRadius: `var(--radius-${radius})`,\n backgroundSize: `${dotSize}px ${dotSize}px`,\n backgroundPosition: \"center\",\n backgroundColor,\n width,\n ...(height && { height }),\n };\n\n return (\n <Card size=\"1\" variant=\"soft\">\n <Flex justify=\"center\" align=\"center\" py=\"4\" style={dotsStyle}>\n <Theme fontFamily=\"sans\">{children}</Theme>\n </Flex>\n </Card>\n );\n }\n\n const imageStyle: React.CSSProperties = {\n backgroundImage: `url(${background})`,\n backgroundSize: \"cover\",\n backgroundPosition: \"center\",\n backgroundRepeat: \"no-repeat\",\n borderRadius: `var(--radius-${radius})`,\n width,\n ...(height && { height }),\n };\n\n return (\n <Card size=\"1\" variant=\"soft\">\n <Flex justify=\"center\" align=\"center\" py=\"4\" style={imageStyle}>\n <Theme fontFamily=\"sans\">{children}</Theme>\n </Flex>\n </Card>\n );\n}\n\n// ============================================\n// Code Section (for runtime highlighting)\n// ============================================\n\ninterface CodeSectionProps {\n code: string;\n language: string;\n showCopy?: boolean;\n showLanguage?: boolean;\n lightTheme?: string;\n darkTheme?: string;\n}\n\nconst CodeSection = memo(function CodeSection({\n code,\n language,\n showCopy = true,\n showLanguage = true,\n lightTheme = DEFAULT_LIGHT_THEME,\n darkTheme = DEFAULT_DARK_THEME,\n}: CodeSectionProps) {\n const [highlighted, setHighlighted] = useState<string | null>(null);\n const [isExpanded, setIsExpanded] = useState(false);\n const [contentHeight, setContentHeight] = useState(COLLAPSED_HEIGHT);\n const [copied, setCopied] = useState(false);\n const contentRef = useRef<HTMLDivElement>(null);\n const resetTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const shouldShowToggle = contentHeight > COLLAPSED_HEIGHT;\n\n useEffect(() => {\n let cancelled = false;\n codeToHtml(code, {\n lang: language,\n themes: { light: lightTheme, dark: darkTheme },\n defaultColor: false,\n })\n .then((html) => {\n if (!cancelled) setHighlighted(html);\n })\n .catch(() => {\n if (!cancelled) setHighlighted(null);\n });\n return () => {\n cancelled = true;\n };\n }, [code, language, lightTheme, darkTheme]);\n\n useEffect(() => {\n if (contentRef.current) {\n setContentHeight(contentRef.current.scrollHeight);\n }\n }, [highlighted]);\n\n useEffect(() => {\n return () => {\n if (resetTimeoutRef.current) clearTimeout(resetTimeoutRef.current);\n };\n }, []);\n\n const handleCopy = useCallback(async () => {\n if (!code.trim()) return;\n try {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n if (resetTimeoutRef.current) clearTimeout(resetTimeoutRef.current);\n resetTimeoutRef.current = setTimeout(() => setCopied(false), 2000);\n } catch {\n // Silently fail\n }\n }, [code]);\n\n const displayLanguage = language === \"text\" ? \"plaintext\" : language;\n\n const contentStyle: React.CSSProperties = {\n maxHeight: isExpanded ? `${contentHeight}px` : `${COLLAPSED_HEIGHT}px`,\n };\n\n return (\n <Box position=\"relative\">\n <Card size=\"1\" variant=\"soft\">\n <Flex direction=\"column\" gap=\"3\">\n <Flex gap=\"2\" justify=\"between\" align=\"start\">\n {showLanguage && (\n <Code size=\"1\" color=\"gray\" highContrast>\n {displayLanguage}\n </Code>\n )}\n <Flex align=\"center\" gap=\"2\" className=\"code-action-buttons\">\n {showCopy && (\n <Button\n size=\"2\"\n variant=\"ghost\"\n color=\"gray\"\n onClick={handleCopy}\n tooltip={copied ? \"Copied!\" : \"Copy\"}\n aria-label={copied ? \"Copied!\" : \"Copy code\"}\n >\n <HugeiconsIcon icon={copied ? Tick01Icon : Copy01Icon} /> Copy\n </Button>\n )}\n </Flex>\n </Flex>\n\n <Box ref={contentRef} style={contentStyle} className=\"code-content\">\n {highlighted ? (\n <Box className=\"code-block-content\" width=\"100%\" style={{ minWidth: 0 }} dangerouslySetInnerHTML={{ __html: highlighted }} />\n ) : (\n <pre className=\"code-block-content\">\n <Code size=\"3\">{code}</Code>\n </pre>\n )}\n </Box>\n\n {shouldShowToggle && !isExpanded && <Box className=\"code-scroll-shadow visible\" />}\n </Flex>\n </Card>\n </Box>\n );\n});\n\n// ============================================\n// Children Code Section (for pre-highlighted MDX)\n// ============================================\n\ninterface ChildrenCodeSectionProps {\n children: ReactNode;\n showCopy?: boolean;\n showLanguage?: boolean;\n}\n\nfunction extractCodeFromChildren(children?: ReactNode): string {\n if (!children) return \"\";\n if (typeof children === \"object\" && children !== null && \"props\" in children) {\n const childProps = (children as any).props;\n if (childProps?.children && typeof childProps.children === \"object\") {\n const codeProps = (childProps.children as any).props;\n const codeChildren = codeProps?.children;\n if (typeof codeChildren === \"string\") return codeChildren;\n }\n if (typeof childProps?.children === \"string\") return childProps.children;\n }\n if (typeof children === \"string\") return children;\n return \"\";\n}\n\nfunction extractLanguageFromChildren(children?: ReactNode): string {\n if (!children) return \"text\";\n if (typeof children === \"object\" && children !== null && \"props\" in children) {\n const childProps = (children as any).props;\n if (childProps?.children && typeof childProps.children === \"object\") {\n const codeProps = (childProps.children as any).props;\n const className = codeProps?.className || \"\";\n const match = className.match(/language-([\\w-]+)/i);\n if (match) return match[1];\n }\n const className = childProps?.className || \"\";\n const match = className.match(/language-([\\w-]+)/i);\n if (match) return match[1];\n }\n return \"text\";\n}\n\nfunction formatLanguageLabel(lang: string): string {\n const aliasMap: Record<string, string> = {\n tsx: \"TSX\",\n ts: \"TS\",\n jsx: \"JSX\",\n js: \"JS\",\n javascript: \"JS\",\n typescript: \"TS\",\n css: \"CSS\",\n html: \"HTML\",\n json: \"JSON\",\n bash: \"SH\",\n sh: \"SH\",\n shell: \"SH\",\n text: \"plaintext\",\n };\n return aliasMap[lang.toLowerCase()] || lang.toLowerCase();\n}\n\nconst ChildrenCodeSection = memo(function ChildrenCodeSection({ children, showCopy = true, showLanguage = true }: ChildrenCodeSectionProps) {\n const [isExpanded, setIsExpanded] = useState(false);\n const [contentHeight, setContentHeight] = useState(COLLAPSED_HEIGHT);\n const [copied, setCopied] = useState(false);\n const contentRef = useRef<HTMLDivElement>(null);\n const resetTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const code = extractCodeFromChildren(children);\n const language = extractLanguageFromChildren(children);\n const displayLanguage = formatLanguageLabel(language);\n\n const shouldShowToggle = contentHeight > COLLAPSED_HEIGHT;\n\n useEffect(() => {\n if (contentRef.current) {\n setContentHeight(contentRef.current.scrollHeight);\n }\n }, [children]);\n\n useEffect(() => {\n return () => {\n if (resetTimeoutRef.current) clearTimeout(resetTimeoutRef.current);\n };\n }, []);\n\n const handleCopy = useCallback(async () => {\n if (!code.trim()) return;\n try {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n if (resetTimeoutRef.current) clearTimeout(resetTimeoutRef.current);\n resetTimeoutRef.current = setTimeout(() => setCopied(false), 2000);\n } catch {\n // Silently fail\n }\n }, [code]);\n\n const contentStyle: React.CSSProperties = {\n maxHeight: isExpanded ? `${contentHeight}px` : `${COLLAPSED_HEIGHT}px`,\n };\n\n return (\n <Box position=\"relative\">\n <Card size=\"1\" variant=\"soft\">\n <Flex direction=\"column\" gap=\"3\">\n <Flex gap=\"2\" justify=\"between\" align=\"start\">\n {showLanguage && (\n <Code size=\"1\" color=\"gray\" highContrast>\n {displayLanguage}\n </Code>\n )}\n <Flex align=\"center\" gap=\"2\" className=\"code-action-buttons\">\n {showCopy && (\n <Button\n size=\"2\"\n variant=\"ghost\"\n color=\"gray\"\n onClick={handleCopy}\n tooltip={copied ? \"Copied!\" : \"Copy\"}\n aria-label={copied ? \"Copied!\" : \"Copy code\"}\n >\n <HugeiconsIcon icon={copied ? Tick01Icon : Copy01Icon} /> Copy\n </Button>\n )}\n </Flex>\n </Flex>\n\n <Box ref={contentRef} style={contentStyle} className=\"code-content\">\n <div className=\"code-block-content\">{children}</div>\n </Box>\n\n {shouldShowToggle && !isExpanded && <Box className=\"code-scroll-shadow visible\" />}\n </Flex>\n </Card>\n </Box>\n );\n});\n\n// ============================================\n// Main CodeBlock Component\n// ============================================\n\nexport function CodeBlock({\n children,\n code,\n language,\n preview,\n showCopy = true,\n showLanguage = true,\n lightTheme,\n darkTheme,\n background,\n backgroundProps,\n}: CodeBlockProps) {\n const hasCode = code || (children && React.Children.count(children) > 0);\n const displayLanguage = language || extractLanguageFromChildren(children) || \"text\";\n\n return (\n <Box className=\"docs-code-block\" mt=\"6\" mb=\"8\">\n <Flex direction=\"column\" gap=\"2\">\n {preview && (\n <PreviewSection background={background} backgroundProps={backgroundProps}>\n {preview}\n </PreviewSection>\n )}\n\n {code && (\n <CodeSection code={code} language={displayLanguage} showCopy={showCopy} showLanguage={showLanguage} lightTheme={lightTheme} darkTheme={darkTheme} />\n )}\n\n {children && !code && (\n <ChildrenCodeSection showCopy={showCopy} showLanguage={showLanguage}>\n {children}\n </ChildrenCodeSection>\n )}\n </Flex>\n </Box>\n );\n}\n"],
5
- "mappings": "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",
6
- "names": ["React", "useState", "useRef", "useEffect", "useCallback", "memo", "Box", "Card", "Flex", "Button", "Code", "Theme", "HugeiconsIcon", "Copy01Icon", "Tick01Icon", "codeToHtml", "COLLAPSED_HEIGHT", "DEFAULT_LIGHT_THEME", "DEFAULT_DARK_THEME", "PreviewSection", "children", "background", "backgroundProps", "dotSize", "color", "backgroundColor", "height", "width", "radius", "dotsStyle", "imageStyle", "CodeSection", "code", "language", "showCopy", "showLanguage", "lightTheme", "darkTheme", "highlighted", "setHighlighted", "isExpanded", "setIsExpanded", "contentHeight", "setContentHeight", "copied", "setCopied", "contentRef", "resetTimeoutRef", "shouldShowToggle", "cancelled", "html", "handleCopy", "displayLanguage", "contentStyle", "extractCodeFromChildren", "childProps", "codeChildren", "extractLanguageFromChildren", "match", "formatLanguageLabel", "lang", "ChildrenCodeSection", "CodeBlock", "preview", "hasCode"]
4
+ "sourcesContent": ["import React, { useState, useRef, useEffect, useCallback, memo, type ReactNode } from \"react\";\nimport { Box, Card, Flex, Button, Code, Theme, ScrollArea } from \"@kushagradhawan/kookie-ui\";\nimport { HugeiconsIcon } from \"@hugeicons/react\";\nimport { Copy01Icon, Tick01Icon, ArrowDown01Icon } from \"@hugeicons/core-free-icons\";\nimport { codeToHtml } from \"shiki\";\nimport type { CodeBlockProps } from \"./types\";\n\nconst COLLAPSED_HEIGHT = 360;\nconst DEFAULT_LIGHT_THEME = \"one-light\";\nconst DEFAULT_DARK_THEME = \"one-dark-pro\";\n\n// ============================================\n// Preview Section\n// ============================================\n\ninterface PreviewSectionProps {\n children: ReactNode;\n background?: \"none\" | \"dots\" | string;\n backgroundProps?: {\n dotSize?: number;\n color?: string;\n backgroundColor?: string;\n height?: string;\n width?: string;\n radius?: string;\n };\n}\n\nfunction PreviewSection({ children, background = \"none\", backgroundProps = {} }: PreviewSectionProps) {\n const { dotSize = 24, color = \"var(--gray-10)\", backgroundColor = \"var(--gray-2)\", height, width = \"100%\", radius = \"3\" } = backgroundProps;\n\n if (background === \"none\") {\n return (\n <Card size=\"1\" variant=\"soft\">\n <Flex justify=\"center\" align=\"center\" py=\"4\">\n <Theme fontFamily=\"sans\">{children}</Theme>\n </Flex>\n </Card>\n );\n }\n\n if (background === \"dots\") {\n const dotsStyle: React.CSSProperties = {\n backgroundImage: `radial-gradient(circle, ${color} 1px, transparent 1px)`,\n borderRadius: `var(--radius-${radius})`,\n backgroundSize: `${dotSize}px ${dotSize}px`,\n backgroundPosition: \"center\",\n backgroundColor,\n width,\n ...(height && { height }),\n };\n\n return (\n <Card size=\"1\" variant=\"soft\">\n <Flex justify=\"center\" align=\"center\" py=\"4\" style={dotsStyle}>\n <Theme fontFamily=\"sans\">{children}</Theme>\n </Flex>\n </Card>\n );\n }\n\n const imageStyle: React.CSSProperties = {\n backgroundImage: `url(${background})`,\n backgroundSize: \"cover\",\n backgroundPosition: \"center\",\n backgroundRepeat: \"no-repeat\",\n borderRadius: `var(--radius-${radius})`,\n width,\n ...(height && { height }),\n };\n\n return (\n <Card size=\"1\" variant=\"soft\">\n <Flex justify=\"center\" align=\"center\" py=\"4\" style={imageStyle}>\n <Theme fontFamily=\"sans\">{children}</Theme>\n </Flex>\n </Card>\n );\n}\n\n// ============================================\n// Code Section (for runtime highlighting)\n// ============================================\n\ninterface CodeSectionProps {\n code: string;\n language: string;\n showCopy?: boolean;\n showLanguage?: boolean;\n lightTheme?: string;\n darkTheme?: string;\n}\n\nconst CodeSection = memo(function CodeSection({\n code,\n language,\n showCopy = true,\n showLanguage = true,\n lightTheme = DEFAULT_LIGHT_THEME,\n darkTheme = DEFAULT_DARK_THEME,\n}: CodeSectionProps) {\n const [highlighted, setHighlighted] = useState<string | null>(null);\n const [isExpanded, setIsExpanded] = useState(false);\n const [contentHeight, setContentHeight] = useState(COLLAPSED_HEIGHT);\n const [copied, setCopied] = useState(false);\n const contentRef = useRef<HTMLDivElement>(null);\n const resetTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const shouldShowToggle = contentHeight > COLLAPSED_HEIGHT;\n\n useEffect(() => {\n let cancelled = false;\n codeToHtml(code, {\n lang: language,\n themes: { light: lightTheme, dark: darkTheme },\n defaultColor: false,\n })\n .then((html) => {\n if (!cancelled) setHighlighted(html);\n })\n .catch(() => {\n if (!cancelled) setHighlighted(null);\n });\n return () => {\n cancelled = true;\n };\n }, [code, language, lightTheme, darkTheme]);\n\n useEffect(() => {\n if (contentRef.current) {\n setContentHeight(contentRef.current.scrollHeight);\n }\n }, [highlighted]);\n\n useEffect(() => {\n return () => {\n if (resetTimeoutRef.current) clearTimeout(resetTimeoutRef.current);\n };\n }, []);\n\n const handleCopy = useCallback(async () => {\n if (!code.trim()) return;\n try {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n if (resetTimeoutRef.current) clearTimeout(resetTimeoutRef.current);\n resetTimeoutRef.current = setTimeout(() => setCopied(false), 2000);\n } catch {\n // Silently fail\n }\n }, [code]);\n\n const displayLanguage = language === \"text\" ? \"plaintext\" : language;\n\n const handleToggle = useCallback(() => {\n setIsExpanded((prev) => !prev);\n }, []);\n\n const contentStyle: React.CSSProperties = {\n maxHeight: isExpanded ? `${contentHeight}px` : `${COLLAPSED_HEIGHT}px`,\n };\n\n const chevronStyle: React.CSSProperties = {\n transform: isExpanded ? \"rotate(180deg)\" : \"rotate(0deg)\",\n };\n\n return (\n <Box position=\"relative\">\n <Card size=\"1\" variant=\"soft\">\n <Flex direction=\"column\" gap=\"3\">\n <Flex gap=\"2\" justify=\"between\" align=\"start\">\n {showLanguage && (\n <Code size=\"1\" color=\"gray\" highContrast>\n {displayLanguage}\n </Code>\n )}\n <Flex align=\"center\" gap=\"2\" className=\"code-action-buttons\">\n {shouldShowToggle && (\n <Button\n size=\"2\"\n variant=\"ghost\"\n color=\"gray\"\n onClick={handleToggle}\n tooltip={isExpanded ? \"Collapse\" : \"Expand\"}\n aria-label={isExpanded ? \"Collapse code\" : \"Expand code\"}\n >\n <HugeiconsIcon icon={ArrowDown01Icon} style={chevronStyle} className=\"code-chevron\" />\n </Button>\n )}\n {showCopy && (\n <Button\n size=\"2\"\n variant=\"ghost\"\n color=\"gray\"\n onClick={handleCopy}\n tooltip={copied ? \"Copied!\" : \"Copy\"}\n aria-label={copied ? \"Copied!\" : \"Copy code\"}\n >\n <HugeiconsIcon icon={copied ? Tick01Icon : Copy01Icon} /> Copy\n </Button>\n )}\n </Flex>\n </Flex>\n\n <Box ref={contentRef} style={contentStyle} className=\"code-content\">\n <ScrollArea type=\"auto\" scrollbars=\"horizontal\">\n {highlighted ? (\n <Box dangerouslySetInnerHTML={{ __html: highlighted }} />\n ) : (\n <pre>\n <Code size=\"3\">{code}</Code>\n </pre>\n )}\n </ScrollArea>\n </Box>\n\n {shouldShowToggle && !isExpanded && <Box className=\"code-scroll-shadow visible\" />}\n </Flex>\n </Card>\n </Box>\n );\n});\n\n// ============================================\n// Children Code Section (for pre-highlighted MDX)\n// ============================================\n\ninterface ChildrenCodeSectionProps {\n children: ReactNode;\n showCopy?: boolean;\n showLanguage?: boolean;\n}\n\nfunction extractCodeFromChildren(children?: ReactNode): string {\n const extractText = (node: any): string => {\n if (typeof node === \"string\") return node;\n if (typeof node === \"number\") return String(node);\n if (!node) return \"\";\n if (Array.isArray(node)) return node.map(extractText).join(\"\");\n if (typeof node === \"object\" && \"props\" in node) {\n const props = node.props;\n if (props?.children) return extractText(props.children);\n }\n return \"\";\n };\n return extractText(children);\n}\n\nfunction extractLanguageFromChildren(children?: ReactNode): string {\n const findLanguage = (node: any): string | null => {\n if (!node) return null;\n if (typeof node === \"object\" && \"props\" in node) {\n const props = node.props;\n\n // Check data-language attribute (rehype-pretty-code)\n if (props?.[\"data-language\"]) {\n return props[\"data-language\"];\n }\n\n // Check className for language-xxx\n const className = props?.className || props?.class || \"\";\n if (typeof className === \"string\") {\n const match = className.match(/language-([\\w-]+)/i);\n if (match) return match[1];\n }\n\n // Recursively check children\n if (props?.children) {\n if (Array.isArray(props.children)) {\n for (const child of props.children) {\n const lang = findLanguage(child);\n if (lang) return lang;\n }\n } else {\n return findLanguage(props.children);\n }\n }\n }\n return null;\n };\n return findLanguage(children) || \"text\";\n}\n\nfunction formatLanguageLabel(lang: string): string {\n const aliasMap: Record<string, string> = {\n tsx: \"TSX\",\n ts: \"TS\",\n jsx: \"JSX\",\n js: \"JS\",\n javascript: \"JS\",\n typescript: \"TS\",\n css: \"CSS\",\n html: \"HTML\",\n json: \"JSON\",\n bash: \"SH\",\n sh: \"SH\",\n shell: \"SH\",\n text: \"plaintext\",\n };\n return aliasMap[lang.toLowerCase()] || lang.toLowerCase();\n}\n\nconst ChildrenCodeSection = memo(function ChildrenCodeSection({ children, showCopy = true, showLanguage = true }: ChildrenCodeSectionProps) {\n const [isExpanded, setIsExpanded] = useState(false);\n const [contentHeight, setContentHeight] = useState(COLLAPSED_HEIGHT);\n const [copied, setCopied] = useState(false);\n const contentRef = useRef<HTMLDivElement>(null);\n const resetTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const code = extractCodeFromChildren(children);\n const language = extractLanguageFromChildren(children);\n const displayLanguage = formatLanguageLabel(language);\n\n const shouldShowToggle = contentHeight > COLLAPSED_HEIGHT;\n\n useEffect(() => {\n if (contentRef.current) {\n setContentHeight(contentRef.current.scrollHeight);\n }\n }, [children]);\n\n useEffect(() => {\n return () => {\n if (resetTimeoutRef.current) clearTimeout(resetTimeoutRef.current);\n };\n }, []);\n\n const handleCopy = useCallback(async () => {\n if (!code.trim()) return;\n try {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n if (resetTimeoutRef.current) clearTimeout(resetTimeoutRef.current);\n resetTimeoutRef.current = setTimeout(() => setCopied(false), 2000);\n } catch {\n // Silently fail\n }\n }, [code]);\n\n const contentStyle: React.CSSProperties = {\n maxHeight: isExpanded ? `${contentHeight}px` : `${COLLAPSED_HEIGHT}px`,\n };\n\n const handleToggle = useCallback(() => {\n setIsExpanded((prev) => !prev);\n }, []);\n\n const chevronStyle: React.CSSProperties = {\n transform: isExpanded ? \"rotate(180deg)\" : \"rotate(0deg)\",\n };\n\n return (\n <Box position=\"relative\">\n <Card size=\"1\" variant=\"soft\">\n <Flex direction=\"column\" gap=\"3\">\n <Flex gap=\"2\" justify=\"between\" align=\"start\">\n {showLanguage && (\n <Code size=\"1\" color=\"gray\" highContrast>\n {displayLanguage}\n </Code>\n )}\n <Flex align=\"center\" gap=\"2\" className=\"code-action-buttons\">\n {shouldShowToggle && (\n <Button\n size=\"2\"\n variant=\"ghost\"\n color=\"gray\"\n onClick={handleToggle}\n tooltip={isExpanded ? \"Collapse\" : \"Expand\"}\n aria-label={isExpanded ? \"Collapse code\" : \"Expand code\"}\n >\n <HugeiconsIcon icon={ArrowDown01Icon} style={chevronStyle} className=\"code-chevron\" />\n </Button>\n )}\n {showCopy && (\n <Button\n size=\"2\"\n variant=\"ghost\"\n color=\"gray\"\n onClick={handleCopy}\n tooltip={copied ? \"Copied!\" : \"Copy\"}\n aria-label={copied ? \"Copied!\" : \"Copy code\"}\n >\n <HugeiconsIcon icon={copied ? Tick01Icon : Copy01Icon} /> Copy\n </Button>\n )}\n </Flex>\n </Flex>\n\n <Box ref={contentRef} style={contentStyle} className=\"code-content\">\n <ScrollArea type=\"auto\" scrollbars=\"horizontal\">\n {children}\n </ScrollArea>\n </Box>\n\n {shouldShowToggle && !isExpanded && <Box className=\"code-scroll-shadow visible\" />}\n </Flex>\n </Card>\n </Box>\n );\n});\n\n// ============================================\n// Main CodeBlock Component\n// ============================================\n\nexport function CodeBlock({\n children,\n code,\n language,\n preview,\n showCopy = true,\n showLanguage = true,\n lightTheme,\n darkTheme,\n background,\n backgroundProps,\n}: CodeBlockProps) {\n const hasCode = code || (children && React.Children.count(children) > 0);\n const displayLanguage = language || extractLanguageFromChildren(children) || \"text\";\n\n return (\n <Box className=\"docs-code-block\" mt=\"6\" mb=\"8\">\n <Flex direction=\"column\" gap=\"2\">\n {preview && (\n <PreviewSection background={background} backgroundProps={backgroundProps}>\n {preview}\n </PreviewSection>\n )}\n\n {code && (\n <CodeSection code={code} language={displayLanguage} showCopy={showCopy} showLanguage={showLanguage} lightTheme={lightTheme} darkTheme={darkTheme} />\n )}\n\n {children && !code && (\n <ChildrenCodeSection showCopy={showCopy} showLanguage={showLanguage}>\n {children}\n </ChildrenCodeSection>\n )}\n </Flex>\n </Box>\n );\n}\n"],
5
+ "mappings": "AAAA,OAAOA,GAAS,YAAAC,EAAU,UAAAC,EAAQ,aAAAC,EAAW,eAAAC,EAAa,QAAAC,MAA4B,QACtF,OAAS,OAAAC,EAAK,QAAAC,EAAM,QAAAC,EAAM,UAAAC,EAAQ,QAAAC,EAAM,SAAAC,EAAO,cAAAC,MAAkB,4BACjE,OAAS,iBAAAC,MAAqB,mBAC9B,OAAS,cAAAC,EAAY,cAAAC,EAAY,mBAAAC,MAAuB,6BACxD,OAAS,cAAAC,MAAkB,QAG3B,MAAMC,EAAmB,IACnBC,EAAsB,YACtBC,EAAqB,eAmB3B,SAASC,EAAe,CAAE,SAAAC,EAAU,WAAAC,EAAa,OAAQ,gBAAAC,EAAkB,CAAC,CAAE,EAAwB,CACpG,KAAM,CAAE,QAAAC,EAAU,GAAI,MAAAC,EAAQ,iBAAkB,gBAAAC,EAAkB,gBAAiB,OAAAC,EAAQ,MAAAC,EAAQ,OAAQ,OAAAC,EAAS,GAAI,EAAIN,EAE5H,GAAID,IAAe,OACjB,OACEvB,EAAA,cAACO,EAAA,CAAK,KAAK,IAAI,QAAQ,QACrBP,EAAA,cAACQ,EAAA,CAAK,QAAQ,SAAS,MAAM,SAAS,GAAG,KACvCR,EAAA,cAACW,EAAA,CAAM,WAAW,QAAQW,CAAS,CACrC,CACF,EAIJ,GAAIC,IAAe,OAAQ,CACzB,MAAMQ,EAAiC,CACrC,gBAAiB,2BAA2BL,CAAK,yBACjD,aAAc,gBAAgBI,CAAM,IACpC,eAAgB,GAAGL,CAAO,MAAMA,CAAO,KACvC,mBAAoB,SACpB,gBAAAE,EACA,MAAAE,EACA,GAAID,GAAU,CAAE,OAAAA,CAAO,CACzB,EAEA,OACE5B,EAAA,cAACO,EAAA,CAAK,KAAK,IAAI,QAAQ,QACrBP,EAAA,cAACQ,EAAA,CAAK,QAAQ,SAAS,MAAM,SAAS,GAAG,IAAI,MAAOuB,GAClD/B,EAAA,cAACW,EAAA,CAAM,WAAW,QAAQW,CAAS,CACrC,CACF,CAEJ,CAEA,MAAMU,EAAkC,CACtC,gBAAiB,OAAOT,CAAU,IAClC,eAAgB,QAChB,mBAAoB,SACpB,iBAAkB,YAClB,aAAc,gBAAgBO,CAAM,IACpC,MAAAD,EACA,GAAID,GAAU,CAAE,OAAAA,CAAO,CACzB,EAEA,OACE5B,EAAA,cAACO,EAAA,CAAK,KAAK,IAAI,QAAQ,QACrBP,EAAA,cAACQ,EAAA,CAAK,QAAQ,SAAS,MAAM,SAAS,GAAG,IAAI,MAAOwB,GAClDhC,EAAA,cAACW,EAAA,CAAM,WAAW,QAAQW,CAAS,CACrC,CACF,CAEJ,CAeA,MAAMW,EAAc5B,EAAK,SAAqB,CAC5C,KAAA6B,EACA,SAAAC,EACA,SAAAC,EAAW,GACX,aAAAC,EAAe,GACf,WAAAC,EAAanB,EACb,UAAAoB,EAAYnB,CACd,EAAqB,CACnB,KAAM,CAACoB,EAAaC,CAAc,EAAIxC,EAAwB,IAAI,EAC5D,CAACyC,EAAYC,CAAa,EAAI1C,EAAS,EAAK,EAC5C,CAAC2C,EAAeC,CAAgB,EAAI5C,EAASiB,CAAgB,EAC7D,CAAC4B,EAAQC,CAAS,EAAI9C,EAAS,EAAK,EACpC+C,EAAa9C,EAAuB,IAAI,EACxC+C,EAAkB/C,EAA6C,IAAI,EAEnEgD,EAAmBN,EAAgB1B,EAEzCf,EAAU,IAAM,CACd,IAAIgD,EAAY,GAChB,OAAAlC,EAAWiB,EAAM,CACf,KAAMC,EACN,OAAQ,CAAE,MAAOG,EAAY,KAAMC,CAAU,EAC7C,aAAc,EAChB,CAAC,EACE,KAAMa,GAAS,CACTD,GAAWV,EAAeW,CAAI,CACrC,CAAC,EACA,MAAM,IAAM,CACND,GAAWV,EAAe,IAAI,CACrC,CAAC,EACI,IAAM,CACXU,EAAY,EACd,CACF,EAAG,CAACjB,EAAMC,EAAUG,EAAYC,CAAS,CAAC,EAE1CpC,EAAU,IAAM,CACV6C,EAAW,SACbH,EAAiBG,EAAW,QAAQ,YAAY,CAEpD,EAAG,CAACR,CAAW,CAAC,EAEhBrC,EAAU,IACD,IAAM,CACP8C,EAAgB,SAAS,aAAaA,EAAgB,OAAO,CACnE,EACC,CAAC,CAAC,EAEL,MAAMI,EAAajD,EAAY,SAAY,CACzC,GAAK8B,EAAK,KAAK,EACf,GAAI,CACF,MAAM,UAAU,UAAU,UAAUA,CAAI,EACxCa,EAAU,EAAI,EACVE,EAAgB,SAAS,aAAaA,EAAgB,OAAO,EACjEA,EAAgB,QAAU,WAAW,IAAMF,EAAU,EAAK,EAAG,GAAI,CACnE,MAAQ,CAER,CACF,EAAG,CAACb,CAAI,CAAC,EAEHoB,EAAkBnB,IAAa,OAAS,YAAcA,EAEtDoB,EAAenD,EAAY,IAAM,CACrCuC,EAAea,GAAS,CAACA,CAAI,CAC/B,EAAG,CAAC,CAAC,EAECC,EAAoC,CACxC,UAAWf,EAAa,GAAGE,CAAa,KAAO,GAAG1B,CAAgB,IACpE,EAMA,OACElB,EAAA,cAACM,EAAA,CAAI,SAAS,YACZN,EAAA,cAACO,EAAA,CAAK,KAAK,IAAI,QAAQ,QACrBP,EAAA,cAACQ,EAAA,CAAK,UAAU,SAAS,IAAI,KAC3BR,EAAA,cAACQ,EAAA,CAAK,IAAI,IAAI,QAAQ,UAAU,MAAM,SACnC6B,GACCrC,EAAA,cAACU,EAAA,CAAK,KAAK,IAAI,MAAM,OAAO,aAAY,IACrC4C,CACH,EAEFtD,EAAA,cAACQ,EAAA,CAAK,MAAM,SAAS,IAAI,IAAI,UAAU,uBACpC0C,GACClD,EAAA,cAACS,EAAA,CACC,KAAK,IACL,QAAQ,QACR,MAAM,OACN,QAAS8C,EACT,QAASb,EAAa,WAAa,SACnC,aAAYA,EAAa,gBAAkB,eAE3C1C,EAAA,cAACa,EAAA,CAAc,KAAMG,EAAiB,MAxBZ,CACxC,UAAW0B,EAAa,iBAAmB,cAC7C,EAsB2E,UAAU,eAAe,CACtF,EAEDN,GACCpC,EAAA,cAACS,EAAA,CACC,KAAK,IACL,QAAQ,QACR,MAAM,OACN,QAAS4C,EACT,QAASP,EAAS,UAAY,OAC9B,aAAYA,EAAS,UAAY,aAEjC9C,EAAA,cAACa,EAAA,CAAc,KAAMiC,EAAS/B,EAAaD,EAAY,EAAE,OAC3D,CAEJ,CACF,EAEAd,EAAA,cAACM,EAAA,CAAI,IAAK0C,EAAY,MAAOS,EAAc,UAAU,gBACnDzD,EAAA,cAACY,EAAA,CAAW,KAAK,OAAO,WAAW,cAChC4B,EACCxC,EAAA,cAACM,EAAA,CAAI,wBAAyB,CAAE,OAAQkC,CAAY,EAAG,EAEvDxC,EAAA,cAAC,WACCA,EAAA,cAACU,EAAA,CAAK,KAAK,KAAKwB,CAAK,CACvB,CAEJ,CACF,EAECgB,GAAoB,CAACR,GAAc1C,EAAA,cAACM,EAAA,CAAI,UAAU,6BAA6B,CAClF,CACF,CACF,CAEJ,CAAC,EAYD,SAASoD,EAAwBpC,EAA8B,CAC7D,MAAMqC,EAAeC,GAAsB,CACzC,GAAI,OAAOA,GAAS,SAAU,OAAOA,EACrC,GAAI,OAAOA,GAAS,SAAU,OAAO,OAAOA,CAAI,EAChD,GAAI,CAACA,EAAM,MAAO,GAClB,GAAI,MAAM,QAAQA,CAAI,EAAG,OAAOA,EAAK,IAAID,CAAW,EAAE,KAAK,EAAE,EAC7D,GAAI,OAAOC,GAAS,UAAY,UAAWA,EAAM,CAC/C,MAAMC,EAAQD,EAAK,MACnB,GAAIC,GAAO,SAAU,OAAOF,EAAYE,EAAM,QAAQ,CACxD,CACA,MAAO,EACT,EACA,OAAOF,EAAYrC,CAAQ,CAC7B,CAEA,SAASwC,EAA4BxC,EAA8B,CACjE,MAAMyC,EAAgBH,GAA6B,CACjD,GAAI,CAACA,EAAM,OAAO,KAClB,GAAI,OAAOA,GAAS,UAAY,UAAWA,EAAM,CAC/C,MAAMC,EAAQD,EAAK,MAGnB,GAAIC,IAAQ,eAAe,EACzB,OAAOA,EAAM,eAAe,EAI9B,MAAMG,EAAYH,GAAO,WAAaA,GAAO,OAAS,GACtD,GAAI,OAAOG,GAAc,SAAU,CACjC,MAAMC,EAAQD,EAAU,MAAM,oBAAoB,EAClD,GAAIC,EAAO,OAAOA,EAAM,CAAC,CAC3B,CAGA,GAAIJ,GAAO,SACT,GAAI,MAAM,QAAQA,EAAM,QAAQ,EAC9B,UAAWK,KAASL,EAAM,SAAU,CAClC,MAAMM,EAAOJ,EAAaG,CAAK,EAC/B,GAAIC,EAAM,OAAOA,CACnB,KAEA,QAAOJ,EAAaF,EAAM,QAAQ,CAGxC,CACA,OAAO,IACT,EACA,OAAOE,EAAazC,CAAQ,GAAK,MACnC,CAEA,SAAS8C,EAAoBD,EAAsB,CAgBjD,MAfyC,CACvC,IAAK,MACL,GAAI,KACJ,IAAK,MACL,GAAI,KACJ,WAAY,KACZ,WAAY,KACZ,IAAK,MACL,KAAM,OACN,KAAM,OACN,KAAM,KACN,GAAI,KACJ,MAAO,KACP,KAAM,WACR,EACgBA,EAAK,YAAY,CAAC,GAAKA,EAAK,YAAY,CAC1D,CAEA,MAAME,EAAsBhE,EAAK,SAA6B,CAAE,SAAAiB,EAAU,SAAAc,EAAW,GAAM,aAAAC,EAAe,EAAK,EAA6B,CAC1I,KAAM,CAACK,EAAYC,CAAa,EAAI1C,EAAS,EAAK,EAC5C,CAAC2C,EAAeC,CAAgB,EAAI5C,EAASiB,CAAgB,EAC7D,CAAC4B,EAAQC,CAAS,EAAI9C,EAAS,EAAK,EACpC+C,EAAa9C,EAAuB,IAAI,EACxC+C,EAAkB/C,EAA6C,IAAI,EAEnEgC,EAAOwB,EAAwBpC,CAAQ,EACvCa,EAAW2B,EAA4BxC,CAAQ,EAC/CgC,EAAkBc,EAAoBjC,CAAQ,EAE9Ce,EAAmBN,EAAgB1B,EAEzCf,EAAU,IAAM,CACV6C,EAAW,SACbH,EAAiBG,EAAW,QAAQ,YAAY,CAEpD,EAAG,CAAC1B,CAAQ,CAAC,EAEbnB,EAAU,IACD,IAAM,CACP8C,EAAgB,SAAS,aAAaA,EAAgB,OAAO,CACnE,EACC,CAAC,CAAC,EAEL,MAAMI,EAAajD,EAAY,SAAY,CACzC,GAAK8B,EAAK,KAAK,EACf,GAAI,CACF,MAAM,UAAU,UAAU,UAAUA,CAAI,EACxCa,EAAU,EAAI,EACVE,EAAgB,SAAS,aAAaA,EAAgB,OAAO,EACjEA,EAAgB,QAAU,WAAW,IAAMF,EAAU,EAAK,EAAG,GAAI,CACnE,MAAQ,CAER,CACF,EAAG,CAACb,CAAI,CAAC,EAEHuB,EAAoC,CACxC,UAAWf,EAAa,GAAGE,CAAa,KAAO,GAAG1B,CAAgB,IACpE,EAEMqC,EAAenD,EAAY,IAAM,CACrCuC,EAAea,GAAS,CAACA,CAAI,CAC/B,EAAG,CAAC,CAAC,EAML,OACExD,EAAA,cAACM,EAAA,CAAI,SAAS,YACZN,EAAA,cAACO,EAAA,CAAK,KAAK,IAAI,QAAQ,QACrBP,EAAA,cAACQ,EAAA,CAAK,UAAU,SAAS,IAAI,KAC3BR,EAAA,cAACQ,EAAA,CAAK,IAAI,IAAI,QAAQ,UAAU,MAAM,SACnC6B,GACCrC,EAAA,cAACU,EAAA,CAAK,KAAK,IAAI,MAAM,OAAO,aAAY,IACrC4C,CACH,EAEFtD,EAAA,cAACQ,EAAA,CAAK,MAAM,SAAS,IAAI,IAAI,UAAU,uBACpC0C,GACClD,EAAA,cAACS,EAAA,CACC,KAAK,IACL,QAAQ,QACR,MAAM,OACN,QAAS8C,EACT,QAASb,EAAa,WAAa,SACnC,aAAYA,EAAa,gBAAkB,eAE3C1C,EAAA,cAACa,EAAA,CAAc,KAAMG,EAAiB,MAxBZ,CACxC,UAAW0B,EAAa,iBAAmB,cAC7C,EAsB2E,UAAU,eAAe,CACtF,EAEDN,GACCpC,EAAA,cAACS,EAAA,CACC,KAAK,IACL,QAAQ,QACR,MAAM,OACN,QAAS4C,EACT,QAASP,EAAS,UAAY,OAC9B,aAAYA,EAAS,UAAY,aAEjC9C,EAAA,cAACa,EAAA,CAAc,KAAMiC,EAAS/B,EAAaD,EAAY,EAAE,OAC3D,CAEJ,CACF,EAEAd,EAAA,cAACM,EAAA,CAAI,IAAK0C,EAAY,MAAOS,EAAc,UAAU,gBACnDzD,EAAA,cAACY,EAAA,CAAW,KAAK,OAAO,WAAW,cAChCU,CACH,CACF,EAEC4B,GAAoB,CAACR,GAAc1C,EAAA,cAACM,EAAA,CAAI,UAAU,6BAA6B,CAClF,CACF,CACF,CAEJ,CAAC,EAMM,SAASgE,GAAU,CACxB,SAAAhD,EACA,KAAAY,EACA,SAAAC,EACA,QAAAoC,EACA,SAAAnC,EAAW,GACX,aAAAC,EAAe,GACf,WAAAC,EACA,UAAAC,EACA,WAAAhB,EACA,gBAAAC,CACF,EAAmB,CACjB,MAAMgD,EAAUtC,GAASZ,GAAYtB,EAAM,SAAS,MAAMsB,CAAQ,EAAI,EAChEgC,EAAkBnB,GAAY2B,EAA4BxC,CAAQ,GAAK,OAE7E,OACEtB,EAAA,cAACM,EAAA,CAAI,UAAU,kBAAkB,GAAG,IAAI,GAAG,KACzCN,EAAA,cAACQ,EAAA,CAAK,UAAU,SAAS,IAAI,KAC1B+D,GACCvE,EAAA,cAACqB,EAAA,CAAe,WAAYE,EAAY,gBAAiBC,GACtD+C,CACH,EAGDrC,GACClC,EAAA,cAACiC,EAAA,CAAY,KAAMC,EAAM,SAAUoB,EAAiB,SAAUlB,EAAU,aAAcC,EAAc,WAAYC,EAAY,UAAWC,EAAW,EAGnJjB,GAAY,CAACY,GACZlC,EAAA,cAACqE,EAAA,CAAoB,SAAUjC,EAAU,aAAcC,GACpDf,CACH,CAEJ,CACF,CAEJ",
6
+ "names": ["React", "useState", "useRef", "useEffect", "useCallback", "memo", "Box", "Card", "Flex", "Button", "Code", "Theme", "ScrollArea", "HugeiconsIcon", "Copy01Icon", "Tick01Icon", "ArrowDown01Icon", "codeToHtml", "COLLAPSED_HEIGHT", "DEFAULT_LIGHT_THEME", "DEFAULT_DARK_THEME", "PreviewSection", "children", "background", "backgroundProps", "dotSize", "color", "backgroundColor", "height", "width", "radius", "dotsStyle", "imageStyle", "CodeSection", "code", "language", "showCopy", "showLanguage", "lightTheme", "darkTheme", "highlighted", "setHighlighted", "isExpanded", "setIsExpanded", "contentHeight", "setContentHeight", "copied", "setCopied", "contentRef", "resetTimeoutRef", "shouldShowToggle", "cancelled", "html", "handleCopy", "displayLanguage", "handleToggle", "prev", "contentStyle", "extractCodeFromChildren", "extractText", "node", "props", "extractLanguageFromChildren", "findLanguage", "className", "match", "child", "lang", "formatLanguageLabel", "ChildrenCodeSection", "CodeBlock", "preview", "hasCode"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kushagradhawan/kookie-blocks",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/KushagraDhawan1997/kookie-blocks.git"
@@ -1,7 +1,7 @@
1
1
  import React, { useState, useRef, useEffect, useCallback, memo, type ReactNode } from "react";
2
- import { Box, Card, Flex, Button, Code, Theme } from "@kushagradhawan/kookie-ui";
2
+ import { Box, Card, Flex, Button, Code, Theme, ScrollArea } from "@kushagradhawan/kookie-ui";
3
3
  import { HugeiconsIcon } from "@hugeicons/react";
4
- import { Copy01Icon, Tick01Icon } from "@hugeicons/core-free-icons";
4
+ import { Copy01Icon, Tick01Icon, ArrowDown01Icon } from "@hugeicons/core-free-icons";
5
5
  import { codeToHtml } from "shiki";
6
6
  import type { CodeBlockProps } from "./types";
7
7
 
@@ -152,10 +152,18 @@ const CodeSection = memo(function CodeSection({
152
152
 
153
153
  const displayLanguage = language === "text" ? "plaintext" : language;
154
154
 
155
+ const handleToggle = useCallback(() => {
156
+ setIsExpanded((prev) => !prev);
157
+ }, []);
158
+
155
159
  const contentStyle: React.CSSProperties = {
156
160
  maxHeight: isExpanded ? `${contentHeight}px` : `${COLLAPSED_HEIGHT}px`,
157
161
  };
158
162
 
163
+ const chevronStyle: React.CSSProperties = {
164
+ transform: isExpanded ? "rotate(180deg)" : "rotate(0deg)",
165
+ };
166
+
159
167
  return (
160
168
  <Box position="relative">
161
169
  <Card size="1" variant="soft">
@@ -167,6 +175,18 @@ const CodeSection = memo(function CodeSection({
167
175
  </Code>
168
176
  )}
169
177
  <Flex align="center" gap="2" className="code-action-buttons">
178
+ {shouldShowToggle && (
179
+ <Button
180
+ size="2"
181
+ variant="ghost"
182
+ color="gray"
183
+ onClick={handleToggle}
184
+ tooltip={isExpanded ? "Collapse" : "Expand"}
185
+ aria-label={isExpanded ? "Collapse code" : "Expand code"}
186
+ >
187
+ <HugeiconsIcon icon={ArrowDown01Icon} style={chevronStyle} className="code-chevron" />
188
+ </Button>
189
+ )}
170
190
  {showCopy && (
171
191
  <Button
172
192
  size="2"
@@ -183,13 +203,15 @@ const CodeSection = memo(function CodeSection({
183
203
  </Flex>
184
204
 
185
205
  <Box ref={contentRef} style={contentStyle} className="code-content">
186
- {highlighted ? (
187
- <Box className="code-block-content" width="100%" style={{ minWidth: 0 }} dangerouslySetInnerHTML={{ __html: highlighted }} />
188
- ) : (
189
- <pre className="code-block-content">
190
- <Code size="3">{code}</Code>
191
- </pre>
192
- )}
206
+ <ScrollArea type="auto" scrollbars="horizontal">
207
+ {highlighted ? (
208
+ <Box dangerouslySetInnerHTML={{ __html: highlighted }} />
209
+ ) : (
210
+ <pre>
211
+ <Code size="3">{code}</Code>
212
+ </pre>
213
+ )}
214
+ </ScrollArea>
193
215
  </Box>
194
216
 
195
217
  {shouldShowToggle && !isExpanded && <Box className="code-scroll-shadow visible" />}
@@ -210,35 +232,53 @@ interface ChildrenCodeSectionProps {
210
232
  }
211
233
 
212
234
  function extractCodeFromChildren(children?: ReactNode): string {
213
- if (!children) return "";
214
- if (typeof children === "object" && children !== null && "props" in children) {
215
- const childProps = (children as any).props;
216
- if (childProps?.children && typeof childProps.children === "object") {
217
- const codeProps = (childProps.children as any).props;
218
- const codeChildren = codeProps?.children;
219
- if (typeof codeChildren === "string") return codeChildren;
235
+ const extractText = (node: any): string => {
236
+ if (typeof node === "string") return node;
237
+ if (typeof node === "number") return String(node);
238
+ if (!node) return "";
239
+ if (Array.isArray(node)) return node.map(extractText).join("");
240
+ if (typeof node === "object" && "props" in node) {
241
+ const props = node.props;
242
+ if (props?.children) return extractText(props.children);
220
243
  }
221
- if (typeof childProps?.children === "string") return childProps.children;
222
- }
223
- if (typeof children === "string") return children;
224
- return "";
244
+ return "";
245
+ };
246
+ return extractText(children);
225
247
  }
226
248
 
227
249
  function extractLanguageFromChildren(children?: ReactNode): string {
228
- if (!children) return "text";
229
- if (typeof children === "object" && children !== null && "props" in children) {
230
- const childProps = (children as any).props;
231
- if (childProps?.children && typeof childProps.children === "object") {
232
- const codeProps = (childProps.children as any).props;
233
- const className = codeProps?.className || "";
234
- const match = className.match(/language-([\w-]+)/i);
235
- if (match) return match[1];
250
+ const findLanguage = (node: any): string | null => {
251
+ if (!node) return null;
252
+ if (typeof node === "object" && "props" in node) {
253
+ const props = node.props;
254
+
255
+ // Check data-language attribute (rehype-pretty-code)
256
+ if (props?.["data-language"]) {
257
+ return props["data-language"];
258
+ }
259
+
260
+ // Check className for language-xxx
261
+ const className = props?.className || props?.class || "";
262
+ if (typeof className === "string") {
263
+ const match = className.match(/language-([\w-]+)/i);
264
+ if (match) return match[1];
265
+ }
266
+
267
+ // Recursively check children
268
+ if (props?.children) {
269
+ if (Array.isArray(props.children)) {
270
+ for (const child of props.children) {
271
+ const lang = findLanguage(child);
272
+ if (lang) return lang;
273
+ }
274
+ } else {
275
+ return findLanguage(props.children);
276
+ }
277
+ }
236
278
  }
237
- const className = childProps?.className || "";
238
- const match = className.match(/language-([\w-]+)/i);
239
- if (match) return match[1];
240
- }
241
- return "text";
279
+ return null;
280
+ };
281
+ return findLanguage(children) || "text";
242
282
  }
243
283
 
244
284
  function formatLanguageLabel(lang: string): string {
@@ -301,6 +341,14 @@ const ChildrenCodeSection = memo(function ChildrenCodeSection({ children, showCo
301
341
  maxHeight: isExpanded ? `${contentHeight}px` : `${COLLAPSED_HEIGHT}px`,
302
342
  };
303
343
 
344
+ const handleToggle = useCallback(() => {
345
+ setIsExpanded((prev) => !prev);
346
+ }, []);
347
+
348
+ const chevronStyle: React.CSSProperties = {
349
+ transform: isExpanded ? "rotate(180deg)" : "rotate(0deg)",
350
+ };
351
+
304
352
  return (
305
353
  <Box position="relative">
306
354
  <Card size="1" variant="soft">
@@ -312,6 +360,18 @@ const ChildrenCodeSection = memo(function ChildrenCodeSection({ children, showCo
312
360
  </Code>
313
361
  )}
314
362
  <Flex align="center" gap="2" className="code-action-buttons">
363
+ {shouldShowToggle && (
364
+ <Button
365
+ size="2"
366
+ variant="ghost"
367
+ color="gray"
368
+ onClick={handleToggle}
369
+ tooltip={isExpanded ? "Collapse" : "Expand"}
370
+ aria-label={isExpanded ? "Collapse code" : "Expand code"}
371
+ >
372
+ <HugeiconsIcon icon={ArrowDown01Icon} style={chevronStyle} className="code-chevron" />
373
+ </Button>
374
+ )}
315
375
  {showCopy && (
316
376
  <Button
317
377
  size="2"
@@ -328,7 +388,9 @@ const ChildrenCodeSection = memo(function ChildrenCodeSection({ children, showCo
328
388
  </Flex>
329
389
 
330
390
  <Box ref={contentRef} style={contentStyle} className="code-content">
331
- <div className="code-block-content">{children}</div>
391
+ <ScrollArea type="auto" scrollbars="horizontal">
392
+ {children}
393
+ </ScrollArea>
332
394
  </Box>
333
395
 
334
396
  {shouldShowToggle && !isExpanded && <Box className="code-scroll-shadow visible" />}
@@ -16,68 +16,15 @@
16
16
  position: relative;
17
17
  }
18
18
 
19
- /* Code block content (the pre part, below the header) */
20
- .code-block-content {
21
- width: 100%;
22
- min-width: 0;
23
- overflow-x: auto;
24
- /* Hide scrollbars while keeping scroll functionality */
25
- scrollbar-width: none; /* Firefox */
26
- -ms-overflow-style: none; /* IE/Edge */
27
- }
28
-
29
- /* Hide scrollbars for webkit browsers */
30
- .code-block-content::-webkit-scrollbar,
31
- .code-block-content::-webkit-scrollbar-horizontal,
32
- .code-block-content::-webkit-scrollbar-vertical,
33
- .code-block-content::-webkit-scrollbar-track,
34
- .code-block-content::-webkit-scrollbar-thumb,
35
- .code-block-content::-webkit-scrollbar-corner {
36
- display: none !important;
37
- width: 0 !important;
38
- height: 0 !important;
39
- }
40
-
41
- /* Also hide scrollbars on any pre/code elements inside code content */
42
- .code-block-content pre::-webkit-scrollbar,
43
- .code-block-content pre::-webkit-scrollbar-horizontal,
44
- .code-block-content pre::-webkit-scrollbar-vertical,
45
- .code-block-content pre::-webkit-scrollbar-track,
46
- .code-block-content pre::-webkit-scrollbar-thumb,
47
- .code-block-content pre::-webkit-scrollbar-corner,
48
- .code-block-content code::-webkit-scrollbar,
49
- .code-block-content code::-webkit-scrollbar-horizontal,
50
- .code-block-content code::-webkit-scrollbar-vertical,
51
- .code-block-content code::-webkit-scrollbar-track,
52
- .code-block-content code::-webkit-scrollbar-thumb,
53
- .code-block-content code::-webkit-scrollbar-corner {
54
- display: none !important;
55
- width: 0 !important;
56
- height: 0 !important;
57
- }
58
-
59
19
  /* Pre elements inside code content */
60
- .code-content pre,
61
- .code-block-content pre {
62
- overflow-x: visible;
63
- max-width: 100%;
64
- min-width: 0;
20
+ .code-content pre {
65
21
  margin: 0;
66
22
  width: 100%;
67
23
  box-sizing: border-box;
68
- scrollbar-width: none;
69
- -ms-overflow-style: none;
70
- }
71
-
72
- /* Ensure Shiki-generated pre elements fill width */
73
- .code-block-content > pre {
74
- width: 100% !important;
75
- min-width: 0;
76
24
  }
77
25
 
78
26
  /* Code elements inside pre */
79
- .code-content pre code,
80
- .code-block-content pre code {
27
+ .code-content pre code {
81
28
  font-family: var(--font-mono);
82
29
  font-size: var(--font-size-2);
83
30
  line-height: 1.75;
@@ -89,16 +36,14 @@
89
36
  }
90
37
 
91
38
  /* Shiki line spans */
92
- .code-content pre code .line,
93
- .code-block-content pre code .line {
39
+ .code-content pre code .line {
94
40
  display: flex;
95
41
  align-items: center;
96
42
  gap: 0;
97
43
  }
98
44
 
99
45
  /* Line numbers */
100
- .code-content pre code .line::before,
101
- .code-block-content pre code .line::before {
46
+ .code-content pre code .line::before {
102
47
  counter-increment: line;
103
48
  content: counter(line);
104
49
  display: inline-block;
@@ -140,7 +85,6 @@
140
85
  }
141
86
 
142
87
  /* Default to light theme for all tokens (codeToHtml with defaultColor: false) */
143
- .code-block-content pre.shiki span,
144
88
  .code-content pre.shiki span {
145
89
  color: var(--shiki-light) !important;
146
90
  font-style: var(--shiki-light-font-style);
@@ -149,9 +93,6 @@
149
93
  }
150
94
 
151
95
  /* Override with dark theme colors when inside a dark context */
152
- .dark .code-block-content pre.shiki span,
153
- .dark-theme .code-block-content pre.shiki span,
154
- [data-appearance="dark"] .code-block-content pre.shiki span,
155
96
  .dark .code-content pre.shiki span,
156
97
  .dark-theme .code-content pre.shiki span,
157
98
  [data-appearance="dark"] .code-content pre.shiki span {
package/styles.css CHANGED
@@ -13,63 +13,14 @@
13
13
  transition: max-height 0.3s ease-in-out;
14
14
  position: relative;
15
15
  }
16
- /* Code block content (the pre part, below the header) */
17
- .code-block-content {
18
- width: 100%;
19
- min-width: 0;
20
- overflow-x: auto;
21
- /* Hide scrollbars while keeping scroll functionality */
22
- scrollbar-width: none; /* Firefox */
23
- -ms-overflow-style: none; /* IE/Edge */
24
- }
25
- /* Hide scrollbars for webkit browsers */
26
- .code-block-content::-webkit-scrollbar,
27
- .code-block-content::-webkit-scrollbar-horizontal,
28
- .code-block-content::-webkit-scrollbar-vertical,
29
- .code-block-content::-webkit-scrollbar-track,
30
- .code-block-content::-webkit-scrollbar-thumb,
31
- .code-block-content::-webkit-scrollbar-corner {
32
- display: none !important;
33
- width: 0 !important;
34
- height: 0 !important;
35
- }
36
- /* Also hide scrollbars on any pre/code elements inside code content */
37
- .code-block-content pre::-webkit-scrollbar,
38
- .code-block-content pre::-webkit-scrollbar-horizontal,
39
- .code-block-content pre::-webkit-scrollbar-vertical,
40
- .code-block-content pre::-webkit-scrollbar-track,
41
- .code-block-content pre::-webkit-scrollbar-thumb,
42
- .code-block-content pre::-webkit-scrollbar-corner,
43
- .code-block-content code::-webkit-scrollbar,
44
- .code-block-content code::-webkit-scrollbar-horizontal,
45
- .code-block-content code::-webkit-scrollbar-vertical,
46
- .code-block-content code::-webkit-scrollbar-track,
47
- .code-block-content code::-webkit-scrollbar-thumb,
48
- .code-block-content code::-webkit-scrollbar-corner {
49
- display: none !important;
50
- width: 0 !important;
51
- height: 0 !important;
52
- }
53
16
  /* Pre elements inside code content */
54
- .code-content pre,
55
- .code-block-content pre {
56
- overflow-x: visible;
57
- max-width: 100%;
58
- min-width: 0;
17
+ .code-content pre {
59
18
  margin: 0;
60
19
  width: 100%;
61
20
  box-sizing: border-box;
62
- scrollbar-width: none;
63
- -ms-overflow-style: none;
64
- }
65
- /* Ensure Shiki-generated pre elements fill width */
66
- .code-block-content > pre {
67
- width: 100% !important;
68
- min-width: 0;
69
21
  }
70
22
  /* Code elements inside pre */
71
- .code-content pre code,
72
- .code-block-content pre code {
23
+ .code-content pre code {
73
24
  font-family: var(--font-mono);
74
25
  font-size: var(--font-size-2);
75
26
  line-height: 1.75;
@@ -80,15 +31,13 @@
80
31
  counter-reset: line;
81
32
  }
82
33
  /* Shiki line spans */
83
- .code-content pre code .line,
84
- .code-block-content pre code .line {
34
+ .code-content pre code .line {
85
35
  display: flex;
86
36
  align-items: center;
87
37
  gap: 0;
88
38
  }
89
39
  /* Line numbers */
90
- .code-content pre code .line::before,
91
- .code-block-content pre code .line::before {
40
+ .code-content pre code .line::before {
92
41
  counter-increment: line;
93
42
  content: counter(line);
94
43
  display: inline-block;
@@ -127,7 +76,6 @@
127
76
  transition: transform 0.2s ease-in-out;
128
77
  }
129
78
  /* Default to light theme for all tokens (codeToHtml with defaultColor: false) */
130
- .code-block-content pre.shiki span,
131
79
  .code-content pre.shiki span {
132
80
  color: var(--shiki-light) !important;
133
81
  font-style: var(--shiki-light-font-style);
@@ -136,9 +84,6 @@
136
84
  text-decoration: var(--shiki-light-text-decoration);
137
85
  }
138
86
  /* Override with dark theme colors when inside a dark context */
139
- .dark .code-block-content pre.shiki span,
140
- .dark-theme .code-block-content pre.shiki span,
141
- [data-appearance="dark"] .code-block-content pre.shiki span,
142
87
  .dark .code-content pre.shiki span,
143
88
  .dark-theme .code-content pre.shiki span,
144
89
  [data-appearance="dark"] .code-content pre.shiki span {