Actual Behavior:
CodePen (or steps to reproduce the issue): *
AngularJS Versions: *
AngularJS Version: 1.5.5AngularJS Material Version: 1.1.5Additional Information:
I am able to reproduce this in the CodePen on Chrome, Windows 10.
I found the main reason why this is happening. It is caused by the way the RTL mode is being detected.
tabsController is checking if RTL applies by calling a bidi method from the mdUtil.
This is the check in the bidi method:
var ltr = !($document[0].dir == 'rtl' || $document[0].body.dir == 'rtl');
As you can see it expects the whole document to be RTL not only the element you want to test.
When you inspect the bottom part of the CodePen (the one showing you the demo) and add dir="rtl" into the body or html of that iframe, it will start behaving properly:
<body dir="rtl">
or
<html dir="rtl">
The question is, can this be totally normal to have just an element within the web page as RTL but the rest being LTR? I am not sure how common it is. If that is quite possible, the RTL check in the mdUtil should be changed then or a different way of detecting the RTL should be implemented.
bidi - https://github.com/angular/material/blob/master/src/core/util/util.js#L90
isRtl - https://github.com/angular/material/blob/master/src/components/tabs/js/tabsController.js#L928
@marosoft are you only seeing this in CodePen then? Or is this affecting your actual production application?
Based on the HTMLElement.dir docs it looks like the dir attribute can be applied to any DOM element.
But then there is also the Document.dir which applies to the whole document.
It looks like the HTMLElement.dir works as an override to the Document.dir. There also appears to be another type of override via the CSS direction property.
I can't seem to find any AngularJS Material documentation on how to use bidi. But it's clear from the code that we currently only support applying dir to the html or body elements.
Here's an updated CodePen where I apply dir="rtl" to the body and it appears to resolve this issue.
I think that it would make sense to update the $mdUtil.bidi() function to check the passed in element's dir attribute in addition to the document and body. Then the tabs isRtl() function could pass in the tabs element. However, I want to make sure that there is a genuine need for supporting this use case before moving forward.
@Splaktar I found this issue and I thought it would be good to investigate where the problem is.
I do not have any production apps with RTL support. So I am not the best person to know how this should be used.
Intuition tells me that it should be handled on the element level. I agree that bidi function should be changed.
I remember seeing other component implementing its own checks rather then using bidi function too.
It looks like the whole codebase should be checked and one standard way should be followed.
@Splaktar I refactored the code a bit to use a standard approach to checking the text direction.
I created one function that checks if the text is RTL or not. This allows to use dir attribute on the component tag too.
It is not perfect. In some cases you need to add a dir attribute on the parent tag too as you can see in a virtual repeat issue #9754.
Please see the CodePen and you can see my commit above too.
I can create a PR if this is fine with you.
@marosoft sorry for the delay. That looks very interesting! I have a few minor syntax and styling review comments, but otherwise it looks good. Please open the PR!
Most helpful comment
@Splaktar I refactored the code a bit to use a standard approach to checking the text direction.
I created one function that checks if the text is RTL or not. This allows to use
dirattribute on the component tag too.It is not perfect. In some cases you need to add a
dirattribute on the parent tag too as you can see in a virtual repeat issue #9754.Please see the CodePen and you can see my commit above too.
I can create a PR if this is fine with you.