Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alignment approach - a discussion #180

Closed
mattkoch614 opened this issue Jan 27, 2019 · 11 comments
Closed

Alignment approach - a discussion #180

mattkoch614 opened this issue Jan 27, 2019 · 11 comments

Comments

@mattkoch614
Copy link

mattkoch614 commented Jan 27, 2019

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:

  • Each node you want to be "alignable" will need a custom schema that incorporates an additional "alignment" attribute.
  • Alignment shouldn't be treated as a mark, because marks can apply to selections inside of a node while alignment feels like it should always be at the node level. For example, I wouldn't typically center align one word or letter, it would normally be the entire paragraph, heading, list item, etc.
  • Setting the alignment itself should be handled via a command.

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?

@mattkoch614
Copy link
Author

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.

@papa-zulu
Copy link

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 #157 (comment).

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.

@petertoth
Copy link

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.

@lbialkowski
Copy link

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.

@u007
Copy link

u007 commented Aug 9, 2019

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)
        }
      }

@tszulc
Copy link

tszulc commented Dec 11, 2019

@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?

#544

@tszulc tszulc mentioned this issue Dec 12, 2019
@tszulc
Copy link

tszulc commented Dec 12, 2019

Building upon this idea, I also implemented indentation:
tszulc#2

@philippkuehn philippkuehn mentioned this issue Dec 16, 2019
@ghost
Copy link

ghost commented Mar 29, 2020

What's the point of a Text Editor when you can't even control a simple alignment?

@mattkoch614
Copy link
Author

We ended up going with CKEditor.

@philippkuehn
Copy link
Contributor

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…

@mnooblet
Copy link

mnooblet commented May 8, 2020

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..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants