Minor(#13715): add table support in block editor (#14290)

* minor(#13715): add table support in block editor

* fix code smell

* address comment
This commit is contained in:
Sachin Chaurasiya 2023-12-07 16:22:35 +05:30 committed by GitHub
parent f1280f97b9
commit f1ec0b322b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 264 additions and 12 deletions

View File

@ -54,12 +54,15 @@
"@okta/okta-auth-js": "^6.4.0",
"@okta/okta-react": "^6.4.3",
"@rjsf/core": "5.4.0",
"rapidoc": "9.3.4",
"@rjsf/utils": "5.4.0",
"@rjsf/validator-ajv8": "5.4.0",
"@tiptap/core": "^2.1.7",
"@tiptap/extension-link": "^2.1.7",
"@tiptap/extension-placeholder": "^2.1.7",
"@tiptap/extension-table": "^2.1.13",
"@tiptap/extension-table-cell": "^2.1.13",
"@tiptap/extension-table-header": "^2.1.13",
"@tiptap/extension-table-row": "^2.1.13",
"@tiptap/extension-task-item": "^2.1.7",
"@tiptap/extension-task-list": "^2.1.7",
"@tiptap/pm": "^2.1.7",
@ -105,6 +108,7 @@
"quill-emoji": "^0.2.0",
"quill-mention": "^4.0.0",
"quilljs-markdown": "^1.1.10",
"rapidoc": "9.3.4",
"react": "^16.14.0",
"react-awesome-query-builder": "5.1.2",
"react-codemirror2": "^7.2.1",

View File

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.99988 3.33346L1.99988 11.3335C1.99988 11.7755 2.17547 12.1994 2.48803 12.512C2.80059 12.8245 3.22452 13.0001 3.66654 13.0001L10.3332 13.0001C10.7752 13.0001 11.1992 12.8245 11.5117 12.512C11.8243 12.1994 11.9999 11.7755 11.9999 11.3335V10.6668C11.9999 10.5784 11.9648 10.4936 11.9022 10.4311C11.8397 10.3686 11.7549 10.3335 11.6665 10.3335C11.5781 10.3335 11.4934 10.3686 11.4308 10.4311C11.3683 10.4936 11.3332 10.5784 11.3332 10.6668V11.3335C11.3332 11.5987 11.2279 11.853 11.0403 12.0406C10.8528 12.2281 10.5984 12.3335 10.3332 12.3335H7.33321L7.33321 2.33346H10.3332C10.5984 2.33346 10.8528 2.43881 11.0403 2.62635C11.2279 2.81389 11.3332 3.06824 11.3332 3.33346V4.00012C11.3332 4.08853 11.3683 4.17331 11.4308 4.23583C11.4934 4.29834 11.5781 4.33346 11.6665 4.33346C11.7549 4.33346 11.8397 4.29834 11.9022 4.23583C11.9648 4.17331 11.9999 4.08853 11.9999 4.00012V3.33346C11.9999 2.89143 11.8243 2.4675 11.5117 2.15494C11.1992 1.84238 10.7752 1.66679 10.3332 1.66679L3.66654 1.66679C3.22452 1.66679 2.80059 1.84238 2.48803 2.15494C2.17547 2.4675 1.99988 2.89143 1.99988 3.33346ZM6.66654 12.3335L3.66654 12.3335C3.40133 12.3335 3.14697 12.2281 2.95944 12.0406C2.7719 11.853 2.66654 11.5987 2.66654 11.3335L2.66654 3.33346C2.66654 3.06824 2.7719 2.81389 2.95944 2.62635C3.14697 2.43881 3.40133 2.33346 3.66654 2.33346L6.66654 2.33346L6.66654 12.3335ZM10.3332 7.00012H11.3332V6.00012C11.3332 5.91172 11.3683 5.82693 11.4308 5.76442C11.4934 5.70191 11.5781 5.66679 11.6665 5.66679C11.7549 5.66679 11.8397 5.70191 11.9022 5.76442C11.9648 5.82693 11.9999 5.91172 11.9999 6.00012V7.00012L12.9999 7.00012C13.0883 7.00012 13.1731 7.03524 13.2356 7.09775C13.2981 7.16027 13.3332 7.24505 13.3332 7.33346C13.3332 7.42186 13.2981 7.50665 13.2356 7.56916C13.1731 7.63167 13.0883 7.66679 12.9999 7.66679L11.9999 7.66679L11.9999 8.66679C11.9999 8.75519 11.9648 8.83998 11.9022 8.90249C11.8397 8.965 11.7549 9.00012 11.6665 9.00012C11.5781 9.00012 11.4934 8.965 11.4308 8.90249C11.3683 8.83998 11.3332 8.75519 11.3332 8.66679L11.3332 7.66679H10.3332C10.2448 7.66679 10.16 7.63167 10.0975 7.56916C10.035 7.50665 9.99988 7.42186 9.99988 7.33346C9.99988 7.24505 10.035 7.16027 10.0975 7.09775C10.16 7.03524 10.2448 7.00012 10.3332 7.00012Z" fill="#292929" stroke="#292929" stroke-width="0.5"/>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.6673 2.00012H3.66728C3.22525 2.00012 2.80133 2.17572 2.48877 2.48828C2.17621 2.80084 2.00061 3.22476 2.00061 3.66679V10.3335C2.00061 10.7755 2.17621 11.1994 2.48877 11.512C2.80133 11.8245 3.22525 12.0001 3.66728 12.0001H4.33394C4.42235 12.0001 4.50713 11.965 4.56965 11.9025C4.63216 11.84 4.66728 11.7552 4.66728 11.6668C4.66728 11.5784 4.63216 11.4936 4.56965 11.4311C4.50713 11.3686 4.42235 11.3335 4.33394 11.3335H3.66728C3.40206 11.3335 3.14771 11.2281 2.96017 11.0406C2.77263 10.853 2.66728 10.5987 2.66728 10.3335V7.33346H12.6673V10.3335C12.6673 10.5987 12.5619 10.853 12.3744 11.0406C12.1868 11.2281 11.9325 11.3335 11.6673 11.3335H11.0006C10.9122 11.3335 10.8274 11.3686 10.7649 11.4311C10.7024 11.4936 10.6673 11.5784 10.6673 11.6668C10.6673 11.7552 10.7024 11.84 10.7649 11.9025C10.8274 11.965 10.9122 12.0001 11.0006 12.0001H11.6673C12.1093 12.0001 12.5332 11.8245 12.8458 11.512C13.1583 11.1994 13.3339 10.7755 13.3339 10.3335V3.66679C13.3339 3.22476 13.1583 2.80084 12.8458 2.48828C12.5332 2.17572 12.1093 2.00012 11.6673 2.00012ZM2.66728 6.66679V3.66679C2.66728 3.40157 2.77263 3.14722 2.96017 2.95968C3.14771 2.77215 3.40206 2.66679 3.66728 2.66679H11.6673C11.9325 2.66679 12.1868 2.77215 12.3744 2.95968C12.5619 3.14722 12.6673 3.40157 12.6673 3.66679V6.66679H2.66728ZM8.00061 10.3335V11.3335H9.00061C9.08902 11.3335 9.1738 11.3686 9.23631 11.4311C9.29882 11.4936 9.33394 11.5784 9.33394 11.6668C9.33394 11.7552 9.29882 11.84 9.23631 11.9025C9.1738 11.965 9.08902 12.0001 9.00061 12.0001H8.00061V13.0001C8.00061 13.0885 7.96549 13.1733 7.90298 13.2358C7.84047 13.2983 7.75568 13.3335 7.66728 13.3335C7.57887 13.3335 7.49409 13.2983 7.43157 13.2358C7.36906 13.1733 7.33394 13.0885 7.33394 13.0001V12.0001H6.33394C6.24554 12.0001 6.16075 11.965 6.09824 11.9025C6.03573 11.84 6.00061 11.7552 6.00061 11.6668C6.00061 11.5784 6.03573 11.4936 6.09824 11.4311C6.16075 11.3686 6.24554 11.3335 6.33394 11.3335H7.33394V10.3335C7.33394 10.2451 7.36906 10.1603 7.43157 10.0978C7.49409 10.0352 7.57887 10.0001 7.66728 10.0001C7.75568 10.0001 7.84047 10.0352 7.90298 10.0978C7.96549 10.1603 8.00061 10.2451 8.00061 10.3335Z" fill="#292929" stroke="#292929" stroke-width="0.5"/>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2 3.66683L2 11.6668C2 12.1089 2.17559 12.5328 2.48816 12.8453C2.80072 13.1579 3.22464 13.3335 3.66667 13.3335L10.3333 13.3335C10.7754 13.3335 11.1993 13.1579 11.5118 12.8453C11.8244 12.5328 12 12.1089 12 11.6668V11.0002C12 10.9118 11.9649 10.827 11.9024 10.7645C11.8399 10.7019 11.7551 10.6668 11.6667 10.6668C11.5783 10.6668 11.4935 10.7019 11.431 10.7645C11.3685 10.827 11.3333 10.9118 11.3333 11.0002V11.6668C11.3333 11.932 11.228 12.1864 11.0404 12.3739C10.8529 12.5615 10.5985 12.6668 10.3333 12.6668H7.33333L7.33333 2.66683H10.3333C10.5985 2.66683 10.8529 2.77219 11.0404 2.95972C11.228 3.14726 11.3333 3.40161 11.3333 3.66683V4.3335C11.3333 4.4219 11.3685 4.50669 11.431 4.5692C11.4935 4.63171 11.5783 4.66683 11.6667 4.66683C11.7551 4.66683 11.8399 4.63171 11.9024 4.5692C11.9649 4.50669 12 4.4219 12 4.3335V3.66683C12 3.2248 11.8244 2.80088 11.5118 2.48832C11.1993 2.17576 10.7754 2.00016 10.3333 2.00016L3.66667 2.00016C3.22464 2.00016 2.80072 2.17576 2.48816 2.48832C2.17559 2.80088 2 3.2248 2 3.66683ZM6.66667 12.6668L3.66667 12.6668C3.40145 12.6668 3.1471 12.5615 2.95956 12.3739C2.77202 12.1864 2.66667 11.932 2.66667 11.6668L2.66667 3.66683C2.66667 3.40161 2.77202 3.14726 2.95956 2.95972C3.1471 2.77219 3.40145 2.66683 3.66667 2.66683L6.66667 2.66683L6.66667 12.6668Z" fill="#292929" stroke="black" stroke-width="0.5"/>
<path d="M12.0039 7.33301H13.0039C13.0923 7.33301 13.1771 7.36813 13.2396 7.43064C13.3021 7.49315 13.3372 7.57794 13.3372 7.66634C13.3372 7.75475 13.3021 7.83953 13.2396 7.90204C13.1771 7.96456 13.0923 7.99967 13.0039 7.99967H12.0039H11.3372H10.3372C10.2488 7.99967 10.164 7.96456 10.1015 7.90204C10.039 7.83953 10.0039 7.75475 10.0039 7.66634C10.0039 7.57794 10.039 7.49315 10.1015 7.43064C10.164 7.36813 10.2488 7.33301 10.3372 7.33301H11.3372L11.8379 7.33317L12.0039 7.33301Z" fill="#292929"/>
<path d="M12.0039 7.99967H13.0039C13.0923 7.99967 13.1771 7.96456 13.2396 7.90204C13.3021 7.83953 13.3372 7.75475 13.3372 7.66634C13.3372 7.57794 13.3021 7.49315 13.2396 7.43064C13.1771 7.36813 13.0923 7.33301 13.0039 7.33301H12.0039L11.8379 7.33317C11.8379 7.33317 11.4256 7.33301 11.3372 7.33301H10.3372C10.2488 7.33301 10.164 7.36813 10.1015 7.43064C10.039 7.49315 10.0039 7.57794 10.0039 7.66634C10.0039 7.75475 10.039 7.83953 10.1015 7.90204C10.164 7.96456 10.2488 7.99967 10.3372 7.99967H11.3372M12.0039 7.99967C12.0039 7.99967 11.3106 7.99967 11.3372 7.99967M12.0039 7.99967H11.3372M12.0039 7.99967C11.9155 7.99967 11.3226 7.98721 11.3372 7.99967" stroke="black" stroke-width="0.5"/>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.6673 3.00012H3.66728C3.22525 3.00012 2.80133 3.17572 2.48877 3.48828C2.17621 3.80084 2.00061 4.22476 2.00061 4.66679V11.3335C2.00061 11.7755 2.17621 12.1994 2.48877 12.512C2.80133 12.8245 3.22525 13.0001 3.66728 13.0001H4.33394C4.42235 13.0001 4.50713 12.965 4.56965 12.9025C4.63216 12.84 4.66728 12.7552 4.66728 12.6668C4.66728 12.5784 4.63216 12.4936 4.56965 12.4311C4.50713 12.3686 4.42235 12.3335 4.33394 12.3335H3.66728C3.40206 12.3335 3.14771 12.2281 2.96017 12.0406C2.77263 11.853 2.66728 11.5987 2.66728 11.3335V8.33346H12.6673V11.3335C12.6673 11.5987 12.5619 11.853 12.3744 12.0406C12.1868 12.2281 11.9325 12.3335 11.6673 12.3335H11.0006C10.9122 12.3335 10.8274 12.3686 10.7649 12.4311C10.7024 12.4936 10.6673 12.5784 10.6673 12.6668C10.6673 12.7552 10.7024 12.84 10.7649 12.9025C10.8274 12.965 10.9122 13.0001 11.0006 13.0001H11.6673C12.1093 13.0001 12.5332 12.8245 12.8458 12.512C13.1583 12.1994 13.3339 11.7755 13.3339 11.3335V4.66679C13.3339 4.22476 13.1583 3.80084 12.8458 3.48828C12.5332 3.17572 12.1093 3.00012 11.6673 3.00012ZM2.66728 7.66679V4.66679C2.66728 4.40157 2.77263 4.14722 2.96017 3.95968C3.14771 3.77215 3.40206 3.66679 3.66728 3.66679H11.6673C11.9325 3.66679 12.1868 3.77215 12.3744 3.95968C12.5619 4.14722 12.6673 4.40157 12.6673 4.66679V7.66679H2.66728ZM8.00061 12.3335H9.00061C9.08902 12.3335 9.1738 12.3686 9.23631 12.4311C9.29882 12.4936 9.33394 12.5784 9.33394 12.6668C9.33394 12.7552 9.29882 12.84 9.23631 12.9025C9.1738 12.965 9.08902 13.0001 9.00061 13.0001H8.00061C8.00061 13.0001 7.30729 13.0001 7.33394 13.0001H8.00061C7.9122 13.0001 7.31929 12.9877 7.33394 13.0001H6.33394C6.24554 13.0001 6.16075 12.965 6.09824 12.9025C6.03573 12.84 6.00061 12.7552 6.00061 12.6668C6.00061 12.5784 6.03573 12.4936 6.09824 12.4311C6.16075 12.3686 6.24554 12.3335 6.33394 12.3335H7.33394C7.42235 12.3335 7.83459 12.3336 7.83459 12.3336L8.00061 12.3335Z" fill="#292929"/>
<path d="M8.00061 13.0001H9.00061C9.08902 13.0001 9.1738 12.965 9.23631 12.9025C9.29882 12.84 9.33394 12.7552 9.33394 12.6668C9.33394 12.5784 9.29882 12.4936 9.23631 12.4311C9.1738 12.3686 9.08902 12.3335 9.00061 12.3335H8.00061L7.83459 12.3336C7.83459 12.3336 7.42235 12.3335 7.33394 12.3335H6.33394C6.24554 12.3335 6.16075 12.3686 6.09824 12.4311C6.03573 12.4936 6.00061 12.5784 6.00061 12.6668C6.00061 12.7552 6.03573 12.84 6.09824 12.9025C6.16075 12.965 6.24554 13.0001 6.33394 13.0001H7.33394M8.00061 13.0001C8.00061 13.0001 7.30729 13.0001 7.33394 13.0001M8.00061 13.0001H7.33394M8.00061 13.0001C7.9122 13.0001 7.31929 12.9877 7.33394 13.0001M11.6673 3.00012H3.66728C3.22525 3.00012 2.80133 3.17572 2.48877 3.48828C2.17621 3.80084 2.00061 4.22476 2.00061 4.66679V11.3335C2.00061 11.7755 2.17621 12.1994 2.48877 12.512C2.80133 12.8245 3.22525 13.0001 3.66728 13.0001H4.33394C4.42235 13.0001 4.50713 12.965 4.56965 12.9025C4.63216 12.84 4.66728 12.7552 4.66728 12.6668C4.66728 12.5784 4.63216 12.4936 4.56965 12.4311C4.50713 12.3686 4.42235 12.3335 4.33394 12.3335H3.66728C3.40206 12.3335 3.14771 12.2281 2.96017 12.0406C2.77263 11.853 2.66728 11.5987 2.66728 11.3335V8.33346H12.6673V11.3335C12.6673 11.5987 12.5619 11.853 12.3744 12.0406C12.1868 12.2281 11.9325 12.3335 11.6673 12.3335H11.0006C10.9122 12.3335 10.8274 12.3686 10.7649 12.4311C10.7024 12.4936 10.6673 12.5784 10.6673 12.6668C10.6673 12.7552 10.7024 12.84 10.7649 12.9025C10.8274 12.965 10.9122 13.0001 11.0006 13.0001H11.6673C12.1093 13.0001 12.5332 12.8245 12.8458 12.512C13.1583 12.1994 13.3339 11.7755 13.3339 11.3335V4.66679C13.3339 4.22476 13.1583 3.80084 12.8458 3.48828C12.5332 3.17572 12.1093 3.00012 11.6673 3.00012ZM2.66728 7.66679V4.66679C2.66728 4.40157 2.77263 4.14722 2.96017 3.95968C3.14771 3.77215 3.40206 3.66679 3.66728 3.66679H11.6673C11.9325 3.66679 12.1868 3.77215 12.3744 3.95968C12.5619 4.14722 12.6673 4.40157 12.6673 4.66679V7.66679H2.66728Z" stroke="#292929" stroke-width="0.5"/>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -0,0 +1 @@
<svg fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path d="M0 4.5a3 3 0 0 1 3 -3h18A3.002 3.002 0 0 1 24 4.5v15a3.003 3.003 0 0 1 -3 3H3A3.002 3.002 0 0 1 0 19.5V4.5zm1.5 0v3h21v-3A1.499 1.499 0 0 0 21 3H3a1.5 1.5 0 0 0 -1.5 1.5zm0 4.5v5.25h9.75V9H1.5zm11.25 0v5.25h9.75V9H12.75zm-1.5 6.75H1.5v3.75a1.499 1.499 0 0 0 1.5 1.5h8.25V15.75zm9.75 5.25a1.498 1.498 0 0 0 1.5 -1.5v-3.75H12.75v5.25h8.25z"/></svg>

After

Width:  |  Height:  |  Size: 458 B

View File

@ -115,7 +115,8 @@ const BubbleMenu: FC<BubbleMenuProps> = ({ editor, toggleLink }) => {
editor.isActive('image') ||
empty ||
isNodeSelection(selection) ||
editor.isActive('link')
editor.isActive('link') ||
editor.isActive('table')
) {
return false;
}

View File

@ -19,6 +19,7 @@ import BlockMenu from './BlockMenu/BlockMenu';
import BubbleMenu from './BubbleMenu/BubbleMenu';
import LinkModal, { LinkData } from './LinkModal/LinkModal';
import LinkPopup from './LinkPopup/LinkPopup';
import TableMenu from './TableMenu/TableMenu';
interface EditorSlotsProps {
editor: Editor | null;
@ -165,7 +166,12 @@ const EditorSlots = forwardRef<EditorSlotsRef, EditorSlotsProps>(
/>
)}
{menus}
{!isNil(editor) && <BlockMenu editor={editor} />}
{!isNil(editor) && (
<>
<BlockMenu editor={editor} />
<TableMenu editor={editor} />
</>
)}
</>
);
}

View File

@ -12,6 +12,10 @@
*/
import Placeholder from '@tiptap/extension-placeholder';
import Table from '@tiptap/extension-table';
import TableCell from '@tiptap/extension-table-cell';
import TableHeader from '@tiptap/extension-table-header';
import TableRow from '@tiptap/extension-table-row';
import TaskItem from '@tiptap/extension-task-item';
import TaskList from '@tiptap/extension-task-list';
import StarterKit from '@tiptap/starter-kit';
@ -115,4 +119,28 @@ export const extensions = [
mode: 'deepest',
}),
Callout,
Table.configure({
HTMLAttributes: {
class: 'om-table',
'data-om-table': 'om-table',
},
}),
TableRow.configure({
HTMLAttributes: {
class: 'om-table-row',
'data-om-table-row': 'om-table-row',
},
}),
TableHeader.configure({
HTMLAttributes: {
class: 'om-table-header',
'data-om-table-header': 'om-table-header',
},
}),
TableCell.configure({
HTMLAttributes: {
class: 'om-table-cell',
'data-om-table-cell': 'om-table-cell',
},
}),
];

View File

@ -24,6 +24,7 @@ import TaskListIcon from '../../../../assets/img/ic-task-list.png';
import IconFormatCallout from '../../../../assets/svg/ic-format-callout.svg';
import CodeBlockImage from '../../../../assets/svg/ic-format-code-block.svg';
import IconFormatImage from '../../../../assets/svg/ic-format-image.svg';
import IconTable from '../../../../assets/svg/ic-format-table.svg';
import MentionImage from '../../../../assets/svg/ic-mentions.svg';
export enum SuggestionItemType {
@ -216,6 +217,21 @@ export const getSuggestionItems = (props: {
type: SuggestionItemType.ADVANCED_BLOCKS,
imgSrc: IconFormatCallout,
},
{
title: 'Table',
description: 'Add tabular content',
searchTerms: ['table', 'row', 'column', 'tabular'],
command: ({ editor, range }) => {
editor
.chain()
.focus()
.deleteRange(range)
.insertTable({ rows: 3, cols: 3, withHeaderRow: true })
.run();
},
type: SuggestionItemType.ADVANCED_BLOCKS,
imgSrc: IconTable,
},
];
const filteredItems = suggestionItems.filter((item) => {

View File

@ -30,7 +30,11 @@ const renderItems = () => {
editor: props.editor,
});
if (!props.clientRect) {
if (
!props.clientRect ||
props.editor.isActive('table') ||
props.editor.isActive('callout')
) {
return;
}

View File

@ -0,0 +1,135 @@
/*
* Copyright 2023 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Editor } from '@tiptap/react';
import { Button, Space, Tooltip } from 'antd';
import React, { useCallback, useEffect, useRef } from 'react';
import tippy, { Instance } from 'tippy.js';
import { ReactComponent as IconDeleteTable } from '../../../assets/svg/ic-delete.svg';
import { ReactComponent as IconAddColumnAfter } from '../../../assets/svg/ic-format-add-column-after.svg';
import { ReactComponent as IconAddRowAfter } from '../../../assets/svg/ic-format-add-row-after.svg';
import { ReactComponent as IconDeleteColumn } from '../../../assets/svg/ic-format-delete-column.svg';
import { ReactComponent as IconDeleteRow } from '../../../assets/svg/ic-format-delete-row.svg';
interface TableMenuProps {
editor: Editor;
}
const TableMenu = (props: TableMenuProps) => {
const { editor } = props;
const { view } = editor;
const menuRef = useRef<HTMLDivElement>(null);
const tableMenuPopup = useRef<Instance | null>(null);
const handleMouseDown = useCallback((event: MouseEvent) => {
const target = event.target as HTMLElement;
const table = target?.closest('[data-om-table]');
if (table?.contains(target)) {
tableMenuPopup.current?.setProps({
getReferenceClientRect: () => table.getBoundingClientRect(),
});
tableMenuPopup.current?.show();
}
}, []);
useEffect(() => {
if (menuRef.current) {
menuRef.current.remove();
menuRef.current.style.visibility = 'visible';
tableMenuPopup.current = tippy(view.dom, {
getReferenceClientRect: null,
content: menuRef.current,
appendTo: 'parent',
trigger: 'manual',
interactive: true,
arrow: false,
placement: 'top',
hideOnClick: true,
onShown: () => {
menuRef.current?.focus();
},
});
}
return () => {
tableMenuPopup.current?.destroy();
tableMenuPopup.current = null;
};
}, []);
useEffect(() => {
document.addEventListener('mousedown', handleMouseDown);
return () => {
document.removeEventListener('mousedown', handleMouseDown);
};
}, [handleMouseDown]);
return (
<div className="table-menu" ref={menuRef}>
<Space size="middle">
<Tooltip showArrow={false} title="Add row after current row">
<Button
data-testid="Add row after current row"
type="text"
onClick={() => editor.chain().focus().addRowAfter().run()}>
<IconAddRowAfter style={{ verticalAlign: 'middle' }} />
</Button>
</Tooltip>
<Tooltip showArrow={false} title="Add column after current column">
<Button
data-testid="Add column after current column"
type="text"
onClick={() => editor.chain().focus().addColumnAfter().run()}>
<IconAddColumnAfter style={{ verticalAlign: 'middle' }} />
</Button>
</Tooltip>
<Tooltip showArrow={false} title="Delete current row">
<Button
data-testid="Delete current row"
type="text"
onClick={() => editor.chain().focus().deleteRow().run()}>
<IconDeleteRow style={{ verticalAlign: 'middle' }} />
</Button>
</Tooltip>
<Tooltip showArrow={false} title="Delete current column">
<Button
data-testid="Delete current col"
type="text"
onClick={() => editor.chain().focus().deleteColumn().run()}>
<IconDeleteColumn style={{ verticalAlign: 'middle' }} />
</Button>
</Tooltip>
<Tooltip showArrow={false} title="Delete table">
<Button
data-testid="Delete table"
type="text"
onClick={() => {
editor.chain().focus().deleteTable().run();
tableMenuPopup.current?.hide();
}}>
<IconDeleteTable style={{ verticalAlign: 'middle' }} width={14} />
</Button>
</Tooltip>
</Space>
</div>
);
};
export default TableMenu;

View File

@ -35,6 +35,17 @@
height: 0;
pointer-events: none;
}
.tiptap.ProseMirror-focused .om-table-header,
.tiptap.ProseMirror-focused .om-table-row,
.tiptap.ProseMirror-focused div[data-type='callout'] {
.is-node-empty.has-focus::before {
color: inherit;
content: none;
float: inherit;
height: 0;
pointer-events: inherit;
}
}
.tiptap.ProseMirror {
font-size: 14px;
h1,
@ -88,7 +99,11 @@
table {
border-collapse: collapse;
margin-left: 35px;
width: 100%;
table-layout: auto;
text-align: left;
margin-top: 2em;
margin-bottom: 2em;
}
th,
@ -96,6 +111,8 @@
border: 1px solid @border-color;
margin: 0;
padding: 8px 16px;
min-width: 200px;
padding: 0.5rem;
}
th {
@ -214,8 +231,8 @@
object-fit: cover;
border-radius: 4px;
background: white;
width: 46px;
height: 46px;
width: 32px;
height: 32px;
box-shadow: rgba(15, 15, 15, 0.1) 0px 0px 0px 1px;
}
}
@ -424,3 +441,13 @@
.om-callout-node-content {
align-self: center;
}
.table-menu {
padding: 4px 8px;
background-color: @white;
border: @global-border;
border-radius: @border-radius-base;
button {
padding: 0px;
}
}

View File

@ -3613,6 +3613,26 @@
resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-2.1.7.tgz#b7b7f49254f1de22416b1415ca88a2a20edd0627"
integrity sha512-ONLXYnuZGM2EoGcxkyvJSDMBeAp7K6l83UXkK9TSj+VpEEDdeV7m8mJs8/vACJjJxD5HMN61+EPgU7VTEukQCA==
"@tiptap/extension-table-cell@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-cell/-/extension-table-cell-2.1.13.tgz#28efbc99480d53346200dcbf50cfb32bade180d1"
integrity sha512-30pyVt2PxGAk8jmsXKxDheql8K/xIRA9FiDo++kS2Kr6Y7I42/kNPQttJ2W+Q1JdRJvedNfQtziQfKWDRLLCNA==
"@tiptap/extension-table-header@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-header/-/extension-table-header-2.1.13.tgz#8d64a0e5a6a5ea128708b866e56a0e04e34d7a5b"
integrity sha512-FwIV5iso5kmpu01QyvrPCjJqZfqxRTjtjMsDyut2uIgx9v5TXk0V5XvMWobx435ANIDJoGTYCMRlIqcgtyqwAQ==
"@tiptap/extension-table-row@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-row/-/extension-table-row-2.1.13.tgz#ef75d6de9c7695bbb90f745aabd72d327f161ac3"
integrity sha512-27Mb9/oYbiLd+/BUFMhQzRIqMd2Z5j1BZMYsktwtDG8vGdYVlaW257UVaoNR9TmiXyIzd3Dh1mOil8G35+HRHg==
"@tiptap/extension-table@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table/-/extension-table-2.1.13.tgz#cfe3fc2665d12d2c946fc83b2cce9d1485ff29a0"
integrity sha512-yMWt2LqotOsWJhLwFNo8fyTwJNLPtnk+eCUxKLlMXP23mJ/lpF+jvTihhHVVic5GqV9vLYZFU2Tn+5k/Vd5P1w==
"@tiptap/extension-task-item@^2.1.7":
version "2.1.7"
resolved "https://registry.yarnpkg.com/@tiptap/extension-task-item/-/extension-task-item-2.1.7.tgz#384a55308f3524f36388560486a2508a4b3c5413"
@ -8197,11 +8217,6 @@ follow-redirects@^1.0.0, follow-redirects@^1.15.0:
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a"
integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==
follow-redirects@^1.15.0:
version "1.15.3"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a"
integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==
for-in@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"