From af929ab7414463a624a04ad3e4d3cc95239e7c21 Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Date: Thu, 31 Aug 2023 16:30:28 +0530 Subject: [PATCH] style: tiptap table (#2033) --- apps/app/components/tiptap/index.tsx | 6 +- .../components/tiptap/table-menu/index.tsx | 113 +++++++++++------- apps/app/styles/editor.css | 22 ++-- apps/app/styles/globals.css | 4 + 4 files changed, 90 insertions(+), 55 deletions(-) diff --git a/apps/app/components/tiptap/index.tsx b/apps/app/components/tiptap/index.tsx index 869e44aad..2ab6bf288 100644 --- a/apps/app/components/tiptap/index.tsx +++ b/apps/app/components/tiptap/index.tsx @@ -76,8 +76,8 @@ const Tiptap = (props: ITipTapRichTextEditor) => { const editorClassNames = `relative w-full max-w-full sm:rounded-lg mt-2 p-3 relative focus:outline-none rounded-md ${noBorder ? "" : "border border-custom-border-200"} ${ - borderOnFocus ? "focus:border border-custom-border-300" : "focus:border-0" - } ${customClassName}`; + borderOnFocus ? "focus:border border-custom-border-300" : "focus:border-0" + } ${customClassName}`; if (!editor) return null; editorRef.current = editor; @@ -93,7 +93,7 @@ const Tiptap = (props: ITipTapRichTextEditor) => { {editor && }
- {editor?.isActive("table") && } + {editor?.isActive("image") && }
diff --git a/apps/app/components/tiptap/table-menu/index.tsx b/apps/app/components/tiptap/table-menu/index.tsx index 878679a29..0da68410e 100644 --- a/apps/app/components/tiptap/table-menu/index.tsx +++ b/apps/app/components/tiptap/table-menu/index.tsx @@ -1,11 +1,13 @@ import { useState, useEffect } from "react"; import { Rows, Columns, ToggleRight } from "lucide-react"; import { cn } from "../utils"; +import { Tooltip } from "components/ui"; interface TableMenuItem { - name: string; command: () => void; icon: any; + key: string; + name: string; } export const findTableAncestor = (node: Node | null): HTMLTableElement | null => { @@ -17,79 +19,108 @@ export const findTableAncestor = (node: Node | null): HTMLTableElement | null => export const TableMenu = ({ editor }: { editor: any }) => { const [tableLocation, setTableLocation] = useState({ bottom: 0, left: 0 }); + const isOpen = editor?.isActive("table"); + const items: TableMenuItem[] = [ { - name: "Insert Column right", command: () => editor.chain().focus().addColumnBefore().run(), icon: Columns, + key: "insert-column-right", + name: "Insert 1 column right", }, { - name: "Insert Row below", command: () => editor.chain().focus().addRowAfter().run(), icon: Rows, + key: "insert-row-below", + name: "Insert 1 row below", }, { - name: "Delete Column", command: () => editor.chain().focus().deleteColumn().run(), icon: Columns, + key: "delete-column", + name: "Delete column", }, { - name: "Delete Rows", command: () => editor.chain().focus().deleteRow().run(), icon: Rows, + key: "delete-row", + name: "Delete row", }, { - name: "Toggle Header Row", command: () => editor.chain().focus().toggleHeaderRow().run(), icon: ToggleRight, - } - + key: "toggle-header-row", + name: "Toggle header row", + }, ]; useEffect(() => { - if (typeof window !== "undefined") { - const handleWindowClick = () => { - const selection: any = window?.getSelection(); - if (selection.rangeCount !== 0) { - const range = selection.getRangeAt(0); - const tableNode = findTableAncestor(range.startContainer); - if (tableNode) { - const tableRect = tableNode.getBoundingClientRect(); - const tableCenter = tableRect.left + tableRect.width / 2; - const menuWidth = 45; - const menuLeft = tableCenter - menuWidth / 2; - const tableBottom = tableRect.bottom; - setTableLocation({ bottom: tableBottom, left: menuLeft }); + if (!window) return; + + const handleWindowClick = () => { + const selection: any = window?.getSelection(); + + if (selection.rangeCount !== 0) { + const range = selection.getRangeAt(0); + const tableNode = findTableAncestor(range.startContainer); + + let parent = tableNode?.parentElement; + + if (tableNode) { + const tableRect = tableNode.getBoundingClientRect(); + const tableCenter = tableRect.left + tableRect.width / 2; + const menuWidth = 45; + const menuLeft = tableCenter - menuWidth / 2; + const tableBottom = tableRect.bottom; + + setTableLocation({ bottom: tableBottom, left: menuLeft }); + + while (parent) { + if (!parent.classList.contains("disable-scroll")) + parent.classList.add("disable-scroll"); + parent = parent.parentElement; } + } else { + const scrollDisabledContainers = document.querySelectorAll(".disable-scroll"); + + scrollDisabledContainers.forEach((container) => { + container.classList.remove("disable-scroll"); + }); } } + }; - window.addEventListener("click", handleWindowClick); + window.addEventListener("click", handleWindowClick); - return () => { - window.removeEventListener("click", handleWindowClick); - }; - } - }, [tableLocation]); + return () => { + window.removeEventListener("click", handleWindowClick); + }; + }, [tableLocation, editor]); return (
{items.map((item, index) => ( - + + + ))}
); diff --git a/apps/app/styles/editor.css b/apps/app/styles/editor.css index 3332185d2..9da250dd1 100644 --- a/apps/app/styles/editor.css +++ b/apps/app/styles/editor.css @@ -144,7 +144,7 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p { height: 20px; border-radius: 50%; border: 3px solid rgba(var(--color-text-200)); - border-top-color: rgba(var(--color-text-800)); + border-top-color: rgba(var(--color-text-800)); animation: spinning 0.6s linear infinite; } } @@ -160,16 +160,13 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p { border-collapse: collapse; table-layout: fixed; margin: 0; - margin-bottom: 1.5rem; - margin-top: 1.5rem; - border: 2px solid rgb(var(--color-border-100)); + border: 1px solid rgb(var(--color-border-200)); width: 100%; - box-shadow: 0 0 10px rgba(0,0,0,0.1); td, th { min-width: 1em; - border: 2px solid rgb(var(--color-border-400)); + border: 1px solid rgb(var(--color-border-200)); padding: 10px 15px; vertical-align: top; box-sizing: border-box; @@ -183,8 +180,8 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p { th { font-weight: bold; - text-align: left; - background-color: rgb(var(--color-primary-300)); + text-align: left; + background-color: rgb(var(--color-primary-100)); } td:hover { @@ -195,7 +192,10 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p { z-index: 2; position: absolute; content: ""; - left: 0; right: 0; top: 0; bottom: 0; + left: 0; + right: 0; + top: 0; + bottom: 0; background-color: rgba(var(--color-primary-300), 0.1); pointer-events: none; } @@ -222,8 +222,8 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p { } .ProseMirror table * p { - padding: 0px 1px; - margin: 6px 2px; + padding: 0px 1px; + margin: 6px 2px; } .ProseMirror table * .is-empty::before { diff --git a/apps/app/styles/globals.css b/apps/app/styles/globals.css index cdb67cbc5..3de1e2c57 100644 --- a/apps/app/styles/globals.css +++ b/apps/app/styles/globals.css @@ -355,3 +355,7 @@ body { .bp4-overlay-content { z-index: 555 !important; } + +.disable-scroll { + overflow: hidden !important; +}