"use client"; import { useEffect, useRef, useCallback } from "react"; import hljs from "highlight.js/lib/core"; import nix from "highlight.js/lib/languages/nix"; import "highlight.js/styles/github-dark.css"; hljs.registerLanguage("nix", nix); declare global { interface Window { showSaveFilePicker?: (options?: { suggestedName?: string; types?: Array<{ description?: string; accept: Record; }>; }) => Promise; } } const code = `{ description = "My personal website"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; } outputs = { self, nixpkgs }: { let system = "x86_64-linux"; pkgs = import nixpkgs { inherit system; }; in { // install pakages nix.settings = { sandbox = false; experimental-features = [ "flakes" ]; }; time.timeZone = "Asia/Seoul"; } }`; const customTheme = ` .hljs { background: #191017 !important; color: #fcf8f9 !important; } .hljs-attr { color: #f38ba8; } .hljs-string { color: #a6e3a1; } .hljs-number { color: #f9e2af; } .hljs-literal { color: #89b4fa; } .hljs-type { color: #f5c2e7; } .hljs-title { color: #94e2d5; } `; export default function FlakeNix() { const codeRef = useRef(null); const downloadFile = useCallback(async () => { if (window.showSaveFilePicker) { try { const handle = await window.showSaveFilePicker({ suggestedName: "flake.nix", types: [ { description: "Nix Files", accept: { "text/plain": [".nix"] }, }, ], }); const writable = await handle.createWritable(); await writable.write(code); await writable.close(); } catch (e) { // 사용자가 취소한 경우 if ((e as Error).name !== "AbortError") { console.error(e); } } } else { // fallback: showSaveFilePicker를 지원하지 않는 브라우저 const blob = new Blob([code], { type: "text/plain" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = "flake.nix"; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } }, []); useEffect(() => { const style = document.createElement("style"); style.textContent = customTheme; document.head.appendChild(style); if (codeRef.current) { hljs.highlightElement(codeRef.current); } const handleKeyDown = (e: KeyboardEvent) => { if ((e.ctrlKey || e.metaKey) && e.key === "s") { e.preventDefault(); downloadFile(); } }; window.addEventListener("keydown", handleKeyDown); return () => { window.removeEventListener("keydown", handleKeyDown); }; }, [downloadFile]); return (
                    
                        {code}
                    
                
); }