1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[12741],{12741:(e,n,o)=>{o.r(n),o.d(n,{default:()=>t});let t='"use client";\nimport { Spinner } from "@/components/nurui/spinner";\nimport { codeSnippetsMap } from "@/registry/code-snippets";\nimport { Index } from "@/registry/components-registry";\nimport { convertTsxToJsx } from "@/utils/convertTsxToJsx";\nimport { ChevronDown } from "lucide-react";\nimport { useTheme } from "next-themes";\nimport { useEffect, useState } from "react";\nimport { BiLogoTypescript } from "react-icons/bi";\nimport { FaJsSquare } from "react-icons/fa";\nimport { FaCheck } from "react-icons/fa6";\nimport { RxCopy } from "react-icons/rx";\nimport { Prism as SyntaxHighlighter } from "react-syntax-highlighter";\nimport {\n atomDark,\n oneLight,\n} from "react-syntax-highlighter/dist/cjs/styles/prism";\n\ntype CodeBlockProps = {\n language?: string;\n code?: string;\n componentName?: keyof typeof Index;\n fileName?: string;\n isLanguage?: boolean;\n snippetKey?: string;\n};\n\nexport const CodeBlock = ({\n language = "tsx",\n code = "",\n componentName,\n fileName,\n isLanguage = true,\n snippetKey,\n}: CodeBlockProps) => {\n const { theme } = useTheme();\n\n // Resolve snippet from map if key provided\n const snippet = snippetKey ? codeSnippetsMap[snippetKey] : undefined;\n const resolvedCode = snippet?.code ?? code;\n const resolvedLang = snippet?.language ?? language;\n const resolvedIsLang =\n snippet !== undefined ? (snippet.isLanguage ?? true) : isLanguage;\n\n const [isOpen, setIsOpen] = useState(false);\n const [selectedLanguage, setSelectedLanguage] = useState("TypeScript (.tsx)");\n const [sourceCode, setSourceCode] = useState(resolvedCode);\n const [originalTsSource, setOriginalTsSource] = useState(resolvedCode);\n const [copied, setCopied] = useState(false);\n const [loading, setLoading] = useState(\n // only show spinner when we need to fetch from registry\n !resolvedCode && !!(componentName && fileName),\n );\n\n const selectedLang = languages.find((l) => l.name === selectedLanguage);\n\n useEffect(() => {\n // If code came from snippetKey or direct prop, nothing to fetch\n if (resolvedCode) {\n setSourceCode(resolvedCode);\n setOriginalTsSource(resolvedCode);\n setLoading(false);\n return;\n }\n\n // Fetch from registry\n const loadCode = async () => {\n if (componentName && fileName) {\n setLoading(true);\n try {\n const matched = Index[componentName]?.othersCode?.find(\n (o) => o.fileName === fileName,\n );\n const loader = matched?.code || Index[componentName]?.code;\n if (loader) {\n const result = await loader();\n setSourceCode(result.default);\n setOriginalTsSource(result.default);\n }\n } finally {\n setLoading(false);\n }\n } else {\n setLoading(false);\n }\n };\n\n loadCode();\n }, [resolvedCode, componentName, fileName]);\n\n const copyToClipboard = async () => {\n if (sourceCode) {\n await navigator.clipboard.writeText(sourceCode);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n }\n };\n\n const handleSelect = async (languageName: string) => {\n setSelectedLanguage(languageName);\n setIsOpen(false);\n\n if (languageName === "JavaScript (.jsx)" && originalTsSource) {\n setSourceCode(await convertTsxToJsx(originalTsSource));\n } else {\n setSourceCode(originalTsSource);\n }\n };\n\n if (loading) {\n return (\n <div className="flex items-center justify-center h-64 border border-[var(--primary-color)] dark:border-[var(--primary-color-3)] rounded-2xl bg-white dark:bg-[var(--primary-color-5)]">\n <Spinner className="text-[var(--primary-color)] size-6" />\n </div>\n );\n }\n\n return (\n <div className="border border-[var(--primary-color)] dark:border-[var(--primary-color-3)] rounded-2xl max-h-[30rem] overflow-auto w-full text-sm">\n <div className="flex items-center justify-end gap-3 p-3 bg-white dark:bg-[var(--primary-color-5)]">\n <button\n onClick={copyToClipboard}\n className="flex items-center gap-1 text-sm text-black dark:text-zinc-400 hover:dark:text-zinc-200 transition-colors"\n >\n {copied ? <FaCheck /> : <RxCopy />}\n </button>\n\n {resolvedIsLang && (\n <div className="relative">\n <button\n onClick={() => setIsOpen(!isOpen)}\n className="flex items-center gap-1"\n >
1\n <span>{selectedLang?.icon}</span>\n <ChevronDown\n className={`w-3 h-3 ${isOpen ? "rotate-180" : ""}`}\n />\n </button>\n\n {isOpen && (\n <div className="absolute z-50 right-0 mt-3.5 border border-[var(--primary-color)] dark:border-[var(--primary-color-3)] rounded-lg min-w-40 bg-white dark:bg-[var(--primary-color-5)] p-1">\n {languages.map((lang, i) => (\n <button\n key={i}\n onClick={() => handleSelect(lang.name)}\n className="w-full flex items-center gap-1 p-2 z-50 hover:dark:bg-[var(--primary-color-4)] rounded-lg"\n >\n <span>{lang.icon}</span>\n <span>{lang.name}</span>\n </button>\n ))}\n </div>\n )}\n\n {isOpen && (\n <div\n className="fixed inset-0 z-0"\n onClick={() => setIsOpen(false)}\n />\n )}\n </div>\n )}\n </div>\n\n <SyntaxHighlighter\n language={resolvedLang}\n style={theme === "light" ? oneLight : atomDark}\n wrapLines\n PreTag="div"\n showLineNumbers\n customStyle={{ margin: 0, padding: 16, background: "transparent" }}\n >\n {sourceCode.trim() ||\n `Component ${componentName} not found in registry.`}\n </SyntaxHighlighter>\n </div>\n );\n};\n\nconst languages = [\n {\n name: "JavaScript (.jsx)",\n icon: <FaJsSquare className="text-[#EFD81D] text-xl" />,\n },\n {\n name: "TypeScript (.tsx)",\n icon: <BiLogoTypescript className="text-[#377CC8] text-xl" />,\n },\n];\n'}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.