import type { DocumentSlotState } from '../documents/useDocumentSlot'; import { resolveDocumentLink } from '../documents/resolveDocumentLink'; import type { OpenDocRequest } from '../workspaces/workspace'; import { DocumentPane } from './DocumentPane'; import type { EditorMode } from './types'; const DEFAULT_EMPTY_HINT = 'Select a file from the sidebar to open it here.'; type DocumentSlotViewProps = { state: DocumentSlotState; className?: string; placeholder?: string; emptyHint?: string; /** Rendering mode for the open editor; defaults to `edit`. */ mode?: EditorMode; /** * Open a document (by provider + entry). When provided, internal-link clicks * in the editor are resolved against the open document and routed here — so a * workspace gets file-to-file navigation just by forwarding its open handler. */ onOpenEntry?: (request: OpenDocRequest) => void; }; function SlotPlaceholder({ message }: { message: string }) { return (
{message}
); } /** * Renders a document slot's empty, loading, error, or open states. * Workspaces compose this inside their layout chrome. */ export function DocumentSlotView({ state, className, placeholder = 'Start writing…', emptyHint = DEFAULT_EMPTY_HINT, mode, onOpenEntry, }: DocumentSlotViewProps) { if (state.kind === 'empty') { return ; } if (state.kind === 'loading') { return ; } if (state.kind === 'error') { return ( ); } // Resolve internal-link targets against this document, then route to the // workspace's open handler. Kept here (not in each workspace) so every // workspace gets file-to-file navigation for free. const { request, handle } = state; const onOpenLink = onOpenEntry ? (target: string) => onOpenEntry( resolveDocumentLink( { providerId: request.providerId, path: handle.id }, target, ), ) : undefined; return ( // Key by document id so switching tabs to a different document remounts a // fresh editor instead of reusing one bound to the previous document. The // shared editor view binds its content on mount only, so without this a // tab switch can leave the previous file's content showing. ); }