doccupine 0.0.87 → 0.0.89

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 (78) hide show
  1. package/README.md +15 -2
  2. package/dist/index.js +177 -4
  3. package/dist/lib/layout.js +38 -24
  4. package/dist/lib/metadata.d.ts +30 -0
  5. package/dist/lib/metadata.js +98 -1
  6. package/dist/lib/structures.js +0 -2
  7. package/dist/lib/types.d.ts +1 -0
  8. package/dist/templates/app/robots.d.ts +1 -1
  9. package/dist/templates/app/robots.js +28 -1
  10. package/dist/templates/app/sitemap.d.ts +7 -0
  11. package/dist/templates/app/sitemap.js +56 -0
  12. package/dist/templates/app/theme.d.ts +1 -1
  13. package/dist/templates/app/theme.js +84 -19
  14. package/dist/templates/components/Chat.d.ts +1 -1
  15. package/dist/templates/components/Chat.js +26 -27
  16. package/dist/templates/components/SearchModalContent.d.ts +1 -1
  17. package/dist/templates/components/SearchModalContent.js +12 -6
  18. package/dist/templates/components/SideBar.d.ts +1 -1
  19. package/dist/templates/components/SideBar.js +3 -1
  20. package/dist/templates/components/layout/Accordion.d.ts +1 -1
  21. package/dist/templates/components/layout/Accordion.js +2 -1
  22. package/dist/templates/components/layout/ActionBar.d.ts +1 -1
  23. package/dist/templates/components/layout/ActionBar.js +4 -6
  24. package/dist/templates/components/layout/Button.d.ts +1 -1
  25. package/dist/templates/components/layout/Button.js +10 -0
  26. package/dist/templates/components/layout/Callout.d.ts +1 -1
  27. package/dist/templates/components/layout/Callout.js +75 -20
  28. package/dist/templates/components/layout/Card.d.ts +1 -1
  29. package/dist/templates/components/layout/Card.js +2 -1
  30. package/dist/templates/components/layout/CherryThemeProvider.d.ts +1 -1
  31. package/dist/templates/components/layout/CherryThemeProvider.js +6 -12
  32. package/dist/templates/components/layout/ClientThemeProvider.d.ts +1 -1
  33. package/dist/templates/components/layout/ClientThemeProvider.js +45 -40
  34. package/dist/templates/components/layout/Code.d.ts +1 -1
  35. package/dist/templates/components/layout/Code.js +223 -255
  36. package/dist/templates/components/layout/ColorSwatch.d.ts +1 -1
  37. package/dist/templates/components/layout/ColorSwatch.js +2 -2
  38. package/dist/templates/components/layout/Columns.d.ts +1 -1
  39. package/dist/templates/components/layout/Columns.js +1 -1
  40. package/dist/templates/components/layout/DemoTheme.d.ts +1 -1
  41. package/dist/templates/components/layout/DemoTheme.js +65 -167
  42. package/dist/templates/components/layout/DocsComponents.d.ts +1 -1
  43. package/dist/templates/components/layout/DocsComponents.js +13 -19
  44. package/dist/templates/components/layout/Field.d.ts +1 -1
  45. package/dist/templates/components/layout/Field.js +6 -4
  46. package/dist/templates/components/layout/Footer.d.ts +1 -1
  47. package/dist/templates/components/layout/Footer.js +1 -2
  48. package/dist/templates/components/layout/GlobalStyles.d.ts +1 -1
  49. package/dist/templates/components/layout/GlobalStyles.js +63 -10
  50. package/dist/templates/components/layout/Header.d.ts +1 -1
  51. package/dist/templates/components/layout/Header.js +14 -11
  52. package/dist/templates/components/layout/SharedStyles.d.ts +1 -1
  53. package/dist/templates/components/layout/SharedStyles.js +4 -5
  54. package/dist/templates/components/layout/StaticLinks.d.ts +1 -1
  55. package/dist/templates/components/layout/StaticLinks.js +4 -6
  56. package/dist/templates/components/layout/Steps.d.ts +1 -1
  57. package/dist/templates/components/layout/Steps.js +3 -3
  58. package/dist/templates/components/layout/Tabs.d.ts +1 -1
  59. package/dist/templates/components/layout/Tabs.js +5 -2
  60. package/dist/templates/components/layout/ThemeToggle.d.ts +1 -1
  61. package/dist/templates/components/layout/ThemeToggle.js +17 -19
  62. package/dist/templates/components/layout/Typography.d.ts +1 -1
  63. package/dist/templates/components/layout/Typography.js +1 -1
  64. package/dist/templates/components/layout/Update.d.ts +1 -1
  65. package/dist/templates/components/layout/Update.js +4 -3
  66. package/dist/templates/env.example.d.ts +1 -1
  67. package/dist/templates/env.example.js +5 -1
  68. package/dist/templates/mdx/deployment-and-hosting.mdx.d.ts +1 -1
  69. package/dist/templates/mdx/deployment-and-hosting.mdx.js +19 -0
  70. package/dist/templates/mdx/globals.mdx.d.ts +1 -1
  71. package/dist/templates/mdx/globals.mdx.js +3 -1
  72. package/dist/templates/mdx/platform/site-settings.mdx.d.ts +1 -1
  73. package/dist/templates/mdx/platform/site-settings.mdx.js +5 -1
  74. package/dist/templates/package.js +17 -18
  75. package/dist/templates/proxy.js +14 -20
  76. package/dist/templates/utils/config.d.ts +1 -1
  77. package/dist/templates/utils/config.js +1 -0
  78. package/package.json +8 -8
@@ -1 +1 @@
1
- export declare const codeTemplate = "\"use client\";\nimport { useState, useCallback, useMemo } from \"react\";\nimport styled from \"styled-components\";\nimport { Theme, styledCode } from \"cherry-styled-components\";\nimport { rgba } from \"polished\";\nimport { unified } from \"unified\";\nimport rehypeParse from \"rehype-parse\";\nimport rehypeHighlight from \"rehype-highlight\";\nimport rehypeStringify from \"rehype-stringify\";\nimport { Icon } from \"@/components/layout/Icon\";\n\ninterface CodeProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n \"theme\"\n> {\n code: string;\n language?: string;\n theme?: Theme;\n}\n\nconst CodeWrapper = styled.span<{ theme: Theme }>`\n position: relative;\n z-index: 2;\n display: block;\n width: 100%;\n border-radius: ${({ theme }) => theme.spacing.radius.lg};\n border: solid 1px\n ${({ theme }) =>\n theme.isDark\n ? rgba(theme.colors.dark, 0.2)\n : rgba(theme.colors.dark, 0.1)};\n`;\n\nconst TopBar = styled.div<{ theme: Theme }>`\n background: ${({ theme }) => (theme.isDark ? \"#0d1117\" : \"#f6f8fa\")};\n border-top-left-radius: ${({ theme }) => theme.spacing.radius.lg};\n border-top-right-radius: ${({ theme }) => theme.spacing.radius.lg};\n border-bottom: solid 1px\n ${({ theme }) =>\n theme.isDark ? rgba(\"#ffffff\", 0.1) : rgba(\"#000000\", 0.1)};\n height: 33px;\n width: 100%;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 5px;\n padding: 0 10px;\n`;\n\nconst DotsContainer = styled.div`\n display: flex;\n gap: 5px;\n`;\n\nconst Dot = styled.span<{ theme: Theme }>`\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: ${({ theme }) =>\n theme.isDark ? rgba(\"#ffffff\", 0.1) : rgba(\"#000000\", 0.1)};\n`;\n\nconst CopyButton = styled.button<{ theme: Theme; $copied: boolean }>`\n background: ${({ theme, $copied }) =>\n $copied\n ? theme.isDark\n ? rgba(\"#7ee787\", 0.2)\n : rgba(\"#2da44e\", 0.1)\n : \"transparent\"};\n border: solid 1px\n ${({ theme, $copied }) =>\n $copied\n ? theme.isDark\n ? \"#7ee787\"\n : \"#2da44e\"\n : theme.isDark\n ? rgba(\"#ffffff\", 0.1)\n : rgba(\"#000000\", 0.1)};\n color: ${({ theme, $copied }) =>\n $copied\n ? theme.isDark\n ? \"#7ee787\"\n : \"#2da44e\"\n : theme.isDark\n ? \"#c9d1d9\"\n : \"#57606a\"};\n border-radius: ${({ theme }) => theme.spacing.radius.xs};\n padding: 4px 8px;\n font-size: 12px;\n font-family: ${({ theme }) => theme.fonts.mono};\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 4px;\n margin-right: -6px;\n\n & svg.lucide {\n color: ${({ theme, $copied }) =>\n $copied\n ? theme.isDark\n ? \"#7ee787\"\n : \"#2da44e\"\n : theme.isDark\n ? \"#c9d1d9\"\n : \"#57606a\"};\n }\n\n &:hover {\n background: ${({ theme, $copied }) =>\n $copied\n ? theme.isDark\n ? rgba(\"#7ee787\", 0.3)\n : rgba(\"#2da44e\", 0.2)\n : theme.isDark\n ? rgba(\"#ffffff\", 0.1)\n : rgba(\"#000000\", 0.05)};\n border-color: ${({ theme, $copied }) =>\n $copied\n ? theme.isDark\n ? \"#7ee787\"\n : \"#2da44e\"\n : theme.isDark\n ? rgba(\"#ffffff\", 0.2)\n : rgba(\"#000000\", 0.2)};\n }\n\n &:active {\n transform: scale(0.95);\n }\n`;\n\nconst Body = styled.div<{ theme: Theme }>`\n background: ${({ theme }) => (theme.isDark ? \"#0d1117\" : \"#ffffff\")};\n border-bottom-left-radius: ${({ theme }) => theme.spacing.radius.lg};\n border-bottom-right-radius: ${({ theme }) => theme.spacing.radius.lg};\n color: ${({ theme }) => (theme.isDark ? \"#ffffff\" : \"#24292f\")};\n padding: 20px;\n font-family: ${({ theme }) => theme.fonts.mono};\n text-align: left;\n overflow-x: auto;\n overflow-y: auto;\n max-height: calc(100dvh - 400px);\n ${({ theme }) => styledCode(theme)};\n\n /* Dark mode syntax highlighting (GitHub Dark) */\n ${({ theme }) =>\n theme.isDark &&\n `\n & .hljs {\n color: #c9d1d9;\n background: #0d1117;\n }\n\n & .hljs-doctag,\n & .hljs-keyword,\n & .hljs-meta .hljs-keyword,\n & .hljs-template-tag,\n & .hljs-template-variable,\n & .hljs-type,\n & .hljs-variable.language_ {\n color: #ff7b72;\n }\n\n & .hljs-title,\n & .hljs-title.class_,\n & .hljs-title.class_.inherited__,\n & .hljs-title.function_ {\n color: #d2a8ff;\n }\n\n & .hljs-attr,\n & .hljs-attribute,\n & .hljs-literal,\n & .hljs-meta,\n & .hljs-number,\n & .hljs-operator,\n & .hljs-selector-attr,\n & .hljs-selector-class,\n & .hljs-selector-id,\n & .hljs-variable {\n color: #79c0ff;\n }\n\n & .hljs-meta .hljs-string,\n & .hljs-regexp,\n & .hljs-string {\n color: #a5d6ff;\n }\n\n & .hljs-built_in,\n & .hljs-symbol {\n color: #ffa657;\n }\n\n & .hljs-code,\n & .hljs-comment,\n & .hljs-formula {\n color: #8b949e;\n }\n\n & .hljs-name,\n & .hljs-quote,\n & .hljs-selector-pseudo,\n & .hljs-selector-tag {\n color: #7ee787;\n }\n\n & .hljs-subst {\n color: #c9d1d9;\n }\n\n & .hljs-section {\n color: #1f6feb;\n font-weight: 700;\n }\n\n & .hljs-bullet {\n color: #f2cc60;\n }\n\n & .hljs-emphasis {\n color: #c9d1d9;\n font-style: italic;\n }\n\n & .hljs-strong {\n color: #c9d1d9;\n font-weight: 700;\n }\n\n & .hljs-addition {\n color: #aff5b4;\n background-color: #033a16;\n }\n\n & .hljs-deletion {\n color: #ffdcd7;\n background-color: #67060c;\n }\n `}\n\n /* Light mode syntax highlighting (GitHub Light) */\n ${({ theme }) =>\n !theme.isDark &&\n `\n & .hljs {\n color: #24292f;\n background: #ffffff;\n }\n\n & .hljs-doctag,\n & .hljs-keyword,\n & .hljs-meta .hljs-keyword,\n & .hljs-template-tag,\n & .hljs-template-variable,\n & .hljs-type,\n & .hljs-variable.language_ {\n color: #cf222e;\n }\n\n & .hljs-title,\n & .hljs-title.class_,\n & .hljs-title.class_.inherited__,\n & .hljs-title.function_ {\n color: #8250df;\n }\n\n & .hljs-attr,\n & .hljs-attribute,\n & .hljs-literal,\n & .hljs-meta,\n & .hljs-number,\n & .hljs-operator,\n & .hljs-selector-attr,\n & .hljs-selector-class,\n & .hljs-selector-id,\n & .hljs-variable {\n color: #0550ae;\n }\n\n & .hljs-meta .hljs-string,\n & .hljs-regexp,\n & .hljs-string {\n color: #0a3069;\n }\n\n & .hljs-built_in,\n & .hljs-symbol {\n color: #953800;\n }\n\n & .hljs-code,\n & .hljs-comment,\n & .hljs-formula {\n color: #6e7781;\n }\n\n & .hljs-name,\n & .hljs-quote,\n & .hljs-selector-pseudo,\n & .hljs-selector-tag {\n color: #116329;\n }\n\n & .hljs-subst {\n color: #24292f;\n }\n\n & .hljs-section {\n color: #0550ae;\n font-weight: 700;\n }\n\n & .hljs-bullet {\n color: #953800;\n }\n\n & .hljs-emphasis {\n color: #24292f;\n font-style: italic;\n }\n\n & .hljs-strong {\n color: #24292f;\n font-weight: 700;\n }\n\n & .hljs-addition {\n color: #116329;\n background-color: #dafbe1;\n }\n\n & .hljs-deletion {\n color: #82071e;\n background-color: #ffebe9;\n }\n `}\n`;\n\nconst escapeHtml = (unsafe: string): string => {\n return unsafe\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#039;\");\n};\n\nconst sanitizeLanguage = (lang: string): string =>\n lang.replace(/[^a-zA-Z0-9_-]/g, \"\");\n\nconst highlightCode = (code: string, language: string): string => {\n const escapedCode = escapeHtml(code);\n const safeLang = sanitizeLanguage(language);\n const result = unified()\n .use(rehypeParse, { fragment: true })\n .use(rehypeHighlight, {\n detect: true,\n ignoreMissing: true,\n })\n .use(rehypeStringify)\n .processSync(\n `<pre><code class=\"language-${safeLang}\">${escapedCode}</code></pre>`,\n );\n\n return String(result);\n};\n\nfunction Code({ code, language = \"javascript\", theme, className }: CodeProps) {\n const [copied, setCopied] = useState(false);\n const highlightedCode = useMemo(\n () => highlightCode(code, language),\n [code, language],\n );\n\n const handleCopy = useCallback(async () => {\n try {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch (err) {\n console.error(\"Failed to copy code:\", err);\n }\n }, [code]);\n\n return (\n <CodeWrapper\n className={`${className ?? \"\"} code-wrapper`.trim()}\n theme={theme}\n >\n <TopBar theme={theme}>\n <DotsContainer>\n <Dot theme={theme} />\n <Dot theme={theme} />\n <Dot theme={theme} />\n </DotsContainer>\n <CopyButton onClick={handleCopy} $copied={copied} theme={theme}>\n {copied ? (\n <>\n <Icon name=\"check\" size={12} />\n <span>Copied!</span>\n </>\n ) : (\n <>\n <Icon name=\"copy\" size={12} />\n <span>Copy</span>\n </>\n )}\n </CopyButton>\n </TopBar>\n <Body\n dangerouslySetInnerHTML={{ __html: highlightedCode }}\n theme={theme}\n className=\"code-wrapper-body\"\n />\n </CodeWrapper>\n );\n}\n\nexport { Code };\n";
1
+ export declare const codeTemplate = "\"use client\";\nimport { useState, useCallback, useMemo } from \"react\";\nimport styled, { css } from \"styled-components\";\nimport { styledCode } from \"cherry-styled-components\";\nimport { Theme } from \"@/app/theme\";\nimport { unified } from \"unified\";\nimport rehypeParse from \"rehype-parse\";\nimport rehypeHighlight from \"rehype-highlight\";\nimport rehypeStringify from \"rehype-stringify\";\nimport { Icon } from \"@/components/layout/Icon\";\n\ninterface CodeProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n \"theme\"\n> {\n code: string;\n language?: string;\n theme?: Theme;\n}\n\nconst CodeWrapper = styled.span<{ theme: Theme }>`\n position: relative;\n z-index: 2;\n display: block;\n width: 100%;\n border-radius: ${({ theme }) => theme.spacing.radius.lg};\n border: solid 1px rgba(0, 0, 0, 0.1);\n\n :root.dark & {\n border-color: rgba(255, 255, 255, 0.2);\n }\n`;\n\n/* Code block uses a fixed GitHub-style palette in both modes. Independent of\n theme.json so syntax highlighting stays legible regardless of brand colors.\n Dark variants live in :root.dark & blocks so the swap happens via the\n active <html> class with no re-render. */\nconst TopBar = styled.div<{ theme: Theme }>`\n background: #f6f8fa;\n border-top-left-radius: ${({ theme }) => theme.spacing.radius.lg};\n border-top-right-radius: ${({ theme }) => theme.spacing.radius.lg};\n border-bottom: solid 1px rgba(0, 0, 0, 0.1);\n height: 33px;\n width: 100%;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 5px;\n padding: 0 10px;\n\n :root.dark & {\n background: #0d1117;\n border-bottom-color: rgba(255, 255, 255, 0.1);\n }\n`;\n\nconst DotsContainer = styled.div`\n display: flex;\n gap: 5px;\n`;\n\nconst Dot = styled.span<{ theme: Theme }>`\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: rgba(0, 0, 0, 0.1);\n\n :root.dark & {\n background: rgba(255, 255, 255, 0.1);\n }\n`;\n\nconst CopyButton = styled.button<{ theme: Theme; $copied: boolean }>`\n background: ${({ $copied }) =>\n $copied ? \"rgba(45, 164, 78, 0.1)\" : \"transparent\"};\n border: solid 1px\n ${({ $copied }) => ($copied ? \"#2da44e\" : \"rgba(0, 0, 0, 0.1)\")};\n color: ${({ $copied }) => ($copied ? \"#2da44e\" : \"#57606a\")};\n border-radius: ${({ theme }) => theme.spacing.radius.xs};\n padding: 4px 8px;\n font-size: 12px;\n font-family: ${({ theme }) => theme.fonts.mono};\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 4px;\n margin-right: -6px;\n\n & svg.lucide {\n color: ${({ $copied }) => ($copied ? \"#2da44e\" : \"#57606a\")};\n }\n\n &:hover {\n background: ${({ $copied }) =>\n $copied ? \"rgba(45, 164, 78, 0.2)\" : \"rgba(0, 0, 0, 0.05)\"};\n border-color: ${({ $copied }) =>\n $copied ? \"#2da44e\" : \"rgba(0, 0, 0, 0.2)\"};\n }\n\n &:active {\n transform: scale(0.95);\n }\n\n :root.dark & {\n background: ${({ $copied }) =>\n $copied ? \"rgba(126, 231, 135, 0.2)\" : \"transparent\"};\n border-color: ${({ $copied }) =>\n $copied ? \"#7ee787\" : \"rgba(255, 255, 255, 0.1)\"};\n color: ${({ $copied }) => ($copied ? \"#7ee787\" : \"#c9d1d9\")};\n\n & svg.lucide {\n color: ${({ $copied }) => ($copied ? \"#7ee787\" : \"#c9d1d9\")};\n }\n\n &:hover {\n background: ${({ $copied }) =>\n $copied ? \"rgba(126, 231, 135, 0.3)\" : \"rgba(255, 255, 255, 0.1)\"};\n border-color: ${({ $copied }) =>\n $copied ? \"#7ee787\" : \"rgba(255, 255, 255, 0.2)\"};\n }\n }\n`;\n\n/* GitHub Light syntax highlighting by default; GitHub Dark in :root.dark.\n Browser resolves which rule wins based on the active <html> class with no\n JS or React re-render involved. */\nconst lightSyntaxHighlight = css`\n & .hljs {\n color: #24292f;\n background: #ffffff;\n }\n & .hljs-doctag,\n & .hljs-keyword,\n & .hljs-meta .hljs-keyword,\n & .hljs-template-tag,\n & .hljs-template-variable,\n & .hljs-type,\n & .hljs-variable.language_ {\n color: #cf222e;\n }\n & .hljs-title,\n & .hljs-title.class_,\n & .hljs-title.class_.inherited__,\n & .hljs-title.function_ {\n color: #8250df;\n }\n & .hljs-attr,\n & .hljs-attribute,\n & .hljs-literal,\n & .hljs-meta,\n & .hljs-number,\n & .hljs-operator,\n & .hljs-selector-attr,\n & .hljs-selector-class,\n & .hljs-selector-id,\n & .hljs-variable {\n color: #0550ae;\n }\n & .hljs-meta .hljs-string,\n & .hljs-regexp,\n & .hljs-string {\n color: #0a3069;\n }\n & .hljs-built_in,\n & .hljs-symbol {\n color: #953800;\n }\n & .hljs-code,\n & .hljs-comment,\n & .hljs-formula {\n color: #6e7781;\n }\n & .hljs-name,\n & .hljs-quote,\n & .hljs-selector-pseudo,\n & .hljs-selector-tag {\n color: #116329;\n }\n & .hljs-subst {\n color: #24292f;\n }\n & .hljs-section {\n color: #0550ae;\n font-weight: 700;\n }\n & .hljs-bullet {\n color: #953800;\n }\n & .hljs-emphasis {\n color: #24292f;\n font-style: italic;\n }\n & .hljs-strong {\n color: #24292f;\n font-weight: 700;\n }\n & .hljs-addition {\n color: #116329;\n background-color: #dafbe1;\n }\n & .hljs-deletion {\n color: #82071e;\n background-color: #ffebe9;\n }\n`;\n\nconst darkSyntaxHighlight = css`\n & .hljs {\n color: #c9d1d9;\n background: #0d1117;\n }\n & .hljs-doctag,\n & .hljs-keyword,\n & .hljs-meta .hljs-keyword,\n & .hljs-template-tag,\n & .hljs-template-variable,\n & .hljs-type,\n & .hljs-variable.language_ {\n color: #ff7b72;\n }\n & .hljs-title,\n & .hljs-title.class_,\n & .hljs-title.class_.inherited__,\n & .hljs-title.function_ {\n color: #d2a8ff;\n }\n & .hljs-attr,\n & .hljs-attribute,\n & .hljs-literal,\n & .hljs-meta,\n & .hljs-number,\n & .hljs-operator,\n & .hljs-selector-attr,\n & .hljs-selector-class,\n & .hljs-selector-id,\n & .hljs-variable {\n color: #79c0ff;\n }\n & .hljs-meta .hljs-string,\n & .hljs-regexp,\n & .hljs-string {\n color: #a5d6ff;\n }\n & .hljs-built_in,\n & .hljs-symbol {\n color: #ffa657;\n }\n & .hljs-code,\n & .hljs-comment,\n & .hljs-formula {\n color: #8b949e;\n }\n & .hljs-name,\n & .hljs-quote,\n & .hljs-selector-pseudo,\n & .hljs-selector-tag {\n color: #7ee787;\n }\n & .hljs-subst {\n color: #c9d1d9;\n }\n & .hljs-section {\n color: #1f6feb;\n font-weight: 700;\n }\n & .hljs-bullet {\n color: #f2cc60;\n }\n & .hljs-emphasis {\n color: #c9d1d9;\n font-style: italic;\n }\n & .hljs-strong {\n color: #c9d1d9;\n font-weight: 700;\n }\n & .hljs-addition {\n color: #aff5b4;\n background-color: #033a16;\n }\n & .hljs-deletion {\n color: #ffdcd7;\n background-color: #67060c;\n }\n`;\n\nconst Body = styled.div<{ theme: Theme }>`\n background: #ffffff;\n border-bottom-left-radius: ${({ theme }) => theme.spacing.radius.lg};\n border-bottom-right-radius: ${({ theme }) => theme.spacing.radius.lg};\n color: #24292f;\n padding: 20px;\n font-family: ${({ theme }) => theme.fonts.mono};\n text-align: left;\n overflow-x: auto;\n overflow-y: auto;\n max-height: calc(100dvh - 400px);\n ${({ theme }) => styledCode(theme)};\n ${lightSyntaxHighlight};\n\n :root.dark & {\n background: #0d1117;\n color: #ffffff;\n ${darkSyntaxHighlight};\n }\n`;\n\nconst escapeHtml = (unsafe: string): string => {\n return unsafe\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#039;\");\n};\n\nconst sanitizeLanguage = (lang: string): string =>\n lang.replace(/[^a-zA-Z0-9_-]/g, \"\");\n\nconst highlightCode = (code: string, language: string): string => {\n const escapedCode = escapeHtml(code);\n const safeLang = sanitizeLanguage(language);\n const result = unified()\n .use(rehypeParse, { fragment: true })\n .use(rehypeHighlight, {\n detect: true,\n ignoreMissing: true,\n })\n .use(rehypeStringify)\n .processSync(\n `<pre><code class=\"language-${safeLang}\">${escapedCode}</code></pre>`,\n );\n\n return String(result);\n};\n\nfunction Code({ code, language = \"javascript\", theme, className }: CodeProps) {\n const [copied, setCopied] = useState(false);\n const highlightedCode = useMemo(\n () => highlightCode(code, language),\n [code, language],\n );\n\n const handleCopy = useCallback(async () => {\n try {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch (err) {\n console.error(\"Failed to copy code:\", err);\n }\n }, [code]);\n\n return (\n <CodeWrapper\n className={`${className ?? \"\"} code-wrapper`.trim()}\n theme={theme}\n >\n <TopBar theme={theme}>\n <DotsContainer>\n <Dot theme={theme} />\n <Dot theme={theme} />\n <Dot theme={theme} />\n </DotsContainer>\n <CopyButton onClick={handleCopy} $copied={copied} theme={theme}>\n {copied ? (\n <>\n <Icon name=\"check\" size={12} />\n <span>Copied!</span>\n </>\n ) : (\n <>\n <Icon name=\"copy\" size={12} />\n <span>Copy</span>\n </>\n )}\n </CopyButton>\n </TopBar>\n <Body\n dangerouslySetInnerHTML={{ __html: highlightedCode }}\n theme={theme}\n className=\"code-wrapper-body\"\n />\n </CodeWrapper>\n );\n}\n\nexport { Code };\n";
@@ -1,8 +1,8 @@
1
1
  export const codeTemplate = `"use client";
2
2
  import { useState, useCallback, useMemo } from "react";
3
- import styled from "styled-components";
4
- import { Theme, styledCode } from "cherry-styled-components";
5
- import { rgba } from "polished";
3
+ import styled, { css } from "styled-components";
4
+ import { styledCode } from "cherry-styled-components";
5
+ import { Theme } from "@/app/theme";
6
6
  import { unified } from "unified";
7
7
  import rehypeParse from "rehype-parse";
8
8
  import rehypeHighlight from "rehype-highlight";
@@ -24,20 +24,22 @@ const CodeWrapper = styled.span<{ theme: Theme }>\`
24
24
  display: block;
25
25
  width: 100%;
26
26
  border-radius: \${({ theme }) => theme.spacing.radius.lg};
27
- border: solid 1px
28
- \${({ theme }) =>
29
- theme.isDark
30
- ? rgba(theme.colors.dark, 0.2)
31
- : rgba(theme.colors.dark, 0.1)};
27
+ border: solid 1px rgba(0, 0, 0, 0.1);
28
+
29
+ :root.dark & {
30
+ border-color: rgba(255, 255, 255, 0.2);
31
+ }
32
32
  \`;
33
33
 
34
+ /* Code block uses a fixed GitHub-style palette in both modes. Independent of
35
+ theme.json so syntax highlighting stays legible regardless of brand colors.
36
+ Dark variants live in :root.dark & blocks so the swap happens via the
37
+ active <html> class with no re-render. */
34
38
  const TopBar = styled.div<{ theme: Theme }>\`
35
- background: \${({ theme }) => (theme.isDark ? "#0d1117" : "#f6f8fa")};
39
+ background: #f6f8fa;
36
40
  border-top-left-radius: \${({ theme }) => theme.spacing.radius.lg};
37
41
  border-top-right-radius: \${({ theme }) => theme.spacing.radius.lg};
38
- border-bottom: solid 1px
39
- \${({ theme }) =>
40
- theme.isDark ? rgba("#ffffff", 0.1) : rgba("#000000", 0.1)};
42
+ border-bottom: solid 1px rgba(0, 0, 0, 0.1);
41
43
  height: 33px;
42
44
  width: 100%;
43
45
  display: flex;
@@ -45,6 +47,11 @@ const TopBar = styled.div<{ theme: Theme }>\`
45
47
  align-items: center;
46
48
  gap: 5px;
47
49
  padding: 0 10px;
50
+
51
+ :root.dark & {
52
+ background: #0d1117;
53
+ border-bottom-color: rgba(255, 255, 255, 0.1);
54
+ }
48
55
  \`;
49
56
 
50
57
  const DotsContainer = styled.div\`
@@ -56,34 +63,19 @@ const Dot = styled.span<{ theme: Theme }>\`
56
63
  width: 10px;
57
64
  height: 10px;
58
65
  border-radius: 50%;
59
- background: \${({ theme }) =>
60
- theme.isDark ? rgba("#ffffff", 0.1) : rgba("#000000", 0.1)};
66
+ background: rgba(0, 0, 0, 0.1);
67
+
68
+ :root.dark & {
69
+ background: rgba(255, 255, 255, 0.1);
70
+ }
61
71
  \`;
62
72
 
63
73
  const CopyButton = styled.button<{ theme: Theme; $copied: boolean }>\`
64
- background: \${({ theme, $copied }) =>
65
- $copied
66
- ? theme.isDark
67
- ? rgba("#7ee787", 0.2)
68
- : rgba("#2da44e", 0.1)
69
- : "transparent"};
74
+ background: \${({ $copied }) =>
75
+ $copied ? "rgba(45, 164, 78, 0.1)" : "transparent"};
70
76
  border: solid 1px
71
- \${({ theme, $copied }) =>
72
- $copied
73
- ? theme.isDark
74
- ? "#7ee787"
75
- : "#2da44e"
76
- : theme.isDark
77
- ? rgba("#ffffff", 0.1)
78
- : rgba("#000000", 0.1)};
79
- color: \${({ theme, $copied }) =>
80
- $copied
81
- ? theme.isDark
82
- ? "#7ee787"
83
- : "#2da44e"
84
- : theme.isDark
85
- ? "#c9d1d9"
86
- : "#57606a"};
77
+ \${({ $copied }) => ($copied ? "#2da44e" : "rgba(0, 0, 0, 0.1)")};
78
+ color: \${({ $copied }) => ($copied ? "#2da44e" : "#57606a")};
87
79
  border-radius: \${({ theme }) => theme.spacing.radius.xs};
88
80
  padding: 4px 8px;
89
81
  font-size: 12px;
@@ -96,45 +88,208 @@ const CopyButton = styled.button<{ theme: Theme; $copied: boolean }>\`
96
88
  margin-right: -6px;
97
89
 
98
90
  & svg.lucide {
99
- color: \${({ theme, $copied }) =>
100
- $copied
101
- ? theme.isDark
102
- ? "#7ee787"
103
- : "#2da44e"
104
- : theme.isDark
105
- ? "#c9d1d9"
106
- : "#57606a"};
91
+ color: \${({ $copied }) => ($copied ? "#2da44e" : "#57606a")};
107
92
  }
108
93
 
109
94
  &:hover {
110
- background: \${({ theme, $copied }) =>
111
- $copied
112
- ? theme.isDark
113
- ? rgba("#7ee787", 0.3)
114
- : rgba("#2da44e", 0.2)
115
- : theme.isDark
116
- ? rgba("#ffffff", 0.1)
117
- : rgba("#000000", 0.05)};
118
- border-color: \${({ theme, $copied }) =>
119
- $copied
120
- ? theme.isDark
121
- ? "#7ee787"
122
- : "#2da44e"
123
- : theme.isDark
124
- ? rgba("#ffffff", 0.2)
125
- : rgba("#000000", 0.2)};
95
+ background: \${({ $copied }) =>
96
+ $copied ? "rgba(45, 164, 78, 0.2)" : "rgba(0, 0, 0, 0.05)"};
97
+ border-color: \${({ $copied }) =>
98
+ $copied ? "#2da44e" : "rgba(0, 0, 0, 0.2)"};
126
99
  }
127
100
 
128
101
  &:active {
129
102
  transform: scale(0.95);
130
103
  }
104
+
105
+ :root.dark & {
106
+ background: \${({ $copied }) =>
107
+ $copied ? "rgba(126, 231, 135, 0.2)" : "transparent"};
108
+ border-color: \${({ $copied }) =>
109
+ $copied ? "#7ee787" : "rgba(255, 255, 255, 0.1)"};
110
+ color: \${({ $copied }) => ($copied ? "#7ee787" : "#c9d1d9")};
111
+
112
+ & svg.lucide {
113
+ color: \${({ $copied }) => ($copied ? "#7ee787" : "#c9d1d9")};
114
+ }
115
+
116
+ &:hover {
117
+ background: \${({ $copied }) =>
118
+ $copied ? "rgba(126, 231, 135, 0.3)" : "rgba(255, 255, 255, 0.1)"};
119
+ border-color: \${({ $copied }) =>
120
+ $copied ? "#7ee787" : "rgba(255, 255, 255, 0.2)"};
121
+ }
122
+ }
123
+ \`;
124
+
125
+ /* GitHub Light syntax highlighting by default; GitHub Dark in :root.dark.
126
+ Browser resolves which rule wins based on the active <html> class with no
127
+ JS or React re-render involved. */
128
+ const lightSyntaxHighlight = css\`
129
+ & .hljs {
130
+ color: #24292f;
131
+ background: #ffffff;
132
+ }
133
+ & .hljs-doctag,
134
+ & .hljs-keyword,
135
+ & .hljs-meta .hljs-keyword,
136
+ & .hljs-template-tag,
137
+ & .hljs-template-variable,
138
+ & .hljs-type,
139
+ & .hljs-variable.language_ {
140
+ color: #cf222e;
141
+ }
142
+ & .hljs-title,
143
+ & .hljs-title.class_,
144
+ & .hljs-title.class_.inherited__,
145
+ & .hljs-title.function_ {
146
+ color: #8250df;
147
+ }
148
+ & .hljs-attr,
149
+ & .hljs-attribute,
150
+ & .hljs-literal,
151
+ & .hljs-meta,
152
+ & .hljs-number,
153
+ & .hljs-operator,
154
+ & .hljs-selector-attr,
155
+ & .hljs-selector-class,
156
+ & .hljs-selector-id,
157
+ & .hljs-variable {
158
+ color: #0550ae;
159
+ }
160
+ & .hljs-meta .hljs-string,
161
+ & .hljs-regexp,
162
+ & .hljs-string {
163
+ color: #0a3069;
164
+ }
165
+ & .hljs-built_in,
166
+ & .hljs-symbol {
167
+ color: #953800;
168
+ }
169
+ & .hljs-code,
170
+ & .hljs-comment,
171
+ & .hljs-formula {
172
+ color: #6e7781;
173
+ }
174
+ & .hljs-name,
175
+ & .hljs-quote,
176
+ & .hljs-selector-pseudo,
177
+ & .hljs-selector-tag {
178
+ color: #116329;
179
+ }
180
+ & .hljs-subst {
181
+ color: #24292f;
182
+ }
183
+ & .hljs-section {
184
+ color: #0550ae;
185
+ font-weight: 700;
186
+ }
187
+ & .hljs-bullet {
188
+ color: #953800;
189
+ }
190
+ & .hljs-emphasis {
191
+ color: #24292f;
192
+ font-style: italic;
193
+ }
194
+ & .hljs-strong {
195
+ color: #24292f;
196
+ font-weight: 700;
197
+ }
198
+ & .hljs-addition {
199
+ color: #116329;
200
+ background-color: #dafbe1;
201
+ }
202
+ & .hljs-deletion {
203
+ color: #82071e;
204
+ background-color: #ffebe9;
205
+ }
206
+ \`;
207
+
208
+ const darkSyntaxHighlight = css\`
209
+ & .hljs {
210
+ color: #c9d1d9;
211
+ background: #0d1117;
212
+ }
213
+ & .hljs-doctag,
214
+ & .hljs-keyword,
215
+ & .hljs-meta .hljs-keyword,
216
+ & .hljs-template-tag,
217
+ & .hljs-template-variable,
218
+ & .hljs-type,
219
+ & .hljs-variable.language_ {
220
+ color: #ff7b72;
221
+ }
222
+ & .hljs-title,
223
+ & .hljs-title.class_,
224
+ & .hljs-title.class_.inherited__,
225
+ & .hljs-title.function_ {
226
+ color: #d2a8ff;
227
+ }
228
+ & .hljs-attr,
229
+ & .hljs-attribute,
230
+ & .hljs-literal,
231
+ & .hljs-meta,
232
+ & .hljs-number,
233
+ & .hljs-operator,
234
+ & .hljs-selector-attr,
235
+ & .hljs-selector-class,
236
+ & .hljs-selector-id,
237
+ & .hljs-variable {
238
+ color: #79c0ff;
239
+ }
240
+ & .hljs-meta .hljs-string,
241
+ & .hljs-regexp,
242
+ & .hljs-string {
243
+ color: #a5d6ff;
244
+ }
245
+ & .hljs-built_in,
246
+ & .hljs-symbol {
247
+ color: #ffa657;
248
+ }
249
+ & .hljs-code,
250
+ & .hljs-comment,
251
+ & .hljs-formula {
252
+ color: #8b949e;
253
+ }
254
+ & .hljs-name,
255
+ & .hljs-quote,
256
+ & .hljs-selector-pseudo,
257
+ & .hljs-selector-tag {
258
+ color: #7ee787;
259
+ }
260
+ & .hljs-subst {
261
+ color: #c9d1d9;
262
+ }
263
+ & .hljs-section {
264
+ color: #1f6feb;
265
+ font-weight: 700;
266
+ }
267
+ & .hljs-bullet {
268
+ color: #f2cc60;
269
+ }
270
+ & .hljs-emphasis {
271
+ color: #c9d1d9;
272
+ font-style: italic;
273
+ }
274
+ & .hljs-strong {
275
+ color: #c9d1d9;
276
+ font-weight: 700;
277
+ }
278
+ & .hljs-addition {
279
+ color: #aff5b4;
280
+ background-color: #033a16;
281
+ }
282
+ & .hljs-deletion {
283
+ color: #ffdcd7;
284
+ background-color: #67060c;
285
+ }
131
286
  \`;
132
287
 
133
288
  const Body = styled.div<{ theme: Theme }>\`
134
- background: \${({ theme }) => (theme.isDark ? "#0d1117" : "#ffffff")};
289
+ background: #ffffff;
135
290
  border-bottom-left-radius: \${({ theme }) => theme.spacing.radius.lg};
136
291
  border-bottom-right-radius: \${({ theme }) => theme.spacing.radius.lg};
137
- color: \${({ theme }) => (theme.isDark ? "#ffffff" : "#24292f")};
292
+ color: #24292f;
138
293
  padding: 20px;
139
294
  font-family: \${({ theme }) => theme.fonts.mono};
140
295
  text-align: left;
@@ -142,200 +297,13 @@ const Body = styled.div<{ theme: Theme }>\`
142
297
  overflow-y: auto;
143
298
  max-height: calc(100dvh - 400px);
144
299
  \${({ theme }) => styledCode(theme)};
300
+ \${lightSyntaxHighlight};
145
301
 
146
- /* Dark mode syntax highlighting (GitHub Dark) */
147
- \${({ theme }) =>
148
- theme.isDark &&
149
- \`
150
- & .hljs {
151
- color: #c9d1d9;
152
- background: #0d1117;
153
- }
154
-
155
- & .hljs-doctag,
156
- & .hljs-keyword,
157
- & .hljs-meta .hljs-keyword,
158
- & .hljs-template-tag,
159
- & .hljs-template-variable,
160
- & .hljs-type,
161
- & .hljs-variable.language_ {
162
- color: #ff7b72;
163
- }
164
-
165
- & .hljs-title,
166
- & .hljs-title.class_,
167
- & .hljs-title.class_.inherited__,
168
- & .hljs-title.function_ {
169
- color: #d2a8ff;
170
- }
171
-
172
- & .hljs-attr,
173
- & .hljs-attribute,
174
- & .hljs-literal,
175
- & .hljs-meta,
176
- & .hljs-number,
177
- & .hljs-operator,
178
- & .hljs-selector-attr,
179
- & .hljs-selector-class,
180
- & .hljs-selector-id,
181
- & .hljs-variable {
182
- color: #79c0ff;
183
- }
184
-
185
- & .hljs-meta .hljs-string,
186
- & .hljs-regexp,
187
- & .hljs-string {
188
- color: #a5d6ff;
189
- }
190
-
191
- & .hljs-built_in,
192
- & .hljs-symbol {
193
- color: #ffa657;
194
- }
195
-
196
- & .hljs-code,
197
- & .hljs-comment,
198
- & .hljs-formula {
199
- color: #8b949e;
200
- }
201
-
202
- & .hljs-name,
203
- & .hljs-quote,
204
- & .hljs-selector-pseudo,
205
- & .hljs-selector-tag {
206
- color: #7ee787;
207
- }
208
-
209
- & .hljs-subst {
210
- color: #c9d1d9;
211
- }
212
-
213
- & .hljs-section {
214
- color: #1f6feb;
215
- font-weight: 700;
216
- }
217
-
218
- & .hljs-bullet {
219
- color: #f2cc60;
220
- }
221
-
222
- & .hljs-emphasis {
223
- color: #c9d1d9;
224
- font-style: italic;
225
- }
226
-
227
- & .hljs-strong {
228
- color: #c9d1d9;
229
- font-weight: 700;
230
- }
231
-
232
- & .hljs-addition {
233
- color: #aff5b4;
234
- background-color: #033a16;
235
- }
236
-
237
- & .hljs-deletion {
238
- color: #ffdcd7;
239
- background-color: #67060c;
240
- }
241
- \`}
242
-
243
- /* Light mode syntax highlighting (GitHub Light) */
244
- \${({ theme }) =>
245
- !theme.isDark &&
246
- \`
247
- & .hljs {
248
- color: #24292f;
249
- background: #ffffff;
250
- }
251
-
252
- & .hljs-doctag,
253
- & .hljs-keyword,
254
- & .hljs-meta .hljs-keyword,
255
- & .hljs-template-tag,
256
- & .hljs-template-variable,
257
- & .hljs-type,
258
- & .hljs-variable.language_ {
259
- color: #cf222e;
260
- }
261
-
262
- & .hljs-title,
263
- & .hljs-title.class_,
264
- & .hljs-title.class_.inherited__,
265
- & .hljs-title.function_ {
266
- color: #8250df;
267
- }
268
-
269
- & .hljs-attr,
270
- & .hljs-attribute,
271
- & .hljs-literal,
272
- & .hljs-meta,
273
- & .hljs-number,
274
- & .hljs-operator,
275
- & .hljs-selector-attr,
276
- & .hljs-selector-class,
277
- & .hljs-selector-id,
278
- & .hljs-variable {
279
- color: #0550ae;
280
- }
281
-
282
- & .hljs-meta .hljs-string,
283
- & .hljs-regexp,
284
- & .hljs-string {
285
- color: #0a3069;
286
- }
287
-
288
- & .hljs-built_in,
289
- & .hljs-symbol {
290
- color: #953800;
291
- }
292
-
293
- & .hljs-code,
294
- & .hljs-comment,
295
- & .hljs-formula {
296
- color: #6e7781;
297
- }
298
-
299
- & .hljs-name,
300
- & .hljs-quote,
301
- & .hljs-selector-pseudo,
302
- & .hljs-selector-tag {
303
- color: #116329;
304
- }
305
-
306
- & .hljs-subst {
307
- color: #24292f;
308
- }
309
-
310
- & .hljs-section {
311
- color: #0550ae;
312
- font-weight: 700;
313
- }
314
-
315
- & .hljs-bullet {
316
- color: #953800;
317
- }
318
-
319
- & .hljs-emphasis {
320
- color: #24292f;
321
- font-style: italic;
322
- }
323
-
324
- & .hljs-strong {
325
- color: #24292f;
326
- font-weight: 700;
327
- }
328
-
329
- & .hljs-addition {
330
- color: #116329;
331
- background-color: #dafbe1;
332
- }
333
-
334
- & .hljs-deletion {
335
- color: #82071e;
336
- background-color: #ffebe9;
337
- }
338
- \`}
302
+ :root.dark & {
303
+ background: #0d1117;
304
+ color: #ffffff;
305
+ \${darkSyntaxHighlight};
306
+ }
339
307
  \`;
340
308
 
341
309
  const escapeHtml = (unsafe: string): string => {
@@ -1 +1 @@
1
- export declare const colorSwatchTemplate = "\"use client\";\nimport styled from \"styled-components\";\nimport { styledText, Theme } from \"cherry-styled-components\";\nimport { mq } from \"@/app/theme\";\n\nconst StyledSwatchGroup = styled.div<{ theme: Theme }>`\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: ${({ theme }) => theme.spacing.gridGap.xs};\n\n ${mq(\"md\")} {\n grid-template-columns: repeat(3, 1fr);\n }\n`;\n\nconst StyledSwatch = styled.div<{ theme: Theme }>`\n border: solid 1px ${({ theme }) => theme.colors.grayLight};\n border-radius: ${({ theme }) => theme.spacing.radius.lg};\n overflow: hidden;\n`;\n\nconst StyledColor = styled.div<{\n theme: Theme;\n $color: string;\n $lightText: boolean;\n}>`\n background: ${({ $color }) => $color};\n height: 80px;\n display: flex;\n align-items: flex-end;\n padding: 8px 12px;\n color: ${({ $lightText }) => ($lightText ? \"#FFFFFF\" : \"#000000\")};\n font-size: 12px;\n font-family: monospace;\n opacity: 0.8;\n border-bottom: solid 1px ${({ theme }) => theme.colors.grayLight};\n`;\n\nconst StyledLabel = styled.div<{ theme: Theme }>`\n padding: 10px 12px;\n background: ${({ theme }) => theme.colors.light};\n ${({ theme }) => styledText(theme)};\n font-size: 13px;\n color: ${({ theme }) => theme.colors.grayDark};\n\n code {\n color: ${({ theme }) => theme.colors.dark};\n font-weight: 600;\n font-size: 13px;\n }\n`;\n\nfunction luminance(hex: string): number {\n const rgb = hex\n .replace(\"#\", \"\")\n .match(/.{2}/g)!\n .map((c) => parseInt(c, 16) / 255);\n\n const [r, g, b] = rgb.map((c) =>\n c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4),\n );\n\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n}\n\ninterface ColorSwatchProps {\n token: string;\n value: string;\n}\n\nfunction ColorSwatch({ token, value }: ColorSwatchProps) {\n const useLightText = luminance(value) < 0.4;\n\n return (\n <StyledSwatch>\n <StyledColor $color={value} $lightText={useLightText}>\n {value}\n </StyledColor>\n <StyledLabel>\n <code className=\"token\">{token}</code>\n </StyledLabel>\n </StyledSwatch>\n );\n}\n\ninterface ColorSwatchGroupProps {\n children: React.ReactNode;\n}\n\nfunction ColorSwatchGroup({ children }: ColorSwatchGroupProps) {\n return <StyledSwatchGroup>{children}</StyledSwatchGroup>;\n}\n\nexport { ColorSwatch, ColorSwatchGroup };\n";
1
+ export declare const colorSwatchTemplate = "\"use client\";\nimport styled from \"styled-components\";\nimport { styledText } from \"cherry-styled-components\";\nimport { mq, Theme } from \"@/app/theme\";\n\nconst StyledSwatchGroup = styled.div<{ theme: Theme }>`\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: ${({ theme }) => theme.spacing.gridGap.xs};\n\n ${mq(\"md\")} {\n grid-template-columns: repeat(3, 1fr);\n }\n`;\n\nconst StyledSwatch = styled.div<{ theme: Theme }>`\n border: solid 1px ${({ theme }) => theme.colors.grayLight};\n border-radius: ${({ theme }) => theme.spacing.radius.lg};\n overflow: hidden;\n`;\n\nconst StyledColor = styled.div<{\n theme: Theme;\n $color: string;\n $lightText: boolean;\n}>`\n background: ${({ $color }) => $color};\n height: 80px;\n display: flex;\n align-items: flex-end;\n padding: 8px 12px;\n color: ${({ $lightText }) => ($lightText ? \"#FFFFFF\" : \"#000000\")};\n font-size: 12px;\n font-family: monospace;\n opacity: 0.8;\n border-bottom: solid 1px ${({ theme }) => theme.colors.grayLight};\n`;\n\nconst StyledLabel = styled.div<{ theme: Theme }>`\n padding: 10px 12px;\n background: ${({ theme }) => theme.colors.light};\n ${({ theme }) => styledText(theme)};\n font-size: 13px;\n color: ${({ theme }) => theme.colors.grayDark};\n\n code {\n color: ${({ theme }) => theme.colors.dark};\n font-weight: 600;\n font-size: 13px;\n }\n`;\n\nfunction luminance(hex: string): number {\n const rgb = hex\n .replace(\"#\", \"\")\n .match(/.{2}/g)!\n .map((c) => parseInt(c, 16) / 255);\n\n const [r, g, b] = rgb.map((c) =>\n c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4),\n );\n\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n}\n\ninterface ColorSwatchProps {\n token: string;\n value: string;\n}\n\nfunction ColorSwatch({ token, value }: ColorSwatchProps) {\n const useLightText = luminance(value) < 0.4;\n\n return (\n <StyledSwatch>\n <StyledColor $color={value} $lightText={useLightText}>\n {value}\n </StyledColor>\n <StyledLabel>\n <code className=\"token\">{token}</code>\n </StyledLabel>\n </StyledSwatch>\n );\n}\n\ninterface ColorSwatchGroupProps {\n children: React.ReactNode;\n}\n\nfunction ColorSwatchGroup({ children }: ColorSwatchGroupProps) {\n return <StyledSwatchGroup>{children}</StyledSwatchGroup>;\n}\n\nexport { ColorSwatch, ColorSwatchGroup };\n";
@@ -1,7 +1,7 @@
1
1
  export const colorSwatchTemplate = `"use client";
2
2
  import styled from "styled-components";
3
- import { styledText, Theme } from "cherry-styled-components";
4
- import { mq } from "@/app/theme";
3
+ import { styledText } from "cherry-styled-components";
4
+ import { mq, Theme } from "@/app/theme";
5
5
 
6
6
  const StyledSwatchGroup = styled.div<{ theme: Theme }>\`
7
7
  display: grid;
@@ -1 +1 @@
1
- export declare const columnsTemplate = "\"use client\";\nimport styled from \"styled-components\";\nimport { mq, Theme } from \"cherry-styled-components\";\n\nconst StyledColumns = styled.div<{ theme: Theme; $columns?: number }>`\n display: flex;\n flex-direction: column;\n gap: 20px;\n\n ${mq(\"lg\")} {\n ${({ $columns }) =>\n $columns && $columns >= 3\n ? `display: grid; grid-template-columns: repeat(2, 1fr);`\n : \"\"}\n }\n\n ${mq(\"xl\")} {\n display: grid;\n grid-template-columns: repeat(${({ $columns }) => $columns ?? 1}, 1fr);\n }\n`;\n\ninterface ColumnsProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n cols?: number;\n}\n\nfunction Columns({ children, cols }: ColumnsProps) {\n return <StyledColumns $columns={cols}>{children}</StyledColumns>;\n}\n\nexport { Columns };\n";
1
+ export declare const columnsTemplate = "\"use client\";\nimport styled from \"styled-components\";\nimport { mq, Theme } from \"@/app/theme\";\n\nconst StyledColumns = styled.div<{ theme: Theme; $columns?: number }>`\n display: flex;\n flex-direction: column;\n gap: 20px;\n\n ${mq(\"lg\")} {\n ${({ $columns }) =>\n $columns && $columns >= 3\n ? `display: grid; grid-template-columns: repeat(2, 1fr);`\n : \"\"}\n }\n\n ${mq(\"xl\")} {\n display: grid;\n grid-template-columns: repeat(${({ $columns }) => $columns ?? 1}, 1fr);\n }\n`;\n\ninterface ColumnsProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n cols?: number;\n}\n\nfunction Columns({ children, cols }: ColumnsProps) {\n return <StyledColumns $columns={cols}>{children}</StyledColumns>;\n}\n\nexport { Columns };\n";
@@ -1,6 +1,6 @@
1
1
  export const columnsTemplate = `"use client";
2
2
  import styled from "styled-components";
3
- import { mq, Theme } from "cherry-styled-components";
3
+ import { mq, Theme } from "@/app/theme";
4
4
 
5
5
  const StyledColumns = styled.div<{ theme: Theme; $columns?: number }>\`
6
6
  display: flex;