fix: styles readOnly RichTextEditor, removes interactivity within when readOnly

This commit is contained in:
Jarrod Flesch
2022-09-23 14:34:02 -04:00
parent b454811698
commit 918130486e
4 changed files with 80 additions and 7 deletions

View File

@@ -70,6 +70,7 @@ const RichText: React.FC<Props> = (props) => {
const [enabledLeaves, setEnabledLeaves] = useState({}); const [enabledLeaves, setEnabledLeaves] = useState({});
const [initialValueKey, setInitialValueKey] = useState(''); const [initialValueKey, setInitialValueKey] = useState('');
const editorRef = useRef(null); const editorRef = useRef(null);
const toolbarRef = useRef(null);
const renderElement = useCallback(({ attributes, children, element }) => { const renderElement = useCallback(({ attributes, children, element }) => {
const matchedElement = enabledElements[element?.type]; const matchedElement = enabledElements[element?.type];
@@ -176,6 +177,17 @@ const RichText: React.FC<Props> = (props) => {
setInitialValueKey(JSON.stringify(initialValue || '')); setInitialValueKey(JSON.stringify(initialValue || ''));
}, [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) { if (!loaded) {
return null; return null;
} }
@@ -215,14 +227,14 @@ const RichText: React.FC<Props> = (props) => {
editor={editor} editor={editor}
value={valueToRender as any[]} value={valueToRender as any[]}
onChange={(val) => { onChange={(val) => {
if (val !== defaultValue && val !== value) { if (!readOnly && val !== defaultValue && val !== value) {
setValue(val); setValue(val);
} }
}} }}
> >
<div className={`${baseClass}__wrapper`}> <div className={`${baseClass}__wrapper`}>
<div className={`${baseClass}__toolbar`}> <div className={`${baseClass}__toolbar`} ref={toolbarRef}>
<div className={`${baseClass}__toolbar-wrap`}> <div className={`${baseClass}__toolbar-wrap`} tabIndex={readOnly ? -1 : undefined}>
{elements.map((element, i) => { {elements.map((element, i) => {
let elementName: string; let elementName: string;
if (typeof element === 'object' && element?.name) elementName = element.name; if (typeof element === 'object' && element?.name) elementName = element.name;

View File

@@ -3,6 +3,7 @@
.rich-text { .rich-text {
margin-bottom: base(2); margin-bottom: base(2);
display: flex; display: flex;
isolation: isolate;
&__toolbar { &__toolbar {
@include blur-bg(var(--theme-elevation-0)); @include blur-bg(var(--theme-elevation-0));
@@ -104,6 +105,25 @@
background-color: var(--theme-elevation-150); background-color: var(--theme-elevation-150);
padding: base(.5); 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 { &__button {

View File

@@ -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 = { function generateRichText() {
selectHasMany: ['one', 'five'], return [
richText: [
{ {
children: [ children: [
{ {
@@ -220,7 +254,13 @@ export const richTextDoc = {
], ],
}; };
}), }),
], ];
}
export const richTextDoc = {
selectHasMany: ['one', 'five'],
richText: generateRichText(),
richTextReadOnly: generateRichText(),
}; };
export default RichTextFields; export default RichTextFields;

View File

@@ -92,6 +92,7 @@ export default buildConfig({
const richTextUploadIndex = richTextDocWithRelationship.richText.findIndex(({ type }) => type === 'upload'); const richTextUploadIndex = richTextDocWithRelationship.richText.findIndex(({ type }) => type === 'upload');
richTextDocWithRelationship.richText[richTextUploadIndex].value = { id: createdUploadDoc.id }; richTextDocWithRelationship.richText[richTextUploadIndex].value = { id: createdUploadDoc.id };
richTextDocWithRelationship.richTextReadOnly[richTextUploadIndex].value = { id: createdUploadDoc.id };
await payload.create({ collection: 'rich-text-fields', data: richTextDocWithRelationship }); await payload.create({ collection: 'rich-text-fields', data: richTextDocWithRelationship });