ionic-team / ionic-framework

A powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.
https://ionicframework.com
MIT License
51.09k stars 13.51k forks source link

Add Right To Left Support #5035

Closed mhartington closed 7 years ago

mhartington commented 8 years ago

From @mashaly100200 on December 30, 2015 17:24

kindly add support rtl to animation and the components

Copied from original issue: driftyco/ionic2#832

mhartington commented 8 years ago

From @adamdbradley on December 30, 2015 17:38

Yes this is on our roadmap to complete and we would love to get more feedback from experienced RTL dev's to help us point out where we need to improve. Would you be able to provide a checklist of certain parts of ionic2 that do not work well with RTL. Our goal would be to provide an additional RTL css file, and have any JS adjust accordingly depending if the html element has dir="rtl" or not. Thanks

mhartington commented 8 years ago

From @mashaly100200 on December 30, 2015 18:39

It's my pleasure to help ionic2 team to support RTL firest it's easy to watch what are the bad effects if we use rtl direction we can add this attr to html tag that will convert all website to to rtl

or we can use it in the body as a style like this style="direction:rtl" if ionic team plan to support rtl thay will need to add the target direction in App configurations , because the application will need to know what is the direction on the start up , and if the developer need to change the app language to rtl language in runtime then we should refresh all app (like native android,windows phone app , ios need to restart the application to change it's direction) now when i try to change ionic2 html direction i found that there are things aleady support rtl direction coz pure html konw how to deal with rtl direction but thare are things need to be support rtl direction first thing is animation i donn't know if ionic team do the animation with css or javascript code , in both cases all animation witch have rtl or ltr will need to add another animation direction , not only change varialbe but add another one coz many things will need to change I would like to provide assistance as i can to ionic team to help in this great library i know my English is not good , but i hope you understand my words :)
mhartington commented 8 years ago

From @mashaly100200 on December 30, 2015 18:44

plz change this goal " Our goal would be to provide an additional RTL css file " because we need the two direction in the same application , based on the user's choice , some time it will be in runtime

mhartington commented 8 years ago

From @adamdbradley on December 30, 2015 18:51

we need the two direction in the same application , based on the user's choice , some time it will be in runtime

Ionic itself will be able to dynamically add this css file for you, depending on the <html dir="rtl">

mhartington commented 8 years ago

From @mashaly100200 on December 30, 2015 19:23

these imgs from trying to change direction of onic-conference-app example if ionic team cover the rtl direction in this example i think it will be not less than 90% of rtl support

Image of Yaktocat

mhartington commented 8 years ago

From @mashaly100200 on December 30, 2015 19:26

Image of Yaktocat

mhartington commented 8 years ago

From @mashaly100200 on December 30, 2015 19:27

Image of Yaktocat

mhartington commented 8 years ago

From @mashaly100200 on December 30, 2015 20:21

any icon which are right,left,back or forward arrow like back-button icon will need this style { -webkit-transform: rotate(180deg); -moz-transform: rotate(180deg); -o-transform: rotate(180deg); -ms-transform: rotate(180deg); transform: rotate(180deg); }

mhartington commented 8 years ago

From @adamdbradley on December 31, 2015 4:27

So @brandyscarney had a good idea that we create all the RTL scss files within the repo and get them ready to be filled.

I was thinking that instead of dynamically adding another rtl css, we could have a default $rtl-support: false sass variable that can be updated in each app's sass variables. So in most cases the extra rtl css wouldn't be added to apps, but for those who require the rtl css they can set $rtl-support: true.

Then within our new rtl scss files, the css can be wrapped with @if $rtl-support. This way we can keep the css files separated and easier to edit, and provide rtl support out of the box. Think this will work @mashaly100200 ?

mhartington commented 8 years ago

From @mashaly100200 on December 31, 2015 11:48

yes load rtl dynamically is a good idea ,

let us start with animation , coz it may be need more effort

if your answer are yes for the previous three questions , then i can congratulate my self coz animation topic don't need any effort and full support rtl direction and ionic team deserve a very big thanks :)

mhartington commented 8 years ago

From @adamdbradley on January 1, 2016 1:53

This is the transition animation for ios: https://github.com/driftyco/ionic2/blob/master/ionic/animations/ios-transition.ts

Not sure if this should add logic for RTL, or if there should be a new animation instead. You can however add your own transition, and override the pageTransition config: https://github.com/driftyco/ionic2/blob/master/ionic/config/modes.ts#L24

mhartington commented 8 years ago

From @mashaly100200 on January 1, 2016 21:55

hi @adamdbradley , merry christmas

i finished a custom animation class which reverse the default animation class behavior depend on documen.dir
https://gist.github.com/mashaly100200/bf713f2b558285322155 i tested it , and i will test it in real projects soon (inshaa allah)

also i finished some of css classes that was need to be reversed https://gist.github.com/mashaly100200/dc23529e570034b0dfb9

and if i face more classes need to be reversed , i will add it to this file until i finish one or two real project

also rtl need these configurations in app constructor https://gist.github.com/mashaly100200/692160b036422d7b018c

i was trying to add all configuration in one place so i found that i can add all things in the app contractor

hope these things can help to make ionic2 fully support rtl

Please feel free to add any corrections or suggestions .

mhartington commented 8 years ago

From @adamdbradley on January 2, 2016 3:2

Cool, so it looks like the RTL transition is pretty darn close to the LTR transition, which makes me think it should be an isRTL option that gets passed into the transition's options and we only have one transition. I can update ionic so it has a common isRTL property that can be referenced throughout the app (with webworkers we want to avoid doing document reads within ionic's logic).

mhartington commented 8 years ago

From @adamdbradley on January 2, 2016 3:36

Added isRTL() to Platform: https://github.com/driftyco/ionic2/blob/0b4b8628bf87cabab92d6563bf9878db8b86c885/ionic/components/modal/test/basic/index.ts#L16

mhartington commented 8 years ago

From @adamdbradley on January 2, 2016 3:58

All transitions are now passed isRTL within the opts: https://github.com/driftyco/ionic2/blob/da986a5fb0ee2c7660ad4494731b5fe98b393812/ionic/components/nav/nav-controller.ts#L798

So now the ios-transition can add the logic for RTL transitions.

mhartington commented 8 years ago

From @adamdbradley on January 2, 2016 4:38

Added how we can include RTL css so it correctly builds within ionic.css (which includes both md and ios css) and ionic.ios.css (just ios). The thought is that apps which want to include both RTL and LTR css within the same file can set $include-rtl: true in their sass variables, otherwise it'll default to only include LTR css. https://github.com/driftyco/ionic2/blob/f38ad4a7d2d8c527a3bc64fd8569b11eb659c290/ionic/components/item/item.ios.scss#L231

mhartington commented 8 years ago

From @MatanYed on January 6, 2016 18:14

Just you to know: RTL apps in iOS are partly LTR: Primary navbar button side is left, side menu is left, transition animation is from left to right.

mhartington commented 8 years ago

From @adamdbradley on January 7, 2016 16:41

Added new methods to platform to get and set language and direction: https://github.com/driftyco/ionic2/commit/942bd9b93b97a88554aafc9972c1c2d86de9273f

mhartington commented 8 years ago

From @mashaly100200 on January 12, 2016 21:2

update for anyone flow this topic replace config.set('backButtonIcon', 'ion-ios-arrow-forward'); with config.set('backButtonIcon', 'arrow-forward');

also i update the animation class https://gist.github.com/mashaly100200/bf713f2b558285322155

mohessaid commented 8 years ago

I have been working on this problem on a moodle mobile app for our company and we need the app to support English and Arabic in the same time, so it's not a problem of switching the direction of everything to RTL but it need to be in run time. I used some tweaks at the beginning using ng-if and some broadcasting through the rootscope in the app, but whenever the user change the language, the app needs a reload, things not working at all with this method. Three days ago, I started fighting with Ionic (it becomes an universal problem :) ), The moodle team open issues at the moment but I don't think they will look at them. I am not using Ionic 2 but my approach in this problem is very simple, with ionic side attribute in ionic directive (I think most concerned directive with the RTL problem has this attribute) will make the solution easier than it looks. I am trying to override the directive to add binding to the side attribute because now, it doesn't then add some alignments to the rest of the content using css in the app.scss, and with the help of angular-translate and the current implementation of the moodle app, update the left in word in classes and side to right and vise versa whenever the language change. I am still implementing it at the moment I hope it will work (it must work anyway).

wis commented 8 years ago

after adding dir="rtl" to index.html, the rendering of elements will start from right, that affects the look of some elements, like the segment button. to fix it I changed

  .segment-button:first-of-type {
    border-radius: 4px 0 4px 0;
    margin-left: 0; }
  .segment-button:not(:first-of-type) {
    border-left-width: 0; }
  .segment-button:last-of-type {
    border-left-width: 0;
    border-radius: 4px 0 0 4px;
    margin-left: 0; }

to

  .segment-button:first-of-type {
    border-radius: 0 4px 4px 0;
    margin-right: 0; }
  .segment-button:not(:first-of-type) {
    border-right-width: 0; }
  .segment-button:last-of-type {
    border-right-width: 0;
    border-radius: 4px 0 0 4px;
    margin-right: 0; }

The Nav animation has to be opposite to the app direction, from left for RTL apps and from the right for LTR apps. to fix it I did this: changed var OFF_RIGHT = '99.5%'; to var OFF_RIGHT = '-99.5%'; and var OFF_LEFT = '-33%'; to var OFF_LEFT = '33%'; and

                if (backDirection) {
                    // leaving content, back direction
                    leavingContent
                        .before.clearStyles([OPACITY])
                        .fromTo(TRANSLATEX, CENTER, '100%');
                }

to

                if (backDirection) {
                    // leaving content, back direction
                    leavingContent
                        .before.clearStyles([OPACITY])
                        .fromTo(TRANSLATEX, CENTER, '-100%');
                }

in ionic-angular/transitions/transition-ios

and for the back element in the Nav bar, I put the icon before the text, and changed the icon to forward.

@App({
    config: {
        backButtonText: 'الرجوع', // this is arabic or whatever
        backButtonIcon:'ios-arrow-forward'
        //          | ion-ios-arrow-back     | ion-md-arrow-back    
    } // http://ionicframework.com/docs/v2/api/config/Config/
})

the placeholder in the searchbar input can be fixed by doing these changes (change everything left to right)

.searchbar-search-icon {
  width: 14px;
  height: 14px;
  background-image: url("data:image/svg+xml;charset=utf-8,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2013%2013'><path%20fill='rgba(0,%200,%200,%200.5)'%20d='M5,1c2.2,0,4,1.8,4,4S7.2,9,5,9S1,7.2,1,5S2.8,1,5,1%20M5,0C2.2,0,0,2.2,0,5s2.2,5,5,5s5-2.2,5-5S7.8,0,5,0%20L5,0z'/><line%20stroke='rgba(0,%200,%200,%200.5)'%20stroke-miterlimit='10'%20x1='12.6'%20y1='12.6'%20x2='8.2'%20y2='8.2'/></svg>");
  background-size: 13px;
  background-repeat: no-repeat;
  position: absolute;
  left: 9px;
  top: 9px;
  margin-left: calc(50% - 60px);
  -webkit-transition: all 400ms cubic-bezier(0.25, 0.45, 0.05, 1);
  transition: all 400ms cubic-bezier(0.25, 0.45, 0.05, 1); }

.searchbar-input {
  height: 3rem;
  line-height: 3rem;
  padding: 0 28px;
  font-size: 1.4rem;
  font-weight: 400;
  border-radius: 5px;
  color: #000;
  background-color: #FFFFFF;
  padding-left: calc(50% - 28px);
  -webkit-transition: all 400ms cubic-bezier(0.25, 0.45, 0.05, 1);
  transition: all 400ms cubic-bezier(0.25, 0.45, 0.05, 1); }
  .searchbar-input::-moz-placeholder {
    color: rgba(0, 0, 0, 0.5); }
  .searchbar-input:-ms-input-placeholder {
    color: rgba(0, 0, 0, 0.5); }
  .searchbar-input::-webkit-input-placeholder {
    color: rgba(0, 0, 0, 0.5);
    text-indent: 0; }

to

.searchbar-search-icon {
  width: 14px;
  height: 14px;
  background-image: url("data:image/svg+xml;charset=utf-8,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2013%2013'><path%20fill='rgba(0,%200,%200,%200.5)'%20d='M5,1c2.2,0,4,1.8,4,4S7.2,9,5,9S1,7.2,1,5S2.8,1,5,1%20M5,0C2.2,0,0,2.2,0,5s2.2,5,5,5s5-2.2,5-5S7.8,0,5,0%20L5,0z'/><line%20stroke='rgba(0,%200,%200,%200.5)'%20stroke-miterlimit='10'%20x1='12.6'%20y1='12.6'%20x2='8.2'%20y2='8.2'/></svg>");
  background-size: 13px;
  background-repeat: no-repeat;
  position: absolute;
  right: 9px;
  top: 9px;
  margin-right: calc(50% - 60px);
  -webkit-transition: all 400ms cubic-bezier(0.25, 0.45, 0.05, 1);
  transition: all 400ms cubic-bezier(0.25, 0.45, 0.05, 1); }

.searchbar-input {
  height: 3rem;
  line-height: 3rem;
  padding: 0 28px;
  font-size: 1.4rem;
  font-weight: 400;
  border-radius: 5px;
  color: #000;
  background-color: #FFFFFF;
  padding-right: calc(50% - 28px);
  -webkit-transition: all 400ms cubic-bezier(0.25, 0.45, 0.05, 1);
  transition: all 400ms cubic-bezier(0.25, 0.45, 0.05, 1); }
  .searchbar-input::-moz-placeholder {
    color: rgba(0, 0, 0, 0.5); }
  .searchbar-input:-ms-input-placeholder {
    color: rgba(0, 0, 0, 0.5); }
  .searchbar-input::-webkit-input-placeholder {
    color: rgba(0, 0, 0, 0.5);
    text-indent: 0; }
MuhammadRashed commented 8 years ago

in the file: ionic.bundle.js change the code:


setTranslateX: ionic.animationFrameThrottle(function(amount) {
var xTransform = content.offsetX + amount;
$element[0].style[ionic.CSS.TRANSFORM] = 'translate3d(' + xTransform + 'px,0,0)';

change it to be:


setTranslateX: ionic.animationFrameThrottle(function(amount) {
var xTransform = content.offsetX + amount;
if (content.offsetX > 0)
{
      xTransform = amount;
}
$element[0].style[ionic.CSS.TRANSFORM] = 'translate3d(' + xTransform + 'px,0,0)';

I know this is not good solution but I had to.


and I added these css:


   a , h1 , h2 , span , div{
      text-align: right;
        }

        .title.title-left.header-item{
            left : 0 !important;
        }
label.item,
ion-nav-buttons,
ion-header-bar{
    direction: rtl;
}

.item-checkbox {
    padding-right: 60px;
}

.ion-android-arrow-back:before {
  content: ""; }

.ion-android-arrow-forward:before {
  content: ""; }

and made the menu on right :


<ion-side-menus enable-menu-with-back-views="false" >

    <ion-side-menu side="right" expose-aside-when="large">
        <ion-header-bar class="bar-positive">
            <h1 class="title">Menu</h1>
        </ion-header-bar>
        <ion-content>
            <ion-list>
                <ion-item menu-close ng-click="login()">
                    Login
                </ion-item>

            </ion-list>
        </ion-content>
    </ion-side-menu>

      <ion-side-menu-content>
        <ion-nav-bar class="bar-positive">

            <ion-nav-back-button>
            </ion-nav-back-button>
            <ion-nav-buttons side="right">
                <button class="button button-icon button-clear ion-navicon" menu-toggle="right"></button>
            </ion-nav-buttons>

        </ion-nav-bar>
        <ion-nav-view name="menuContent"></ion-nav-view>
    </ion-side-menu-content>

</ion-side-menus>
alaa-alshamy commented 8 years ago

yeah that's what we are waiting for , and that's will be awesome

thanks ionic team

go ahead :+1:

sijav commented 8 years ago

EDIT: nevermind this has already been fixed

hemedani commented 8 years ago

ion-item-sliding needs to be swipe-left option for rtl version like this :

        <ion-item-sliding swipe-left>
            <ion-item>
                <ion-avatar item-right>
                    <img src="img/slimer.png">
                </ion-avatar>
                <h2>Slimer</h2>
            </ion-item>
            <ion-item-options>
                <button primary>
                    <ion-icon name="text"></ion-icon>
                    Text
                </button>
                <button secondary>
                    <ion-icon name="call"></ion-icon>
                    Call
                </button>
            </ion-item-options>
        </ion-item-sliding>
rejeeshrajan10 commented 8 years ago

Hi, I am working on ionic 2.0. how can i reduce the left navigation width.

msoni11 commented 8 years ago

How are you handling Gestures with rtl in v2?

I need to fix it for iOS platform in ionic v1. Not sure how iPhone capture swipe-right in RTL.

I was able to change the direction of sidemenu and swiping direction in rtl. https://github.com/msoni11/ionic/releases/tag/v1.1.1-rtl https://github.com/msoni11/ionic-bower/releases/tag/v1.1.1-rtl

MatanYadaev commented 8 years ago

When RTL feature will be publish, it would be able to change it after running the app (i mean live change between ltr to rtl? Just like native apps that have change language page in app.

msoni11 commented 8 years ago

@MatanYed : Yes it will. It must actually. It's pretty straight in hybrid app by just changing direction and text-align using CSS.

devoraf commented 8 years ago

@mhartington : when using floating ion-label with RTL direction, the floating label does not being aligned to the right, but somewhere in the middle, when typing text in the input field. is there any solution for it?

<ion-list dir="rtl"> <ion-item> <ion-label floating >{{ usrTitle }}</ion-label> <ion-input type="text" [(ngModel)]="usrValue"></ion-input> </ion-item> <ion-item> <ion-label floating >{{ pswTitle }}</ion-label> <ion-input type="password" [(ngModel)]="pswValue"></ion-input> </ion-item></ion-list>

floating

royipressburger commented 8 years ago

+1

trakhimenok commented 8 years ago

@royipressburger (regards "+1") - there is "thumb up" emoticon & "Subscribe" button if you want to support or follow.

devoraf commented 8 years ago

@mhartington, @msoni11: any answer? i'm really stuck with it.

msoni11 commented 8 years ago

@devoraf : I'm not sure which version of ionic you are using. In ionic v1 I've played with RTL css and form element worked for me.

devoraf commented 8 years ago

@msoni11: ionic v2. did this particular floating behavior worked well for you?

msoni11 commented 8 years ago

@devoraf : I haven't tried v2 yet. My app has a lot of code written in v1 so I hacked v1 to allow RTL.

devoraf commented 8 years ago

@msoni11 : can you please attach sample css that might effect the alignment/direction of the floating label?

RezaHaidari commented 8 years ago

+1

msoni11 commented 8 years ago

@devoraf : Sorry but I haven't used floating labels. I've used these form elements and made it right aligned for RTL.

loolooii commented 8 years ago

I don't know if it has been stated, but even navigating through pages gets messed up when dir="rtl" is added to <html> tag. In Ionic 2 a lot of components I used did not support it and I ended up switching back to Ionic 1. Right now I can do something about components and haven't come across any that are a problem for me, but the navigation gets messed up and I get white screens or laggy pages. When I remove dir="rtl" everything works perfectly.

Am I doing something wrong or $state.go() actually does not work with rtl at all?

msoni11 commented 8 years ago

@loolooii : You have to add css to make ionic 1 work for RTL

.rtl, html[dir=rtl] {
  direction: rtl;
  text-align: right;
}

/** To fix empty page issue in rtl. **/
.rtl .click-block-hide {
  @include translate3d(9999px, 0, 0);
}

Use this ionic rtl version https://github.com/msoni11/ionic/releases/tag/v1.1.1-rtl and you will be able to swipe right in RTL.

loolooii commented 8 years ago

@msoni11 Thanks! Awesome stuff.

msoni11 commented 8 years ago

@loolooii : :) I've written a small post also where I mentioned how actual implementation will work in ionic app. Check here

MatanYadaev commented 8 years ago

Any update about the RTL issue?

OmarHassan25 commented 7 years ago

Any updates regarding this ? , also why ionic team removed it from beta 12 ?

Khalid-Nowaf commented 7 years ago

I think if we list all the RTL issues from developer feedbacks, we can contribute and fix them one by one, eventually, we will end up with full RTL support.

AmitMY commented 7 years ago

RTL is really important! Is there a timeframe?

msoni11 commented 7 years ago

@AmitMY Not sure about ionic2 but for ionic1 one of my live app is running pretty well with RTL support.

AmitMY commented 7 years ago

@msoni11 Thanks. I am talking about Ionic2.

Khalid-Nowaf commented 7 years ago

@AmitMY @msoni11 I will work soon in a mid-size project using IONIC 2, then I will spot all RTL Issues if any .