From 918130486e1e38a3d57fb993f466207209c5c0bb Mon Sep 17 00:00:00 2001 From: Jarrod Flesch Date: Fri, 23 Sep 2022 14:34:02 -0400 Subject: [PATCH] fix: styles readOnly RichTextEditor, removes interactivity within when readOnly --- .../forms/field-types/RichText/RichText.tsx | 18 +++++-- .../forms/field-types/RichText/index.scss | 20 ++++++++ test/fields/collections/RichText/index.ts | 48 +++++++++++++++++-- test/fields/config.ts | 1 + 4 files changed, 80 insertions(+), 7 deletions(-) diff --git a/src/admin/components/forms/field-types/RichText/RichText.tsx b/src/admin/components/forms/field-types/RichText/RichText.tsx index cadd9f4be..e3fed8b81 100644 --- a/src/admin/components/forms/field-types/RichText/RichText.tsx +++ b/src/admin/components/forms/field-types/RichText/RichText.tsx @@ -70,6 +70,7 @@ const RichText: React.FC = (props) => { const [enabledLeaves, setEnabledLeaves] = useState({}); const [initialValueKey, setInitialValueKey] = useState(''); const editorRef = useRef(null); + const toolbarRef = useRef(null); const renderElement = useCallback(({ attributes, children, element }) => { const matchedElement = enabledElements[element?.type]; @@ -176,6 +177,17 @@ const RichText: React.FC = (props) => { setInitialValueKey(JSON.stringify(initialValue || '')); }, [initialValue]); + useEffect(() => { + if (loaded && readOnly) { + // disable interactions on all editor elements when read only + Array.from(editorRef.current.children).forEach((child) => { + const childAsElement = child as HTMLElement; + childAsElement.tabIndex = -1; + childAsElement.style.pointerEvents = 'none'; + }); + } + }, [loaded, readOnly]); + if (!loaded) { return null; } @@ -215,14 +227,14 @@ const RichText: React.FC = (props) => { editor={editor} value={valueToRender as any[]} onChange={(val) => { - if (val !== defaultValue && val !== value) { + if (!readOnly && val !== defaultValue && val !== value) { setValue(val); } }} >
-
-
+
+
{elements.map((element, i) => { let elementName: string; if (typeof element === 'object' && element?.name) elementName = element.name; diff --git a/src/admin/components/forms/field-types/RichText/index.scss b/src/admin/components/forms/field-types/RichText/index.scss index 730fbe195..01bb21ce9 100644 --- a/src/admin/components/forms/field-types/RichText/index.scss +++ b/src/admin/components/forms/field-types/RichText/index.scss @@ -3,6 +3,7 @@ .rich-text { margin-bottom: base(2); display: flex; + isolation: isolate; &__toolbar { @include blur-bg(var(--theme-elevation-0)); @@ -104,6 +105,25 @@ background-color: var(--theme-elevation-150); padding: base(.5); } + + .rich-text__toolbar { + pointer-events: none; + position: relative; + top: 0; + + &::after { + content: ' '; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: var(--theme-elevation-150); + opacity: .85; + z-index: 2; + backdrop-filter: unset; + } + } } &__button { diff --git a/test/fields/collections/RichText/index.ts b/test/fields/collections/RichText/index.ts index 579d3ea86..5c0d04b71 100644 --- a/test/fields/collections/RichText/index.ts +++ b/test/fields/collections/RichText/index.ts @@ -73,12 +73,46 @@ const RichTextFields: CollectionConfig = { }, }, }, + { + name: 'richTextReadOnly', + type: 'richText', + admin: { + readOnly: true, + link: { + fields: [ + { + name: 'rel', + label: 'Rel Attribute', + type: 'select', + hasMany: true, + options: [ + 'noopener', 'noreferrer', 'nofollow', + ], + admin: { + description: 'The rel attribute defines the relationship between a linked resource and the current document. This is a custom link field.', + }, + }, + ], + }, + upload: { + collections: { + uploads: { + fields: [ + { + name: 'caption', + type: 'richText', + }, + ], + }, + }, + }, + }, + }, ], }; -export const richTextDoc = { - selectHasMany: ['one', 'five'], - richText: [ +function generateRichText() { + return [ { children: [ { @@ -220,7 +254,13 @@ export const richTextDoc = { ], }; }), - ], + ]; +} + +export const richTextDoc = { + selectHasMany: ['one', 'five'], + richText: generateRichText(), + richTextReadOnly: generateRichText(), }; export default RichTextFields; diff --git a/test/fields/config.ts b/test/fields/config.ts index f0d6b3ae7..b014ebac1 100644 --- a/test/fields/config.ts +++ b/test/fields/config.ts @@ -92,6 +92,7 @@ export default buildConfig({ const richTextUploadIndex = richTextDocWithRelationship.richText.findIndex(({ type }) => type === 'upload'); richTextDocWithRelationship.richText[richTextUploadIndex].value = { id: createdUploadDoc.id }; + richTextDocWithRelationship.richTextReadOnly[richTextUploadIndex].value = { id: createdUploadDoc.id }; await payload.create({ collection: 'rich-text-fields', data: richTextDocWithRelationship });