ultisuite-client/components/drive/richtext/docs-editor-workspace.tsx
R3D347HR4Y 2a7c153748
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
wrap page
2026-06-10 12:48:27 +02:00

171 lines
5.1 KiB
TypeScript

"use client"
import { useEffect, useRef, useState, type ReactNode } from "react"
import type { Editor } from "@tiptap/react"
import { DocsPageView } from "@/components/drive/richtext/docs-page-view"
import {
DocsRulerToolbarRow,
DocsRulersLeftRail,
} from "@/components/drive/richtext/docs-rulers-chrome"
import type { DocPageLayout } from "@/lib/drive/doc-page-setup"
import { DOCS_VERTICAL_RULER_WIDTH_PX } from "@/lib/drive/docs-page-layout-constants"
import { docsZoomToScale } from "@/lib/drive/docs-ruler-scale"
import { useDocsRulerSync } from "@/lib/drive/use-docs-ruler-sync"
import { useDocsRulerMarginDrag } from "@/components/drive/richtext/use-docs-ruler-margin-drag"
import { DocsRulerMarginDragTooltip } from "@/components/drive/richtext/docs-ruler-markers"
import { cn } from "@/lib/utils"
export function DocsEditorWorkspace({
editor,
pageLayout,
zoom,
editable,
showLayout,
showRuler,
showNonPrintableChars,
editorMode,
outlineExpanded,
onToggleOutline,
onPageCountChange,
onCurrentPageChange,
toolbar,
toolbarShellClassName,
onRegionContentChange,
onPageSetupChange,
onRegionEditorChange,
}: {
editor: Editor
pageLayout: DocPageLayout
zoom: number
editable: boolean
showLayout: boolean
showRuler: boolean
showNonPrintableChars: boolean
editorMode: "edit" | "suggest" | "view"
outlineExpanded?: boolean
onToggleOutline?: () => void
onPageCountChange?: (count: number) => void
onCurrentPageChange?: (page: number) => void
toolbar?: ReactNode
toolbarShellClassName?: string
onRegionContentChange?: (
region: "header" | "footer",
content: Record<string, unknown>,
meta: { pageIndex: number; contentHeightPx: number }
) => void
onPageSetupChange?: (
patch: Partial<import("@/lib/drive/doc-page-setup").DocPageSetup>,
options?: { immediate?: boolean }
) => void
onRegionEditorChange?: (editor: import("@tiptap/react").Editor | null) => void
}) {
const canvasRef = useRef<HTMLDivElement>(null)
const rulerTrackRef = useRef<HTMLDivElement>(null)
const [pageCount, setPageCount] = useState(1)
const [narrowViewport, setNarrowViewport] = useState(false)
const rulersVisible = showLayout && showRuler
const scale = docsZoomToScale(zoom)
const showToolbarShell = Boolean(toolbar) || rulersVisible
const marginsEditable = editable && editorMode !== "view"
const {
pageLayoutWithMargins,
beginMarginDrag,
moveMarginDrag,
endMarginDrag,
dragTooltip,
} = useDocsRulerMarginDrag({
pageLayout,
editable: marginsEditable,
onPageSetupChange,
})
const rulerSync = useDocsRulerSync({
canvasRef,
rulerTrackRef,
editor,
pageLayout: pageLayoutWithMargins,
zoom,
pageCount,
narrowViewport,
})
useEffect(() => {
onCurrentPageChange?.(rulerSync.currentPage + 1)
}, [onCurrentPageChange, rulerSync.currentPage])
return (
<div className="docs-editor-workspace flex min-h-0 flex-1 flex-col">
<DocsRulerMarginDragTooltip tooltip={dragTooltip} />
{showToolbarShell ? (
<div
className={cn(
"docs-toolbar-shell shrink-0",
toolbarShellClassName
)}
>
{toolbar}
{rulersVisible ? (
<DocsRulerToolbarRow
pageLayout={pageLayoutWithMargins}
scale={scale}
rulerSync={rulerSync}
rulerTrackRef={rulerTrackRef}
outlineExpanded={outlineExpanded}
onToggleOutline={onToggleOutline}
editable={marginsEditable}
onMarginDragStart={beginMarginDrag}
onMarginDrag={moveMarginDrag}
onMarginDragEnd={endMarginDrag}
/>
) : null}
</div>
) : null}
<div className="relative min-h-0 flex-1 overflow-hidden">
{rulersVisible ? (
<DocsRulersLeftRail
pageLayout={pageLayoutWithMargins}
scale={scale}
rulerSync={rulerSync}
editable={marginsEditable}
onMarginDragStart={beginMarginDrag}
onMarginDrag={moveMarginDrag}
onMarginDragEnd={endMarginDrag}
/>
) : null}
<div
className="flex h-full min-h-0 flex-col"
style={
rulersVisible
? { paddingLeft: DOCS_VERTICAL_RULER_WIDTH_PX }
: undefined
}
>
<DocsPageView
editor={editor}
pageLayout={pageLayoutWithMargins}
zoom={zoom}
editable={editable}
showLayout={showLayout}
showRuler={false}
showNonPrintableChars={showNonPrintableChars}
editorMode={editorMode}
canvasRef={canvasRef}
onPageCountChange={(count) => {
setPageCount(count)
onPageCountChange?.(count)
}}
onNarrowViewportChange={setNarrowViewport}
onRegionContentChange={onRegionContentChange}
onPageSetupChange={onPageSetupChange}
onRegionEditorChange={onRegionEditorChange}
/>
</div>
</div>
</div>
)
}