Refactor Editor components to be injected by associated extension (#6093)
This commit is contained in:
@@ -5,6 +5,7 @@ import * as React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { toast } from "sonner";
|
||||
import styled from "styled-components";
|
||||
import { richExtensions } from "@shared/editor/nodes";
|
||||
import { s } from "@shared/styles";
|
||||
import Collection from "~/models/Collection";
|
||||
import Arrow from "~/components/Arrow";
|
||||
@@ -12,9 +13,19 @@ import ButtonLink from "~/components/ButtonLink";
|
||||
import Editor from "~/components/Editor";
|
||||
import LoadingIndicator from "~/components/LoadingIndicator";
|
||||
import NudeButton from "~/components/NudeButton";
|
||||
import BlockMenuExtension from "~/editor/extensions/BlockMenu";
|
||||
import EmojiMenuExtension from "~/editor/extensions/EmojiMenu";
|
||||
import HoverPreviewsExtension from "~/editor/extensions/HoverPreviews";
|
||||
import usePolicy from "~/hooks/usePolicy";
|
||||
import useStores from "~/hooks/useStores";
|
||||
|
||||
const extensions = [
|
||||
...richExtensions,
|
||||
BlockMenuExtension,
|
||||
EmojiMenuExtension,
|
||||
HoverPreviewsExtension,
|
||||
];
|
||||
|
||||
type Props = {
|
||||
collection: Collection;
|
||||
};
|
||||
@@ -104,6 +115,7 @@ function CollectionDescription({ collection }: Props) {
|
||||
readOnly={!isEditing}
|
||||
autoFocus={isEditing}
|
||||
onBlur={handleStopEditing}
|
||||
extensions={extensions}
|
||||
maxLength={1000}
|
||||
embedsDisabled
|
||||
canUpdate
|
||||
|
||||
@@ -19,7 +19,6 @@ import { AttachmentValidation } from "@shared/validations";
|
||||
import Document from "~/models/Document";
|
||||
import ClickablePadding from "~/components/ClickablePadding";
|
||||
import ErrorBoundary from "~/components/ErrorBoundary";
|
||||
import HoverPreview from "~/components/HoverPreview";
|
||||
import type { Props as EditorProps, Editor as SharedEditor } from "~/editor";
|
||||
import useCurrentUser from "~/hooks/useCurrentUser";
|
||||
import useDictionary from "~/hooks/useDictionary";
|
||||
@@ -47,7 +46,6 @@ export type Props = Optional<
|
||||
> & {
|
||||
shareId?: string | undefined;
|
||||
embedsDisabled?: boolean;
|
||||
previewsDisabled?: boolean;
|
||||
onHeadingsChange?: (headings: Heading[]) => void;
|
||||
onSynced?: () => Promise<void>;
|
||||
onPublish?: (event: React.MouseEvent) => void;
|
||||
@@ -62,7 +60,6 @@ function Editor(props: Props, ref: React.RefObject<SharedEditor> | null) {
|
||||
onHeadingsChange,
|
||||
onCreateCommentMark,
|
||||
onDeleteCommentMark,
|
||||
previewsDisabled,
|
||||
} = props;
|
||||
const userLocale = useUserLocale();
|
||||
const locale = dateLocale(userLocale);
|
||||
@@ -73,22 +70,8 @@ function Editor(props: Props, ref: React.RefObject<SharedEditor> | null) {
|
||||
const localRef = React.useRef<SharedEditor>();
|
||||
const preferences = useCurrentUser({ rejectOnEmpty: false })?.preferences;
|
||||
const previousHeadings = React.useRef<Heading[] | null>(null);
|
||||
const [activeLinkElement, setActiveLink] =
|
||||
React.useState<HTMLAnchorElement | null>(null);
|
||||
const previousCommentIds = React.useRef<string[]>();
|
||||
|
||||
const handleLinkActive = React.useCallback(
|
||||
(element: HTMLAnchorElement | null) => {
|
||||
setActiveLink(element);
|
||||
return false;
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const handleLinkInactive = React.useCallback(() => {
|
||||
setActiveLink(null);
|
||||
}, []);
|
||||
|
||||
const handleSearchLink = React.useCallback(
|
||||
async (term: string) => {
|
||||
if (isInternalUrl(term)) {
|
||||
@@ -339,7 +322,6 @@ function Editor(props: Props, ref: React.RefObject<SharedEditor> | null) {
|
||||
userPreferences={preferences}
|
||||
dictionary={dictionary}
|
||||
{...props}
|
||||
onHoverLink={previewsDisabled ? undefined : handleLinkActive}
|
||||
onClickLink={handleClickLink}
|
||||
onSearchLink={handleSearchLink}
|
||||
onChange={handleChange}
|
||||
@@ -354,12 +336,6 @@ function Editor(props: Props, ref: React.RefObject<SharedEditor> | null) {
|
||||
minHeight={props.editorStyle.paddingBottom}
|
||||
/>
|
||||
)}
|
||||
{!shareId && (
|
||||
<HoverPreview
|
||||
element={activeLinkElement}
|
||||
onClose={handleLinkInactive}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
|
||||
@@ -24,7 +24,7 @@ const POINTER_WIDTH = 22;
|
||||
|
||||
type Props = {
|
||||
/** The HTML element that is being hovered over, or null if none. */
|
||||
element: HTMLAnchorElement | null;
|
||||
element: HTMLElement | null;
|
||||
/** A callback on close of the hover preview. */
|
||||
onClose: () => void;
|
||||
};
|
||||
@@ -35,7 +35,7 @@ enum Direction {
|
||||
}
|
||||
|
||||
function HoverPreviewDesktop({ element, onClose }: Props) {
|
||||
const url = element?.href || element?.dataset.url;
|
||||
const url = element?.getAttribute("href") || element?.dataset.url;
|
||||
const previousUrl = usePrevious(url, true);
|
||||
const [isVisible, setVisible] = React.useState(false);
|
||||
const timerClose = React.useRef<ReturnType<typeof setTimeout>>();
|
||||
@@ -200,7 +200,7 @@ function useHoverPosition({
|
||||
isVisible,
|
||||
}: {
|
||||
cardRef: React.RefObject<HTMLDivElement>;
|
||||
element: HTMLAnchorElement | null;
|
||||
element: HTMLElement | null;
|
||||
isVisible: boolean;
|
||||
}) {
|
||||
const [cardLeft, setCardLeft] = React.useState(0);
|
||||
|
||||
@@ -64,7 +64,6 @@ function NotificationListItem({ notification, onNavigate }: Props) {
|
||||
{notification.comment && (
|
||||
<StyledCommentEditor
|
||||
defaultValue={toJS(notification.comment.data)}
|
||||
previewsDisabled
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
|
||||
Reference in New Issue
Block a user