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

RTL Support #116

Closed
GabrielKol opened this issue Dec 3, 2018 · 13 comments
Closed

RTL Support #116

GabrielKol opened this issue Dec 3, 2018 · 13 comments

Comments

@GabrielKol
Copy link

GabrielKol commented Dec 3, 2018

Is there a way to inject the dir="auto" attribute to all p tags?
It would be nice if each paragraph's direction would automatically change based on the language in it.

@philippkuehn
Copy link
Contributor

Hey @GabrielKol,
I do not needed RTL support for my latest projects. Isn't that something you can do with CSS?

@GabrielKol
Copy link
Author

GabrielKol commented Dec 5, 2018

Hey @philippkuehn

I would like the direction to automatically change based on the language I'm using.
For example, if I start typing in Hebrew or Arabic, it would be presented from right to left,
but If I would press enter and on the next paragraph would type in English, then it would be presented from left to right.

It should automatically switch the direction based on the text's language.
It behaves this way in Gmail and Iv'e seen the same behavior in other editors such as Draft.js and Slate.js.

The only way I know of to implement this, is using the dir attribute on an html tag and setting it to "auto". So if I could give each p tag the dir="auto" attribute it would behave as I expect it to.
But I cannot figure out how to change the p tags in the editor.

Example from Gmail:
gmail_editor

@philippkuehn
Copy link
Contributor

Okay, I'm not sure about implementing this by default. What you can do is to use a custom paragraph extension. Since it's a default extension you have to overwrite it.

import { setBlockType } from 'tiptap-commands'
import { Node } from 'tiptap'

export default class Paragraph extends Node {

  get name() {
    return 'paragraph'
  }

  get schema() {
    return {
      content: 'inline*',
      group: 'block',
      draggable: false,
      parseDOM: [{
        tag: 'p',
      }],
      toDOM: () => ['p', { dir: 'auto' }, 0],
    }
  }

  commands({ type }) {
    return () => setBlockType(type)
  }

}

There is an option to disable the default extensions (useBuiltInExtensions). But you have to import Doc and Text.

import { Doc, Text } from 'tiptap'
import Paragraph from './CustomParagraph.js'

const editor = new Editor({
  useBuiltInExtensions: false,
  extensions: [
    new Doc(), // default extension
    new Text(), // default extension
    new Paragraph(), // your custom extension
    ... // all other extensions
  ],
})

@GabrielKol
Copy link
Author

Thank you @philippkuehn
It works perfectly! :)

@mrg0lden
Copy link

mrg0lden commented Mar 12, 2019

I still hope it gets implemented by default or activated through an option instead of making a custom paragraph plugin. Slate has it by default and it's a really great addition with almost no cost.

@AmirrezaNasiri
Copy link

AmirrezaNasiri commented Apr 13, 2020

@philippkuehn At least 4% of the web is based on RTL languages. Could you please reconsider?

@themedleb
Copy link

@philippkuehn Your amazing project is getting adopted by the mainstream since it is part of what Nextcloud is making, it only make sense to support the languages that has the opposite direction, all it needs is implementing dir="auto" in the tags p li h1 h2 h3 ... Not sure how hard it is to implement, but it is really really needed. And I have no idea how to use/implement the code you posted here in Nextcloud Text app.

I tried to add dir=auto but unfortunately I can't contribute directly to the project, since this is beyond my knowledge, all I know is HTML, CSS and a little bit of Javascript/jQuery and PHP.

@mrg0lden
Copy link

@themedleb There're two ways to achieve that.

  1. giving the parent element dir="auto", and it's the easiest. drawback: the direction is determined by the first character in the first child element, if it's an LTR character then that's the direction for the whole thing, and vice versa.
  2. the other way is by re-implementing each text component of tiptap, it's a lot of work, but that's how it's done, unless it gets supported natively by tiptap.

@themedleb
Copy link

@mrg0lden

the direction is determined by the first character in the first child element

I noticed that when I was playing with the HTML in the browser inspector.

re-implementing each text component of tiptap

That's how it should be done of course, yesterday I mentioned it in here nextcloud/text#882 (comment), but I guess the developer is not caring much about it.

@Lazar-Matic
Copy link

Lazar-Matic commented May 12, 2021

If anyone else needs this, I have done it through simple CSS, just direction="rtl" and text-align: "right".

// This is SCSS

.tiptap-editor__content>div {
    text-align: right;
    p {
      direction: rtl;
    }
  }

It seems to work just as it should. It is not Automatic, but if you have information about language, ( navigator.language for example ) it will work.

@anasoft90
Copy link

anasoft90 commented Feb 25, 2022

I had the same problem and eventually I decided to extend TextAlign extension like the following

import TextAlign from '@tiptap/extension-text-align'
  mounted() {
    // Extend TextAlign and overwrite the functionality
    const CustomTextAlign = TextAlign.extend({
      addGlobalAttributes() {
        return [
          {
            types: [
              'heading',
              'paragraph',
            ],
            attributes: {
              textAlign: {
                default: 'left',
                renderHTML: attributes => ({
                  style: `text-align: ${attributes.textAlign}`,
                }),
                parseHTML: element => element.style.textAlign || 'left',
              },
            },
          },
        ]
      },
    })
    this.editor = new Editor({
      content: this.value,
      extensions: [
        StarterKit,
        Underline,
        BulletList,
         Heading.configure({
          levels: [1, 2, 3],
        }),
        // Initialize the custom extension here
        CustomTextAlign.configure({
          types: ['heading', 'paragraph'],
        })
      ],
      onUpdate: () => {
        this.$emit('input', this.editor.getHTML())
      },
    })
  },

  beforeDestroy() {
    this.editor.destroy()
  },

Hope that helps :)

@amirhhashemi
Copy link
Contributor

amirhhashemi commented Apr 5, 2023

Hey everyone. I wrote a small extension that automatically adds dir="rtl" or dir="ltr" based on the node's content. You might find it useful: https://github.com/amirhhashemi/tiptap-text-direction

@themedleb
Copy link

Thank you @amirhhashemi will check it out.

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