import { lazy, Suspense } from "react"; import { Download, X } from "lucide-react"; import { type DocumentEditorBackend, type DocumentEditorMode, type DocumentEditorPaneCollaborationConfig, } from "../editor/document-editor-pane"; import { ArtifactPane, type ArtifactPaneProps } from "../primitives/artifact-pane"; import { detectFileFormat } from "./file-format"; import { FilePreview, type FilePreviewProps } from "./file-preview"; import { FileTabs, type FileTabData } from "./file-tabs"; const LazyDocumentEditorPane = lazy(async () => { const module = await import("../editor/document-editor-pane"); return { default: module.DocumentEditorPane }; }); export interface FileArtifactPaneEditorOptions { enabled?: boolean; mode?: DocumentEditorMode; defaultMode?: DocumentEditorMode; onModeChange?: (mode: DocumentEditorMode) => void; backend?: DocumentEditorBackend; collaboration?: DocumentEditorPaneCollaborationConfig; placeholder?: string; autoFocus?: boolean; readOnly?: boolean; saving?: boolean; saveLabel?: string; onChange?: (markdown: string) => void; onSave?: (markdown: string) => Promise | void; previewClassName?: string; editorClassName?: string; } export interface FileArtifactPaneProps extends Omit { path?: string; tabs?: FileTabData[]; activeTabId?: string; onTabSelect?: (id: string) => void; onTabClose?: (id: string) => void; eyebrow?: ArtifactPaneProps["eyebrow"]; meta?: ArtifactPaneProps["meta"]; toolbar?: ArtifactPaneProps["toolbar"]; footer?: ArtifactPaneProps["footer"]; className?: string; headerClassName?: ArtifactPaneProps["headerClassName"]; hideTitleBlock?: ArtifactPaneProps["hideTitleBlock"]; editor?: FileArtifactPaneEditorOptions; } /** * FileArtifactPane — opinionated artifact frame for file previews with tabs and * header actions. */ export function FileArtifactPane({ filename, content, blobUrl, mimeType, onClose, onDownload, path, tabs = [], activeTabId, onTabSelect, onTabClose, eyebrow = "Artifact", meta, toolbar, footer, className, headerClassName, hideTitleBlock, editor, }: FileArtifactPaneProps) { const showTabs = tabs.length > 0 && onTabSelect && onTabClose; const paneTabs = showTabs ? ( ) : undefined; const isMarkdown = detectFileFormat(filename, mimeType) === "markdown" || (path ? detectFileFormat(path, mimeType) === "markdown" : false); const isEditableMarkdown = isMarkdown && editor?.enabled; // Undefined (not an empty fragment) when there are no actions, so ArtifactPane // can collapse the header row entirely under hideTitleBlock. const headerActions = onDownload || onClose ? ( <> {onDownload && ( )} {onClose && ( )} ) : undefined; if (isEditableMarkdown) { return (
Loading editor…
)} >
); } return ( ); }