138 lines
4.3 KiB
TypeScript
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>
|
|
)
|
|
}
|