import { createContext, useContext, useId, useState, type ReactNode } from "react"; import { FolderKanban, MessageSquareText, type LucideIcon } from "lucide-react"; import { cn } from "../../../core/cn"; import { Button } from "@/openpress/ui/button"; type DocumentPanelProps = { children: ReactNode; }; type DocumentPanelTabValue = "comments" | "project" | "notes"; type DocumentPanelContextValue = { activeTab: DocumentPanelTabValue; setActiveTab: (tab: DocumentPanelTabValue) => void; baseId: string; }; const DocumentPanelContext = createContext(null); const PANEL_TABS: Array<{ value: DocumentPanelTabValue; label: string; icon: LucideIcon }> = [ { value: "comments", label: "註解", icon: MessageSquareText }, { value: "notes", label: "Notes", icon: MessageSquareText }, { value: "project", label: "Project", icon: FolderKanban }, ]; const DOCUMENT_PANEL_CLASS = "openpress-document-panel grid h-full min-h-0 grid-rows-[auto_minmax(0,1fr)] overflow-hidden"; const DOCUMENT_PANEL_TABS_CLASS = [ "op-workspace-control-tabs openpress-document-panel-tabs", "mx-[22px] grid grid-cols-[repeat(2,minmax(0,1fr))] gap-[18px] border-b border-white/[0.08] pt-0.5", ].join(" "); const DOCUMENT_PANEL_TAB_CLASS = [ "relative inline-flex min-w-0 cursor-pointer items-center justify-start gap-1.5 border-0 bg-transparent pb-2.5", "text-left text-xs font-medium leading-[1.2] text-[rgb(180_186_193_/_0.72)] [font-family:inherit]", "hover:text-[rgb(242_242_240_/_0.94)]", "after:absolute after:bottom-[-1px] after:left-0 after:right-0 after:h-px after:bg-transparent after:content-['']", "[&_svg]:h-[13px] [&_svg]:w-[13px] [&_svg]:shrink-0 [&_svg]:text-current [&_svg]:opacity-[0.78]", "[&_span]:max-w-full [&_span]:overflow-hidden [&_span]:text-ellipsis [&_span]:whitespace-nowrap", ].join(" "); const DOCUMENT_PANEL_TAB_ACTIVE_CLASS = "is-active text-[rgb(242_242_240_/_0.94)] after:bg-[rgb(242_242_240_/_0.78)]"; const DOCUMENT_PANEL_TAB_PANEL_CLASS = "min-h-0 overflow-hidden"; const DOCUMENT_PANEL_SLOT_CLASS = "min-h-0 overflow-hidden"; function useDocumentPanel() { const value = useContext(DocumentPanelContext); if (!value) throw new Error("DocumentPanel compound components must be rendered inside ."); return value; } function DocumentPanelRoot({ children }: DocumentPanelProps) { const reactId = useId(); const [activeTab, setActiveTab] = useState("comments"); const baseId = `openpress-document-panel-${reactId.replaceAll(":", "")}`; return (
{children}
); } function DocumentPanelTabs() { const { activeTab, setActiveTab, baseId } = useDocumentPanel(); return (
{PANEL_TABS.map((item) => { const Icon = item.icon; const selected = activeTab === item.value; return ( ); })}
); } function DocumentPanelTabPanel({ value, className, children, }: DocumentPanelProps & { value: DocumentPanelTabValue; className?: string; }) { const { activeTab, baseId } = useDocumentPanel(); const active = activeTab === value; return ( ); } function DocumentPanelProject({ children }: DocumentPanelProps) { return ( {children} ); } function DocumentPanelPendingComments({ children }: DocumentPanelProps) { return ( {children} ); } function DocumentPanelNotes({ children }: DocumentPanelProps) { return ( {children} ); } function DocumentPanelSlot({ children }: DocumentPanelProps) { return <>{children}; } export const DocumentPanel = Object.assign(DocumentPanelRoot, { Tabs: DocumentPanelTabs, Project: DocumentPanelProject, PendingComments: DocumentPanelPendingComments, Notes: DocumentPanelNotes, Actions: DocumentPanelSlot, CurrentPage: DocumentPanelSlot, });