From 8454e4f1e067f2cd3c11a91f93b069f0d936c264 Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Date: Mon, 15 Apr 2024 19:45:03 +0530 Subject: [PATCH] [WEB-986] fix: editor slash command positioning (#4186) * fix: table selected cell border * chore: add syncing message when revalidating page data * fix: slash command positioning * fix: mentions list dropdown positioning --- packages/editor/core/src/styles/editor.css | 12 ++++----- packages/editor/core/src/styles/table.css | 13 +-------- .../editor/core/src/ui/extensions/index.tsx | 2 +- .../core/src/ui/mentions/mention-list.tsx | 2 +- .../src/extensions/slash-commands.tsx | 27 ++++++++++--------- .../pages/editor/header/extra-options.tsx | 9 ++++++- web/components/pages/editor/header/root.tsx | 3 +++ .../projects/[projectId]/pages/[pageId].tsx | 3 ++- 8 files changed, 36 insertions(+), 35 deletions(-) diff --git a/packages/editor/core/src/styles/editor.css b/packages/editor/core/src/styles/editor.css index 63bc5a6d6..4cb4e9772 100644 --- a/packages/editor/core/src/styles/editor.css +++ b/packages/editor/core/src/styles/editor.css @@ -49,15 +49,12 @@ } } -/* Custom list item styles */ - /* Custom gap cursor styles */ .ProseMirror-gapcursor::after { border-top: 1px solid rgb(var(--color-text-100)) !important; } -/* Custom TODO list checkboxes – shoutout to this awesome tutorial: https://moderncss.dev/pure-css-custom-checkbox-style/ */ - +/* to-do list */ ul[data-type="taskList"] li { font-size: 1rem; line-height: 1.5; @@ -143,6 +140,7 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p { text-decoration: line-through; text-decoration-thickness: 2px; } +/* end to-do list */ /* Overwrite tippy-box original max-width */ @@ -238,7 +236,7 @@ div[data-type="horizontalRule"] { margin-bottom: 0; & > div { - border-bottom: 1px solid rgb(var(--color-text-100)); + border-bottom: 1px solid rgb(var(--color-border-200)); } } @@ -277,7 +275,7 @@ span:focus .fake-cursor { z-index: 1; } -/* number, bulleted and to-do lists */ +/* numbered, bulleted and to-do lists spacing */ .prose ol:where(.prose > :first-child):not(:where([class~="not-prose"], [class~="not-prose"] *)), .prose ul:not([data-type="taskList"]):where(.prose > :first-child):not(:where([class~="not-prose"], [class~="not-prose"] *)), @@ -306,7 +304,7 @@ ul:not([data-type="taskList"]) ol { ul[data-type="taskList"] ul[data-type="taskList"] { margin-top: 0.6rem; } -/* end number, bulleted and to-do lists */ +/* end numbered, bulleted and to-do lists spacing */ /* tailwind typography */ .prose :where(h1):not(:where([class~="not-prose"], [class~="not-prose"] *)) { diff --git a/packages/editor/core/src/styles/table.css b/packages/editor/core/src/styles/table.css index 433b77bfe..d5adac9b5 100644 --- a/packages/editor/core/src/styles/table.css +++ b/packages/editor/core/src/styles/table.css @@ -31,17 +31,6 @@ } } -.table-wrapper table td > *, -.table-wrapper table th > * { - margin: 0 !important; - padding: 0.25rem 0 !important; -} - -.table-wrapper table td.has-focus, -.table-wrapper table th.has-focus { - box-shadow: rgba(var(--color-primary-300), 0.1) 0px 0px 0px 2px inset !important; -} - .table-wrapper table th { font-weight: 500; text-align: left; @@ -49,7 +38,7 @@ } .table-wrapper table .selectedCell { - border-color: rgba(var(--color-primary-100)); + outline: 0.5px solid rgba(var(--color-primary-100)); } /* table dropdown */ diff --git a/packages/editor/core/src/ui/extensions/index.tsx b/packages/editor/core/src/ui/extensions/index.tsx index 1a68ee46e..bf7f36067 100644 --- a/packages/editor/core/src/ui/extensions/index.tsx +++ b/packages/editor/core/src/ui/extensions/index.tsx @@ -69,7 +69,7 @@ export const CoreEditorExtensions = ( CustomQuoteExtension, CustomHorizontalRule.configure({ HTMLAttributes: { - class: "my-4", + class: "my-4 border-custom-border-400", }, }), CustomKeymap, diff --git a/packages/editor/core/src/ui/mentions/mention-list.tsx b/packages/editor/core/src/ui/mentions/mention-list.tsx index cd0bf8354..b9ac11d13 100644 --- a/packages/editor/core/src/ui/mentions/mention-list.tsx +++ b/packages/editor/core/src/ui/mentions/mention-list.tsx @@ -135,7 +135,7 @@ export const MentionList = forwardRef((props: MentionListProps, ref) => { return (
{isLoading ? (
Loading...
diff --git a/packages/editor/extensions/src/extensions/slash-commands.tsx b/packages/editor/extensions/src/extensions/slash-commands.tsx index 049accb27..752fbe63c 100644 --- a/packages/editor/extensions/src/extensions/slash-commands.tsx +++ b/packages/editor/extensions/src/extensions/slash-commands.tsx @@ -247,14 +247,15 @@ export const updateScrollView = (container: HTMLElement, item: HTMLElement) => { }; const CommandList = ({ items, command }: { items: CommandItemProps[]; command: any; editor: any; range: any }) => { + // states const [selectedIndex, setSelectedIndex] = useState(0); + // refs + const commandListContainer = useRef(null); const selectItem = useCallback( (index: number) => { const item = items[index]; - if (item) { - command(item); - } + if (item) command(item); }, [command, items] ); @@ -289,8 +290,6 @@ const CommandList = ({ items, command }: { items: CommandItemProps[]; command: a setSelectedIndex(0); }, [items]); - const commandListContainer = useRef(null); - useLayoutEffect(() => { const container = commandListContainer?.current; @@ -299,29 +298,31 @@ const CommandList = ({ items, command }: { items: CommandItemProps[]; command: a if (item && container) updateScrollView(container, item); }, [selectedIndex]); - return items.length > 0 ? ( + if (items.length <= 0) return null; + + return (
{items.map((item, index) => ( ))}
- ) : null; + ); }; interface CommandListInstance { @@ -338,10 +339,12 @@ const renderItems = () => { editor: props.editor, }); + const tippyContainer = document.querySelector(".active-editor") ?? document.querySelector("#editor-container"); + // @ts-expect-error Tippy overloads are messed up popup = tippy("body", { getReferenceClientRect: props.clientRect, - appendTo: () => document.querySelector(".active-editor") ?? document.querySelector("#editor-container"), + appendTo: tippyContainer, content: component.element, showOnCreate: true, interactive: true, diff --git a/web/components/pages/editor/header/extra-options.tsx b/web/components/pages/editor/header/extra-options.tsx index 1b00cce34..3615cfa1b 100644 --- a/web/components/pages/editor/header/extra-options.tsx +++ b/web/components/pages/editor/header/extra-options.tsx @@ -19,13 +19,14 @@ import { IPageStore } from "@/store/pages/page.store"; type Props = { editorRef: React.RefObject; handleDuplicatePage: () => void; + isSyncing: boolean; pageStore: IPageStore; projectId: string; readOnlyEditorRef: React.RefObject; }; export const PageExtraOptions: React.FC = observer((props) => { - const { editorRef, handleDuplicatePage, pageStore, projectId, readOnlyEditorRef } = props; + const { editorRef, handleDuplicatePage, isSyncing, pageStore, projectId, readOnlyEditorRef } = props; // states const [gptModalOpen, setGptModal] = useState(false); // store hooks @@ -52,6 +53,12 @@ export const PageExtraOptions: React.FC = observer((props) => { {isSubmitting === "submitting" ? "Saving..." : "Saved"}
)} + {isSyncing && ( +
+ + Syncing... +
+ )} {is_locked && (
diff --git a/web/components/pages/editor/header/root.tsx b/web/components/pages/editor/header/root.tsx index b3bae94ba..f48921191 100644 --- a/web/components/pages/editor/header/root.tsx +++ b/web/components/pages/editor/header/root.tsx @@ -11,6 +11,7 @@ type Props = { editorRef: React.RefObject; readOnlyEditorRef: React.RefObject; handleDuplicatePage: () => void; + isSyncing: boolean; markings: IMarking[]; pageStore: IPageStore; projectId: string; @@ -28,6 +29,7 @@ export const PageEditorHeaderRoot: React.FC = observer((props) => { markings, readOnlyEditorReady, handleDuplicatePage, + isSyncing, pageStore, projectId, sidePeekVisible, @@ -61,6 +63,7 @@ export const PageEditorHeaderRoot: React.FC = observer((props) => { { }); // fetching page details - const { data: swrPageDetails } = useSWR( + const { data: swrPageDetails, isValidating } = useSWR( pageId ? `PAGE_DETAILS_${pageId}` : null, pageId ? () => getPageById(pageId.toString()) : null, { @@ -120,6 +120,7 @@ const PageDetailsPage: NextPageWithLayout = observer(() => { editorReady={editorReady} readOnlyEditorReady={readOnlyEditorReady} handleDuplicatePage={handleDuplicatePage} + isSyncing={isValidating} markings={markings} pageStore={pageStore} projectId={projectId.toString()}