Skip to content

Commit

Permalink
fix(vue-3): on editor destruction, transition smoothly (#5772)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ericlm authored Nov 7, 2024
1 parent 8a2e548 commit 94a8d25
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 18 deletions.
5 changes: 5 additions & 0 deletions .changeset/five-flowers-eat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tiptap/vue-3": patch
---

Fix editor destruction before transition end if editor is nested
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Before submitting a pull request:
- Check the codebase to ensure that your feature doesn't already exist.
- Check the pull requests to ensure that another person hasn't already submitted the feature or fix.

Before commiting:
Before committing:

- Make sure to run the tests and linter before committing your changes.
- If you are making changes to one of the packages, make sure to **always** include a [changeset](https://github.com/changesets/changesets) in your PR describing **what changed** with a **description** of the change. Those are responsible for changelog creation
Expand Down
2 changes: 1 addition & 1 deletion demos/src/Examples/Transition/Vue/Extension.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { mergeAttributes, Node } from '@tiptap/core'
import { VueNodeViewRenderer } from '@tiptap/vue-3'

import Component from './Component.vue'
import Component from './VueComponent.vue'

export default Node.create({
name: 'vueComponent',
Expand Down
36 changes: 36 additions & 0 deletions demos/src/Examples/Transition/Vue/ParentComponent.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<template>
<div>
<EditorContent :editor="editor" />
</div>
</template>

<script setup lang="ts">
import StarterKit from '@tiptap/starter-kit'
import { EditorContent, useEditor } from '@tiptap/vue-3'
import { ref } from 'vue'
import VueComponent from './Extension.js'
import type { TNote } from './types.js'
const note = ref<TNote>({
id: 'note-1',
content: `
<p>Some random note text</p>
<vue-component count="0"></vue-component>
`,
})
const editor = useEditor({
content: note.value.content,
editorProps: {
attributes: {
class: 'textarea',
},
},
extensions: [
StarterKit,
VueComponent,
],
})
</script>
18 changes: 11 additions & 7 deletions demos/src/Examples/Transition/Vue/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,30 @@ context('/src/Examples/Transition/Vue/', () => {
cy.visit('/src/Examples/Transition/Vue/')
})

it('should not have an active tiptap instance but a button', () => {
it('should have two buttons and no active tiptap instance', () => {
cy.get('.tiptap').should('not.exist')

cy.get('#toggle-editor').should('exist')
cy.get('#toggle-direct-editor').should('exist')
cy.get('#toggle-nested-editor').should('exist')
})

it('clicking the button should show the editor', () => {
cy.get('#toggle-editor').click()
it('clicking the buttons should show two editors', () => {
cy.get('#toggle-direct-editor').click()
cy.get('#toggle-nested-editor').click()

cy.get('.tiptap').should('exist')
cy.get('.tiptap').should('be.visible')
})

it('clicking the button again should hide the editor', () => {
cy.get('#toggle-editor').click()
it('clicking the buttons again should hide the editors', () => {
cy.get('#toggle-direct-editor').click()
cy.get('#toggle-nested-editor').click()

cy.get('.tiptap').should('exist')
cy.get('.tiptap').should('be.visible')

cy.get('#toggle-editor').click()
cy.get('#toggle-direct-editor').click()
cy.get('#toggle-nested-editor').click()

cy.get('.tiptap').should('not.exist')
})
Expand Down
46 changes: 38 additions & 8 deletions demos/src/Examples/Transition/Vue/index.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
<script setup lang="ts">
import StarterKit from '@tiptap/starter-kit'
import { EditorContent, useEditor } from '@tiptap/vue-3'
import { ref } from 'vue'
import VueComponent from './Extension.js'
import ParentComponent from './ParentComponent.vue'
import type { TNote } from './types.js'
/** Display editor in the same component */
const showDirectEditor = ref(false)
/** Display editor in a child component */
const showNestedEditor = ref(false)
const note = ref<TNote>({
id: 'note-1',
content: `
Expand All @@ -28,24 +34,43 @@ const editor = useEditor({
],
})
const showEditor = ref(false)
</script>

<template>
<!-- Transition with editor in the same component -->
<div>
<button
id="toggle-direct-editor"
type="button"
@click="showEditor = !showEditor"
style="margin-bottom: 1rem;"
id="toggle-editor"
@click="showDirectEditor = !showDirectEditor"
>
{{ showEditor ? 'Hide editor' : 'Show editor' }}
{{ showDirectEditor ? 'Hide direct editor' : 'Show direct editor' }}
</button>

<transition name="fade">
<div v-if="showEditor" class="tiptap-wrapper">
<editor-content :editor="editor" />
<div v-if="showDirectEditor" class="tiptap-wrapper">
<EditorContent :editor="editor" />
</div>
</transition>
</div>

<hr>

<!-- Transition with editor in a child component -->
<div>
<button
id="toggle-nested-editor"
type="button"
style="margin-bottom: 1rem;"
@click="showNestedEditor = !showNestedEditor"
>
{{ showNestedEditor ? 'Hide nested editor' : 'Show nested editor' }}
</button>

<transition name="fade">
<div v-if="showNestedEditor" class="tiptap-wrapper">
<ParentComponent />
</div>
</transition>
</div>
Expand All @@ -62,6 +87,11 @@ const showEditor = ref(false)
opacity: 0;
}
hr {
margin-top: 1rem;
margin-bottom: 1rem;
}
.tiptap-wrapper {
background-color: var(--purple-light);
border: 2px solid var(--purple);
Expand Down
1 change: 0 additions & 1 deletion packages/vue-3/src/EditorContent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ export const EditorContent = defineComponent({

editor.createNodeViews()
})

}
})

Expand Down
6 changes: 6 additions & 0 deletions packages/vue-3/src/useEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ export const useEditor = (options: Partial<EditorOptions> = {}) => {
})

onBeforeUnmount(() => {
// Cloning root node (and its children) to avoid content being lost by destroy
const nodes = editor.value?.options.element
const newEl = nodes?.cloneNode(true) as HTMLElement

nodes?.parentNode?.replaceChild(newEl, nodes)

editor.value?.destroy()
})

Expand Down

0 comments on commit 94a8d25

Please sign in to comment.