diff --git a/docs/.vitepress/locale.ts b/docs/.vitepress/locale.ts
index 09da974..3767ac7 100644
--- a/docs/.vitepress/locale.ts
+++ b/docs/.vitepress/locale.ts
@@ -54,6 +54,10 @@ export function getLocaleConfig(lang: string) {
text: t('Bubble Menu'),
link: `${urlPrefix}/guide/bubble-menu`,
},
+ {
+ text: t('Customize'),
+ link: `${urlPrefix}/guide/customize.md`,
+ },
{
text: t('Internationalization'),
link: `${urlPrefix}/guide/internationalization`,
diff --git a/docs/guide/customize.md b/docs/guide/customize.md
new file mode 100644
index 0000000..ce95124
--- /dev/null
+++ b/docs/guide/customize.md
@@ -0,0 +1,241 @@
+---
+description: How to customize the Reactjs-Tiptap-Editor.
+
+next:
+ text: Customize
+ link: /guide/customize.md
+---
+
+# Customizing Reactjs-Tiptap-Editor
+
+There are 3 main ways to customize the Reactjs-Tiptap-Editor:
+
+### 1. Extensions
+
+Add extensions to enhance editor functionality:
+
+```tsx
+import React from 'react'
+import RichTextEditor, { BaseKit, Bold, BulletList, Heading, Italic } from 'reactjs-tiptap-editor'
+import 'reactjs-tiptap-editor/style.css'
+
+const extensions = [BaseKit, Heading, Italic, Bold, BulletList]
+
+export default function App() {
+ return (
+
+ )
+}
+```
+
+### 2. Editor Options
+
+The `useEditorOptions` property provides configuration options for customizing the editor's behavior with the `UseEditorOptions` interface.
+
+### Interface
+
+```tsx
+interface UseEditorOptions {
+ /** Called when editor content is updated */
+ onUpdate?: (props: { editor: Editor, transaction: Transaction }) => void
+
+ /** Called when editor selection changes */
+ onSelectionUpdate?: (props: { editor: Editor, transaction: Transaction }) => void
+
+ /** Called when editor gains focus */
+ onFocus?: (props: { editor: Editor, event: FocusEvent }) => void
+
+ /** Called when editor loses focus */
+ onBlur?: (props: { editor: Editor, event: FocusEvent }) => void
+
+ /** Called when editor transaction is created */
+ onTransaction?: (props: { editor: Editor, transaction: Transaction }) => void
+
+ /** Called when editor is created */
+ onCreate?: (props: { editor: Editor }) => void
+
+ /** Called before editor is destroyed */
+ onDestroy?: () => void
+
+ /** Initial editor state */
+ editorState?: string
+
+ /** Enable or disable parsing content */
+ enableInputRules?: boolean
+ enablePasteRules?: boolean
+
+ /** Enable or disable content editing */
+ editable?: boolean
+
+ /** Custom autofocus behavior */
+ autofocus?: boolean | 'start' | 'end' | number
+
+ /** Editor view props */
+ editorProps?: EditorProps
+}
+```
+
+Example with editor options:
+
+```tsx
+import React from 'react'
+import RichTextEditor, { BaseKit, type UseEditorOptions } from 'reactjs-tiptap-editor'
+import 'reactjs-tiptap-editor/style.css'
+
+const extensions = [BaseKit]
+
+const customOptions: UseEditorOptions = {
+ onUpdate: ({ editor }) => console.log('Content updated:', editor.getText()),
+ onSelectionUpdate: ({ editor }) => console.log('Selection updated:', editor.getText()),
+ onFocus: () => console.log('Editor focused'),
+ onBlur: () => console.log('Editor blurred'),
+ editable: true,
+ autofocus: 'start',
+}
+
+export default function App() {
+ return (
+
+ )
+}
+```
+
+### 3. Accessing the Editor Instance
+
+There are two ways to access the editor instance:
+Direct access to the editor instance using `useRef` or `useEditorState`
+
+#### Using useRef:
+
+```tsx
+import React, { useRef } from 'react'
+import RichTextEditor, { BaseKit, type Editor } from 'reactjs-tiptap-editor'
+import 'reactjs-tiptap-editor/style.css'
+
+const extensions = [BaseKit]
+
+export default function App() {
+ const editorRef = useRef<{ editor: Editor | null }>(null)
+
+ const handleCustomButton = () => {
+ if (editorRef.current?.editor) {
+ const text = editorRef.current.editor.getText()
+ console.log('Current selected text:', text)
+ }
+ }
+
+ return (
+
+
+
+
+ )
+}
+```
+
+#### Using useEditorState:
+
+```tsx
+import RichTextEditor, { BaseKit, useEditorState } from 'reactjs-tiptap-editor'
+import 'reactjs-tiptap-editor/style.css'
+
+const extensions = [BaseKit]
+
+export default function App() {
+ const { isReady, editor, editorRef } = useEditorState()
+
+ const handleCustomButton = () => {
+ if (editor) {
+ const text = editor.getText()
+ console.log('Current text:', text)
+ }
+ }
+
+ return (
+
+
+ {isReady && (
+
+ )}
+
+ )
+}
+```
+
+### Example: Custom Bubble Menu with Selection Text
+
+```tsx
+import RichTextEditor, { BaseKit, BubbleMenu, useEditorState } from 'reactjs-tiptap-editor'
+import type { Editor } from 'reactjs-tiptap-editor'
+import 'reactjs-tiptap-editor/style.css'
+
+interface CustomBubbleMenuProps {
+ editor: Editor
+}
+
+function CustomBubbleMenu({ editor }: CustomBubbleMenuProps) {
+ if (!editor)
+ return null
+
+ const handlePrintSelection = () => {
+ const { from, to } = editor.state.selection
+ const text = editor.state.doc.textBetween(from, to)
+ console.log('Selected text:', text)
+ }
+
+ return (
+
+
+
+ )
+}
+
+const extensions = [BaseKit]
+
+export default function App() {
+ const { isReady, editor, editorRef } = useEditorState()
+
+ return (
+
+
+ {isReady && editor && }
+
+ )
+}
+```
diff --git a/src/hooks/useEditorState.tsx b/src/hooks/useEditorState.tsx
new file mode 100644
index 0000000..19a1edd
--- /dev/null
+++ b/src/hooks/useEditorState.tsx
@@ -0,0 +1,23 @@
+import type { Editor } from '@tiptap/core'
+import { useEffect, useRef, useState } from 'react'
+
+export interface UseEditorStateReturn {
+ isReady: boolean
+ editor: Editor | null
+ editorRef: React.MutableRefObject<{ editor: Editor | null }>
+}
+
+export function useEditorState(): UseEditorStateReturn {
+ const editorRef = useRef<{ editor: Editor | null }>({ editor: null })
+ const [isReady, setIsReady] = useState(false)
+ const [editor, setEditor] = useState(null)
+
+ useEffect(() => {
+ if (editorRef.current?.editor) {
+ setIsReady(true)
+ setEditor(editorRef.current.editor)
+ }
+ }, [editorRef, editorRef.current?.editor])
+
+ return { isReady, editor, editorRef }
+}
diff --git a/src/index.ts b/src/index.ts
index 0abff3c..8fe11bb 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -4,5 +4,11 @@ export * from '@/extensions'
export { default } from '@/components/RichTextEditor'
import locale, { en, pt_BR, vi, zh_CN } from './locales'
+import { useEditorState } from '@/hooks/useEditorState'
export { locale, en, vi, zh_CN, pt_BR }
+
+export type { UseEditorStateReturn } from '@/hooks/useEditorState'
+export { useEditorState }
+export type { Editor, UseEditorOptions } from '@tiptap/react'
+export { BubbleMenu } from '@tiptap/react'