From d24b3f72ce222e4551c12e202238f171f9cc4b97 Mon Sep 17 00:00:00 2001 From: James Date: Wed, 24 Mar 2021 20:53:40 -0400 Subject: [PATCH] feat: saves cursor position when relationship element is added to richText --- .../richText/elements/Button/Button/index.tsx | 21 ++++++++++++------- .../forms/field-types/RichText/RichText.tsx | 5 +++++ .../elements/relationship/Button/index.tsx | 12 ++++++++++- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/demo/client/components/richText/elements/Button/Button/index.tsx b/demo/client/components/richText/elements/Button/Button/index.tsx index f3a0f1ab5a..ff5a4c3021 100644 --- a/demo/client/components/richText/elements/Button/Button/index.tsx +++ b/demo/client/components/richText/elements/Button/Button/index.tsx @@ -1,8 +1,7 @@ import React, { Fragment, useCallback } from 'react'; -import PropTypes from 'prop-types'; import { Modal, useModal } from '@faceless-ui/modal'; import { Transforms } from 'slate'; -import { useSlate } from 'slate-react'; +import { useSlate, ReactEditor } from 'slate-react'; import MinimalTemplate from '../../../../../../../src/admin/components/templates/Minimal'; import { ElementButton } from '../../../../../../../components/rich-text'; import X from '../../../../../../../src/admin/components/icons/X'; @@ -17,7 +16,7 @@ const initialFormData = { style: 'primary', }; -const insertButton = (editor, { href, label, style, newTab = false }) => { +const insertButton = (editor, { href, label, style, newTab = false }: any) => { const text = { text: ' ' }; const button = { type: 'button', @@ -32,10 +31,20 @@ const insertButton = (editor, { href, label, style, newTab = false }) => { const nodes = [button, { children: [{ text: '' }] }]; + if (editor.blurSelection) { + Transforms.select(editor, editor.blurSelection); + } + Transforms.insertNodes(editor, nodes); + + const currentPath = editor.selection.anchor.path[0]; + const newSelection = { anchor: { path: [currentPath + 1, 0], offset: 0 }, focus: { path: [currentPath + 1, 0], offset: 0 } }; + + Transforms.select(editor, newSelection); + ReactEditor.focus(editor); }; -const ToolbarButton: React.FC = ({ path }) => { +const ToolbarButton: React.FC<{path: string}> = ({ path }) => { const { open, closeAll } = useModal(); const editor = useSlate(); @@ -112,8 +121,4 @@ const ToolbarButton: React.FC = ({ path }) => { ); }; -ToolbarButton.propTypes = { - path: PropTypes.string.isRequired, -}; - export default ToolbarButton; diff --git a/src/admin/components/forms/field-types/RichText/RichText.tsx b/src/admin/components/forms/field-types/RichText/RichText.tsx index a39ead7ac9..6001c27c36 100644 --- a/src/admin/components/forms/field-types/RichText/RichText.tsx +++ b/src/admin/components/forms/field-types/RichText/RichText.tsx @@ -126,6 +126,10 @@ const RichText: React.FC = (props) => { return CreatedEditor; }, [elements, leaves]); + const onBlur = useCallback(() => { + editor.blurSelection = editor.selection; + }, [editor]); + useEffect(() => { if (!loaded) { const mergedElements = mergeCustomFunctions(elements, elementTypes); @@ -222,6 +226,7 @@ const RichText: React.FC = (props) => { placeholder={placeholder} spellCheck readOnly={readOnly} + onBlur={onBlur} onKeyDown={(event) => { Object.keys(hotkeys).forEach((hotkey) => { if (isHotkey(hotkey, event as any)) { diff --git a/src/admin/components/forms/field-types/RichText/elements/relationship/Button/index.tsx b/src/admin/components/forms/field-types/RichText/elements/relationship/Button/index.tsx index 59ee5af1b6..7b15aa0792 100644 --- a/src/admin/components/forms/field-types/RichText/elements/relationship/Button/index.tsx +++ b/src/admin/components/forms/field-types/RichText/elements/relationship/Button/index.tsx @@ -1,7 +1,7 @@ import React, { Fragment, useCallback, useState } from 'react'; import { Modal, useModal } from '@faceless-ui/modal'; import { Transforms } from 'slate'; -import { useSlate } from 'slate-react'; +import { ReactEditor, useSlate } from 'slate-react'; import { useConfig } from '@payloadcms/config-provider'; import ElementButton from '../../Button'; import RelationshipIcon from '../../../../../../icons/Relationship'; @@ -36,7 +36,17 @@ const insertRelationship = (editor, { value, relationTo, depth }) => { const nodes = [relationship, { children: [{ text: '' }] }]; + if (editor.blurSelection) { + Transforms.select(editor, editor.blurSelection); + } + Transforms.insertNodes(editor, nodes); + + const currentPath = editor.selection.anchor.path[0]; + const newSelection = { anchor: { path: [currentPath + 1, 0], offset: 0 }, focus: { path: [currentPath + 1, 0], offset: 0 } }; + + Transforms.select(editor, newSelection); + ReactEditor.focus(editor); }; const RelationshipButton = ({ path }) => {