I've read through several closed issues related to alignment and would like to see if I'm on the right track. Essentially, here is what I've landed on:
There are several other posts related to this, where most folks have also come to the same conclusion.
Is this the general approach that most would consider appropriate? Am I missing anything?
I've been trying to get this set up for some time and have been failing miserably. Even if the above approach is correct, I just can't seem to get a custom command wired up to a button properly so that it will fire off said command (e.g. alignment) against the currently selected nodes.
One approach that actually does work is the following, which provides a demo. I think this is using React:
https://github.com/chanzuckerberg/czi-prosemirror
In any case, it looks like what was done here is to define a set of "allowable" node types that can be aligned, and establish a menu that contains all of the commands, and modify each node spec accordingly:
I believe the above contains pieces of what is required to make this work, and I'm sure this could somehow be re-written in a Vue/tiptap friendly fashion. I really do wish I could get alignment working, as this is a key area we'll need to implement in our project.
Hi @mattkoch614,
I was also recently trying to figure out how to add an alignment functionality to the TipTap editor.
I posted a part of my final solution in another thread https://github.com/scrumpy/tiptap/issues/157#issuecomment-476515593.
I think the best way is to create a custom Mark instead of Node. And use the span element with display:block; css style. The span element is necessary so that it can be included in paragraph html tag. But because we need a block to align contents, we change the display attribute to block.
It is a bit hackish way of achieving what we want, but I think it is satisfactionary.
And when using a Mark, the alignment won't change the element's tag (for example, changing H1 to p), but will add the span element into the selected node.
Thanks for keeping this thread open, I think that this editor really needs this alignment, as this is a standard in other editors and users usually really want it.
I find the least hacky solution(but still) to add text align attribute to relevant nodes(ie paragraph and heading) on selection programatically.
You would then need to do weird checks for alignment like isActive.paragraph({ textAlign: 'left' }) || isActive.heading({ level: 1, textAlign: 'left' }) || isActive.heading({ level: 2, textAlign: 'left' }) but at least you are not applying text align style to inline elements.
I have found this solution isActive.alignment() && editor.activeMarkAttrs.alignment.textAlign === 'left', but I belive easier solution exists. I also tried to use menu getMarkAttrs function but couldn't find right arguments to use it correct.
i did a quick hack, but its not ideal, so i have 3 different component.
what i could not solve is understanding how inputrules works.
basically this is one of the align middle, but this will overlap with other alignment
import { Mark } from 'tiptap'
import { markInputRule, toggleMark } from 'tiptap-commands'
export default class Align extends Mark {
align: String = 'center'
get name() {
return 'align_center'
}
get schema() {
return {
parseDOM: [
{
tag: 'span'
},
{
style: `text-align=${this.align}`
}
], //${mark.attrs.textAlign}
toDOM: (mark) => [
'span',
{
style: `text-align: ${this.align}; display: block`
},
0
]
}
}
commands({ type }) {
console.log('commands', type)
return (attrs) => toggleMark(type)
}
inputRules({ type }) {
console.log('inputrules', type)
let res = [
markInputRule(/(?:^|[^_])(_([^_]+)_)$/, type),
markInputRule(/(?:^|[^*])(\*([^*]+)\*)$/, type)
]
console.log('res', res)
return res
}
}
may i ask, how inputrule work?
{
match: {
exec: (e, e2) => {
console.log('matching', e, e2)
return [0, 0]
}
},
handler: (state, match, from, to) => {
console.log('handle!', state, match, from, to)
}
}
@mattkoch614 @philippkuehn I've made an attempt at solving the issue of alignment, using chanzuckerberg/czi-prosemirror as the basis. How do you feel about this implementation? Any issues foreseeable issues?
scrumpy/tiptap#544
Building upon this idea, I also implemented indentation:
tszulc/tiptap#2
What's the point of a Text Editor when you can't even control a simple alignment?
We ended up going with CKEditor.
What's the point of a Text Editor when you can't even control a simple alignment?
It IS possible but you have to do it for yourself. With tiptap v2 it will be easier to extend default nodes with a feature like alignment.
And there are sooo many use cases where you don't need alignment. Just think of comment sections or slack or twitter…
well I understand that you want to keep the core clean and small, but every other editor offers alignment, I've also started with tiptap and replaced it because I couldn't get alignment to work properly with all comments and stuff from the issues.
if you don't offer alignment out of the box I wouldn't call it RICH text editor..
Most helpful comment
What's the point of a Text Editor when you can't even control a simple alignment?