mirror of
https://github.com/ueberdosis/tiptap.git
synced 2025-06-08 01:53:04 +08:00
I only feel comfortable copying the attributes of the current node if the selection is only within a single node (I don't know what is expected if you had a selection of multiple nodes, the intersection of the attributes maybe?) --------- Co-authored-by: Dominik Biedebach <dominik.biedebach@tiptap.dev>
This commit is contained in:
parent
dcffe441c5
commit
07fa49d026
5
.changeset/metal-shrimps-press.md
Normal file
5
.changeset/metal-shrimps-press.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@tiptap/core": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Copy over node attributes on node toggling (for example to keep text styles while toggling a headline)
|
@ -58,7 +58,21 @@ export default () => {
|
|||||||
>
|
>
|
||||||
Justify
|
Justify
|
||||||
</button>
|
</button>
|
||||||
<button onClick={() => editor.chain().focus().unsetTextAlign().run()}>Unset text align</button>
|
<button onClick={() => editor.chain().focus().unsetTextAlign().run()}>
|
||||||
|
Unset text align
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => editor.chain().focus().toggleHeading({ level: 1 }).run()}
|
||||||
|
className={editor.isActive({ level: 1 }) ? 'is-active' : ''}
|
||||||
|
>
|
||||||
|
Toggle H1
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => editor.chain().focus().toggleHeading({ level: 2 }).run()}
|
||||||
|
className={editor.isActive({ level: 2 }) ? 'is-active' : ''}
|
||||||
|
>
|
||||||
|
Toggle H2
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<EditorContent editor={editor} />
|
<EditorContent editor={editor} />
|
||||||
|
@ -37,6 +37,21 @@ context('/src/Extensions/TextAlign/React/', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should keep the text aligned when toggling headings', () => {
|
||||||
|
const alignments = ['center', 'right', 'justify']
|
||||||
|
const headings = [1, 2]
|
||||||
|
|
||||||
|
cy.get('.tiptap').then(([{ editor }]) => {
|
||||||
|
alignments.forEach(alignment => {
|
||||||
|
headings.forEach(level => {
|
||||||
|
editor.commands.setContent(`<p style="text-align: ${alignment}">Example Text</p>`)
|
||||||
|
editor.commands.toggleHeading({ level })
|
||||||
|
expect(editor.getHTML()).to.eq(`<h${level} style="text-align: ${alignment}">Example Text</h${level}>`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it('aligns the text left on the 1st button', () => {
|
it('aligns the text left on the 1st button', () => {
|
||||||
cy.get('button:nth-child(1)').click()
|
cy.get('button:nth-child(1)').click()
|
||||||
|
|
||||||
|
@ -37,6 +37,21 @@ context('/src/Extensions/TextAlign/Vue/', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should keep the text aligned when toggling headings', () => {
|
||||||
|
const alignments = ['center', 'right', 'justify']
|
||||||
|
const headings = [1, 2]
|
||||||
|
|
||||||
|
cy.get('.tiptap').then(([{ editor }]) => {
|
||||||
|
alignments.forEach(alignment => {
|
||||||
|
headings.forEach(level => {
|
||||||
|
editor.commands.setContent(`<p style="text-align: ${alignment}">Example Text</p>`)
|
||||||
|
editor.commands.toggleHeading({ level })
|
||||||
|
expect(editor.getHTML()).to.eq(`<h${level} style="text-align: ${alignment}">Example Text</h${level}>`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it('aligns the text left on the 1st button', () => {
|
it('aligns the text left on the 1st button', () => {
|
||||||
cy.get('button:nth-child(1)')
|
cy.get('button:nth-child(1)')
|
||||||
.click()
|
.click()
|
||||||
|
@ -28,9 +28,18 @@ export const toggleNode: RawCommands['toggleNode'] = (typeOrName, toggleTypeOrNa
|
|||||||
const toggleType = getNodeType(toggleTypeOrName, state.schema)
|
const toggleType = getNodeType(toggleTypeOrName, state.schema)
|
||||||
const isActive = isNodeActive(state, type, attributes)
|
const isActive = isNodeActive(state, type, attributes)
|
||||||
|
|
||||||
if (isActive) {
|
let attributesToCopy: Record<string, any> | undefined
|
||||||
return commands.setNode(toggleType)
|
|
||||||
|
if (state.selection.$anchor.sameParent(state.selection.$head)) {
|
||||||
|
// only copy attributes if the selection is pointing to a node of the same type
|
||||||
|
attributesToCopy = state.selection.$anchor.parent.attrs
|
||||||
}
|
}
|
||||||
|
|
||||||
return commands.setNode(type, attributes)
|
if (isActive) {
|
||||||
|
return commands.setNode(toggleType, attributesToCopy)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the node is not active, we want to set the new node type with the given attributes
|
||||||
|
// Copying over the attributes from the current node if the selection is pointing to a node of the same type
|
||||||
|
return commands.setNode(type, { ...attributesToCopy, ...attributes })
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user