@bergetai/ui 0.17.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/components/code-block/CodeBlock.cjs +50 -48
  2. package/dist/components/code-block/CodeBlock.cjs.map +1 -1
  3. package/dist/components/code-block/CodeBlock.d.cts +27 -7
  4. package/dist/components/code-block/CodeBlock.d.cts.map +1 -1
  5. package/dist/components/code-block/CodeBlock.d.mts +27 -7
  6. package/dist/components/code-block/CodeBlock.d.mts.map +1 -1
  7. package/dist/components/code-block/CodeBlock.mjs +45 -50
  8. package/dist/components/code-block/CodeBlock.mjs.map +1 -1
  9. package/dist/components/code-block/index.d.cts +3 -0
  10. package/dist/components/code-block/index.d.mts +3 -0
  11. package/dist/components/container/Container.d.cts +2 -2
  12. package/dist/components/container/Container.d.mts +2 -2
  13. package/dist/hooks/use-highlighted-code.cjs +58 -0
  14. package/dist/hooks/use-highlighted-code.cjs.map +1 -0
  15. package/dist/hooks/use-highlighted-code.d.cts +5 -0
  16. package/dist/hooks/use-highlighted-code.d.cts.map +1 -0
  17. package/dist/hooks/use-highlighted-code.d.mts +5 -0
  18. package/dist/hooks/use-highlighted-code.d.mts.map +1 -0
  19. package/dist/hooks/use-highlighted-code.mjs +56 -0
  20. package/dist/hooks/use-highlighted-code.mjs.map +1 -0
  21. package/dist/index.cjs +10 -0
  22. package/dist/index.d.cts +5 -2
  23. package/dist/index.d.mts +5 -2
  24. package/dist/index.mjs +4 -2
  25. package/dist/lib/highlighter.cjs +81 -0
  26. package/dist/lib/highlighter.cjs.map +1 -0
  27. package/dist/lib/highlighter.mjs +79 -0
  28. package/dist/lib/highlighter.mjs.map +1 -0
  29. package/dist/primitives/button.d.cts +1 -1
  30. package/dist/primitives/button.d.mts +1 -1
  31. package/dist/primitives/code-block.cjs +133 -0
  32. package/dist/primitives/code-block.cjs.map +1 -0
  33. package/dist/primitives/code-block.d.cts +29 -0
  34. package/dist/primitives/code-block.d.cts.map +1 -0
  35. package/dist/primitives/code-block.d.mts +29 -0
  36. package/dist/primitives/code-block.d.mts.map +1 -0
  37. package/dist/primitives/code-block.mjs +124 -0
  38. package/dist/primitives/code-block.mjs.map +1 -0
  39. package/dist/styles/index.css +32 -0
  40. package/package.json +2 -1
@@ -1,61 +1,63 @@
1
1
  "use client";
2
2
  const require_utils = require("../../lib/utils.cjs");
3
- const require_shiki = require("../../lib/shiki.cjs");
4
- let react = require("react");
3
+ const require_code_block = require("../../primitives/code-block.cjs");
5
4
  let react_jsx_runtime = require("react/jsx-runtime");
6
- let lucide_react = require("lucide-react");
7
5
  //#region src/components/code-block/CodeBlock.tsx
8
- function CodeBlock({ code, language = "text", title, className }) {
9
- const [html, setHtml] = (0, react.useState)(null);
10
- const [copied, setCopied] = (0, react.useState)(false);
11
- (0, react.useEffect)(() => {
12
- require_shiki.getHighlighter().then((highlighter) => {
13
- const lang = highlighter.getLoadedLanguages().includes(language) ? language : "text";
14
- setHtml(highlighter.codeToHtml(code, {
15
- lang,
16
- theme: "berget"
17
- }));
18
- });
19
- }, [code, language]);
20
- const handleCopy = (0, react.useCallback)(async () => {
21
- await navigator.clipboard.writeText(code);
22
- setCopied(true);
23
- setTimeout(() => setCopied(false), 2e3);
24
- }, [code]);
25
- const copyButton = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
26
- onClick: handleCopy,
27
- className: "\n flex size-6 items-center justify-center text-berget-muted-foreground\n transition-colors\n hover:text-berget-foreground\n ",
28
- "aria-label": "Copy code",
29
- children: copied ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Check, { className: "size-3.5" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Copy, { className: "size-3.5" })
6
+ /**
7
+ * Compound code block built on the shadcn base `code-block` primitive. The
8
+ * parts add Berget styling and nothing else — compose them the way shadcn
9
+ * documents (ui.shadcn.com/docs/components/base/code-block):
10
+ *
11
+ * <CodeBlock>
12
+ * <CodeBlockHeader>
13
+ * <CodeBlockTitle>file.ts</CodeBlockTitle>
14
+ * <CodeBlockActions>
15
+ * <CodeBlockCopyButton value={code} />
16
+ * </CodeBlockActions>
17
+ * </CodeBlockHeader>
18
+ * <CodeBlockContent wrap lineNumbers>
19
+ * {code}
20
+ * </CodeBlockContent>
21
+ * </CodeBlock>
22
+ *
23
+ * For syntax highlighting, pass `useHighlightedCode(code, language)` output
24
+ * through `CodeBlockLine` elements. Highlighting is optional; a string child
25
+ * renders as plain text.
26
+ */
27
+ function CodeBlock({ className, ...props }) {
28
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_code_block.CodeBlock, {
29
+ className: require_utils.cn(`
30
+ rounded-berget-xs border-berget-border bg-berget-codeblock-bg
31
+ backdrop-blur-md
32
+ dark:bg-berget-codeblock-bg
33
+ `, className),
34
+ ...props
30
35
  });
31
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
36
+ }
37
+ function CodeBlockHeader({ className, ...props }) {
38
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_code_block.CodeBlockHeader, {
32
39
  className: require_utils.cn(`
33
- relative isolate overflow-hidden rounded-berget-xs border
34
- border-berget-border bg-berget-codeblock-bg backdrop-blur-md
40
+ h-10 shrink-0 gap-2 border-b border-berget-border
41
+ bg-berget-codeblock-header-bg px-4 pt-0
42
+ dark:bg-berget-codeblock-header-bg
35
43
  `, className),
36
- children: [
37
- title && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
38
- className: "\n flex h-10! items-center border-b border-berget-border\n bg-berget-codeblock-header-bg px-4! text-xs/normal!\n ",
39
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
40
- className: "text-berget-muted-foreground",
41
- children: title
42
- })
43
- }),
44
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
45
- className: "absolute top-2 right-2 z-10",
46
- children: copyButton
47
- }),
48
- html ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
49
- className: "\n [&_.shiki]:m-0! [&_.shiki]:overflow-x-auto [&_.shiki]:bg-transparent\n [&_.shiki]:p-4! [&_.shiki]:text-caption/relaxed!\n ",
50
- dangerouslySetInnerHTML: { __html: html }
51
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
52
- className: "\n m-0! overflow-x-auto p-4! text-caption/relaxed!\n text-berget-muted-foreground\n ",
53
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: code })
54
- })
55
- ]
44
+ ...props
45
+ });
46
+ }
47
+ function CodeBlockTitle({ className, ...props }) {
48
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_code_block.CodeBlockTitle, {
49
+ className: require_utils.cn("text-berget-muted-foreground", className),
50
+ ...props
56
51
  });
57
52
  }
58
53
  //#endregion
59
54
  exports.CodeBlock = CodeBlock;
55
+ exports.CodeBlockActions = require_code_block.CodeBlockActions;
56
+ exports.CodeBlockContent = require_code_block.CodeBlockContent;
57
+ exports.CodeBlockCopyButton = require_code_block.CodeBlockCopyButton;
58
+ exports.CodeBlockFooter = require_code_block.CodeBlockFooter;
59
+ exports.CodeBlockHeader = CodeBlockHeader;
60
+ exports.CodeBlockLine = require_code_block.CodeBlockLine;
61
+ exports.CodeBlockTitle = CodeBlockTitle;
60
62
 
61
63
  //# sourceMappingURL=CodeBlock.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"CodeBlock.cjs","names":["useState","useCallback","Check","Copy","cn"],"sources":["../../../src/components/code-block/CodeBlock.tsx"],"sourcesContent":["'use client';\n\nimport { useState, useEffect, useCallback } from 'react';\nimport { Copy, Check } from 'lucide-react';\nimport { cn } from '../../lib/utils';\nimport { getHighlighter } from '../../lib/shiki';\n\nexport interface CodeBlockProps {\n code: string;\n language?: string;\n title?: string;\n className?: string;\n}\n\nexport function CodeBlock({ code, language = 'text', title, className }: CodeBlockProps) {\n const [html, setHtml] = useState<string | null>(null);\n const [copied, setCopied] = useState(false);\n\n useEffect(() => {\n getHighlighter().then((highlighter) => {\n const loadedLangs = highlighter.getLoadedLanguages();\n const lang = loadedLangs.includes(language) ? language : 'text';\n setHtml(highlighter.codeToHtml(code, { lang, theme: 'berget' }));\n });\n }, [code, language]);\n\n const handleCopy = useCallback(async () => {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n }, [code]);\n\n const copyButton = (\n <button\n onClick={handleCopy}\n className=\"\n flex size-6 items-center justify-center text-berget-muted-foreground\n transition-colors\n hover:text-berget-foreground\n \"\n aria-label=\"Copy code\"\n >\n {copied ? <Check className=\"size-3.5\" /> : <Copy className=\"size-3.5\" />}\n </button>\n );\n\n return (\n <div\n className={cn(\n `\n relative isolate overflow-hidden rounded-berget-xs border\n border-berget-border bg-berget-codeblock-bg backdrop-blur-md\n `,\n className,\n )}\n >\n {title && (\n <div\n className=\"\n flex h-10! items-center border-b border-berget-border\n bg-berget-codeblock-header-bg px-4! text-xs/normal!\n \"\n >\n <span className=\"text-berget-muted-foreground\">{title}</span>\n </div>\n )}\n <div className=\"absolute top-2 right-2 z-10\">{copyButton}</div>\n {html ? (\n <div\n className=\"\n [&_.shiki]:m-0! [&_.shiki]:overflow-x-auto [&_.shiki]:bg-transparent\n [&_.shiki]:p-4! [&_.shiki]:text-caption/relaxed!\n \"\n dangerouslySetInnerHTML={{ __html: html }}\n />\n ) : (\n <pre\n className=\"\n m-0! overflow-x-auto p-4! text-caption/relaxed!\n text-berget-muted-foreground\n \"\n >\n <code>{code}</code>\n </pre>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;AAcA,SAAgB,UAAU,EAAE,MAAM,WAAW,QAAQ,OAAO,aAA6B;CACvF,MAAM,CAAC,MAAM,YAAA,GAAWA,MAAAA,SAAAA,CAAwB,IAAI;CACpD,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,CAAS,KAAK;CAE1C,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,cAAA,eAAe,CAAC,CAAC,MAAM,gBAAgB;GAErC,MAAM,OADc,YAAY,mBACT,CAAC,CAAC,SAAS,QAAQ,IAAI,WAAW;GACzD,QAAQ,YAAY,WAAW,MAAM;IAAE;IAAM,OAAO;GAAS,CAAC,CAAC;EACjE,CAAC;CACH,GAAG,CAAC,MAAM,QAAQ,CAAC;CAEnB,MAAM,cAAA,GAAaC,MAAAA,YAAAA,CAAY,YAAY;EACzC,MAAM,UAAU,UAAU,UAAU,IAAI;EACxC,UAAU,IAAI;EACd,iBAAiB,UAAU,KAAK,GAAG,GAAI;CACzC,GAAG,CAAC,IAAI,CAAC;CAET,MAAM,aACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;EACE,SAAS;EACT,WAAU;EAKV,cAAW;EAEV,UAAA,SAAS,iBAAA,GAAA,kBAAA,IAAA,CAACC,aAAAA,OAAD,EAAO,WAAU,WAAY,CAAA,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAACC,aAAAA,MAAD,EAAM,WAAU,WAAY,CAAA;CACjE,CAAA;CAGV,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;EACE,WAAWC,cAAAA,GACT;;;WAIA,SACF;EAPF,UAAA;GASG,SACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IACE,WAAU;IAKV,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAU;KAAgC,UAAA;IAAY,CAAA;GACzD,CAAA;GAEP,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAU;IAA+B,UAAA;GAAgB,CAAA;GAC7D,OACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IACE,WAAU;IAIV,yBAAyB,EAAE,QAAQ,KAAK;GACzC,CAAA,IAED,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IACE,WAAU;IAKV,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAO,KAAW,CAAA;GACf,CAAA;EAEJ;;AAET"}
1
+ {"version":3,"file":"CodeBlock.cjs","names":["CodeBlockPrimitive","cn","CodeBlockHeaderPrimitive","CodeBlockTitlePrimitive"],"sources":["../../../src/components/code-block/CodeBlock.tsx"],"sourcesContent":["'use client';\n\nimport type { ComponentProps } from 'react';\nimport {\n CodeBlock as CodeBlockPrimitive,\n CodeBlockHeader as CodeBlockHeaderPrimitive,\n CodeBlockTitle as CodeBlockTitlePrimitive,\n} from '../../primitives/code-block';\nimport { cn } from '../../lib/utils';\n\n/**\n * Compound code block built on the shadcn base `code-block` primitive. The\n * parts add Berget styling and nothing else — compose them the way shadcn\n * documents (ui.shadcn.com/docs/components/base/code-block):\n *\n * <CodeBlock>\n * <CodeBlockHeader>\n * <CodeBlockTitle>file.ts</CodeBlockTitle>\n * <CodeBlockActions>\n * <CodeBlockCopyButton value={code} />\n * </CodeBlockActions>\n * </CodeBlockHeader>\n * <CodeBlockContent wrap lineNumbers>\n * {code}\n * </CodeBlockContent>\n * </CodeBlock>\n *\n * For syntax highlighting, pass `useHighlightedCode(code, language)` output\n * through `CodeBlockLine` elements. Highlighting is optional; a string child\n * renders as plain text.\n */\n\nexport function CodeBlock({ className, ...props }: ComponentProps<typeof CodeBlockPrimitive>) {\n return (\n <CodeBlockPrimitive\n className={cn(\n `\n rounded-berget-xs border-berget-border bg-berget-codeblock-bg\n backdrop-blur-md\n dark:bg-berget-codeblock-bg\n `,\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function CodeBlockHeader({\n className,\n ...props\n}: ComponentProps<typeof CodeBlockHeaderPrimitive>) {\n return (\n <CodeBlockHeaderPrimitive\n className={cn(\n `\n h-10 shrink-0 gap-2 border-b border-berget-border\n bg-berget-codeblock-header-bg px-4 pt-0\n dark:bg-berget-codeblock-header-bg\n `,\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function CodeBlockTitle({\n className,\n ...props\n}: ComponentProps<typeof CodeBlockTitlePrimitive>) {\n return (\n <CodeBlockTitlePrimitive className={cn('text-berget-muted-foreground', className)} {...props} />\n );\n}\n\nexport {\n CodeBlockActions,\n CodeBlockContent,\n CodeBlockCopyButton,\n CodeBlockFooter,\n CodeBlockLine,\n} from '../../primitives/code-block';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,SAAgB,UAAU,EAAE,WAAW,GAAG,SAAoD;CAC5F,OACE,iBAAA,GAAA,kBAAA,IAAA,CAACA,mBAAAA,WAAD;EACE,WAAWC,cAAAA,GACT;;;;WAKA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAgB,gBAAgB,EAC9B,WACA,GAAG,SAC+C;CAClD,OACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,mBAAAA,iBAAD;EACE,WAAWD,cAAAA,GACT;;;;WAKA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAgB,eAAe,EAC7B,WACA,GAAG,SAC8C;CACjD,OACE,iBAAA,GAAA,kBAAA,IAAA,CAACE,mBAAAA,gBAAD;EAAyB,WAAWF,cAAAA,GAAG,gCAAgC,SAAS;EAAG,GAAI;CAAQ,CAAA;AAEnG"}
@@ -1,10 +1,30 @@
1
+ import { CodeBlock as CodeBlock$1, CodeBlockActions, CodeBlockContent, CodeBlockCopyButton, CodeBlockFooter, CodeBlockHeader as CodeBlockHeader$1, CodeBlockLine, CodeBlockTitle as CodeBlockTitle$1 } from "../../primitives/code-block.cjs";
2
+ import { ComponentProps } from "react";
1
3
  //#region src/components/code-block/CodeBlock.d.ts
2
- export interface CodeBlockProps {
3
- code: string;
4
- language?: string;
5
- title?: string;
6
- className?: string;
7
- }
8
- export declare function CodeBlock({ code, language, title, className }: CodeBlockProps): import("react/jsx-runtime").JSX.Element;
4
+ /**
5
+ * Compound code block built on the shadcn base `code-block` primitive. The
6
+ * parts add Berget styling and nothing else — compose them the way shadcn
7
+ * documents (ui.shadcn.com/docs/components/base/code-block):
8
+ *
9
+ * <CodeBlock>
10
+ * <CodeBlockHeader>
11
+ * <CodeBlockTitle>file.ts</CodeBlockTitle>
12
+ * <CodeBlockActions>
13
+ * <CodeBlockCopyButton value={code} />
14
+ * </CodeBlockActions>
15
+ * </CodeBlockHeader>
16
+ * <CodeBlockContent wrap lineNumbers>
17
+ * {code}
18
+ * </CodeBlockContent>
19
+ * </CodeBlock>
20
+ *
21
+ * For syntax highlighting, pass `useHighlightedCode(code, language)` output
22
+ * through `CodeBlockLine` elements. Highlighting is optional; a string child
23
+ * renders as plain text.
24
+ */
25
+ export declare function CodeBlock({ className, ...props }: ComponentProps<typeof CodeBlock$1>): import("react/jsx-runtime").JSX.Element;
26
+ export declare function CodeBlockHeader({ className, ...props }: ComponentProps<typeof CodeBlockHeader$1>): import("react/jsx-runtime").JSX.Element;
27
+ export declare function CodeBlockTitle({ className, ...props }: ComponentProps<typeof CodeBlockTitle$1>): import("react/jsx-runtime").JSX.Element;
9
28
  //#endregion
29
+ export { CodeBlockActions, CodeBlockContent, CodeBlockCopyButton, CodeBlockFooter, CodeBlockLine };
10
30
  //# sourceMappingURL=CodeBlock.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CodeBlock.d.cts","names":[],"sources":["../../../src/components/code-block/CodeBlock.tsx"],"mappings":";iBAOiB;EACf;EACA;EACA;EACA;;wBAGc,YAAY,MAAM,UAAmB,OAAO,aAAa,6CAAc,IAAA"}
1
+ {"version":3,"file":"CodeBlock.d.cts","names":["CodeBlockPrimitive","CodeBlockHeaderPrimitive","CodeBlockTitlePrimitive"],"sources":["../../../src/components/code-block/CodeBlock.tsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;wBAgCgB,YAAY,cAAc,SAAS,sBAAsBA,2CAAmB,IAAA;wBAgB5E,kBACd,cACG,SACF,sBAAsBC,iDAAyB,IAAA;wBAgBlC,iBACd,cACG,SACF,sBAAsBC,gDAAwB,IAAA"}
@@ -1,10 +1,30 @@
1
+ import { CodeBlock as CodeBlock$1, CodeBlockActions, CodeBlockContent, CodeBlockCopyButton, CodeBlockFooter, CodeBlockHeader as CodeBlockHeader$1, CodeBlockLine, CodeBlockTitle as CodeBlockTitle$1 } from "../../primitives/code-block.mjs";
2
+ import { ComponentProps } from "react";
1
3
  //#region src/components/code-block/CodeBlock.d.ts
2
- export interface CodeBlockProps {
3
- code: string;
4
- language?: string;
5
- title?: string;
6
- className?: string;
7
- }
8
- export declare function CodeBlock({ code, language, title, className }: CodeBlockProps): import("react/jsx-runtime").JSX.Element;
4
+ /**
5
+ * Compound code block built on the shadcn base `code-block` primitive. The
6
+ * parts add Berget styling and nothing else — compose them the way shadcn
7
+ * documents (ui.shadcn.com/docs/components/base/code-block):
8
+ *
9
+ * <CodeBlock>
10
+ * <CodeBlockHeader>
11
+ * <CodeBlockTitle>file.ts</CodeBlockTitle>
12
+ * <CodeBlockActions>
13
+ * <CodeBlockCopyButton value={code} />
14
+ * </CodeBlockActions>
15
+ * </CodeBlockHeader>
16
+ * <CodeBlockContent wrap lineNumbers>
17
+ * {code}
18
+ * </CodeBlockContent>
19
+ * </CodeBlock>
20
+ *
21
+ * For syntax highlighting, pass `useHighlightedCode(code, language)` output
22
+ * through `CodeBlockLine` elements. Highlighting is optional; a string child
23
+ * renders as plain text.
24
+ */
25
+ export declare function CodeBlock({ className, ...props }: ComponentProps<typeof CodeBlock$1>): import("react/jsx-runtime").JSX.Element;
26
+ export declare function CodeBlockHeader({ className, ...props }: ComponentProps<typeof CodeBlockHeader$1>): import("react/jsx-runtime").JSX.Element;
27
+ export declare function CodeBlockTitle({ className, ...props }: ComponentProps<typeof CodeBlockTitle$1>): import("react/jsx-runtime").JSX.Element;
9
28
  //#endregion
29
+ export { CodeBlockActions, CodeBlockContent, CodeBlockCopyButton, CodeBlockFooter, CodeBlockLine };
10
30
  //# sourceMappingURL=CodeBlock.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CodeBlock.d.mts","names":[],"sources":["../../../src/components/code-block/CodeBlock.tsx"],"mappings":";iBAOiB;EACf;EACA;EACA;EACA;;wBAGc,YAAY,MAAM,UAAmB,OAAO,aAAa,6CAAc,IAAA"}
1
+ {"version":3,"file":"CodeBlock.d.mts","names":["CodeBlockPrimitive","CodeBlockHeaderPrimitive","CodeBlockTitlePrimitive"],"sources":["../../../src/components/code-block/CodeBlock.tsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;wBAgCgB,YAAY,cAAc,SAAS,sBAAsBA,2CAAmB,IAAA;wBAgB5E,kBACd,cACG,SACF,sBAAsBC,iDAAyB,IAAA;wBAgBlC,iBACd,cACG,SACF,sBAAsBC,gDAAwB,IAAA"}
@@ -1,61 +1,56 @@
1
1
  "use client";
2
2
  import { cn } from "../../lib/utils.mjs";
3
- import { getHighlighter } from "../../lib/shiki.mjs";
4
- import { useCallback, useEffect, useState } from "react";
5
- import { jsx, jsxs } from "react/jsx-runtime";
6
- import { Check, Copy } from "lucide-react";
3
+ import { CodeBlock as CodeBlock$1, CodeBlockActions, CodeBlockContent, CodeBlockCopyButton, CodeBlockFooter, CodeBlockHeader as CodeBlockHeader$1, CodeBlockLine, CodeBlockTitle as CodeBlockTitle$1 } from "../../primitives/code-block.mjs";
4
+ import { jsx } from "react/jsx-runtime";
7
5
  //#region src/components/code-block/CodeBlock.tsx
8
- function CodeBlock({ code, language = "text", title, className }) {
9
- const [html, setHtml] = useState(null);
10
- const [copied, setCopied] = useState(false);
11
- useEffect(() => {
12
- getHighlighter().then((highlighter) => {
13
- const lang = highlighter.getLoadedLanguages().includes(language) ? language : "text";
14
- setHtml(highlighter.codeToHtml(code, {
15
- lang,
16
- theme: "berget"
17
- }));
18
- });
19
- }, [code, language]);
20
- const handleCopy = useCallback(async () => {
21
- await navigator.clipboard.writeText(code);
22
- setCopied(true);
23
- setTimeout(() => setCopied(false), 2e3);
24
- }, [code]);
25
- const copyButton = /* @__PURE__ */ jsx("button", {
26
- onClick: handleCopy,
27
- className: "\n flex size-6 items-center justify-center text-berget-muted-foreground\n transition-colors\n hover:text-berget-foreground\n ",
28
- "aria-label": "Copy code",
29
- children: copied ? /* @__PURE__ */ jsx(Check, { className: "size-3.5" }) : /* @__PURE__ */ jsx(Copy, { className: "size-3.5" })
6
+ /**
7
+ * Compound code block built on the shadcn base `code-block` primitive. The
8
+ * parts add Berget styling and nothing else — compose them the way shadcn
9
+ * documents (ui.shadcn.com/docs/components/base/code-block):
10
+ *
11
+ * <CodeBlock>
12
+ * <CodeBlockHeader>
13
+ * <CodeBlockTitle>file.ts</CodeBlockTitle>
14
+ * <CodeBlockActions>
15
+ * <CodeBlockCopyButton value={code} />
16
+ * </CodeBlockActions>
17
+ * </CodeBlockHeader>
18
+ * <CodeBlockContent wrap lineNumbers>
19
+ * {code}
20
+ * </CodeBlockContent>
21
+ * </CodeBlock>
22
+ *
23
+ * For syntax highlighting, pass `useHighlightedCode(code, language)` output
24
+ * through `CodeBlockLine` elements. Highlighting is optional; a string child
25
+ * renders as plain text.
26
+ */
27
+ function CodeBlock({ className, ...props }) {
28
+ return /* @__PURE__ */ jsx(CodeBlock$1, {
29
+ className: cn(`
30
+ rounded-berget-xs border-berget-border bg-berget-codeblock-bg
31
+ backdrop-blur-md
32
+ dark:bg-berget-codeblock-bg
33
+ `, className),
34
+ ...props
30
35
  });
31
- return /* @__PURE__ */ jsxs("div", {
36
+ }
37
+ function CodeBlockHeader({ className, ...props }) {
38
+ return /* @__PURE__ */ jsx(CodeBlockHeader$1, {
32
39
  className: cn(`
33
- relative isolate overflow-hidden rounded-berget-xs border
34
- border-berget-border bg-berget-codeblock-bg backdrop-blur-md
40
+ h-10 shrink-0 gap-2 border-b border-berget-border
41
+ bg-berget-codeblock-header-bg px-4 pt-0
42
+ dark:bg-berget-codeblock-header-bg
35
43
  `, className),
36
- children: [
37
- title && /* @__PURE__ */ jsx("div", {
38
- className: "\n flex h-10! items-center border-b border-berget-border\n bg-berget-codeblock-header-bg px-4! text-xs/normal!\n ",
39
- children: /* @__PURE__ */ jsx("span", {
40
- className: "text-berget-muted-foreground",
41
- children: title
42
- })
43
- }),
44
- /* @__PURE__ */ jsx("div", {
45
- className: "absolute top-2 right-2 z-10",
46
- children: copyButton
47
- }),
48
- html ? /* @__PURE__ */ jsx("div", {
49
- className: "\n [&_.shiki]:m-0! [&_.shiki]:overflow-x-auto [&_.shiki]:bg-transparent\n [&_.shiki]:p-4! [&_.shiki]:text-caption/relaxed!\n ",
50
- dangerouslySetInnerHTML: { __html: html }
51
- }) : /* @__PURE__ */ jsx("pre", {
52
- className: "\n m-0! overflow-x-auto p-4! text-caption/relaxed!\n text-berget-muted-foreground\n ",
53
- children: /* @__PURE__ */ jsx("code", { children: code })
54
- })
55
- ]
44
+ ...props
45
+ });
46
+ }
47
+ function CodeBlockTitle({ className, ...props }) {
48
+ return /* @__PURE__ */ jsx(CodeBlockTitle$1, {
49
+ className: cn("text-berget-muted-foreground", className),
50
+ ...props
56
51
  });
57
52
  }
58
53
  //#endregion
59
- export { CodeBlock };
54
+ export { CodeBlock, CodeBlockActions, CodeBlockContent, CodeBlockCopyButton, CodeBlockFooter, CodeBlockHeader, CodeBlockLine, CodeBlockTitle };
60
55
 
61
56
  //# sourceMappingURL=CodeBlock.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"CodeBlock.mjs","names":[],"sources":["../../../src/components/code-block/CodeBlock.tsx"],"sourcesContent":["'use client';\n\nimport { useState, useEffect, useCallback } from 'react';\nimport { Copy, Check } from 'lucide-react';\nimport { cn } from '../../lib/utils';\nimport { getHighlighter } from '../../lib/shiki';\n\nexport interface CodeBlockProps {\n code: string;\n language?: string;\n title?: string;\n className?: string;\n}\n\nexport function CodeBlock({ code, language = 'text', title, className }: CodeBlockProps) {\n const [html, setHtml] = useState<string | null>(null);\n const [copied, setCopied] = useState(false);\n\n useEffect(() => {\n getHighlighter().then((highlighter) => {\n const loadedLangs = highlighter.getLoadedLanguages();\n const lang = loadedLangs.includes(language) ? language : 'text';\n setHtml(highlighter.codeToHtml(code, { lang, theme: 'berget' }));\n });\n }, [code, language]);\n\n const handleCopy = useCallback(async () => {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n }, [code]);\n\n const copyButton = (\n <button\n onClick={handleCopy}\n className=\"\n flex size-6 items-center justify-center text-berget-muted-foreground\n transition-colors\n hover:text-berget-foreground\n \"\n aria-label=\"Copy code\"\n >\n {copied ? <Check className=\"size-3.5\" /> : <Copy className=\"size-3.5\" />}\n </button>\n );\n\n return (\n <div\n className={cn(\n `\n relative isolate overflow-hidden rounded-berget-xs border\n border-berget-border bg-berget-codeblock-bg backdrop-blur-md\n `,\n className,\n )}\n >\n {title && (\n <div\n className=\"\n flex h-10! items-center border-b border-berget-border\n bg-berget-codeblock-header-bg px-4! text-xs/normal!\n \"\n >\n <span className=\"text-berget-muted-foreground\">{title}</span>\n </div>\n )}\n <div className=\"absolute top-2 right-2 z-10\">{copyButton}</div>\n {html ? (\n <div\n className=\"\n [&_.shiki]:m-0! [&_.shiki]:overflow-x-auto [&_.shiki]:bg-transparent\n [&_.shiki]:p-4! [&_.shiki]:text-caption/relaxed!\n \"\n dangerouslySetInnerHTML={{ __html: html }}\n />\n ) : (\n <pre\n className=\"\n m-0! overflow-x-auto p-4! text-caption/relaxed!\n text-berget-muted-foreground\n \"\n >\n <code>{code}</code>\n </pre>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;AAcA,SAAgB,UAAU,EAAE,MAAM,WAAW,QAAQ,OAAO,aAA6B;CACvF,MAAM,CAAC,MAAM,WAAW,SAAwB,IAAI;CACpD,MAAM,CAAC,QAAQ,aAAa,SAAS,KAAK;CAE1C,gBAAgB;EACd,eAAe,CAAC,CAAC,MAAM,gBAAgB;GAErC,MAAM,OADc,YAAY,mBACT,CAAC,CAAC,SAAS,QAAQ,IAAI,WAAW;GACzD,QAAQ,YAAY,WAAW,MAAM;IAAE;IAAM,OAAO;GAAS,CAAC,CAAC;EACjE,CAAC;CACH,GAAG,CAAC,MAAM,QAAQ,CAAC;CAEnB,MAAM,aAAa,YAAY,YAAY;EACzC,MAAM,UAAU,UAAU,UAAU,IAAI;EACxC,UAAU,IAAI;EACd,iBAAiB,UAAU,KAAK,GAAG,GAAI;CACzC,GAAG,CAAC,IAAI,CAAC;CAET,MAAM,aACJ,oBAAC,UAAD;EACE,SAAS;EACT,WAAU;EAKV,cAAW;EAEV,UAAA,SAAS,oBAAC,OAAD,EAAO,WAAU,WAAY,CAAA,IAAI,oBAAC,MAAD,EAAM,WAAU,WAAY,CAAA;CACjE,CAAA;CAGV,OACE,qBAAC,OAAD;EACE,WAAW,GACT;;;WAIA,SACF;EAPF,UAAA;GASG,SACC,oBAAC,OAAD;IACE,WAAU;IAKV,UAAA,oBAAC,QAAD;KAAM,WAAU;KAAgC,UAAA;IAAY,CAAA;GACzD,CAAA;GAEP,oBAAC,OAAD;IAAK,WAAU;IAA+B,UAAA;GAAgB,CAAA;GAC7D,OACC,oBAAC,OAAD;IACE,WAAU;IAIV,yBAAyB,EAAE,QAAQ,KAAK;GACzC,CAAA,IAED,oBAAC,OAAD;IACE,WAAU;IAKV,UAAA,oBAAC,QAAD,EAAA,UAAO,KAAW,CAAA;GACf,CAAA;EAEJ;;AAET"}
1
+ {"version":3,"file":"CodeBlock.mjs","names":["CodeBlockPrimitive","CodeBlockHeaderPrimitive","CodeBlockTitlePrimitive"],"sources":["../../../src/components/code-block/CodeBlock.tsx"],"sourcesContent":["'use client';\n\nimport type { ComponentProps } from 'react';\nimport {\n CodeBlock as CodeBlockPrimitive,\n CodeBlockHeader as CodeBlockHeaderPrimitive,\n CodeBlockTitle as CodeBlockTitlePrimitive,\n} from '../../primitives/code-block';\nimport { cn } from '../../lib/utils';\n\n/**\n * Compound code block built on the shadcn base `code-block` primitive. The\n * parts add Berget styling and nothing else — compose them the way shadcn\n * documents (ui.shadcn.com/docs/components/base/code-block):\n *\n * <CodeBlock>\n * <CodeBlockHeader>\n * <CodeBlockTitle>file.ts</CodeBlockTitle>\n * <CodeBlockActions>\n * <CodeBlockCopyButton value={code} />\n * </CodeBlockActions>\n * </CodeBlockHeader>\n * <CodeBlockContent wrap lineNumbers>\n * {code}\n * </CodeBlockContent>\n * </CodeBlock>\n *\n * For syntax highlighting, pass `useHighlightedCode(code, language)` output\n * through `CodeBlockLine` elements. Highlighting is optional; a string child\n * renders as plain text.\n */\n\nexport function CodeBlock({ className, ...props }: ComponentProps<typeof CodeBlockPrimitive>) {\n return (\n <CodeBlockPrimitive\n className={cn(\n `\n rounded-berget-xs border-berget-border bg-berget-codeblock-bg\n backdrop-blur-md\n dark:bg-berget-codeblock-bg\n `,\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function CodeBlockHeader({\n className,\n ...props\n}: ComponentProps<typeof CodeBlockHeaderPrimitive>) {\n return (\n <CodeBlockHeaderPrimitive\n className={cn(\n `\n h-10 shrink-0 gap-2 border-b border-berget-border\n bg-berget-codeblock-header-bg px-4 pt-0\n dark:bg-berget-codeblock-header-bg\n `,\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function CodeBlockTitle({\n className,\n ...props\n}: ComponentProps<typeof CodeBlockTitlePrimitive>) {\n return (\n <CodeBlockTitlePrimitive className={cn('text-berget-muted-foreground', className)} {...props} />\n );\n}\n\nexport {\n CodeBlockActions,\n CodeBlockContent,\n CodeBlockCopyButton,\n CodeBlockFooter,\n CodeBlockLine,\n} from '../../primitives/code-block';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,SAAgB,UAAU,EAAE,WAAW,GAAG,SAAoD;CAC5F,OACE,oBAACA,aAAD;EACE,WAAW,GACT;;;;WAKA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAgB,gBAAgB,EAC9B,WACA,GAAG,SAC+C;CAClD,OACE,oBAACC,mBAAD;EACE,WAAW,GACT;;;;WAKA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAgB,eAAe,EAC7B,WACA,GAAG,SAC8C;CACjD,OACE,oBAACC,kBAAD;EAAyB,WAAW,GAAG,gCAAgC,SAAS;EAAG,GAAI;CAAQ,CAAA;AAEnG"}
@@ -0,0 +1,3 @@
1
+ import { CodeBlockActions, CodeBlockContent, CodeBlockCopyButton, CodeBlockFooter, CodeBlockLine } from "../../primitives/code-block.cjs";
2
+ import { CodeBlock, CodeBlockHeader, CodeBlockTitle } from "./CodeBlock.cjs";
3
+ export { CodeBlock, CodeBlockActions, CodeBlockContent, CodeBlockCopyButton, CodeBlockFooter, CodeBlockHeader, CodeBlockLine, CodeBlockTitle };
@@ -0,0 +1,3 @@
1
+ import { CodeBlockActions, CodeBlockContent, CodeBlockCopyButton, CodeBlockFooter, CodeBlockLine } from "../../primitives/code-block.mjs";
2
+ import { CodeBlock, CodeBlockHeader, CodeBlockTitle } from "./CodeBlock.mjs";
3
+ export { CodeBlock, CodeBlockActions, CodeBlockContent, CodeBlockCopyButton, CodeBlockFooter, CodeBlockHeader, CodeBlockLine, CodeBlockTitle };
@@ -3,8 +3,8 @@ import { VariantProps } from "class-variance-authority";
3
3
  import { useRender } from "@base-ui/react/use-render";
4
4
  //#region src/components/container/Container.d.ts
5
5
  declare const containerVariants: (props?: ({
6
- size?: "sm" | "lg" | "md" | "xl" | "full" | null | undefined;
7
- padding?: "none" | "sm" | "lg" | "md" | null | undefined;
6
+ size?: "sm" | "md" | "lg" | "xl" | "full" | null | undefined;
7
+ padding?: "none" | "sm" | "md" | "lg" | null | undefined;
8
8
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
9
9
  export interface ContainerProps extends useRender.ComponentProps<'div'>, VariantProps<typeof containerVariants> {
10
10
  children?: React.ReactNode;
@@ -3,8 +3,8 @@ import { VariantProps } from "class-variance-authority";
3
3
  import { useRender } from "@base-ui/react/use-render";
4
4
  //#region src/components/container/Container.d.ts
5
5
  declare const containerVariants: (props?: ({
6
- size?: "sm" | "lg" | "md" | "xl" | "full" | null | undefined;
7
- padding?: "none" | "sm" | "lg" | "md" | null | undefined;
6
+ size?: "sm" | "md" | "lg" | "xl" | "full" | null | undefined;
7
+ padding?: "none" | "sm" | "md" | "lg" | null | undefined;
8
8
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
9
9
  export interface ContainerProps extends useRender.ComponentProps<'div'>, VariantProps<typeof containerVariants> {
10
10
  children?: React.ReactNode;
@@ -0,0 +1,58 @@
1
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
2
+ const require_highlighter = require("../lib/highlighter.cjs");
3
+ let react = require("react");
4
+ react = require_runtime.__toESM(react, 1);
5
+ //#region src/hooks/use-highlighted-code.ts
6
+ function useHighlightedCode(value, language) {
7
+ const code = value.endsWith("\n") ? value.slice(0, -1) : value;
8
+ const [loaded, setLoaded] = react.useState(null);
9
+ const highlighter = loaded?.language === language ? loaded.highlighter : null;
10
+ react.useEffect(() => {
11
+ let cancelled = false;
12
+ require_highlighter.loadHighlighter(language).then((next) => {
13
+ if (!cancelled) setLoaded({
14
+ language,
15
+ highlighter: next
16
+ });
17
+ }).catch(() => {});
18
+ return () => {
19
+ cancelled = true;
20
+ };
21
+ }, [language]);
22
+ const [done, setDone] = react.useState({
23
+ highlighter: null,
24
+ text: "",
25
+ lines: []
26
+ });
27
+ let next = done;
28
+ if (next.highlighter !== highlighter || !code.startsWith(next.text)) next = {
29
+ highlighter,
30
+ text: "",
31
+ lines: []
32
+ };
33
+ const end = code.lastIndexOf("\n") + 1;
34
+ if (highlighter && end > next.text.length) {
35
+ const result = highlighter.highlight(code.slice(next.text.length, end - 1), next.state);
36
+ next = {
37
+ highlighter,
38
+ text: code.slice(0, end),
39
+ lines: [...next.lines, ...result.lines],
40
+ state: result.state
41
+ };
42
+ }
43
+ if (next !== done) setDone(next);
44
+ const tail = code.slice(end);
45
+ return react.useMemo(() => {
46
+ if (!highlighter) return code.split("\n");
47
+ return [...next.lines, highlighter.highlight(tail, next.state).lines[0]];
48
+ }, [
49
+ code,
50
+ highlighter,
51
+ next,
52
+ tail
53
+ ]);
54
+ }
55
+ //#endregion
56
+ exports.useHighlightedCode = useHighlightedCode;
57
+
58
+ //# sourceMappingURL=use-highlighted-code.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-highlighted-code.cjs","names":["React"],"sources":["../../src/hooks/use-highlighted-code.ts"],"sourcesContent":["// BERGET: upstream uses an intentional mutate-during-render streaming pattern\n// (see the init/render loop below); the React Compiler skips this file, which\n// is safe and expected. Keep this minimal when replaying upstream updates.\n/* eslint-disable react-hooks/preserve-manual-memoization */\nimport * as React from 'react';\n\nimport { loadHighlighter } from '@/lib/highlighter';\n\nexport function useHighlightedCode(value: string, language: string) {\n // A trailing newline would render as an extra empty line.\n const code = value.endsWith('\\n') ? value.slice(0, -1) : value;\n const [loaded, setLoaded] = React.useState<{\n language: string;\n highlighter: Awaited<ReturnType<typeof loadHighlighter>>;\n } | null>(null);\n const highlighter = loaded?.language === language ? loaded.highlighter : null;\n\n React.useEffect(() => {\n let cancelled = false;\n\n loadHighlighter(language)\n .then((next) => {\n if (!cancelled) {\n setLoaded({ language, highlighter: next });\n }\n })\n .catch(() => {});\n\n return () => {\n cancelled = true;\n };\n }, [language]);\n\n // The complete lines, highlighted. While the code streams, only the new\n // lines are tokenized, starting from the grammar state of the last one.\n const [done, setDone] = React.useState<{\n highlighter: typeof highlighter;\n text: string;\n lines: React.ReactNode[];\n state?: Parameters<NonNullable<typeof highlighter>['highlight']>[1];\n }>({ highlighter: null, text: '', lines: [] });\n\n let next = done;\n\n if (next.highlighter !== highlighter || !code.startsWith(next.text)) {\n next = { highlighter, text: '', lines: [] };\n }\n\n const end = code.lastIndexOf('\\n') + 1;\n\n if (highlighter && end > next.text.length) {\n const result = highlighter.highlight(code.slice(next.text.length, end - 1), next.state);\n\n next = {\n highlighter,\n text: code.slice(0, end),\n lines: [...next.lines, ...result.lines],\n state: result.state,\n };\n }\n\n if (next !== done) {\n setDone(next);\n }\n\n // The last line is still being written, so it is tokenized on every render.\n const tail = code.slice(end);\n\n return React.useMemo(() => {\n if (!highlighter) {\n return code.split('\\n');\n }\n\n return [...next.lines, highlighter.highlight(tail, next.state).lines[0]];\n }, [code, highlighter, next, tail]);\n}\n"],"mappings":";;;;;AAQA,SAAgB,mBAAmB,OAAe,UAAkB;CAElE,MAAM,OAAO,MAAM,SAAS,IAAI,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI;CACzD,MAAM,CAAC,QAAQ,aAAaA,MAAM,SAGxB,IAAI;CACd,MAAM,cAAc,QAAQ,aAAa,WAAW,OAAO,cAAc;CAEzE,MAAM,gBAAgB;EACpB,IAAI,YAAY;EAEhB,oBAAA,gBAAgB,QAAQ,CAAC,CACtB,MAAM,SAAS;GACd,IAAI,CAAC,WACH,UAAU;IAAE;IAAU,aAAa;GAAK,CAAC;EAE7C,CAAC,CAAC,CACD,YAAY,CAAC,CAAC;EAEjB,aAAa;GACX,YAAY;EACd;CACF,GAAG,CAAC,QAAQ,CAAC;CAIb,MAAM,CAAC,MAAM,WAAWA,MAAM,SAK3B;EAAE,aAAa;EAAM,MAAM;EAAI,OAAO,CAAC;CAAE,CAAC;CAE7C,IAAI,OAAO;CAEX,IAAI,KAAK,gBAAgB,eAAe,CAAC,KAAK,WAAW,KAAK,IAAI,GAChE,OAAO;EAAE;EAAa,MAAM;EAAI,OAAO,CAAC;CAAE;CAG5C,MAAM,MAAM,KAAK,YAAY,IAAI,IAAI;CAErC,IAAI,eAAe,MAAM,KAAK,KAAK,QAAQ;EACzC,MAAM,SAAS,YAAY,UAAU,KAAK,MAAM,KAAK,KAAK,QAAQ,MAAM,CAAC,GAAG,KAAK,KAAK;EAEtF,OAAO;GACL;GACA,MAAM,KAAK,MAAM,GAAG,GAAG;GACvB,OAAO,CAAC,GAAG,KAAK,OAAO,GAAG,OAAO,KAAK;GACtC,OAAO,OAAO;EAChB;CACF;CAEA,IAAI,SAAS,MACX,QAAQ,IAAI;CAId,MAAM,OAAO,KAAK,MAAM,GAAG;CAE3B,OAAOA,MAAM,cAAc;EACzB,IAAI,CAAC,aACH,OAAO,KAAK,MAAM,IAAI;EAGxB,OAAO,CAAC,GAAG,KAAK,OAAO,YAAY,UAAU,MAAM,KAAK,KAAK,CAAC,CAAC,MAAM,EAAE;CACzE,GAAG;EAAC;EAAM;EAAa;EAAM;CAAI,CAAC;AACpC"}
@@ -0,0 +1,5 @@
1
+ import * as React from "react";
2
+ //#region src/hooks/use-highlighted-code.d.ts
3
+ export declare function useHighlightedCode(value: string, language: string): (string | number | bigint | boolean | import("react/jsx-runtime").JSX.Element[] | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined)[];
4
+ //#endregion
5
+ //# sourceMappingURL=use-highlighted-code.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-highlighted-code.d.cts","names":[],"sources":["../../src/hooks/use-highlighted-code.ts"],"mappings":";;wBAQgB,mBAAmB,eAAe,qFAAgB,IAAA,YAAA,MAAA,+BAAA,MAAA,8BAAA,SAAA,MAAA,aAAA,6CAAA,MAAA,cAAA,MAAA,+BAAA,MAAA,8BAAA,SAAA,MAAA"}
@@ -0,0 +1,5 @@
1
+ import * as React from "react";
2
+ //#region src/hooks/use-highlighted-code.d.ts
3
+ export declare function useHighlightedCode(value: string, language: string): (string | number | bigint | boolean | import("react/jsx-runtime").JSX.Element[] | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined)[];
4
+ //#endregion
5
+ //# sourceMappingURL=use-highlighted-code.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-highlighted-code.d.mts","names":[],"sources":["../../src/hooks/use-highlighted-code.ts"],"mappings":";;wBAQgB,mBAAmB,eAAe,qFAAgB,IAAA,YAAA,MAAA,+BAAA,MAAA,8BAAA,SAAA,MAAA,aAAA,6CAAA,MAAA,cAAA,MAAA,+BAAA,MAAA,8BAAA,SAAA,MAAA"}
@@ -0,0 +1,56 @@
1
+ import { loadHighlighter } from "../lib/highlighter.mjs";
2
+ import * as React from "react";
3
+ //#region src/hooks/use-highlighted-code.ts
4
+ function useHighlightedCode(value, language) {
5
+ const code = value.endsWith("\n") ? value.slice(0, -1) : value;
6
+ const [loaded, setLoaded] = React.useState(null);
7
+ const highlighter = loaded?.language === language ? loaded.highlighter : null;
8
+ React.useEffect(() => {
9
+ let cancelled = false;
10
+ loadHighlighter(language).then((next) => {
11
+ if (!cancelled) setLoaded({
12
+ language,
13
+ highlighter: next
14
+ });
15
+ }).catch(() => {});
16
+ return () => {
17
+ cancelled = true;
18
+ };
19
+ }, [language]);
20
+ const [done, setDone] = React.useState({
21
+ highlighter: null,
22
+ text: "",
23
+ lines: []
24
+ });
25
+ let next = done;
26
+ if (next.highlighter !== highlighter || !code.startsWith(next.text)) next = {
27
+ highlighter,
28
+ text: "",
29
+ lines: []
30
+ };
31
+ const end = code.lastIndexOf("\n") + 1;
32
+ if (highlighter && end > next.text.length) {
33
+ const result = highlighter.highlight(code.slice(next.text.length, end - 1), next.state);
34
+ next = {
35
+ highlighter,
36
+ text: code.slice(0, end),
37
+ lines: [...next.lines, ...result.lines],
38
+ state: result.state
39
+ };
40
+ }
41
+ if (next !== done) setDone(next);
42
+ const tail = code.slice(end);
43
+ return React.useMemo(() => {
44
+ if (!highlighter) return code.split("\n");
45
+ return [...next.lines, highlighter.highlight(tail, next.state).lines[0]];
46
+ }, [
47
+ code,
48
+ highlighter,
49
+ next,
50
+ tail
51
+ ]);
52
+ }
53
+ //#endregion
54
+ export { useHighlightedCode };
55
+
56
+ //# sourceMappingURL=use-highlighted-code.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-highlighted-code.mjs","names":[],"sources":["../../src/hooks/use-highlighted-code.ts"],"sourcesContent":["// BERGET: upstream uses an intentional mutate-during-render streaming pattern\n// (see the init/render loop below); the React Compiler skips this file, which\n// is safe and expected. Keep this minimal when replaying upstream updates.\n/* eslint-disable react-hooks/preserve-manual-memoization */\nimport * as React from 'react';\n\nimport { loadHighlighter } from '@/lib/highlighter';\n\nexport function useHighlightedCode(value: string, language: string) {\n // A trailing newline would render as an extra empty line.\n const code = value.endsWith('\\n') ? value.slice(0, -1) : value;\n const [loaded, setLoaded] = React.useState<{\n language: string;\n highlighter: Awaited<ReturnType<typeof loadHighlighter>>;\n } | null>(null);\n const highlighter = loaded?.language === language ? loaded.highlighter : null;\n\n React.useEffect(() => {\n let cancelled = false;\n\n loadHighlighter(language)\n .then((next) => {\n if (!cancelled) {\n setLoaded({ language, highlighter: next });\n }\n })\n .catch(() => {});\n\n return () => {\n cancelled = true;\n };\n }, [language]);\n\n // The complete lines, highlighted. While the code streams, only the new\n // lines are tokenized, starting from the grammar state of the last one.\n const [done, setDone] = React.useState<{\n highlighter: typeof highlighter;\n text: string;\n lines: React.ReactNode[];\n state?: Parameters<NonNullable<typeof highlighter>['highlight']>[1];\n }>({ highlighter: null, text: '', lines: [] });\n\n let next = done;\n\n if (next.highlighter !== highlighter || !code.startsWith(next.text)) {\n next = { highlighter, text: '', lines: [] };\n }\n\n const end = code.lastIndexOf('\\n') + 1;\n\n if (highlighter && end > next.text.length) {\n const result = highlighter.highlight(code.slice(next.text.length, end - 1), next.state);\n\n next = {\n highlighter,\n text: code.slice(0, end),\n lines: [...next.lines, ...result.lines],\n state: result.state,\n };\n }\n\n if (next !== done) {\n setDone(next);\n }\n\n // The last line is still being written, so it is tokenized on every render.\n const tail = code.slice(end);\n\n return React.useMemo(() => {\n if (!highlighter) {\n return code.split('\\n');\n }\n\n return [...next.lines, highlighter.highlight(tail, next.state).lines[0]];\n }, [code, highlighter, next, tail]);\n}\n"],"mappings":";;;AAQA,SAAgB,mBAAmB,OAAe,UAAkB;CAElE,MAAM,OAAO,MAAM,SAAS,IAAI,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI;CACzD,MAAM,CAAC,QAAQ,aAAa,MAAM,SAGxB,IAAI;CACd,MAAM,cAAc,QAAQ,aAAa,WAAW,OAAO,cAAc;CAEzE,MAAM,gBAAgB;EACpB,IAAI,YAAY;EAEhB,gBAAgB,QAAQ,CAAC,CACtB,MAAM,SAAS;GACd,IAAI,CAAC,WACH,UAAU;IAAE;IAAU,aAAa;GAAK,CAAC;EAE7C,CAAC,CAAC,CACD,YAAY,CAAC,CAAC;EAEjB,aAAa;GACX,YAAY;EACd;CACF,GAAG,CAAC,QAAQ,CAAC;CAIb,MAAM,CAAC,MAAM,WAAW,MAAM,SAK3B;EAAE,aAAa;EAAM,MAAM;EAAI,OAAO,CAAC;CAAE,CAAC;CAE7C,IAAI,OAAO;CAEX,IAAI,KAAK,gBAAgB,eAAe,CAAC,KAAK,WAAW,KAAK,IAAI,GAChE,OAAO;EAAE;EAAa,MAAM;EAAI,OAAO,CAAC;CAAE;CAG5C,MAAM,MAAM,KAAK,YAAY,IAAI,IAAI;CAErC,IAAI,eAAe,MAAM,KAAK,KAAK,QAAQ;EACzC,MAAM,SAAS,YAAY,UAAU,KAAK,MAAM,KAAK,KAAK,QAAQ,MAAM,CAAC,GAAG,KAAK,KAAK;EAEtF,OAAO;GACL;GACA,MAAM,KAAK,MAAM,GAAG,GAAG;GACvB,OAAO,CAAC,GAAG,KAAK,OAAO,GAAG,OAAO,KAAK;GACtC,OAAO,OAAO;EAChB;CACF;CAEA,IAAI,SAAS,MACX,QAAQ,IAAI;CAId,MAAM,OAAO,KAAK,MAAM,GAAG;CAE3B,OAAO,MAAM,cAAc;EACzB,IAAI,CAAC,aACH,OAAO,KAAK,MAAM,IAAI;EAGxB,OAAO,CAAC,GAAG,KAAK,OAAO,YAAY,UAAU,MAAM,KAAK,KAAK,CAAC,CAAC,MAAM,EAAE;CACzE,GAAG;EAAC;EAAM;EAAa;EAAM;CAAI,CAAC;AACpC"}
package/dist/index.cjs CHANGED
@@ -58,7 +58,9 @@ const require_Grid = require("./components/grid/Grid.cjs");
58
58
  const require_Box = require("./components/box/Box.cjs");
59
59
  const require_LanguageSelect = require("./components/language-select/LanguageSelect.cjs");
60
60
  const require_List = require("./components/list/List.cjs");
61
+ const require_code_block = require("./primitives/code-block.cjs");
61
62
  const require_CodeBlock = require("./components/code-block/CodeBlock.cjs");
63
+ const require_use_highlighted_code = require("./hooks/use-highlighted-code.cjs");
62
64
  const require_WindowFrame = require("./components/window-frame/WindowFrame.cjs");
63
65
  const require_FogIllustration = require("./components/fog-illustration/FogIllustration.cjs");
64
66
  let _shadcn_react_message_scroller = require("@shadcn/react/message-scroller");
@@ -95,6 +97,13 @@ exports.CardHeader = require_card.CardHeader;
95
97
  exports.CardTitle = require_card.CardTitle;
96
98
  exports.Checkbox = require_Checkbox.Checkbox;
97
99
  exports.CodeBlock = require_CodeBlock.CodeBlock;
100
+ exports.CodeBlockActions = require_code_block.CodeBlockActions;
101
+ exports.CodeBlockContent = require_code_block.CodeBlockContent;
102
+ exports.CodeBlockCopyButton = require_code_block.CodeBlockCopyButton;
103
+ exports.CodeBlockFooter = require_code_block.CodeBlockFooter;
104
+ exports.CodeBlockHeader = require_CodeBlock.CodeBlockHeader;
105
+ exports.CodeBlockLine = require_code_block.CodeBlockLine;
106
+ exports.CodeBlockTitle = require_CodeBlock.CodeBlockTitle;
98
107
  exports.Combobox = require_combobox.Combobox;
99
108
  exports.ComboboxClear = require_combobox.ComboboxClear;
100
109
  exports.ComboboxContent = require_combobox.ComboboxContent;
@@ -295,6 +304,7 @@ exports.switchThumbVariants = require_Switch.switchThumbVariants;
295
304
  exports.tabsListVariants = require_Tabs.tabsListVariants;
296
305
  exports.tabsTriggerVariants = require_Tabs.tabsTriggerVariants;
297
306
  exports.typographyVariants = require_Typography.typographyVariants;
307
+ exports.useHighlightedCode = require_use_highlighted_code.useHighlightedCode;
298
308
  Object.defineProperty(exports, "useMessageScroller", {
299
309
  enumerable: true,
300
310
  get: function() {