Skip to content

Commit

Permalink
chore(SDK React): bring Inline Editing for Block Editor
Browse files Browse the repository at this point in the history
  • Loading branch information
rjvelazco committed Nov 12, 2024
1 parent ae3aec7 commit 7281db1
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 23 deletions.
6 changes: 4 additions & 2 deletions core-web/libs/sdk/client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import {
editContentlet,
initEditor,
isInsideEditor,
updateNavigation
updateNavigation,
initInlineEditing
} from './lib/editor/sdk-editor';
import { getPageRequestParams, graphqlToPageEntity } from './lib/utils';

Expand All @@ -30,5 +31,6 @@ export {
initEditor,
updateNavigation,
destroyEditor,
ClientConfig
ClientConfig,
initInlineEditing
};
35 changes: 35 additions & 0 deletions core-web/libs/sdk/client/src/lib/editor/sdk-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,38 @@ export function addClassToEmptyContentlets(): void {
contentlet.classList.add('empty-contentlet');
});
}

const INLINE_EDITING_EVENT: Record<string, CLIENT_ACTIONS> = {
blockEditor: CLIENT_ACTIONS.INIT_BLOCK_EDITOR_INLINE_EDITING
};

/**
* Initializes the block editor inline editing.
*
* @export
* @param {*} { inode, language_id, blockEditorContent }
*/
export function initInlineEditing(
type: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
{ inode, languageId, contentType, fieldName, content }: any // Any for now
) {
const action = INLINE_EDITING_EVENT[type];

if (!action) {
return;
}

const contentString = typeof content === 'string' ? content : JSON.stringify(content ?? {});

postMessageToEditor({
action,
payload: {
inode,
fieldName,
contentType,
languageId,
blockEditorContent: contentString
}
});
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import { useEffect, useRef } from 'react';

import { initInlineEditing } from '@dotcms/client';

import { BlockEditorBlock } from './item/BlockEditorBlock';

import { DotCMSContentlet } from '../../models';
import { Block } from '../../models/blocks.interface';
import { CustomRenderer } from '../../models/content-node.interface';

export interface BlockEditorRendererProps {
blocks: Block;
editable?: boolean;
contentlet?: DotCMSContentlet;
fieldName?: string;
customRenderers?: CustomRenderer;
className?: string;
style?: React.CSSProperties;
Expand All @@ -23,12 +31,27 @@ export interface BlockEditorRendererProps {
*/
export const BlockEditorRenderer = ({
blocks,
editable,
contentlet,
fieldName,
customRenderers,
className,
style
}: BlockEditorRendererProps) => {
const ref = useRef<HTMLDivElement>(null);

useEffect(() => {
if (!editable || !ref.current) {
return;
}

ref.current?.addEventListener('click', () => {
initInlineEditing('blockEditor', { ...contentlet, fieldName, content: blocks.content });
});
}, [editable, contentlet, blocks.content, fieldName]);

return (
<div className={className} style={style}>
<div className={className} style={style} ref={ref}>
<BlockEditorBlock content={blocks.content} customRenderers={customRenderers} />
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion dotCMS/src/main/webapp/html/js/editor-js/sdk-editor.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 29 additions & 19 deletions examples/nextjs/src/components/content-types/blog.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,38 @@ const CustomParagraph = ({ content }) => {
return null;
}
const [{ text }] = content;
return <h1 style={{color: 'red'}}>{text}</h1>
}
return <h1 style={{ color: "red" }}>{text}</h1>;
};

const ActivityBlock = (props) => {
const { title, description } = props.attrs.data;

return (<div>
<h1>{title}</h1>
<p>{description}</p>
</div>)
}

return (
<div>
<h1>{title}</h1>
<p>{description}</p>
</div>
);
};

function BlogWithBlockEditor({blockEditorItem}){
return <BlockEditorRenderer
blocks={blockEditorItem}
customRenderers={{
'Activity': ActivityBlock,
'paragraph': CustomParagraph
}}
style={{ backgroundColor: 'lightblue', padding: '10px', fontSize: '40px' }}
className="blocks"
/>
function Blog({ blockEditorItem, ...contentlet }) {
return (
<BlockEditorRenderer
editable={true}
contentlet={contentlet}
blocks={blockEditorItem}
fieldName="blockEditorItem"
customRenderers={{
Activity: ActivityBlock,
paragraph: CustomParagraph,
}}
style={{
backgroundColor: "lightblue",
padding: "10px",
fontSize: "40px",
}}
className="blocks"
/>
);
}
export default BlogWithBlockEditor;
export default Blog;

0 comments on commit 7281db1

Please sign in to comment.