import React from "react";
import type { DocContent, DocNode, DocRenderHandlers, DocSourceId } from "../../types/doc-source";
/** Color tokens for the doc-viewer chrome. Hub-side `DocViewer` callers share
* this constant; no need to override per source — the palette is intentionally
* uniform across knowledge-base + data-room (both use ODS dark tokens). */
export declare const DEFAULT_DOC_VIEWER_PALETTE: {
readonly background: "bg-ods-bg";
readonly containerBackground: "transparent";
readonly headerText: "text-ods-text-primary";
readonly primaryText: "text-ods-text-primary";
readonly secondaryText: "text-ods-text-secondary";
readonly accent: "var(--ods-accent)";
readonly border: "border-ods-border";
readonly cardBackground: "bg-ods-card";
};
export interface DocViewerProps {
/**
* Registry source id (`'openframe-docs'`, `'data-room-docs'`, …). Flowed through
* `renderContent`'s handlers for `/api/docs/resolve-link` POSTs.
*/
sourceId: DocSourceId;
/**
* Render the content body. The page shell owns this — it picks the markdown
* renderer, dispatches PDF/Figma/Sheets/file branches, etc. No renderer
* interface in between.
*/
renderContent: (content: DocContent, handlers: DocRenderHandlers) => React.ReactNode;
/**
* Render the loading skeleton. Receives the selected node's `documentType`
* (undefined while structure is still loading) so the caller can return a
* markdown-shaped skeleton vs an embed-shaped skeleton.
*/
renderSkeleton: (documentType: DocNode['documentType']) => React.ReactNode;
/**
* Chat-source identifier — passed in by the page shell from server-side
* `currentPlatform()`. Lib has no platform context; the page shell is the
* trusted boundary that wires this. NEVER pass user input here.
*/
chatSource: string;
/** Page title — rendered as the inline hero `
` (same DOM
* ``'s hero uses) so the doc-viewer chrome matches the
* dev-section pages. ReactNode is intentionally not supported here —
* every consumer renders the same typography. */
title?: string;
/** Optional icon rendered inline before the title text — same slot
* ``'s hero uses (Map for Roadmap, Rocket for Releases,
* etc.). Pass a pre-rendered React element styled with
* `SECTION_HERO_ICON_CLASS` (`h-10 w-10 text-ods-accent`) for visual
* parity with other lib pages. */
titleIcon?: React.ReactNode;
/** Subtitle (h6, secondary text) rendered beneath the title. */
subtitle?: string;
/** Render a yellow accent dot (`.`) after the title — same flag as
* the hub's legacy `` so the docs-hub
* surface keeps its existing accent styling after the migration. */
accentDot?: boolean;
/** Override the default ODS palette. Optional — most callers should omit. */
colorPalette?: typeof DEFAULT_DOC_VIEWER_PALETTE;
className?: string;
/** Render the standalone `` (own `` + bg + max-width). Default
* true. Pass false when the host layout already provides the page container —
* only the padding box renders, avoiding a nested ``. */
shell?: boolean;
/** Initial doc path (URL `[...path]`). */
docPath?: string;
/** Sidebar header copy (`'DOCUMENTATION'`, `'DATA ROOM'`). */
sidebarLabel?: string;
/**
* API endpoint for fetching the document tree structure. Defaults to the
* dispatcher path `/api/docs/sources/${sourceId}/structure`. Override only
* if hosting the viewer behind a different route.
*/
structureEndpoint?: string;
/** Same shape as `structureEndpoint`. Defaults to `/api/docs/sources/${sourceId}/content`. */
contentEndpoint?: string;
/** RAG-search endpoint that backs the in-source search bar (when `showAIChat`
* is on). Defaults to `/api/docs/search`. Override for proxy-prefix embeds —
* same injectability pattern as `structureEndpoint` / `contentEndpoint`. */
searchEndpoint?: string;
/** POST internal-link resolver. The viewer threads an async `onResolveLink`
* into `renderContent`'s `handlers` that posts `{ link, currentPath, source }`
* here. Defaults to `/api/docs/resolve-link`. Override for proxy-prefix embeds —
* same injectability pattern as `structureEndpoint` / `contentEndpoint` /
* `searchEndpoint`, with `ChatRuntime.endpoints.docsResolveLinkUrl` as a
* runtime fallback (prop → runtime → default). */
resolveLinkEndpoint?: string;
/** Base route path for URL navigation. */
baseRoute: string;
/** Empty state copy when no doc is selected. */
emptyStateText?: string;
/** Whether to render the doc-search bar (bound to chat). */
showAIChat?: boolean;
/** Folder-index filename (default `'README.md'`). */
folderIndexFile?: string;
/** Back-button shown above the title. Mirrors `` /
* `` / `` so every embeddable surface
* shares the same chrome. Defaults to `{ label: 'Back to home', href: '/' }`.
* Pass `false` to hide; pass `{ href: '/docs' }` etc. when the embed's
* home isn't `/`. */
backButton?: {
label?: string;
href?: string;
} | false;
}
export declare function DocViewer(props: DocViewerProps): React.JSX.Element;
//# sourceMappingURL=doc-viewer.d.ts.map