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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

add RTL support #78

Closed
fshareef opened this issue Oct 15, 2020 · 11 comments
Closed

add RTL support #78

fshareef opened this issue Oct 15, 2020 · 11 comments

Comments

@fshareef
Copy link

Hello 馃憢,

This plugin currently doesn't support RTL content: https://play.tailwindcss.com/a8xvjnNlhi

image

I've thought about what the best way to do this is, and I think I have a good solution.

I don't think it's a good approach to override the default LTR styles or add additional css to figure out if the page/content is in RTL or not. Instead, it should be up to the developer to add RTL formatting when they want to.

RTL support should include:

  • Resetting default LTR behavior for all elements like border-left on blockquotes, and adding border-right instead.
  • Resetting left padding or margin values and adding right padding or margin instead.
  • Changing list-style-type for ordered lists to arabic-indic instead of the default.

I think the best way to do this is to add overrides for RTL that reset LTR formatting and add some additional formatting for RTL content. This way if a website is multidirectional and offers content in both English/Arabic for example, the developer can choose RTL or LTR formatting based on the selected locale, or whatever other behavior they want.

So I think the following new modifiers should exist in this plugin by default:

  • 'rtl': for resetting LTR rules in the default modifier.
  • 'rtl-sm': for resetting values in the default 'sm' modifier and adding the same values but for rtl.
  • 'rtl-lg': for resetting values in the default 'lg' modifier and adding the same values but for rtl.
  • 'rtl-xl': for resetting values in the default 'xl' modifier and adding the same values but for rtl.
  • 'rtl-2xl': for resetting values in the default '2xl' modifier and adding the same values but for rtl.

Here's a working version:

image

https://play.tailwindcss.com/n38SuXw2rC?file=config

If this is a good approach, I will begin working on this and submit a PR soon.

Kindly offer feedback on this approach and if anyone else has other ideas on how to add RTL support to this plugin, please discuss them here 馃檹.

@fshareef
Copy link
Author

@adamwathan are you currently open to accepting PRs to add RTL support or should I just make a fork of this project instead? Also I would appreciate any input you have on whether or not this is a good way to do it.

@adamwathan
Copy link
Member

Hey thanks for this issue! Unfortunately no one on the team has any expertise building RTL sites so we have opted not to include first-class support for it in Tailwind or our official plugins right now:

tailwindlabs/discuss#64 (comment)

However we do try really hard to make sure the plugin + customization APIs are powerful enough that people with RTL expertise can build support for it as plugins. For example I recommend this plugin when people ask about RTL support in Tailwind.

In this case, you could add the new RTL modifiers by adding new modifiers using the typography customization API 馃憤馃徎 This could even be released as a separate plugin that just adds some extra theme defaults, so anyone else needing RTL support would just need to install the typography plugin + the RTL extension should you or another community member decide to build it.

Hope that helps!

@mouhsinelonly
Copy link

@adamwathan i can help with this

@mokhosh
Copy link

mokhosh commented May 21, 2021

I've added the necessary config to make blockquote, ol, li, and tables work with RTL here:

https://play.tailwindcss.com/q4oONoWM55

@mokhosh
Copy link

mokhosh commented May 21, 2021

@adamwathan I would appreciate it if you told me how to add extra theme defaults using a plugin so i can make this into a plugin.

@obezzad
Copy link

obezzad commented Jun 21, 2021

@mokhosh I believe that adding a new "rtl" modifier is better than overriding the defaults since it gives more control to the user.

@nemo369
Copy link

nemo369 commented Oct 31, 2021

I wrote some CSS to overwrite the default:

.rtl .prose blockquote{
    border-right-width: 0.25rem;
    border-left-width: 0;
}
.rtl .prose ul > li,
.rtl .prose ol > li{
    padding-right: 1.75em;
    padding-left: 0;
}
.rtl .prose ol > li:before{
    right:0.25em ;
    left: auto;
}
.rtl .prose ol > li:before,
.rtl .prose ul > li:before{
    right:0.25em ;
    left: auto;
}
 
.rtl .prose thead td:first-child,
.rtl .prose thead th:first-child{
    padding-right: 0;
}
 
.rtl .prose thead td:last-child,
.rtl .prose thead th:last-child{
    padding-left: 0;
}
 

@majd-albandik
Copy link

majd-albandik commented Sep 8, 2022

Hello everyone,

@mokhosh @fshareef

I've added the necessary config to make blockquote, ol, li, and tables work with RTL here:

https://play.tailwindcss.com/q4oONoWM55

I also need rt-support in my project. Could you please till me what to do to get it up and running? We are using "@tailwindcss/typography": "^0.4.1",
Regards

@lewishowles
Copy link

Is there any chance this can be considered again given TailwindCSS 3.3's new logical properties and better support for RTL generally?

@evil1morty
Copy link

any news on this?

@danielvdm2000
Copy link

I have written this function to replace left/right-specific properties/values with ones that are appropriate for both LTR and RTL layouts. The function is used as a wrapper around the plugin.

It seems to be working, but it's just something I quickly wrote to add support for a project at work.

function addRtlSupport(plugin) {
  function traverseAndModify(object, modifier) {
    return Object.entries(object).reduce((acc, [key, value]) => {
      // Apply the modifier to the current key-value pair
      let [newKey, newValue] = modifier(key, value);

      // If the value is an array, recursively modify each item
      if (Array.isArray(newValue)) {
        newValue = newValue.map(item => traverseAndModify(item, modifier))
      }
      // If the value is a nested object, recursively modify it
      else if (newValue != null && typeof newValue === 'object') {
        newValue = traverseAndModify(newValue, modifier);
      }

      acc[newKey] = newValue;
      return acc;
    }, {});
  }

  function modifiedPlugin(...args) {
    const original = plugin(...args);

    const modifiedConfig = traverseAndModify(original.config, (key, value) => {
      if (key === 'paddingLeft') key = 'paddingInlineStart';
      else if (key === 'paddingRight') key = 'paddingInlineEnd';
      else if (key === 'borderLeftWidth') key = 'borderInlineStartWidth';
      else if (key === 'borderLeftColor') key = 'borderInlineStartColor';
      else if (key === 'textAlign' && value === 'left') value = 'start';

      if (key.includes('left') || key.includes('right')) {
        console.warn(`It looks like "${key}" is a left/right specific property that is not handled by "addRtlSupport" in tailwind.config.js. Please take a look at this`);
      }

      if (typeof value === 'string' && (value.includes('left') || value.includes('right'))) {
        console.warn(`It looks like "${value}" with the key of "${key}" is a left/right specific value that is not handled by "addRtlSupport" in tailwind.config.js. Please take a look at this`);
      }

      return [key, value];
    })

    // Uncomment the following lines to debug the transformation
    // const fs = require('fs');
    // fs.writeFileSync('tailwind.before.log', JSON.stringify(original.config, null, 2))
    // fs.writeFileSync('tailwind.after.log', JSON.stringify(modifiedConfig, null, 2))

    original.config = modifiedConfig;
    return original;
  }

  // There are some properties on the plugin function that we need to copy over
  Object.entries(plugin).forEach(([key, value]) => {
    modifiedPlugin[key] = value;
  });

  return modifiedPlugin;
}

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

11 participants