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

138 lines
4.3 KiB
TypeScript

"use client"
import type { RefObject } from "react"
import { ListTree } from "lucide-react"
import { DocsHorizontalRuler } from "@/components/drive/richtext/docs-horizontal-ruler"
import { DocsVerticalRuler } from "@/components/drive/richtext/docs-vertical-ruler"
import type { DocPageLayout } from "@/lib/drive/doc-page-setup"
import type { DocsRulerMarginSide } from "@/lib/drive/docs-ruler-margin-math"
import {
DOCS_HORIZONTAL_RULER_HEIGHT_PX,
DOCS_VERTICAL_RULER_WIDTH_PX,
} from "@/lib/drive/docs-page-layout-constants"
import { docsPageLengthToScreen } from "@/lib/drive/docs-ruler-scale"
import type { DocsRulerSyncState } from "@/lib/drive/use-docs-ruler-sync"
import { cn } from "@/lib/utils"
export function DocsRulerToolbarRow({
pageLayout,
scale,
rulerSync,
rulerTrackRef,
outlineExpanded,
onToggleOutline,
editable,
onMarginDragStart,
onMarginDrag,
onMarginDragEnd,
}: {
pageLayout: DocPageLayout
scale: number
rulerSync: DocsRulerSyncState
rulerTrackRef: RefObject<HTMLDivElement | null>
outlineExpanded?: boolean
onToggleOutline?: () => void
editable?: boolean
onMarginDragStart?: (side: DocsRulerMarginSide) => void
onMarginDrag?: (side: DocsRulerMarginSide, pagePx: number, clientX: number, clientY: number) => void
onMarginDragEnd?: () => void
}) {
const scaledPageWidth = docsPageLengthToScreen(pageLayout.widthPx, scale)
return (
<div
className="docs-toolbar-ruler-row flex shrink-0 bg-transparent"
style={{ height: DOCS_HORIZONTAL_RULER_HEIGHT_PX }}
>
<div
className="flex shrink-0 items-end justify-center border-r border-[#dadce0]/80 bg-transparent pb-0.5 dark:border-border/80"
style={{
width: DOCS_VERTICAL_RULER_WIDTH_PX,
height: DOCS_HORIZONTAL_RULER_HEIGHT_PX,
}}
>
<button
type="button"
className={cn(
"pointer-events-auto flex size-7 items-center justify-center rounded-full border border-[#dadce0] bg-white text-[#5f6368] shadow-sm transition-colors hover:bg-[#e8eaed] dark:border-border dark:bg-background dark:text-muted-foreground dark:hover:bg-muted",
outlineExpanded && "border-[#1a73e8] text-[#1a73e8]"
)}
aria-label="Afficher le plan du document"
aria-pressed={outlineExpanded}
onClick={onToggleOutline}
>
<ListTree className="size-3.5" />
</button>
</div>
<div
ref={rulerTrackRef}
className="relative min-w-0 flex-1 overflow-visible"
style={{
height: DOCS_HORIZONTAL_RULER_HEIGHT_PX,
paddingRight: rulerSync.canvasScrollbarWidth,
}}
>
<div
className="mx-auto"
style={{
width: scaledPageWidth,
transform: rulerSync.canvasScrollLeft
? `translateX(${-rulerSync.canvasScrollLeft}px)`
: undefined,
}}
>
<DocsHorizontalRuler
pageLayout={pageLayout}
scale={scale}
indents={rulerSync.indents}
editable={editable}
onMarginDragStart={onMarginDragStart}
onMarginDrag={onMarginDrag}
onMarginDragEnd={onMarginDragEnd}
/>
</div>
</div>
</div>
)
}
export function DocsRulersLeftRail({
pageLayout,
scale,
rulerSync,
editable,
onMarginDragStart,
onMarginDrag,
onMarginDragEnd,
}: {
pageLayout: DocPageLayout
scale: number
rulerSync: DocsRulerSyncState
editable?: boolean
onMarginDragStart?: (side: DocsRulerMarginSide) => void
onMarginDrag?: (side: DocsRulerMarginSide, pagePx: number, clientX: number, clientY: number) => void
onMarginDragEnd?: () => void
}) {
return (
<div
className={cn(
"docs-rulers-left-rail absolute bottom-0 left-0 top-0 z-20 overflow-visible bg-transparent",
!editable && "pointer-events-none"
)}
style={{ width: DOCS_VERTICAL_RULER_WIDTH_PX }}
>
<div className="pointer-events-auto absolute left-0" style={{ top: rulerSync.pageTopInViewport }}>
<DocsVerticalRuler
pageLayout={pageLayout}
scale={scale}
editable={editable}
onMarginDragStart={onMarginDragStart}
onMarginDrag={onMarginDrag}
onMarginDragEnd={onMarginDragEnd}
/>
</div>
</div>
)
}