Docs
Plugins
Plugins
Plugins for shadcn/ui.
Here are three important files to extend the functionality of shadcn/editor that would be created on initialization of the editor under /components/blocks/editor-00
directory.
editor.tsx
'use client'
import {
InitialConfigType,
LexicalComposer,
} from '@lexical/react/LexicalComposer'
import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin'
import { EditorState, SerializedEditorState } from 'lexical'
import { editorTheme } from '@/registry/default/editor/themes/editor-theme'
import { TooltipProvider } from '@/registry/default/ui/tooltip'
import { nodes } from './nodes'
import { Plugins } from './plugins'
const editorConfig: InitialConfigType = {
namespace: 'Editor',
theme: editorTheme,
nodes,
onError: (error: Error) => {
console.error(error)
},
}
export function Editor({
editorState,
editorSerializedState,
onChange,
onSerializedChange,
}: {
editorState?: EditorState
editorSerializedState?: SerializedEditorState
onChange?: (editorState: EditorState) => void
onSerializedChange?: (editorSerializedState: SerializedEditorState) => void
}) {
return (
<div className="overflow-hidden rounded-lg border bg-background shadow">
<LexicalComposer
initialConfig={{
...editorConfig,
...(editorState ? { editorState } : {}),
...(editorSerializedState
? { editorState: JSON.stringify(editorSerializedState) }
: {}),
}}
>
<TooltipProvider>
<Plugins />
<OnChangePlugin
ignoreSelectionChange={true}
onChange={(editorState) => {
onChange?.(editorState)
onSerializedChange?.(editorState.toJSON())
}}
/>
</TooltipProvider>
</LexicalComposer>
</div>
)
}
nodes.tsx
import { Klass, LexicalNode, LexicalNodeReplacement } from 'lexical'
export const nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement> =
[]
plugins.tsx
import { useState } from 'react';
import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';
import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';
import { ContentEditable } from '@/registry/default/editor/editor-ui/content-editable';
export function Plugins() {
const [floatingAnchorElem, setFloatingAnchorElem] =
useState<HTMLDivElement | null>(null);
const onRef = (_floatingAnchorElem: HTMLDivElement) => {
if (_floatingAnchorElem !== null) {
setFloatingAnchorElem(_floatingAnchorElem);
}
};
return (
<div className="relative">
{/* toolbar plugins */}
<div className="relative">
<RichTextPlugin
contentEditable={
<div className="">
<div className="" ref={onRef}>
<ContentEditable placeholder={'Start typing ...'} />
</div>
</div>
}
ErrorBoundary={LexicalErrorBoundary}
/>
{/* editor plugins */}
</div>
{/* actions plugins */}
</div>
);
}
To extend the functionality with plugins, you can add the plugins to the plugins.tsx
file and add the nodes to the nodes.tsx
file (if needed).
If you want different type of editors (notion-like, google docs-like, markdown-editor etc), you would require to create these three files for each editor.