diff --git a/docs/src/demos/Guide/NodeViews/TableOfContents/Component.vue b/docs/src/demos/Guide/NodeViews/TableOfContents/Component.vue index ebbc2b01..95055dd1 100644 --- a/docs/src/demos/Guide/NodeViews/TableOfContents/Component.vue +++ b/docs/src/demos/Guide/NodeViews/TableOfContents/Component.vue @@ -7,7 +7,9 @@ v-for="(heading, index) in headings" :key="index" > - {{ heading.text }} + + {{ heading.text }} + @@ -32,23 +34,38 @@ export default { methods: { handleUpdate() { const headings = [] + const transaction = this.editor.state.tr - this.editor.state.doc.descendants(node => { + this.editor.state.doc.descendants((node, pos) => { if (node.type.name === 'heading') { + const id = `heading-${headings.length + 1}` + + if (node.attrs.id !== id) { + transaction.setNodeMarkup(pos, undefined, { + ...node.attrs, + id, + }) + } + headings.push({ level: node.attrs.level, text: node.textContent, + id, }) } }) + transaction.setMeta('preventUpdate', true) + + this.editor.view.dispatch(transaction) + this.headings = headings }, }, mounted() { this.editor.on('update', this.handleUpdate) - this.handleUpdate() + this.$nextTick(this.handleUpdate) }, } @@ -75,7 +92,7 @@ export default { &::before { display: block; - content: "In this document"; + content: "Table of Contents"; font-weight: 700; letter-spacing: 0.025rem; font-size: 0.75rem; @@ -85,6 +102,10 @@ export default { } &__item { + a:hover { + opacity: 0.5; + } + &--3 { padding-left: 1rem; } diff --git a/docs/src/demos/Guide/NodeViews/TableOfContents/TableOfContents.js b/docs/src/demos/Guide/NodeViews/TableOfContents/TableOfContents.js index 94a612c4..c686545f 100644 --- a/docs/src/demos/Guide/NodeViews/TableOfContents/TableOfContents.js +++ b/docs/src/demos/Guide/NodeViews/TableOfContents/TableOfContents.js @@ -24,4 +24,19 @@ export default Node.create({ addNodeView() { return VueNodeViewRenderer(Component) }, + + addGlobalAttributes() { + return [ + { + types: [ + 'heading', + ], + attributes: { + id: { + default: null, + }, + }, + }, + ] + }, })