fix: styles readOnly RichTextEditor, removes interactivity within when readOnly
This commit is contained in:
@@ -70,6 +70,7 @@ const RichText: React.FC<Props> = (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> = (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> = (props) => {
|
||||
editor={editor}
|
||||
value={valueToRender as any[]}
|
||||
onChange={(val) => {
|
||||
if (val !== defaultValue && val !== value) {
|
||||
if (!readOnly && val !== defaultValue && val !== value) {
|
||||
setValue(val);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className={`${baseClass}__wrapper`}>
|
||||
<div className={`${baseClass}__toolbar`}>
|
||||
<div className={`${baseClass}__toolbar-wrap`}>
|
||||
<div className={`${baseClass}__toolbar`} ref={toolbarRef}>
|
||||
<div className={`${baseClass}__toolbar-wrap`} tabIndex={readOnly ? -1 : undefined}>
|
||||
{elements.map((element, i) => {
|
||||
let elementName: string;
|
||||
if (typeof element === 'object' && element?.name) elementName = element.name;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 });
|
||||
|
||||
|
||||
Reference in New Issue
Block a user