Repository navigation
fix(rtl): respect dir of ancestor elements throughout components - #31459
OS-jacobbell wants to merge 16 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
dir setting of ancestor elements throughout components
dir setting of ancestor elements throughout componentsdir of ancestor elements throughout components
ShaneK
left a comment
There was a problem hiding this comment.
Nice sweep of this! Just a few comments inline, though I'd want the test coverage added before it goes in.
Co-authored-by: Shane <shane.king@outsystems.com>
ShaneK
left a comment
There was a problem hiding this comment.
Thanks for adding the tests and taking the suggestions! Most of them pass on main too though, so they aren't covering the change yet, and CI is red on the new popover one. I've left comments inline.
ShaneK
left a comment
There was a problem hiding this comment.
Really close! Just a few more comments inline.
| * hierarchy. Copy the current direction onto this element so that child | ||
| * elements can match. | ||
| */ | ||
| el.dir = isRTL(el) ? 'rtl' : 'ltr'; |
There was a problem hiding this comment.
This dir never gets removed on dismiss, and isRTL checks the host's own dir first, so every present after the first one reads back whatever was written the first time. If an app switches the document from ltr to rtl between presents, the popover gets positioned for rtl but its content still renders ltr, where on main the content follows the document. It also permanently replaces a dir="auto" someone set on the ion-popover.
This seems like a big issue since runtime language switching works on main today. Setting it only when the host doesn't already have a dir, and removing it on dismiss, fixed every case I tried without breaking the position tests:
if (!el.hasAttribute('dir')) {
el.setAttribute('dir', isRTL(el) ? 'rtl' : 'ltr');
this.dirSetOnPresent = true;
}with a private dirSetOnPresent = false; field, and this in dismiss() right after detachComponent:
if (this.dirSetOnPresent) {
this.el.removeAttribute('dir');
this.dirSetOnPresent = false;
}| await expect(nextPrevIcons.first()).toHaveClass(/flip-rtl/); | ||
| await expect(nextPrevIcons.last()).toHaveClass(/flip-rtl/); |
There was a problem hiding this comment.
| await expect(nextPrevIcons.first()).toHaveClass(/flip-rtl/); | |
| await expect(nextPrevIcons.last()).toHaveClass(/flip-rtl/); | |
| await expect(nextPrevIcons.first()).toHaveClass(/icon-rtl/); | |
| await expect(nextPrevIcons.last()).toHaveClass(/icon-rtl/); |
This one passes on main too, because ion-icon adds flip-rtl whenever flipRtl is set, whatever the direction is. The class that follows direction is icon-rtl, which is missing on main here and present with your change. The test above has the same gap, but it was already there, so up to you on that one. The describe title and its comment also still say RTL is set on the component.
| }; | ||
|
|
||
| const CALC_STYLE = `calc(calc(3 / var(--ion-grid-columns, 12)) * 100%)`; | ||
| const COL_PARAMS = `<ion-col offset="3" push="2" pull="1"></ion-col>`; |
There was a problem hiding this comment.
Following up on push/pull from last round, the margins are covered now, but nothing asserts left or right, so hardcoding pull to right and push to left still leaves all three green. Something like this catches it and fails on main:
const cols = (n: number) => `calc(calc(${n} / var(--ion-grid-columns, 12)) * 100%)`;
it('should mirror push and pull when an ancestor declares rtl', async () => {
const col = await newCol(`<div dir="rtl"><div>${COL_PARAMS}</div></div>`);
expect(col.style.right).toBe(cols(2));
expect(col.style.left).toBe(cols(1));
});plus the reverse for the ltr-in-an-rtl-document case.
Also, this constant already includes the <ion-col> tags, and the tests wrap it in another <ion-col ...>, so <ion-col gets parsed as an attribute name and a stray > is left in the body. It only works by accident. I'd make this just the attributes.
| </ion-popover> | ||
| </div> | ||
|
|
||
| <div class="grid-item" , dir="rtl"> |
There was a problem hiding this comment.
| <div class="grid-item" , dir="rtl"> | |
| <div class="grid-item" dir="rtl"> |
Stray comma here.
Issue number: internal
What is the current behavior?
Some components check
document.dir === 'rtl'to determine whether to be left-to-right or right-to-left.What is the new behavior?
isRTL(this.el). This way, any element in the parent chain can define RTL, not just the root document element.isRTL.Does this introduce a breaking change?