"use client" import { memo, useCallback, useEffect, useState } from "react" import { createPortal } from "react-dom" import type { Editor } from "@tiptap/react" import { Icon } from "@iconify/react" import { ArrowDownToLine, ArrowUpToLine, Columns2, Merge, PaintBucket, Rows2, Split, Square, Trash2, } from "lucide-react" import { Button } from "@/components/ui/button" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { docsClearTableCellBorders, docsDefaultTableBorder, docsSetTableCellBackground, docsSetTableCellBordersAll, docsSetTableCellVerticalAlign, docsTableActive, docsTableCanMerge, docsTableCanSplit, } from "@/lib/drive/docs-table-actions" import { DOCS_TABLE_BORDER_COLOR_PRESETS, DOCS_TABLE_CELL_BACKGROUND_PRESETS, } from "@/lib/drive/docs-table-types" import { cn } from "@/lib/utils" function ToolbarDivider() { return } function IconToolbarButton({ label, disabled, onClick, children, }: { label: string disabled?: boolean onClick: () => void children: React.ReactNode }) { return ( ) } function DocsTableFloatingToolbarInner({ editor, canvasRef, disabled, }: { editor: Editor | null canvasRef: React.RefObject disabled?: boolean }) { const [rect, setRect] = useState(null) const [, setTick] = useState(0) const refresh = useCallback(() => { setTick((value) => value + 1) if (!editor || !docsTableActive(editor)) { setRect(null) return } const selectedCell = editor.view.dom.querySelector( "td.selectedCell, th.selectedCell, .ProseMirror-selectednode table" ) as HTMLElement | null const table = selectedCell?.closest("table") ?? (editor.view.dom.querySelector(".ProseMirror-selectednode table") as HTMLElement | null) if (!table) { setRect(null) return } setRect(table.getBoundingClientRect()) }, [editor]) useEffect(() => { if (!editor) return refresh() editor.on("selectionUpdate", refresh) editor.on("transaction", refresh) const canvas = canvasRef.current canvas?.addEventListener("scroll", refresh, { passive: true }) window.addEventListener("resize", refresh) return () => { editor.off("selectionUpdate", refresh) editor.off("transaction", refresh) canvas?.removeEventListener("scroll", refresh) window.removeEventListener("resize", refresh) } }, [canvasRef, editor, refresh]) if (!editor || disabled || !docsTableActive(editor) || !rect) return null const canMerge = docsTableCanMerge(editor) const canSplit = docsTableCanSplit(editor) const toolbar = (
editor.chain().focus().addRowBefore().run()} > editor.chain().focus().addRowAfter().run()} > editor.chain().focus().addColumnBefore().run()} > editor.chain().focus().addColumnAfter().run()} > editor.chain().focus().mergeCells().run()} > editor.chain().focus().splitCell().run()} > docsSetTableCellBordersAll(editor, docsDefaultTableBorder("#000000")) } > Bordures noires docsClearTableCellBorders(editor)}> Supprimer les bordures {DOCS_TABLE_BORDER_COLOR_PRESETS.slice(0, 6).map((color) => ( docsSetTableCellBordersAll(editor, docsDefaultTableBorder(color)) } > {color} ))} {DOCS_TABLE_CELL_BACKGROUND_PRESETS.map((preset) => ( docsSetTableCellBackground(editor, preset.color || null)} > {preset.label} ))} docsSetTableCellVerticalAlign(editor, "top")}> Haut docsSetTableCellVerticalAlign(editor, "middle")}> Milieu docsSetTableCellVerticalAlign(editor, "bottom")}> Bas editor.chain().focus().toggleHeaderRow().run()}> Ligne d'en-tête editor.chain().focus().toggleHeaderColumn().run()}> Colonne d'en-tête editor.chain().focus().deleteRow().run()}> Supprimer la ligne editor.chain().focus().deleteColumn().run()}> Supprimer la colonne editor.chain().focus().deleteTable().run()} > Supprimer le tableau
) return createPortal(toolbar, document.body) } export const DocsTableFloatingToolbar = memo(DocsTableFloatingToolbarInner)