Need advice on RTL support

default discord avatar
ibrahem
last month
76

Greetings lovely people ๐Ÿ‘‹


I've been working with payload for the last two months for a project and I'm trying to translate the admin dashboard into Arabic.


the translation is almost done (needs testing) but it would be useless if I can't solve some issues I'm facing so I would much appreciate your input ๐Ÿ™


1) you guessed it! ๐Ÿ˜… rtl support for the layout, it's a bit overwhelming since I did get the opportunity to dig a little in source but not to a point where I have a plan of execution, how can I integrate this in a "none-hacky" way? what do I have to consider?


2) a subsequent of num 1 is the that any text field might need to be rtl too, but in an opt-in way, so I would imagine it being like a property on the field that's only activated in case the field is localized and the current locale being edited is rtl and it sets the default text alignment. another approach would be to just create a custom version of the text fields that uses the hooks and maybe a property in "custom" field key to signal to the custom component to be rtl but then I'd have to package it as a plugin and the translation would be part standard and part plugin ๐Ÿค” am I missing something or does any of these sound like a reasonable approach?

  • discord user avatar
    jmikrut
    Payload Team
    last month

    @DasMergo is also interested in adding RTL support!



    I could help here for sure



    but i see what you're saying about certain text fields



    it's worth brainstorming a bit around the proper field UX

  • default discord avatar
    DasMergo
    last month

    @jmikrut we need an option for dynamic direction change in admin panel (when user switched language) the direction changes at the same time something that injects dir attribute to <html> element like <html dir="rtl"> and also <html dir="ltr"> for english and non rtl langs



    @jmikrut also we need to have another sass file for rtl

    https://stackoverflow.com/questions/39293509/how-to-support-rtl-and-ltr-in-sass
  • default discord avatar
    ibrahem
    4 weeks ago

    do you have any ideas about where to start with that? and I can start experimenting



    it says here that the sass doesn't need to be compiled twice here if we go with the html dir attribute



    @jmikrut in regards to the fields I suggest an optional property on localized text fields (text/rich text) since it's only dependant on the locale being edited and not the dashboard language and in a sense, the field component would be "locale aware" and uses the hooks to adjust accordingly, what do you think?

  • default discord avatar
    DasMergo
    4 weeks ago

    @ibrahem well we can do this trough the API I think but we have to create an option or a check field in admin settings then return it in the code but this is not a standard solution i think correct me if im wrong



    you can check this out too:

    https://github.com/vercel/next.js/discussions/19049

    its for next but maybe useful for this purpose



    @jmikrut thoughts would be more helpful

  • default discord avatar
    ibrahem
    4 weeks ago

    do you mean to check if the dashboard language has changed or do you mean the fields? because the fields issue isn't affected by the language of the dashboard, only the locale (via useLocale) and a custom option on the field config. if you are referring to the html dir attribute then I'm not sure the api would be any help



    just to be clear, we set the dir attribute whenever the user changes the language



    @DasMergo let me draw all the possible states and test them a bit and I'll get back to you with a clearer mapping

  • default discord avatar
    DasMergo
    4 weeks ago

    ok, thanks, if is possible please send me a friend request I'm not able to add you

  • default discord avatar
    ibrahem
    4 weeks ago

    @DasMergo @jmikrut


    so let me suggest the following to solve both issues and we can brainstorm from there:


    1) when the user changes the dashboard language in the preferences โžก๏ธ check if the new language is rtl or ltr and set the html dir attribute accordingly for future requests, while the default can be set as an option on the admin config (here the next.js solution might be useful)


    2) now let's see what possible combinations exist:


    - locale rtl and language rtl


    dashboard is rtl and fields are rtl except for fields with special flag


    - locale rtl and language ltr


    dashboard is ltr and fields are rtl except for fields with special flag


    - locale ltr and language ltr


    dashboard is ltr and fields are ltr


    - locale ltr and language rtl


    dashboard is rtl and fields are ltr



    it seems the only factor that affects alignment of the fields is the locale being edited. so the alignment of the cursor only depends on the locale as a general rule and an exception is made where the flag is set.


    ###############


    possible solutions:


    for part 1) I'm not entirely sure honestly ๐Ÿค”


    for part 2)


    - add prop initialAlignment on field configs of text / rich text / textarea of the following shape:


    initialAlignment: {


    'ar': 'rtl'|'ltr'


    'en': 'rtl'|'ltr'


    }


    - field should receive the prop and set a data attribute on the html input element (maybe) according to the locale, that it can retrieve from useLocale.


    - sass for rtl should include two rules based on the data attribute to target the input element



    I hope I'm not missing something ๐Ÿคท

  • discord user avatar
    jmikrut
    Payload Team
    4 weeks ago

    so all of the above is great



    the terminology we use (which is basically just a way to refer to stuff honestly) is:



    - i18n refers to the actual admin UI languages (navigation, errors, button and field labels, etc)


    - localization refers to the data that the CMS stores



    so



    for i18n, i think there, we just need to apply the

    dir="rtl"

    to the HTML and then use SCSS to style all the i18n-specific text in the admin UI to go RTL



    but then for

    localization

    , we need to have a way to specify if the locale is an RTL locale or not. And if it is, then it would make sense to me to then force-style all of the text / textarea / rich text / etc. inputs themselves to also be RTL if that locale is being edited



    right now, our localization config is as follows:



    localization: {
      locales: string []
    }


    I'd say that we should adjust that property to take either a string, or an object of a new shape so we could do things like this:



    localization: {
      locales: [
        'en',
        {
          locale: 'myLocaleID',
          rtl: true,
      ]
    }


    that way the admin UI could look at the active locale being edited, and if it is

    rtl: true

    , then the inputs should render themselves

    rtl

    as well



    basically, i'm saying that the "flag" that @ibrahem is mentioning would go on the localization config, rather than the field config(s) themselves

  • default discord avatar
    ibrahem
    4 weeks ago

    @jmikrut I think it's better I rephrase what I said earlier: on the i18n plane, it's fairly straightforward, but no matter the dashboard language itself, the text fields still have two states that are dependant on the locale being edited + flag, the locale (if it's rtl) makes all text fields rtl except for those that have the flag. that's why the flag should be set on the field config itself because if the locale being edited is rtl, the text fields should be rtl regardless as default, only special cases need the flag. I'm not sure I'm articulating it the way I understand it but please let me know if I got the point across

  • discord user avatar
    jmikrut
    Payload Team
    4 weeks ago

    what are the special cases?



    is that going to be a common occurrence?



    seems to me like if you are editing in Persian locale, for example, then all text-based fields would be RTL

  • default discord avatar
    ibrahem
    4 weeks ago

    that's the point, the ui (text alignment of text fields) is dependant on the current locale being rtl not the i18n setting, so even then, the sass should apply to those fields only under the condition that the locale is rtl, the dashboard language is irrelevant

  • discord user avatar
    jmikrut
    Payload Team
    4 weeks ago

    thats why im saying to extend the localization config



    allowing you to detect if the locale being edited is RTL or not



    it would just be done on the locale level rather than the field level



    problem right now is that there is no way to identify which of your locales in your config are RTL and which are not

  • default discord avatar
    ibrahem
    4 weeks ago

    I understand and that's right, but the flags point is to opt out of this behavior for certain fields



    for example, a phone number

  • discord user avatar
    jmikrut
    Payload Team
    4 weeks ago

    ahhh yes now i understand



    that is the example i was looking for

  • default discord avatar
    ibrahem
    4 weeks ago

    serial numbers also

  • discord user avatar
    jmikrut
    Payload Team
    4 weeks ago

    BUT



    would those fields still need to be

    localized: true

    ?

  • default discord avatar
    ibrahem
    4 weeks ago

    I would've said email but there's a field for that

  • discord user avatar
    jmikrut
    Payload Team
    4 weeks ago

    i guess there could be cases where yes, i guess

  • default discord avatar
    ibrahem
    4 weeks ago

    yes, because it's not really localization if I only have the whole project set up in Arabic ๐Ÿ˜…

  • discord user avatar
    jmikrut
    Payload Team
    4 weeks ago

    hmm



    what if we were able to set RTL: true by default for all fields, without opting into localization?



    i guess that would still be kinda weird



    regardless this is a good discussion



    yeah i guess we could expose a flag

    field.admin.rtl: boolean


    so it would be probably both of our ideas



    1. set the flag on the locale in the localization config (all text-based fields respect rtl of locale being edited by default and render accordingly)


    2. look at the

    admin.rtl

    field as a way to "override" the built-in behavior

  • default discord avatar
    ibrahem
    4 weeks ago

    the default would be true

  • discord user avatar
    jmikrut
    Payload Team
    4 weeks ago

    yes

  • default discord avatar
    ibrahem
    4 weeks ago

    do we need flag on the locale?



    because it's really most cases

  • discord user avatar
    jmikrut
    Payload Team
    4 weeks ago

    well, the problem is, because our locales are just

    any string

    , they are not necessarily language / country codes

  • default discord avatar
    ibrahem
    4 weeks ago

    oh I guess that makes sense now



    I'm sorry for asking so many questions but I tried to start on it yesterday and I couldn't even get anything to work ๐Ÿ˜… do you guys have some guidelines or something on where to start? like a workflow?

  • discord user avatar
    dribbens
    Payload Team
    4 weeks ago

    In another discussion I floated the idea of allowing locales to be an option object so that we can have: { value: 'en', label: 'English' }


    Building on that work you could very easily add more properties like RTL.

  • discord user avatar
    jmikrut
    Payload Team
    4 weeks ago

    @dribbens VERY good call



    @ibrahem check out our Contributing guide:



    https://github.com/payloadcms/payload/blob/master/contributing.md
  • default discord avatar
    ibrahem
    4 weeks ago

    I read it again and I think it makes more sense now ๐Ÿ˜…, I'll try again later. thank you ๐Ÿ™



    is there anyone working on that so I can build on top of it or can I do that in the same pr?

  • discord user avatar
    dribbens
    Payload Team
    4 weeks ago

    There isn't any work started that I know of. You could absolutely jump on it.

  • default discord avatar
    ibrahem
    4 weeks ago

    @jmikrut @dribbens I'm running into an issue with the way i18n stores and retrieves the cookie, because of some race condition, I'm apparently setting the html dir (tried setting html lang also but didn't work) and it's persisting in the cookie, but when I refresh it's all reset, can you share some insight about the way i18n handles things?

  • discord user avatar
    dribbens
    Payload Team
    4 weeks ago

    The I18n provider is added in our Root component, I don't know how you would adjust the <html> tag of the document. Some more research is needed. How did you do what you have in the screen recording?

    https://github.com/payloadcms/payload/blob/5e029852060d6475eccada35ffbcdd0178d5e690/src/admin/Root.tsx
  • discord user avatar
    jmikrut
    Payload Team
    4 weeks ago

    just regular JS can target the html tag from anywhere within react app

  • discord user avatar
    dribbens
    Payload Team
    4 weeks ago

    I saw it in this article, but I thought it was too simple...

    https://medium.com/@saif.as/localization-react-i18-next-and-rtl-support-including-material-ui-to-a-react-project-eeab31817467


    function App()  {
        const { t, i18n } = useTranslation();
        const theme = useTheme();
        document.body.dir = i18n.dir();
    // ...
  • default discord avatar
    ibrahem
    4 weeks ago

    I actually used useInsertionEffect hook from react to change the tag before the browser paints anything so that I can keep it on the client and don't have to do anything server side



    but the problem is that I'm not sure how it works, it is imported from a provider component and I'm not sure when or where it works and what's it's scope, does it work on the client, the server or both? it keeps the html lang attribute as 'en' even when the language changes, and even when I change it manually, was that intentional?

  • default discord avatar
    fedoraman
    2 weeks ago

    I think locale switcher should be in the collection level (in Admin sidebar) where you can select the locale of the content instead of having it in the left side of the Admin dashboard, because it is for the language of the content not for the Admin UI and it should be a field that can be used to filter the collection list view.

Open the post
Continue the discussion in Discord
Like what we're doing?
Star us on GitHub!

Star

Connect with the Payload Community on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.