@bergetai/ui 0.16.2 → 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 (118) hide show
  1. package/dist/components/alert/Alert.d.cts +1 -1
  2. package/dist/components/alert/Alert.d.mts +1 -1
  3. package/dist/components/badge/Badge.d.cts +1 -1
  4. package/dist/components/badge/Badge.d.mts +1 -1
  5. package/dist/components/box/Box.d.cts +2 -2
  6. package/dist/components/box/Box.d.mts +2 -2
  7. package/dist/components/button/Button.cjs +21 -4
  8. package/dist/components/button/Button.cjs.map +1 -1
  9. package/dist/components/button/Button.d.cts +2 -1
  10. package/dist/components/button/Button.d.cts.map +1 -1
  11. package/dist/components/button/Button.d.mts +2 -1
  12. package/dist/components/button/Button.d.mts.map +1 -1
  13. package/dist/components/button/Button.mjs +19 -5
  14. package/dist/components/button/Button.mjs.map +1 -1
  15. package/dist/components/button/anchorVariants.cjs +56 -0
  16. package/dist/components/button/anchorVariants.cjs.map +1 -0
  17. package/dist/components/button/anchorVariants.d.cts +45 -0
  18. package/dist/components/button/anchorVariants.d.cts.map +1 -0
  19. package/dist/components/button/anchorVariants.d.mts +45 -0
  20. package/dist/components/button/anchorVariants.d.mts.map +1 -0
  21. package/dist/components/button/anchorVariants.mjs +55 -0
  22. package/dist/components/button/anchorVariants.mjs.map +1 -0
  23. package/dist/components/button/index.d.cts +2 -1
  24. package/dist/components/button/index.d.mts +2 -1
  25. package/dist/components/code-block/CodeBlock.cjs +50 -48
  26. package/dist/components/code-block/CodeBlock.cjs.map +1 -1
  27. package/dist/components/code-block/CodeBlock.d.cts +27 -7
  28. package/dist/components/code-block/CodeBlock.d.cts.map +1 -1
  29. package/dist/components/code-block/CodeBlock.d.mts +27 -7
  30. package/dist/components/code-block/CodeBlock.d.mts.map +1 -1
  31. package/dist/components/code-block/CodeBlock.mjs +45 -50
  32. package/dist/components/code-block/CodeBlock.mjs.map +1 -1
  33. package/dist/components/code-block/index.d.cts +3 -0
  34. package/dist/components/code-block/index.d.mts +3 -0
  35. package/dist/components/combobox/index.d.cts +2 -0
  36. package/dist/components/combobox/index.d.mts +2 -0
  37. package/dist/components/country-select/CountrySelect.cjs +1 -1
  38. package/dist/components/country-select/CountrySelect.mjs +1 -1
  39. package/dist/components/grid/Grid.d.cts +2 -2
  40. package/dist/components/grid/Grid.d.mts +2 -2
  41. package/dist/components/popover/index.d.cts +2 -0
  42. package/dist/components/popover/index.d.mts +2 -0
  43. package/dist/components/radio-group/index.d.cts +2 -0
  44. package/dist/components/radio-group/index.d.mts +2 -0
  45. package/dist/components/tabs/Tabs.cjs +109 -0
  46. package/dist/components/tabs/Tabs.cjs.map +1 -0
  47. package/dist/components/tabs/Tabs.d.cts +29 -0
  48. package/dist/components/tabs/Tabs.d.cts.map +1 -0
  49. package/dist/components/tabs/Tabs.d.mts +29 -0
  50. package/dist/components/tabs/Tabs.d.mts.map +1 -0
  51. package/dist/components/tabs/Tabs.mjs +103 -0
  52. package/dist/components/tabs/Tabs.mjs.map +1 -0
  53. package/dist/components/tabs/index.d.cts +2 -0
  54. package/dist/components/tabs/index.d.mts +2 -0
  55. package/dist/hooks/use-highlighted-code.cjs +58 -0
  56. package/dist/hooks/use-highlighted-code.cjs.map +1 -0
  57. package/dist/hooks/use-highlighted-code.d.cts +5 -0
  58. package/dist/hooks/use-highlighted-code.d.cts.map +1 -0
  59. package/dist/hooks/use-highlighted-code.d.mts +5 -0
  60. package/dist/hooks/use-highlighted-code.d.mts.map +1 -0
  61. package/dist/hooks/use-highlighted-code.mjs +56 -0
  62. package/dist/hooks/use-highlighted-code.mjs.map +1 -0
  63. package/dist/index.cjs +44 -0
  64. package/dist/index.d.cts +14 -2
  65. package/dist/index.d.mts +14 -2
  66. package/dist/index.mjs +9 -2
  67. package/dist/lib/highlighter.cjs +81 -0
  68. package/dist/lib/highlighter.cjs.map +1 -0
  69. package/dist/lib/highlighter.mjs +79 -0
  70. package/dist/lib/highlighter.mjs.map +1 -0
  71. package/dist/primitives/button.d.cts +1 -1
  72. package/dist/primitives/button.d.mts +1 -1
  73. package/dist/primitives/code-block.cjs +133 -0
  74. package/dist/primitives/code-block.cjs.map +1 -0
  75. package/dist/primitives/code-block.d.cts +29 -0
  76. package/dist/primitives/code-block.d.cts.map +1 -0
  77. package/dist/primitives/code-block.d.mts +29 -0
  78. package/dist/primitives/code-block.d.mts.map +1 -0
  79. package/dist/primitives/code-block.mjs +124 -0
  80. package/dist/primitives/code-block.mjs.map +1 -0
  81. package/dist/primitives/combobox.cjs +123 -0
  82. package/dist/primitives/combobox.cjs.map +1 -0
  83. package/dist/primitives/combobox.d.cts +25 -0
  84. package/dist/primitives/combobox.d.cts.map +1 -0
  85. package/dist/primitives/combobox.d.mts +25 -0
  86. package/dist/primitives/combobox.d.mts.map +1 -0
  87. package/dist/primitives/combobox.mjs +111 -0
  88. package/dist/primitives/combobox.mjs.map +1 -0
  89. package/dist/primitives/message-scroller.cjs +1 -1
  90. package/dist/primitives/message-scroller.mjs +1 -1
  91. package/dist/primitives/popover.cjs +24 -0
  92. package/dist/primitives/popover.cjs.map +1 -1
  93. package/dist/primitives/popover.d.cts +12 -0
  94. package/dist/primitives/popover.d.cts.map +1 -0
  95. package/dist/primitives/popover.d.mts +12 -0
  96. package/dist/primitives/popover.d.mts.map +1 -0
  97. package/dist/primitives/popover.mjs +22 -1
  98. package/dist/primitives/popover.mjs.map +1 -1
  99. package/dist/primitives/radio-group.cjs +23 -0
  100. package/dist/primitives/radio-group.cjs.map +1 -0
  101. package/dist/primitives/radio-group.d.cts +8 -0
  102. package/dist/primitives/radio-group.d.cts.map +1 -0
  103. package/dist/primitives/radio-group.d.mts +8 -0
  104. package/dist/primitives/radio-group.d.mts.map +1 -0
  105. package/dist/primitives/radio-group.mjs +22 -0
  106. package/dist/primitives/radio-group.mjs.map +1 -0
  107. package/dist/primitives/sidebar.cjs +1 -1
  108. package/dist/primitives/sidebar.mjs +1 -1
  109. package/dist/primitives/tabs.cjs +51 -0
  110. package/dist/primitives/tabs.cjs.map +1 -0
  111. package/dist/primitives/tabs.d.cts +11 -0
  112. package/dist/primitives/tabs.d.cts.map +1 -0
  113. package/dist/primitives/tabs.d.mts +11 -0
  114. package/dist/primitives/tabs.d.mts.map +1 -0
  115. package/dist/primitives/tabs.mjs +47 -0
  116. package/dist/primitives/tabs.mjs.map +1 -0
  117. package/dist/styles/index.css +61 -0
  118. package/package.json +2 -1
@@ -0,0 +1,81 @@
1
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
2
+ const require_shiki_theme = require("./shiki-theme.cjs");
3
+ let react = require("react");
4
+ react = require_runtime.__toESM(react, 1);
5
+ let react_jsx_runtime = require("react/jsx-runtime");
6
+ let shiki_core = require("shiki/core");
7
+ let shiki_engine_javascript = require("shiki/engine/javascript");
8
+ //#region src/lib/highlighter.tsx
9
+ const languages = {
10
+ bash: () => import("shiki/langs/shellscript.mjs"),
11
+ css: () => import("shiki/langs/css.mjs"),
12
+ diff: () => import("shiki/langs/diff.mjs"),
13
+ html: () => import("shiki/langs/html.mjs"),
14
+ javascript: () => import("shiki/langs/javascript.mjs"),
15
+ json: () => import("shiki/langs/json.mjs"),
16
+ jsx: () => import("shiki/langs/jsx.mjs"),
17
+ markdown: () => import("shiki/langs/markdown.mjs"),
18
+ python: () => import("shiki/langs/python.mjs"),
19
+ sql: () => import("shiki/langs/sql.mjs"),
20
+ tsx: () => import("shiki/langs/tsx.mjs"),
21
+ typescript: () => import("shiki/langs/typescript.mjs"),
22
+ yaml: () => import("shiki/langs/yaml.mjs"),
23
+ dockerfile: () => import("shiki/langs/dockerfile.mjs")
24
+ };
25
+ const aliases = {
26
+ js: "javascript",
27
+ md: "markdown",
28
+ py: "python",
29
+ sh: "bash",
30
+ shell: "bash",
31
+ shellscript: "bash",
32
+ ts: "typescript",
33
+ yml: "yaml",
34
+ zsh: "bash",
35
+ docker: "dockerfile"
36
+ };
37
+ let highlighter;
38
+ function getHighlighter() {
39
+ highlighter ??= (0, shiki_core.createHighlighterCore)({
40
+ themes: [require_shiki_theme.bergetShikiTheme],
41
+ langs: [],
42
+ engine: (0, shiki_engine_javascript.createJavaScriptRegexEngine)({ forgiving: true })
43
+ });
44
+ return highlighter;
45
+ }
46
+ function getLanguage(language) {
47
+ const name = language.toLowerCase();
48
+ if (name === "ansi") return name;
49
+ if (name in languages) return name;
50
+ return aliases[name] ?? null;
51
+ }
52
+ async function loadHighlighter(language) {
53
+ const lang = getLanguage(language);
54
+ if (!lang) return null;
55
+ const shiki = await getHighlighter();
56
+ if (lang !== "ansi" && !shiki.getLoadedLanguages().includes(lang)) await shiki.loadLanguage(languages[lang]);
57
+ return { highlight(code, state) {
58
+ const tokenize = (text) => shiki.codeToTokens(text, {
59
+ lang,
60
+ themes: {
61
+ light: "berget",
62
+ dark: "berget"
63
+ },
64
+ defaultColor: false,
65
+ grammarState: state
66
+ }).tokens;
67
+ const tokens = lang === "ansi" ? code.split("\n").flatMap((line) => tokenize(line)) : tokenize(code);
68
+ return {
69
+ lines: tokens.map((line) => line.map((token, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
70
+ style: token.htmlStyle,
71
+ className: "\n text-(--shiki-light)\n dark:text-(--shiki-dark)\n ",
72
+ children: token.content
73
+ }, index))),
74
+ state: shiki.getLastGrammarState(tokens)
75
+ };
76
+ } };
77
+ }
78
+ //#endregion
79
+ exports.loadHighlighter = loadHighlighter;
80
+
81
+ //# sourceMappingURL=highlighter.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"highlighter.cjs","names":["createHighlighterCore","bergetShikiTheme","createJavaScriptRegexEngine"],"sources":["../../src/lib/highlighter.tsx"],"sourcesContent":["import * as React from 'react';\nimport { createHighlighterCore, type GrammarState, type HighlighterCore } from 'shiki/core';\nimport { createJavaScriptRegexEngine } from 'shiki/engine/javascript';\n\n// BERGET: brand syntax-highlighting theme. CSS-variables theme backed by the\n// --berget-shiki-* tokens in styles/index.css (dark + light). Keep this patch\n// minimal so re-running `npx shadcn@latest add code-block --overwrite` is easy.\nimport { bergetShikiTheme } from './shiki-theme';\n\n// Add the languages you need. Each one loads the first time it is used.\nconst languages = {\n bash: () => import('shiki/langs/shellscript.mjs'),\n css: () => import('shiki/langs/css.mjs'),\n diff: () => import('shiki/langs/diff.mjs'),\n html: () => import('shiki/langs/html.mjs'),\n javascript: () => import('shiki/langs/javascript.mjs'),\n json: () => import('shiki/langs/json.mjs'),\n jsx: () => import('shiki/langs/jsx.mjs'),\n markdown: () => import('shiki/langs/markdown.mjs'),\n python: () => import('shiki/langs/python.mjs'),\n sql: () => import('shiki/langs/sql.mjs'),\n tsx: () => import('shiki/langs/tsx.mjs'),\n typescript: () => import('shiki/langs/typescript.mjs'),\n yaml: () => import('shiki/langs/yaml.mjs'),\n dockerfile: () => import('shiki/langs/dockerfile.mjs'),\n};\n\nconst aliases: Record<string, keyof typeof languages> = {\n js: 'javascript',\n md: 'markdown',\n py: 'python',\n sh: 'bash',\n shell: 'bash',\n shellscript: 'bash',\n ts: 'typescript',\n yml: 'yaml',\n zsh: 'bash',\n docker: 'dockerfile',\n};\n\nlet highlighter: Promise<HighlighterCore> | undefined;\n\nfunction getHighlighter() {\n highlighter ??= createHighlighterCore({\n // BERGET: single CSS-variables theme instead of github-light/dark.\n themes: [bergetShikiTheme],\n langs: [],\n engine: createJavaScriptRegexEngine({ forgiving: true }),\n });\n\n return highlighter;\n}\n\nfunction getLanguage(language: string) {\n const name = language.toLowerCase();\n\n if (name === 'ansi') {\n return name;\n }\n\n if (name in languages) {\n return name as keyof typeof languages;\n }\n\n return aliases[name] ?? null;\n}\n\n// Loads a language and returns a highlighter for it, or null for a language\n// that is not listed.\nexport async function loadHighlighter(language: string) {\n const lang = getLanguage(language);\n\n if (!lang) {\n return null;\n }\n\n const shiki = await getHighlighter();\n\n if (lang !== 'ansi' && !shiki.getLoadedLanguages().includes(lang)) {\n await shiki.loadLanguage(languages[lang]);\n }\n\n return {\n // Returns one React node per line, and the grammar state after the last\n // line. Pass that state back to continue where the code left off.\n highlight(code: string, state?: GrammarState) {\n const tokenize = (text: string) =>\n shiki.codeToTokens(text, {\n lang,\n // BERGET: light/dark slots both resolve to the berget theme, whose\n // token colors are var(--berget-shiki-*) and already flip with the\n // data-theme attribute in styles/index.css.\n themes: { light: 'berget', dark: 'berget' },\n defaultColor: false,\n grammarState: state,\n }).tokens;\n\n // ANSI has no grammar state, so each line is tokenized on its own and\n // gets the same colors whether it arrives in one piece or streams.\n const tokens =\n lang === 'ansi' ? code.split('\\n').flatMap((line) => tokenize(line)) : tokenize(code);\n\n return {\n lines: tokens.map((line) =>\n line.map((token, index) => (\n <span\n key={index}\n style={token.htmlStyle as React.CSSProperties}\n className=\"\n text-(--shiki-light)\n dark:text-(--shiki-dark)\n \"\n >\n {token.content}\n </span>\n )),\n ),\n state: shiki.getLastGrammarState(tokens),\n };\n },\n };\n}\n\n// Returns one React node per line, or null for a language that is not listed.\nexport async function highlightCode(code: string, language: string) {\n const highlighter = await loadHighlighter(language);\n\n return highlighter ? highlighter.highlight(code).lines : null;\n}\n"],"mappings":";;;;;;;;AAUA,MAAM,YAAY;CAChB,YAAY,OAAO;CACnB,WAAW,OAAO;CAClB,YAAY,OAAO;CACnB,YAAY,OAAO;CACnB,kBAAkB,OAAO;CACzB,YAAY,OAAO;CACnB,WAAW,OAAO;CAClB,gBAAgB,OAAO;CACvB,cAAc,OAAO;CACrB,WAAW,OAAO;CAClB,WAAW,OAAO;CAClB,kBAAkB,OAAO;CACzB,YAAY,OAAO;CACnB,kBAAkB,OAAO;AAC3B;AAEA,MAAM,UAAkD;CACtD,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,OAAO;CACP,aAAa;CACb,IAAI;CACJ,KAAK;CACL,KAAK;CACL,QAAQ;AACV;AAEA,IAAI;AAEJ,SAAS,iBAAiB;CACxB,iBAAA,GAAgBA,WAAAA,sBAAAA,CAAsB;EAEpC,QAAQ,CAACC,oBAAAA,gBAAgB;EACzB,OAAO,CAAC;EACR,SAAA,GAAQC,wBAAAA,4BAAAA,CAA4B,EAAE,WAAW,KAAK,CAAC;CACzD,CAAC;CAED,OAAO;AACT;AAEA,SAAS,YAAY,UAAkB;CACrC,MAAM,OAAO,SAAS,YAAY;CAElC,IAAI,SAAS,QACX,OAAO;CAGT,IAAI,QAAQ,WACV,OAAO;CAGT,OAAO,QAAQ,SAAS;AAC1B;AAIA,eAAsB,gBAAgB,UAAkB;CACtD,MAAM,OAAO,YAAY,QAAQ;CAEjC,IAAI,CAAC,MACH,OAAO;CAGT,MAAM,QAAQ,MAAM,eAAe;CAEnC,IAAI,SAAS,UAAU,CAAC,MAAM,mBAAmB,CAAC,CAAC,SAAS,IAAI,GAC9D,MAAM,MAAM,aAAa,UAAU,KAAK;CAG1C,OAAO,EAGL,UAAU,MAAc,OAAsB;EAC5C,MAAM,YAAY,SAChB,MAAM,aAAa,MAAM;GACvB;GAIA,QAAQ;IAAE,OAAO;IAAU,MAAM;GAAS;GAC1C,cAAc;GACd,cAAc;EAChB,CAAC,CAAC,CAAC;EAIL,MAAM,SACJ,SAAS,SAAS,KAAK,MAAM,IAAI,CAAC,CAAC,SAAS,SAAS,SAAS,IAAI,CAAC,IAAI,SAAS,IAAI;EAEtF,OAAO;GACL,OAAO,OAAO,KAAK,SACjB,KAAK,KAAK,OAAO,UACf,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;IAEE,OAAO,MAAM;IACb,WAAU;IAKT,UAAA,MAAM;GACH,GARC,KAQD,CACP,CACH;GACA,OAAO,MAAM,oBAAoB,MAAM;EACzC;CACF,EACF;AACF"}
@@ -0,0 +1,79 @@
1
+ import { bergetShikiTheme } from "./shiki-theme.mjs";
2
+ import "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ import { createHighlighterCore } from "shiki/core";
5
+ import { createJavaScriptRegexEngine } from "shiki/engine/javascript";
6
+ //#region src/lib/highlighter.tsx
7
+ const languages = {
8
+ bash: () => import("shiki/langs/shellscript.mjs"),
9
+ css: () => import("shiki/langs/css.mjs"),
10
+ diff: () => import("shiki/langs/diff.mjs"),
11
+ html: () => import("shiki/langs/html.mjs"),
12
+ javascript: () => import("shiki/langs/javascript.mjs"),
13
+ json: () => import("shiki/langs/json.mjs"),
14
+ jsx: () => import("shiki/langs/jsx.mjs"),
15
+ markdown: () => import("shiki/langs/markdown.mjs"),
16
+ python: () => import("shiki/langs/python.mjs"),
17
+ sql: () => import("shiki/langs/sql.mjs"),
18
+ tsx: () => import("shiki/langs/tsx.mjs"),
19
+ typescript: () => import("shiki/langs/typescript.mjs"),
20
+ yaml: () => import("shiki/langs/yaml.mjs"),
21
+ dockerfile: () => import("shiki/langs/dockerfile.mjs")
22
+ };
23
+ const aliases = {
24
+ js: "javascript",
25
+ md: "markdown",
26
+ py: "python",
27
+ sh: "bash",
28
+ shell: "bash",
29
+ shellscript: "bash",
30
+ ts: "typescript",
31
+ yml: "yaml",
32
+ zsh: "bash",
33
+ docker: "dockerfile"
34
+ };
35
+ let highlighter;
36
+ function getHighlighter() {
37
+ highlighter ??= createHighlighterCore({
38
+ themes: [bergetShikiTheme],
39
+ langs: [],
40
+ engine: createJavaScriptRegexEngine({ forgiving: true })
41
+ });
42
+ return highlighter;
43
+ }
44
+ function getLanguage(language) {
45
+ const name = language.toLowerCase();
46
+ if (name === "ansi") return name;
47
+ if (name in languages) return name;
48
+ return aliases[name] ?? null;
49
+ }
50
+ async function loadHighlighter(language) {
51
+ const lang = getLanguage(language);
52
+ if (!lang) return null;
53
+ const shiki = await getHighlighter();
54
+ if (lang !== "ansi" && !shiki.getLoadedLanguages().includes(lang)) await shiki.loadLanguage(languages[lang]);
55
+ return { highlight(code, state) {
56
+ const tokenize = (text) => shiki.codeToTokens(text, {
57
+ lang,
58
+ themes: {
59
+ light: "berget",
60
+ dark: "berget"
61
+ },
62
+ defaultColor: false,
63
+ grammarState: state
64
+ }).tokens;
65
+ const tokens = lang === "ansi" ? code.split("\n").flatMap((line) => tokenize(line)) : tokenize(code);
66
+ return {
67
+ lines: tokens.map((line) => line.map((token, index) => /* @__PURE__ */ jsx("span", {
68
+ style: token.htmlStyle,
69
+ className: "\n text-(--shiki-light)\n dark:text-(--shiki-dark)\n ",
70
+ children: token.content
71
+ }, index))),
72
+ state: shiki.getLastGrammarState(tokens)
73
+ };
74
+ } };
75
+ }
76
+ //#endregion
77
+ export { loadHighlighter };
78
+
79
+ //# sourceMappingURL=highlighter.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"highlighter.mjs","names":[],"sources":["../../src/lib/highlighter.tsx"],"sourcesContent":["import * as React from 'react';\nimport { createHighlighterCore, type GrammarState, type HighlighterCore } from 'shiki/core';\nimport { createJavaScriptRegexEngine } from 'shiki/engine/javascript';\n\n// BERGET: brand syntax-highlighting theme. CSS-variables theme backed by the\n// --berget-shiki-* tokens in styles/index.css (dark + light). Keep this patch\n// minimal so re-running `npx shadcn@latest add code-block --overwrite` is easy.\nimport { bergetShikiTheme } from './shiki-theme';\n\n// Add the languages you need. Each one loads the first time it is used.\nconst languages = {\n bash: () => import('shiki/langs/shellscript.mjs'),\n css: () => import('shiki/langs/css.mjs'),\n diff: () => import('shiki/langs/diff.mjs'),\n html: () => import('shiki/langs/html.mjs'),\n javascript: () => import('shiki/langs/javascript.mjs'),\n json: () => import('shiki/langs/json.mjs'),\n jsx: () => import('shiki/langs/jsx.mjs'),\n markdown: () => import('shiki/langs/markdown.mjs'),\n python: () => import('shiki/langs/python.mjs'),\n sql: () => import('shiki/langs/sql.mjs'),\n tsx: () => import('shiki/langs/tsx.mjs'),\n typescript: () => import('shiki/langs/typescript.mjs'),\n yaml: () => import('shiki/langs/yaml.mjs'),\n dockerfile: () => import('shiki/langs/dockerfile.mjs'),\n};\n\nconst aliases: Record<string, keyof typeof languages> = {\n js: 'javascript',\n md: 'markdown',\n py: 'python',\n sh: 'bash',\n shell: 'bash',\n shellscript: 'bash',\n ts: 'typescript',\n yml: 'yaml',\n zsh: 'bash',\n docker: 'dockerfile',\n};\n\nlet highlighter: Promise<HighlighterCore> | undefined;\n\nfunction getHighlighter() {\n highlighter ??= createHighlighterCore({\n // BERGET: single CSS-variables theme instead of github-light/dark.\n themes: [bergetShikiTheme],\n langs: [],\n engine: createJavaScriptRegexEngine({ forgiving: true }),\n });\n\n return highlighter;\n}\n\nfunction getLanguage(language: string) {\n const name = language.toLowerCase();\n\n if (name === 'ansi') {\n return name;\n }\n\n if (name in languages) {\n return name as keyof typeof languages;\n }\n\n return aliases[name] ?? null;\n}\n\n// Loads a language and returns a highlighter for it, or null for a language\n// that is not listed.\nexport async function loadHighlighter(language: string) {\n const lang = getLanguage(language);\n\n if (!lang) {\n return null;\n }\n\n const shiki = await getHighlighter();\n\n if (lang !== 'ansi' && !shiki.getLoadedLanguages().includes(lang)) {\n await shiki.loadLanguage(languages[lang]);\n }\n\n return {\n // Returns one React node per line, and the grammar state after the last\n // line. Pass that state back to continue where the code left off.\n highlight(code: string, state?: GrammarState) {\n const tokenize = (text: string) =>\n shiki.codeToTokens(text, {\n lang,\n // BERGET: light/dark slots both resolve to the berget theme, whose\n // token colors are var(--berget-shiki-*) and already flip with the\n // data-theme attribute in styles/index.css.\n themes: { light: 'berget', dark: 'berget' },\n defaultColor: false,\n grammarState: state,\n }).tokens;\n\n // ANSI has no grammar state, so each line is tokenized on its own and\n // gets the same colors whether it arrives in one piece or streams.\n const tokens =\n lang === 'ansi' ? code.split('\\n').flatMap((line) => tokenize(line)) : tokenize(code);\n\n return {\n lines: tokens.map((line) =>\n line.map((token, index) => (\n <span\n key={index}\n style={token.htmlStyle as React.CSSProperties}\n className=\"\n text-(--shiki-light)\n dark:text-(--shiki-dark)\n \"\n >\n {token.content}\n </span>\n )),\n ),\n state: shiki.getLastGrammarState(tokens),\n };\n },\n };\n}\n\n// Returns one React node per line, or null for a language that is not listed.\nexport async function highlightCode(code: string, language: string) {\n const highlighter = await loadHighlighter(language);\n\n return highlighter ? highlighter.highlight(code).lines : null;\n}\n"],"mappings":";;;;;;AAUA,MAAM,YAAY;CAChB,YAAY,OAAO;CACnB,WAAW,OAAO;CAClB,YAAY,OAAO;CACnB,YAAY,OAAO;CACnB,kBAAkB,OAAO;CACzB,YAAY,OAAO;CACnB,WAAW,OAAO;CAClB,gBAAgB,OAAO;CACvB,cAAc,OAAO;CACrB,WAAW,OAAO;CAClB,WAAW,OAAO;CAClB,kBAAkB,OAAO;CACzB,YAAY,OAAO;CACnB,kBAAkB,OAAO;AAC3B;AAEA,MAAM,UAAkD;CACtD,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,OAAO;CACP,aAAa;CACb,IAAI;CACJ,KAAK;CACL,KAAK;CACL,QAAQ;AACV;AAEA,IAAI;AAEJ,SAAS,iBAAiB;CACxB,gBAAgB,sBAAsB;EAEpC,QAAQ,CAAC,gBAAgB;EACzB,OAAO,CAAC;EACR,QAAQ,4BAA4B,EAAE,WAAW,KAAK,CAAC;CACzD,CAAC;CAED,OAAO;AACT;AAEA,SAAS,YAAY,UAAkB;CACrC,MAAM,OAAO,SAAS,YAAY;CAElC,IAAI,SAAS,QACX,OAAO;CAGT,IAAI,QAAQ,WACV,OAAO;CAGT,OAAO,QAAQ,SAAS;AAC1B;AAIA,eAAsB,gBAAgB,UAAkB;CACtD,MAAM,OAAO,YAAY,QAAQ;CAEjC,IAAI,CAAC,MACH,OAAO;CAGT,MAAM,QAAQ,MAAM,eAAe;CAEnC,IAAI,SAAS,UAAU,CAAC,MAAM,mBAAmB,CAAC,CAAC,SAAS,IAAI,GAC9D,MAAM,MAAM,aAAa,UAAU,KAAK;CAG1C,OAAO,EAGL,UAAU,MAAc,OAAsB;EAC5C,MAAM,YAAY,SAChB,MAAM,aAAa,MAAM;GACvB;GAIA,QAAQ;IAAE,OAAO;IAAU,MAAM;GAAS;GAC1C,cAAc;GACd,cAAc;EAChB,CAAC,CAAC,CAAC;EAIL,MAAM,SACJ,SAAS,SAAS,KAAK,MAAM,IAAI,CAAC,CAAC,SAAS,SAAS,SAAS,IAAI,CAAC,IAAI,SAAS,IAAI;EAEtF,OAAO;GACL,OAAO,OAAO,KAAK,SACjB,KAAK,KAAK,OAAO,UACf,oBAAC,QAAD;IAEE,OAAO,MAAM;IACb,WAAU;IAKT,UAAA,MAAM;GACH,GARC,KAQD,CACP,CACH;GACA,OAAO,MAAM,oBAAoB,MAAM;EACzC;CACF,EACF;AACF"}
@@ -3,7 +3,7 @@ import { VariantProps } from "class-variance-authority";
3
3
  //#region src/primitives/button.d.ts
4
4
  declare const buttonVariants: (props?: ({
5
5
  variant?: "link" | "default" | "secondary" | "outline" | "ghost" | "destructive" | null | undefined;
6
- size?: "default" | "xs" | "sm" | "icon" | "lg" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
6
+ size?: "default" | "icon" | "xs" | "sm" | "lg" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
7
7
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
8
8
  declare function Button$1({ className, variant, size, ...props }: Button.Props & VariantProps<typeof buttonVariants>): import("react/jsx-runtime").JSX.Element;
9
9
  //#endregion
@@ -3,7 +3,7 @@ import { VariantProps } from "class-variance-authority";
3
3
  //#region src/primitives/button.d.ts
4
4
  declare const buttonVariants: (props?: ({
5
5
  variant?: "link" | "default" | "secondary" | "outline" | "ghost" | "destructive" | null | undefined;
6
- size?: "default" | "xs" | "sm" | "icon" | "lg" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
6
+ size?: "default" | "icon" | "xs" | "sm" | "lg" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
7
7
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
8
8
  declare function Button$1({ className, variant, size, ...props }: Button.Props & VariantProps<typeof buttonVariants>): import("react/jsx-runtime").JSX.Element;
9
9
  //#endregion
@@ -0,0 +1,133 @@
1
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
2
+ const require_button = require("./button.cjs");
3
+ let react = require("react");
4
+ react = require_runtime.__toESM(react, 1);
5
+ let react_jsx_runtime = require("react/jsx-runtime");
6
+ let class_variance_authority = require("class-variance-authority");
7
+ let cn = require("cn");
8
+ let lucide_react = require("lucide-react");
9
+ //#region src/primitives/code-block.tsx
10
+ const codeBlockVariants = (0, class_variance_authority.cva)("group/code-block relative flex w-full min-w-0 flex-col overflow-hidden rounded-lg text-sm has-[>[data-slot=code-block-content]:focus-visible]:ring-3 has-[>[data-slot=code-block-content]:focus-visible]:ring-ring/50 data-[size=sm]:text-xs", {
11
+ variants: { variant: {
12
+ default: "border border-input text-foreground has-[>[data-slot=code-block-content]:focus-visible]:border-ring dark:bg-input/30",
13
+ destructive: "border border-destructive/30 text-destructive dark:border-destructive/40"
14
+ } },
15
+ defaultVariants: { variant: "default" }
16
+ });
17
+ function CodeBlock({ className, variant = "default", size = "default", ...props }) {
18
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
19
+ "data-slot": "code-block",
20
+ "data-variant": variant,
21
+ "data-size": size,
22
+ className: (0, cn.cn)(codeBlockVariants({ variant }), className),
23
+ ...props
24
+ });
25
+ }
26
+ function CodeBlockHeader({ className, ...props }) {
27
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
28
+ "data-slot": "code-block-header",
29
+ className: (0, cn.cn)("flex min-w-0 shrink-0 items-center gap-2 px-3 pt-3 text-muted-foreground group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:pt-2.5 group-data-[variant=destructive]/code-block:text-destructive *:has-[>[data-slot=code-block-title]]:min-w-0", className),
30
+ ...props
31
+ });
32
+ }
33
+ function CodeBlockTitle({ className, ...props }) {
34
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
35
+ "data-slot": "code-block-title",
36
+ className: (0, cn.cn)("min-w-0 truncate font-sans text-sm font-medium text-foreground group-data-[size=sm]/code-block:text-xs group-data-[variant=destructive]/code-block:text-destructive [&_svg]:pointer-events-none [&_svg]:inline-block [&_svg]:align-middle [&_svg:not([class*='size-'])]:size-3.5 *:[svg]:me-1.5", className),
37
+ ...props
38
+ });
39
+ }
40
+ function CodeBlockActions({ className, ...props }) {
41
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
42
+ "data-slot": "code-block-actions",
43
+ className: (0, cn.cn)("-my-1 ms-auto -me-1.5 flex shrink-0 items-center gap-1 [[data-slot=code-block]>&]:absolute [[data-slot=code-block]>&]:end-2 [[data-slot=code-block]>&]:top-2 [[data-slot=code-block]>&]:z-10 [[data-slot=code-block]>&]:m-0 [[data-slot=code-block]>&]:opacity-0 [[data-slot=code-block]>&]:transition-opacity [[data-slot=code-block]>&]:group-focus-within/code-block:opacity-100 [[data-slot=code-block]>&]:group-hover/code-block:opacity-100 group-data-[size=sm]/code-block:[[data-slot=code-block]>&]:end-1.5 group-data-[size=sm]/code-block:[[data-slot=code-block]>&]:top-1.5 [[data-slot=code-block]>&]:pointer-coarse:opacity-100 [[data-slot=code-block]>&]:*:[button]:bg-background [[data-slot=code-block]>&]:*:[button]:ring-1 [[data-slot=code-block]>&]:*:[button]:ring-foreground/10", className),
44
+ ...props
45
+ });
46
+ }
47
+ function CodeBlockCopyButton({ value, variant = "ghost", size = "icon-xs", className, onClick, ...props }) {
48
+ const [copied, setCopied] = react.useState(false);
49
+ react.useEffect(() => {
50
+ if (!copied) return;
51
+ const timeout = setTimeout(() => setCopied(false), 2e3);
52
+ return () => clearTimeout(timeout);
53
+ }, [copied]);
54
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_button.Button, {
55
+ "data-slot": "code-block-copy-button",
56
+ "data-copied": copied || void 0,
57
+ variant,
58
+ size,
59
+ "aria-label": copied ? "Copied" : "Copy",
60
+ className: (0, cn.cn)(className),
61
+ onClick: (event) => {
62
+ onClick?.(event);
63
+ navigator.clipboard.writeText(value).then(() => setCopied(true)).catch(() => {});
64
+ },
65
+ ...props,
66
+ children: copied ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.CheckIcon, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.CopyIcon, {})
67
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
68
+ "aria-live": "polite",
69
+ className: "sr-only",
70
+ children: copied ? "Copied" : ""
71
+ })] });
72
+ }
73
+ function CodeBlockContent({ className, children, style, wrap = false, lineNumbers = false, startLine = 1, ...props }) {
74
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
75
+ "data-slot": "code-block-content",
76
+ "data-wrap": wrap || void 0,
77
+ "data-numbered": lineNumbers || void 0,
78
+ dir: "ltr",
79
+ tabIndex: 0,
80
+ style: {
81
+ counterReset: `line ${startLine - 1}`,
82
+ ...style
83
+ },
84
+ className: (0, cn.cn)("min-h-0 min-w-0 scroll-fade-x scrollbar-thin overflow-auto px-3 py-3 text-start font-mono leading-relaxed outline-none group-has-data-[slot=code-block-footer]/code-block:pb-2 group-has-data-[slot=code-block-header]/code-block:pt-2 group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:py-2.5 group-data-[size=sm]/code-block:group-has-data-[slot=code-block-header]/code-block:pt-1.5 data-wrap:scroll-fade-y data-wrap:wrap-break-word data-wrap:whitespace-pre-wrap", className),
85
+ ...props,
86
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
87
+ "data-slot": "code-block-code",
88
+ className: "grid min-h-lh min-w-max content-start in-data-numbered:grid-cols-[auto_1fr] in-data-wrap:min-w-0",
89
+ children: lineNumbers && typeof children === "string" ? children.replace(/\n$/, "").split("\n").map((line, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodeBlockLine, { children: line }, index)) : children
90
+ })
91
+ });
92
+ }
93
+ const codeBlockLineVariants = (0, class_variance_authority.cva)("relative -mx-3 block min-h-lh px-3 group-data-[size=sm]/code-block:-mx-2.5 group-data-[size=sm]/code-block:px-2.5 before:min-w-6 before:text-end before:text-muted-foreground after:absolute after:start-1 after:top-0 after:text-muted-foreground after:select-none in-data-numbered:col-span-2 in-data-numbered:grid in-data-numbered:grid-cols-subgrid in-data-numbered:gap-x-3 in-data-numbered:[counter-increment:line] in-data-numbered:before:content-[counter(line)] in-data-numbered:before:select-none in-data-numbered:supports-[content:counter(line)_/_'']:before:content-[counter(line)_/_'']", {
94
+ variants: { variant: {
95
+ default: "",
96
+ added: "bg-muted after:content-['+']",
97
+ removed: "bg-destructive/10 after:text-destructive after:content-['−']",
98
+ highlighted: "bg-muted"
99
+ } },
100
+ defaultVariants: { variant: "default" }
101
+ });
102
+ function CodeBlockLine({ className, variant = "default", children, ...props }) {
103
+ const empty = children === void 0 || children === null || children === "" || Array.isArray(children) && children.length === 0;
104
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
105
+ "data-slot": "code-block-line",
106
+ "data-variant": variant,
107
+ className: (0, cn.cn)(codeBlockLineVariants({ variant }), className),
108
+ ...props,
109
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
110
+ "data-slot": "code-block-line-content",
111
+ className: "min-w-0",
112
+ children: empty ? "\n" : children
113
+ })
114
+ });
115
+ }
116
+ function CodeBlockFooter({ className, ...props }) {
117
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
118
+ "data-slot": "code-block-footer",
119
+ className: (0, cn.cn)("flex min-w-0 shrink-0 items-center gap-2 px-3 pb-3 text-muted-foreground group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:pb-2.5", className),
120
+ ...props
121
+ });
122
+ }
123
+ //#endregion
124
+ exports.CodeBlock = CodeBlock;
125
+ exports.CodeBlockActions = CodeBlockActions;
126
+ exports.CodeBlockContent = CodeBlockContent;
127
+ exports.CodeBlockCopyButton = CodeBlockCopyButton;
128
+ exports.CodeBlockFooter = CodeBlockFooter;
129
+ exports.CodeBlockHeader = CodeBlockHeader;
130
+ exports.CodeBlockLine = CodeBlockLine;
131
+ exports.CodeBlockTitle = CodeBlockTitle;
132
+
133
+ //# sourceMappingURL=code-block.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-block.cjs","names":["cva","React","Button","CheckIcon","CopyIcon"],"sources":["../../src/primitives/code-block.tsx"],"sourcesContent":["import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"cn\"\n\nimport { Button } from \"@/primitives/button\"\nimport { CheckIcon, CopyIcon } from \"lucide-react\"\n\nconst codeBlockVariants = cva(\n \"group/code-block relative flex w-full min-w-0 flex-col overflow-hidden rounded-lg text-sm has-[>[data-slot=code-block-content]:focus-visible]:ring-3 has-[>[data-slot=code-block-content]:focus-visible]:ring-ring/50 data-[size=sm]:text-xs\",\n {\n variants: {\n variant: {\n default:\n \"border border-input text-foreground has-[>[data-slot=code-block-content]:focus-visible]:border-ring dark:bg-input/30\",\n destructive:\n \"border border-destructive/30 text-destructive dark:border-destructive/40\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction CodeBlock({\n className,\n variant = \"default\",\n size = \"default\",\n ...props\n}: React.ComponentProps<\"div\"> &\n VariantProps<typeof codeBlockVariants> & { size?: \"default\" | \"sm\" }) {\n return (\n <div\n data-slot=\"code-block\"\n data-variant={variant}\n data-size={size}\n className={cn(codeBlockVariants({ variant }), className)}\n {...props}\n />\n )\n}\n\nfunction CodeBlockHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"code-block-header\"\n className={cn(\n \"flex min-w-0 shrink-0 items-center gap-2 px-3 pt-3 text-muted-foreground group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:pt-2.5 group-data-[variant=destructive]/code-block:text-destructive *:has-[>[data-slot=code-block-title]]:min-w-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CodeBlockTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"code-block-title\"\n className={cn(\n \"min-w-0 truncate font-sans text-sm font-medium text-foreground group-data-[size=sm]/code-block:text-xs group-data-[variant=destructive]/code-block:text-destructive [&_svg]:pointer-events-none [&_svg]:inline-block [&_svg]:align-middle [&_svg:not([class*='size-'])]:size-3.5 *:[svg]:me-1.5\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CodeBlockActions({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"code-block-actions\"\n className={cn(\n \"-my-1 ms-auto -me-1.5 flex shrink-0 items-center gap-1 [[data-slot=code-block]>&]:absolute [[data-slot=code-block]>&]:end-2 [[data-slot=code-block]>&]:top-2 [[data-slot=code-block]>&]:z-10 [[data-slot=code-block]>&]:m-0 [[data-slot=code-block]>&]:opacity-0 [[data-slot=code-block]>&]:transition-opacity [[data-slot=code-block]>&]:group-focus-within/code-block:opacity-100 [[data-slot=code-block]>&]:group-hover/code-block:opacity-100 group-data-[size=sm]/code-block:[[data-slot=code-block]>&]:end-1.5 group-data-[size=sm]/code-block:[[data-slot=code-block]>&]:top-1.5 [[data-slot=code-block]>&]:pointer-coarse:opacity-100 [[data-slot=code-block]>&]:*:[button]:bg-background [[data-slot=code-block]>&]:*:[button]:ring-1 [[data-slot=code-block]>&]:*:[button]:ring-foreground/10\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CodeBlockCopyButton({\n value,\n variant = \"ghost\",\n size = \"icon-xs\",\n className,\n onClick,\n ...props\n}: React.ComponentProps<typeof Button> & { value: string }) {\n const [copied, setCopied] = React.useState(false)\n\n React.useEffect(() => {\n if (!copied) {\n return\n }\n\n const timeout = setTimeout(() => setCopied(false), 2000)\n return () => clearTimeout(timeout)\n }, [copied])\n\n return (\n <>\n <Button\n data-slot=\"code-block-copy-button\"\n data-copied={copied || undefined}\n variant={variant}\n size={size}\n aria-label={copied ? \"Copied\" : \"Copy\"}\n className={cn(className)}\n onClick={(event) => {\n onClick?.(event)\n navigator.clipboard\n .writeText(value)\n .then(() => setCopied(true))\n .catch(() => {})\n }}\n {...props}\n >\n {copied ? (\n <CheckIcon\n />\n ) : (\n <CopyIcon\n />\n )}\n </Button>\n <span aria-live=\"polite\" className=\"sr-only\">\n {copied ? \"Copied\" : \"\"}\n </span>\n </>\n )\n}\n\nfunction CodeBlockContent({\n className,\n children,\n style,\n wrap = false,\n lineNumbers = false,\n startLine = 1,\n ...props\n}: React.ComponentProps<\"pre\"> & {\n wrap?: boolean\n lineNumbers?: boolean\n startLine?: number\n}) {\n return (\n <pre\n data-slot=\"code-block-content\"\n data-wrap={wrap || undefined}\n data-numbered={lineNumbers || undefined}\n dir=\"ltr\"\n tabIndex={0}\n style={{ counterReset: `line ${startLine - 1}`, ...style }}\n className={cn(\n \"min-h-0 min-w-0 scroll-fade-x scrollbar-thin overflow-auto px-3 py-3 text-start font-mono leading-relaxed outline-none group-has-data-[slot=code-block-footer]/code-block:pb-2 group-has-data-[slot=code-block-header]/code-block:pt-2 group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:py-2.5 group-data-[size=sm]/code-block:group-has-data-[slot=code-block-header]/code-block:pt-1.5 data-wrap:scroll-fade-y data-wrap:wrap-break-word data-wrap:whitespace-pre-wrap\",\n className\n )}\n {...props}\n >\n <code\n data-slot=\"code-block-code\"\n className=\"grid min-h-lh min-w-max content-start in-data-numbered:grid-cols-[auto_1fr] in-data-wrap:min-w-0\"\n >\n {lineNumbers && typeof children === \"string\"\n ? children\n .replace(/\\n$/, \"\")\n .split(\"\\n\")\n .map((line, index) => (\n <CodeBlockLine key={index}>{line}</CodeBlockLine>\n ))\n : children}\n </code>\n </pre>\n )\n}\n\nconst codeBlockLineVariants = cva(\n \"relative -mx-3 block min-h-lh px-3 group-data-[size=sm]/code-block:-mx-2.5 group-data-[size=sm]/code-block:px-2.5 before:min-w-6 before:text-end before:text-muted-foreground after:absolute after:start-1 after:top-0 after:text-muted-foreground after:select-none in-data-numbered:col-span-2 in-data-numbered:grid in-data-numbered:grid-cols-subgrid in-data-numbered:gap-x-3 in-data-numbered:[counter-increment:line] in-data-numbered:before:content-[counter(line)] in-data-numbered:before:select-none in-data-numbered:supports-[content:counter(line)_/_'']:before:content-[counter(line)_/_'']\",\n {\n variants: {\n variant: {\n default: \"\",\n added: \"bg-muted after:content-['+']\",\n removed: \"bg-destructive/10 after:text-destructive after:content-['−']\",\n highlighted: \"bg-muted\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction CodeBlockLine({\n className,\n variant = \"default\",\n children,\n ...props\n}: React.ComponentProps<\"span\"> & VariantProps<typeof codeBlockLineVariants>) {\n // An empty line holds a newline so copying a selection keeps blank lines.\n const empty =\n children === undefined ||\n children === null ||\n children === \"\" ||\n (Array.isArray(children) && children.length === 0)\n\n return (\n <span\n data-slot=\"code-block-line\"\n data-variant={variant}\n className={cn(codeBlockLineVariants({ variant }), className)}\n {...props}\n >\n <span data-slot=\"code-block-line-content\" className=\"min-w-0\">\n {empty ? \"\\n\" : children}\n </span>\n </span>\n )\n}\n\nfunction CodeBlockFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"code-block-footer\"\n className={cn(\n \"flex min-w-0 shrink-0 items-center gap-2 px-3 pb-3 text-muted-foreground group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:pb-2.5\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n CodeBlock,\n CodeBlockHeader,\n CodeBlockTitle,\n CodeBlockActions,\n CodeBlockCopyButton,\n CodeBlockContent,\n CodeBlockLine,\n CodeBlockFooter,\n}\n"],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { Button } from "./button.cjs";
2
+ import * as React from "react";
3
+ import { VariantProps } from "class-variance-authority";
4
+ //#region src/primitives/code-block.d.ts
5
+ declare const codeBlockVariants: (props?: ({
6
+ variant?: "default" | "destructive" | null | undefined;
7
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
8
+ declare function CodeBlock({ className, variant, size, ...props }: React.ComponentProps<"div"> & VariantProps<typeof codeBlockVariants> & {
9
+ size?: "default" | "sm";
10
+ }): import("react/jsx-runtime").JSX.Element;
11
+ declare function CodeBlockHeader({ className, ...props }: React.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
12
+ declare function CodeBlockTitle({ className, ...props }: React.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
13
+ declare function CodeBlockActions({ className, ...props }: React.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
14
+ declare function CodeBlockCopyButton({ value, variant, size, className, onClick, ...props }: React.ComponentProps<typeof Button> & {
15
+ value: string;
16
+ }): import("react/jsx-runtime").JSX.Element;
17
+ declare function CodeBlockContent({ className, children, style, wrap, lineNumbers, startLine, ...props }: React.ComponentProps<"pre"> & {
18
+ wrap?: boolean;
19
+ lineNumbers?: boolean;
20
+ startLine?: number;
21
+ }): import("react/jsx-runtime").JSX.Element;
22
+ declare const codeBlockLineVariants: (props?: ({
23
+ variant?: "default" | "added" | "removed" | "highlighted" | null | undefined;
24
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
25
+ declare function CodeBlockLine({ className, variant, children, ...props }: React.ComponentProps<"span"> & VariantProps<typeof codeBlockLineVariants>): import("react/jsx-runtime").JSX.Element;
26
+ declare function CodeBlockFooter({ className, ...props }: React.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
27
+ //#endregion
28
+ export { CodeBlock, CodeBlockActions, CodeBlockContent, CodeBlockCopyButton, CodeBlockFooter, CodeBlockHeader, CodeBlockLine, CodeBlockTitle };
29
+ //# sourceMappingURL=code-block.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-block.d.cts","names":[],"sources":["../../src/primitives/code-block.tsx"],"mappings":";;;;cAOM,oBAAiB;;6CAetB;iBAEQ,YACP,WACA,SACA,SACG,SACF,MAAM,wBACP,oBAAoB;EAAuB;gCAAyB,IAAA;iBAY7D,kBAAkB,cAAc,SAAS,MAAM,oDAAqB,IAAA;iBAapE,iBAAiB,cAAc,SAAS,MAAM,oDAAqB,IAAA;iBAanE,mBACP,cACG,SACF,MAAM,oDAAqB,IAAA;iBAarB,sBACP,OACA,SACA,MACA,WACA,YACG,SACF,MAAM,sBAAsB;EAAY;gCAAe,IAAA;iBA6CjD,mBACP,WACA,UACA,OACA,MACA,aACA,cACG,SACF,MAAM;EACP;EACA;EACA;gCACD,IAAA;cAgCK,wBAAqB;;6CAe1B;iBAEQ,gBACP,WACA,SACA,aACG,SACF,MAAM,yBAAyB,oBAAoB,qDAAsB,IAAA;iBAsBnE,kBAAkB,cAAc,SAAS,MAAM,oDAAqB,IAAA"}
@@ -0,0 +1,29 @@
1
+ import { Button } from "./button.mjs";
2
+ import * as React from "react";
3
+ import { VariantProps } from "class-variance-authority";
4
+ //#region src/primitives/code-block.d.ts
5
+ declare const codeBlockVariants: (props?: ({
6
+ variant?: "default" | "destructive" | null | undefined;
7
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
8
+ declare function CodeBlock({ className, variant, size, ...props }: React.ComponentProps<"div"> & VariantProps<typeof codeBlockVariants> & {
9
+ size?: "default" | "sm";
10
+ }): import("react/jsx-runtime").JSX.Element;
11
+ declare function CodeBlockHeader({ className, ...props }: React.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
12
+ declare function CodeBlockTitle({ className, ...props }: React.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
13
+ declare function CodeBlockActions({ className, ...props }: React.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
14
+ declare function CodeBlockCopyButton({ value, variant, size, className, onClick, ...props }: React.ComponentProps<typeof Button> & {
15
+ value: string;
16
+ }): import("react/jsx-runtime").JSX.Element;
17
+ declare function CodeBlockContent({ className, children, style, wrap, lineNumbers, startLine, ...props }: React.ComponentProps<"pre"> & {
18
+ wrap?: boolean;
19
+ lineNumbers?: boolean;
20
+ startLine?: number;
21
+ }): import("react/jsx-runtime").JSX.Element;
22
+ declare const codeBlockLineVariants: (props?: ({
23
+ variant?: "default" | "added" | "removed" | "highlighted" | null | undefined;
24
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
25
+ declare function CodeBlockLine({ className, variant, children, ...props }: React.ComponentProps<"span"> & VariantProps<typeof codeBlockLineVariants>): import("react/jsx-runtime").JSX.Element;
26
+ declare function CodeBlockFooter({ className, ...props }: React.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
27
+ //#endregion
28
+ export { CodeBlock, CodeBlockActions, CodeBlockContent, CodeBlockCopyButton, CodeBlockFooter, CodeBlockHeader, CodeBlockLine, CodeBlockTitle };
29
+ //# sourceMappingURL=code-block.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-block.d.mts","names":[],"sources":["../../src/primitives/code-block.tsx"],"mappings":";;;;cAOM,oBAAiB;;6CAetB;iBAEQ,YACP,WACA,SACA,SACG,SACF,MAAM,wBACP,oBAAoB;EAAuB;gCAAyB,IAAA;iBAY7D,kBAAkB,cAAc,SAAS,MAAM,oDAAqB,IAAA;iBAapE,iBAAiB,cAAc,SAAS,MAAM,oDAAqB,IAAA;iBAanE,mBACP,cACG,SACF,MAAM,oDAAqB,IAAA;iBAarB,sBACP,OACA,SACA,MACA,WACA,YACG,SACF,MAAM,sBAAsB;EAAY;gCAAe,IAAA;iBA6CjD,mBACP,WACA,UACA,OACA,MACA,aACA,cACG,SACF,MAAM;EACP;EACA;EACA;gCACD,IAAA;cAgCK,wBAAqB;;6CAe1B;iBAEQ,gBACP,WACA,SACA,aACG,SACF,MAAM,yBAAyB,oBAAoB,qDAAsB,IAAA;iBAsBnE,kBAAkB,cAAc,SAAS,MAAM,oDAAqB,IAAA"}
@@ -0,0 +1,124 @@
1
+ import { Button } from "./button.mjs";
2
+ import * as React from "react";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+ import { cva } from "class-variance-authority";
5
+ import { cn } from "cn";
6
+ import { CheckIcon, CopyIcon } from "lucide-react";
7
+ //#region src/primitives/code-block.tsx
8
+ const codeBlockVariants = cva("group/code-block relative flex w-full min-w-0 flex-col overflow-hidden rounded-lg text-sm has-[>[data-slot=code-block-content]:focus-visible]:ring-3 has-[>[data-slot=code-block-content]:focus-visible]:ring-ring/50 data-[size=sm]:text-xs", {
9
+ variants: { variant: {
10
+ default: "border border-input text-foreground has-[>[data-slot=code-block-content]:focus-visible]:border-ring dark:bg-input/30",
11
+ destructive: "border border-destructive/30 text-destructive dark:border-destructive/40"
12
+ } },
13
+ defaultVariants: { variant: "default" }
14
+ });
15
+ function CodeBlock({ className, variant = "default", size = "default", ...props }) {
16
+ return /* @__PURE__ */ jsx("div", {
17
+ "data-slot": "code-block",
18
+ "data-variant": variant,
19
+ "data-size": size,
20
+ className: cn(codeBlockVariants({ variant }), className),
21
+ ...props
22
+ });
23
+ }
24
+ function CodeBlockHeader({ className, ...props }) {
25
+ return /* @__PURE__ */ jsx("div", {
26
+ "data-slot": "code-block-header",
27
+ className: cn("flex min-w-0 shrink-0 items-center gap-2 px-3 pt-3 text-muted-foreground group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:pt-2.5 group-data-[variant=destructive]/code-block:text-destructive *:has-[>[data-slot=code-block-title]]:min-w-0", className),
28
+ ...props
29
+ });
30
+ }
31
+ function CodeBlockTitle({ className, ...props }) {
32
+ return /* @__PURE__ */ jsx("div", {
33
+ "data-slot": "code-block-title",
34
+ className: cn("min-w-0 truncate font-sans text-sm font-medium text-foreground group-data-[size=sm]/code-block:text-xs group-data-[variant=destructive]/code-block:text-destructive [&_svg]:pointer-events-none [&_svg]:inline-block [&_svg]:align-middle [&_svg:not([class*='size-'])]:size-3.5 *:[svg]:me-1.5", className),
35
+ ...props
36
+ });
37
+ }
38
+ function CodeBlockActions({ className, ...props }) {
39
+ return /* @__PURE__ */ jsx("div", {
40
+ "data-slot": "code-block-actions",
41
+ className: cn("-my-1 ms-auto -me-1.5 flex shrink-0 items-center gap-1 [[data-slot=code-block]>&]:absolute [[data-slot=code-block]>&]:end-2 [[data-slot=code-block]>&]:top-2 [[data-slot=code-block]>&]:z-10 [[data-slot=code-block]>&]:m-0 [[data-slot=code-block]>&]:opacity-0 [[data-slot=code-block]>&]:transition-opacity [[data-slot=code-block]>&]:group-focus-within/code-block:opacity-100 [[data-slot=code-block]>&]:group-hover/code-block:opacity-100 group-data-[size=sm]/code-block:[[data-slot=code-block]>&]:end-1.5 group-data-[size=sm]/code-block:[[data-slot=code-block]>&]:top-1.5 [[data-slot=code-block]>&]:pointer-coarse:opacity-100 [[data-slot=code-block]>&]:*:[button]:bg-background [[data-slot=code-block]>&]:*:[button]:ring-1 [[data-slot=code-block]>&]:*:[button]:ring-foreground/10", className),
42
+ ...props
43
+ });
44
+ }
45
+ function CodeBlockCopyButton({ value, variant = "ghost", size = "icon-xs", className, onClick, ...props }) {
46
+ const [copied, setCopied] = React.useState(false);
47
+ React.useEffect(() => {
48
+ if (!copied) return;
49
+ const timeout = setTimeout(() => setCopied(false), 2e3);
50
+ return () => clearTimeout(timeout);
51
+ }, [copied]);
52
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Button, {
53
+ "data-slot": "code-block-copy-button",
54
+ "data-copied": copied || void 0,
55
+ variant,
56
+ size,
57
+ "aria-label": copied ? "Copied" : "Copy",
58
+ className: cn(className),
59
+ onClick: (event) => {
60
+ onClick?.(event);
61
+ navigator.clipboard.writeText(value).then(() => setCopied(true)).catch(() => {});
62
+ },
63
+ ...props,
64
+ children: copied ? /* @__PURE__ */ jsx(CheckIcon, {}) : /* @__PURE__ */ jsx(CopyIcon, {})
65
+ }), /* @__PURE__ */ jsx("span", {
66
+ "aria-live": "polite",
67
+ className: "sr-only",
68
+ children: copied ? "Copied" : ""
69
+ })] });
70
+ }
71
+ function CodeBlockContent({ className, children, style, wrap = false, lineNumbers = false, startLine = 1, ...props }) {
72
+ return /* @__PURE__ */ jsx("pre", {
73
+ "data-slot": "code-block-content",
74
+ "data-wrap": wrap || void 0,
75
+ "data-numbered": lineNumbers || void 0,
76
+ dir: "ltr",
77
+ tabIndex: 0,
78
+ style: {
79
+ counterReset: `line ${startLine - 1}`,
80
+ ...style
81
+ },
82
+ className: cn("min-h-0 min-w-0 scroll-fade-x scrollbar-thin overflow-auto px-3 py-3 text-start font-mono leading-relaxed outline-none group-has-data-[slot=code-block-footer]/code-block:pb-2 group-has-data-[slot=code-block-header]/code-block:pt-2 group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:py-2.5 group-data-[size=sm]/code-block:group-has-data-[slot=code-block-header]/code-block:pt-1.5 data-wrap:scroll-fade-y data-wrap:wrap-break-word data-wrap:whitespace-pre-wrap", className),
83
+ ...props,
84
+ children: /* @__PURE__ */ jsx("code", {
85
+ "data-slot": "code-block-code",
86
+ className: "grid min-h-lh min-w-max content-start in-data-numbered:grid-cols-[auto_1fr] in-data-wrap:min-w-0",
87
+ children: lineNumbers && typeof children === "string" ? children.replace(/\n$/, "").split("\n").map((line, index) => /* @__PURE__ */ jsx(CodeBlockLine, { children: line }, index)) : children
88
+ })
89
+ });
90
+ }
91
+ const codeBlockLineVariants = cva("relative -mx-3 block min-h-lh px-3 group-data-[size=sm]/code-block:-mx-2.5 group-data-[size=sm]/code-block:px-2.5 before:min-w-6 before:text-end before:text-muted-foreground after:absolute after:start-1 after:top-0 after:text-muted-foreground after:select-none in-data-numbered:col-span-2 in-data-numbered:grid in-data-numbered:grid-cols-subgrid in-data-numbered:gap-x-3 in-data-numbered:[counter-increment:line] in-data-numbered:before:content-[counter(line)] in-data-numbered:before:select-none in-data-numbered:supports-[content:counter(line)_/_'']:before:content-[counter(line)_/_'']", {
92
+ variants: { variant: {
93
+ default: "",
94
+ added: "bg-muted after:content-['+']",
95
+ removed: "bg-destructive/10 after:text-destructive after:content-['−']",
96
+ highlighted: "bg-muted"
97
+ } },
98
+ defaultVariants: { variant: "default" }
99
+ });
100
+ function CodeBlockLine({ className, variant = "default", children, ...props }) {
101
+ const empty = children === void 0 || children === null || children === "" || Array.isArray(children) && children.length === 0;
102
+ return /* @__PURE__ */ jsx("span", {
103
+ "data-slot": "code-block-line",
104
+ "data-variant": variant,
105
+ className: cn(codeBlockLineVariants({ variant }), className),
106
+ ...props,
107
+ children: /* @__PURE__ */ jsx("span", {
108
+ "data-slot": "code-block-line-content",
109
+ className: "min-w-0",
110
+ children: empty ? "\n" : children
111
+ })
112
+ });
113
+ }
114
+ function CodeBlockFooter({ className, ...props }) {
115
+ return /* @__PURE__ */ jsx("div", {
116
+ "data-slot": "code-block-footer",
117
+ className: cn("flex min-w-0 shrink-0 items-center gap-2 px-3 pb-3 text-muted-foreground group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:pb-2.5", className),
118
+ ...props
119
+ });
120
+ }
121
+ //#endregion
122
+ export { CodeBlock, CodeBlockActions, CodeBlockContent, CodeBlockCopyButton, CodeBlockFooter, CodeBlockHeader, CodeBlockLine, CodeBlockTitle };
123
+
124
+ //# sourceMappingURL=code-block.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-block.mjs","names":[],"sources":["../../src/primitives/code-block.tsx"],"sourcesContent":["import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"cn\"\n\nimport { Button } from \"@/primitives/button\"\nimport { CheckIcon, CopyIcon } from \"lucide-react\"\n\nconst codeBlockVariants = cva(\n \"group/code-block relative flex w-full min-w-0 flex-col overflow-hidden rounded-lg text-sm has-[>[data-slot=code-block-content]:focus-visible]:ring-3 has-[>[data-slot=code-block-content]:focus-visible]:ring-ring/50 data-[size=sm]:text-xs\",\n {\n variants: {\n variant: {\n default:\n \"border border-input text-foreground has-[>[data-slot=code-block-content]:focus-visible]:border-ring dark:bg-input/30\",\n destructive:\n \"border border-destructive/30 text-destructive dark:border-destructive/40\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction CodeBlock({\n className,\n variant = \"default\",\n size = \"default\",\n ...props\n}: React.ComponentProps<\"div\"> &\n VariantProps<typeof codeBlockVariants> & { size?: \"default\" | \"sm\" }) {\n return (\n <div\n data-slot=\"code-block\"\n data-variant={variant}\n data-size={size}\n className={cn(codeBlockVariants({ variant }), className)}\n {...props}\n />\n )\n}\n\nfunction CodeBlockHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"code-block-header\"\n className={cn(\n \"flex min-w-0 shrink-0 items-center gap-2 px-3 pt-3 text-muted-foreground group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:pt-2.5 group-data-[variant=destructive]/code-block:text-destructive *:has-[>[data-slot=code-block-title]]:min-w-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CodeBlockTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"code-block-title\"\n className={cn(\n \"min-w-0 truncate font-sans text-sm font-medium text-foreground group-data-[size=sm]/code-block:text-xs group-data-[variant=destructive]/code-block:text-destructive [&_svg]:pointer-events-none [&_svg]:inline-block [&_svg]:align-middle [&_svg:not([class*='size-'])]:size-3.5 *:[svg]:me-1.5\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CodeBlockActions({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"code-block-actions\"\n className={cn(\n \"-my-1 ms-auto -me-1.5 flex shrink-0 items-center gap-1 [[data-slot=code-block]>&]:absolute [[data-slot=code-block]>&]:end-2 [[data-slot=code-block]>&]:top-2 [[data-slot=code-block]>&]:z-10 [[data-slot=code-block]>&]:m-0 [[data-slot=code-block]>&]:opacity-0 [[data-slot=code-block]>&]:transition-opacity [[data-slot=code-block]>&]:group-focus-within/code-block:opacity-100 [[data-slot=code-block]>&]:group-hover/code-block:opacity-100 group-data-[size=sm]/code-block:[[data-slot=code-block]>&]:end-1.5 group-data-[size=sm]/code-block:[[data-slot=code-block]>&]:top-1.5 [[data-slot=code-block]>&]:pointer-coarse:opacity-100 [[data-slot=code-block]>&]:*:[button]:bg-background [[data-slot=code-block]>&]:*:[button]:ring-1 [[data-slot=code-block]>&]:*:[button]:ring-foreground/10\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CodeBlockCopyButton({\n value,\n variant = \"ghost\",\n size = \"icon-xs\",\n className,\n onClick,\n ...props\n}: React.ComponentProps<typeof Button> & { value: string }) {\n const [copied, setCopied] = React.useState(false)\n\n React.useEffect(() => {\n if (!copied) {\n return\n }\n\n const timeout = setTimeout(() => setCopied(false), 2000)\n return () => clearTimeout(timeout)\n }, [copied])\n\n return (\n <>\n <Button\n data-slot=\"code-block-copy-button\"\n data-copied={copied || undefined}\n variant={variant}\n size={size}\n aria-label={copied ? \"Copied\" : \"Copy\"}\n className={cn(className)}\n onClick={(event) => {\n onClick?.(event)\n navigator.clipboard\n .writeText(value)\n .then(() => setCopied(true))\n .catch(() => {})\n }}\n {...props}\n >\n {copied ? (\n <CheckIcon\n />\n ) : (\n <CopyIcon\n />\n )}\n </Button>\n <span aria-live=\"polite\" className=\"sr-only\">\n {copied ? \"Copied\" : \"\"}\n </span>\n </>\n )\n}\n\nfunction CodeBlockContent({\n className,\n children,\n style,\n wrap = false,\n lineNumbers = false,\n startLine = 1,\n ...props\n}: React.ComponentProps<\"pre\"> & {\n wrap?: boolean\n lineNumbers?: boolean\n startLine?: number\n}) {\n return (\n <pre\n data-slot=\"code-block-content\"\n data-wrap={wrap || undefined}\n data-numbered={lineNumbers || undefined}\n dir=\"ltr\"\n tabIndex={0}\n style={{ counterReset: `line ${startLine - 1}`, ...style }}\n className={cn(\n \"min-h-0 min-w-0 scroll-fade-x scrollbar-thin overflow-auto px-3 py-3 text-start font-mono leading-relaxed outline-none group-has-data-[slot=code-block-footer]/code-block:pb-2 group-has-data-[slot=code-block-header]/code-block:pt-2 group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:py-2.5 group-data-[size=sm]/code-block:group-has-data-[slot=code-block-header]/code-block:pt-1.5 data-wrap:scroll-fade-y data-wrap:wrap-break-word data-wrap:whitespace-pre-wrap\",\n className\n )}\n {...props}\n >\n <code\n data-slot=\"code-block-code\"\n className=\"grid min-h-lh min-w-max content-start in-data-numbered:grid-cols-[auto_1fr] in-data-wrap:min-w-0\"\n >\n {lineNumbers && typeof children === \"string\"\n ? children\n .replace(/\\n$/, \"\")\n .split(\"\\n\")\n .map((line, index) => (\n <CodeBlockLine key={index}>{line}</CodeBlockLine>\n ))\n : children}\n </code>\n </pre>\n )\n}\n\nconst codeBlockLineVariants = cva(\n \"relative -mx-3 block min-h-lh px-3 group-data-[size=sm]/code-block:-mx-2.5 group-data-[size=sm]/code-block:px-2.5 before:min-w-6 before:text-end before:text-muted-foreground after:absolute after:start-1 after:top-0 after:text-muted-foreground after:select-none in-data-numbered:col-span-2 in-data-numbered:grid in-data-numbered:grid-cols-subgrid in-data-numbered:gap-x-3 in-data-numbered:[counter-increment:line] in-data-numbered:before:content-[counter(line)] in-data-numbered:before:select-none in-data-numbered:supports-[content:counter(line)_/_'']:before:content-[counter(line)_/_'']\",\n {\n variants: {\n variant: {\n default: \"\",\n added: \"bg-muted after:content-['+']\",\n removed: \"bg-destructive/10 after:text-destructive after:content-['−']\",\n highlighted: \"bg-muted\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction CodeBlockLine({\n className,\n variant = \"default\",\n children,\n ...props\n}: React.ComponentProps<\"span\"> & VariantProps<typeof codeBlockLineVariants>) {\n // An empty line holds a newline so copying a selection keeps blank lines.\n const empty =\n children === undefined ||\n children === null ||\n children === \"\" ||\n (Array.isArray(children) && children.length === 0)\n\n return (\n <span\n data-slot=\"code-block-line\"\n data-variant={variant}\n className={cn(codeBlockLineVariants({ variant }), className)}\n {...props}\n >\n <span data-slot=\"code-block-line-content\" className=\"min-w-0\">\n {empty ? \"\\n\" : children}\n </span>\n </span>\n )\n}\n\nfunction CodeBlockFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"code-block-footer\"\n className={cn(\n \"flex min-w-0 shrink-0 items-center gap-2 px-3 pb-3 text-muted-foreground group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:pb-2.5\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n CodeBlock,\n CodeBlockHeader,\n CodeBlockTitle,\n CodeBlockActions,\n CodeBlockCopyButton,\n CodeBlockContent,\n CodeBlockLine,\n CodeBlockFooter,\n}\n"],"mappings":"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"}