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 4b4cb9c8d0c..e1ee606d527 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 @@ -12,6 +12,7 @@ import Submit from '../../../../../Submit'; import X from '../../../../../../icons/X'; import Fields from './Fields'; import { requests } from '../../../../../../../api'; +import { injectVoidElement } from '../../../injectVoid'; import './index.scss'; @@ -31,13 +32,12 @@ const insertRelationship = (editor, { value, relationTo }) => { ], }; - const nodes = [relationship, { type: 'p', children: [{ text: '' }] }]; - if (editor.blurSelection) { Transforms.select(editor, editor.blurSelection); } - Transforms.insertNodes(editor, nodes); + injectVoidElement(editor, relationship); + ReactEditor.focus(editor); }; diff --git a/src/admin/components/forms/field-types/RichText/elements/upload/Button/index.tsx b/src/admin/components/forms/field-types/RichText/elements/upload/Button/index.tsx index 289e1333b40..0f875f0d9da 100644 --- a/src/admin/components/forms/field-types/RichText/elements/upload/Button/index.tsx +++ b/src/admin/components/forms/field-types/RichText/elements/upload/Button/index.tsx @@ -16,6 +16,7 @@ import MinimalTemplate from '../../../../../../templates/Minimal'; import Button from '../../../../../../elements/Button'; import { SanitizedCollectionConfig } from '../../../../../../../../collections/config/types'; import PerPage from '../../../../../../elements/PerPage'; +import { injectVoidElement } from '../../../injectVoid'; import './index.scss'; import '../addSwapModals.scss'; @@ -35,13 +36,12 @@ const insertUpload = (editor, { value, relationTo }) => { ], }; - const nodes = [upload, { type: 'p', children: [{ text: '' }] }]; - if (editor.blurSelection) { Transforms.select(editor, editor.blurSelection); } - Transforms.insertNodes(editor, nodes); + injectVoidElement(editor, upload); + ReactEditor.focus(editor); }; diff --git a/src/admin/components/forms/field-types/RichText/injectVoid.ts b/src/admin/components/forms/field-types/RichText/injectVoid.ts new file mode 100644 index 00000000000..90f96537649 --- /dev/null +++ b/src/admin/components/forms/field-types/RichText/injectVoid.ts @@ -0,0 +1,25 @@ +import { Editor, Element, Transforms } from 'slate'; +import { isLastSelectedElementEmpty } from './isLastSelectedElementEmpty'; + +export const injectVoidElement = (editor: Editor, element: Element): void => { + const lastSelectedElementIsEmpty = isLastSelectedElementEmpty(editor); + const previous = Editor.previous(editor); + + if (lastSelectedElementIsEmpty) { + // If previous node is void + if (Editor.isVoid(editor, previous?.[0])) { + // Insert a blank element between void nodes + // so user can place cursor between void nodes + Transforms.insertNodes(editor, { children: [{ text: '' }] }); + Transforms.setNodes(editor, element); + // Otherwise just set the empty node equal to new upload + } else { + Transforms.setNodes(editor, element); + } + + // Add an empty node after the new upload + Transforms.insertNodes(editor, { children: [{ text: '' }] }); + } else { + Transforms.insertNodes(editor, [element, { children: [{ text: '' }] }]); + } +}; diff --git a/src/admin/components/forms/field-types/RichText/isLastSelectedElementEmpty.ts b/src/admin/components/forms/field-types/RichText/isLastSelectedElementEmpty.ts new file mode 100644 index 00000000000..bb4b4de8776 --- /dev/null +++ b/src/admin/components/forms/field-types/RichText/isLastSelectedElementEmpty.ts @@ -0,0 +1,14 @@ +import { Editor, Element } from 'slate'; + +export const isLastSelectedElementEmpty = (editor: Editor): boolean => { + const currentlySelectedNodes = Array.from(Editor.nodes(editor, { + at: Editor.unhangRange(editor, editor.selection), + match: (n) => !Editor.isEditor(n) && Element.isElement(n) && (!n.type || n.type === 'p'), + })); + + const lastSelectedNode = currentlySelectedNodes?.[currentlySelectedNodes?.length - 1]; + + return lastSelectedNode && Element.isElement(lastSelectedNode[0]) + && (!lastSelectedNode[0].type || lastSelectedNode[0].type === 'p') + && lastSelectedNode[0].children?.[0].text === ''; +}; diff --git a/src/fields/richText/defaultValue.ts b/src/fields/richText/defaultValue.ts index 974d1f4fd94..cc7d0f9f66b 100644 --- a/src/fields/richText/defaultValue.ts +++ b/src/fields/richText/defaultValue.ts @@ -1,4 +1,3 @@ export default [{ - type: 'p', children: [{ text: '' }], }];