Example: unmount
import 'prosekit/basic/style.css' import 'prosekit/basic/typography.css' import { defineBasicExtension } from 'prosekit/basic' import { createEditor } from 'prosekit/core' import { ProseKit } from 'prosekit/react' import { useMemo } from 'react' import ExtensionComponent from './extension-component' export default function EditorComponent({ placeholder, }: { placeholder: string }) { const editor = useMemo(() => { return createEditor({ extension: defineBasicExtension() }) }, []) return ( <ProseKit editor={editor}> <div className='box-border h-full w-full min-h-36 overflow-y-hidden overflow-x-hidden rounded-md border border-solid border-gray-200 dark:border-gray-700 shadow flex flex-col bg-white dark:bg-gray-950 color-black dark:color-white'> <div className='relative w-full flex-1 box-border overflow-y-scroll'> <div ref={editor.mount} className='ProseMirror box-border min-h-full px-[max(4rem,_calc(50%-20rem))] py-8 outline-none outline-0 [&_span[data-mention="user"]]:text-blue-500 [&_span[data-mention="tag"]]:text-violet-500'></div> </div> </div> <ExtensionComponent placeholder={placeholder} /> </ProseKit> ) }
import { useCallback, useEffect, useRef, useState, } from 'react' import EditorComponent from './editor-component' function EditorGroup() { const nextKeyRef = useRef(1) const [editorKeys, setEditorKeys] = useState<number[]>([]) const addEditor = useCallback(() => { const key = nextKeyRef.current nextKeyRef.current += 1 setEditorKeys((keys) => [...keys, key]) }, []) const removeEditor = useCallback((key: number) => { setEditorKeys((keys) => keys.filter((k) => k !== key)) }, []) useEffect(() => { if (nextKeyRef.current === 1) { addEditor() } }, [addEditor]) return ( <div className="flex flex-col gap-2"> <div className="flex gap-2"> <button onClick={addEditor} className="border p-2"> Add editor </button> {editorKeys.map((key) => ( <button key={key} onClick={() => removeEditor(key)} className="border p-2" > Unmount No.{key} </button> ))} </div> {editorKeys.map((key) => ( <div key={key} className="h-32"> <EditorComponent placeholder={`Editor No.${key} of ${editorKeys.length}`} /> </div> ))} </div> ) } export default EditorGroup
import { definePlaceholder } from 'prosekit/extensions/placeholder' import { useExtension } from 'prosekit/react' import { useMemo } from 'react' export default function ExtensionComponent({ placeholder, }: { placeholder: string }) { const extension = useMemo( () => definePlaceholder({ placeholder }), [placeholder], ) useExtension(extension) return null }
<script setup lang="ts"> import 'prosekit/basic/style.css' import 'prosekit/basic/typography.css' import { defineBasicExtension } from 'prosekit/basic' import { createEditor } from 'prosekit/core' import { ProseKit } from 'prosekit/vue' import { ref, watchPostEffect, } from 'vue' import ExtensionComponent from './extension-component.vue' const props = defineProps<{ placeholder: string }>() const editor = createEditor({ extension: defineBasicExtension() }) const editorRef = ref<HTMLDivElement | null>(null) watchPostEffect((onCleanup) => { editor.mount(editorRef.value) onCleanup(() => editor.unmount()) }) </script> <template> <ProseKit :editor="editor"> <div class='box-border h-full w-full min-h-36 overflow-y-hidden overflow-x-hidden rounded-md border border-solid border-gray-200 dark:border-gray-700 shadow flex flex-col bg-white dark:bg-gray-950 color-black dark:color-white'> <div class='relative w-full flex-1 box-border overflow-y-scroll'> <div ref="editorRef" class='ProseMirror box-border min-h-full px-[max(4rem,_calc(50%-20rem))] py-8 outline-none outline-0 [&_span[data-mention="user"]]:text-blue-500 [&_span[data-mention="tag"]]:text-violet-500' /> </div> </div> <ExtensionComponent :placeholder="props.placeholder" /> </ProseKit> </template>
<script setup lang="ts"> import { ref, watchEffect, } from 'vue' import EditorComponent from './editor-component.vue' const editorKeys = ref<number[]>([]) const nextKey = ref(1) function addEditor() { const key = nextKey.value nextKey.value += 1 editorKeys.value.push(key) } function removeEditor(key: number) { editorKeys.value = editorKeys.value.filter((k) => k !== key) } watchEffect(() => { if (nextKey.value === 1) { addEditor() } }) </script> <template> <div className="flex flex-col gap-2"> <div className="flex gap-2"> <button className="border p-2" @click="addEditor">Add editor</button> <button v-for="key in editorKeys" :key="key" className="border p-2" @click="() => removeEditor(key)" > Unmount No.{{ key }} </button> </div> <div v-for="key in editorKeys" :key="key" className="h-32"> <EditorComponent :placeholder="`Editor No.${key} of ${editorKeys.length}`" /> </div> </div> </template>
<script setup lang="ts"> import { definePlaceholder } from 'prosekit/extensions/placeholder' import { useExtension } from 'prosekit/vue' import { computed } from 'vue' const props = defineProps<{ placeholder: string }>() const extension = computed(() => definePlaceholder({ placeholder: props.placeholder })) useExtension(extension) </script>