Skip to content

Commit

Permalink
fix(icon): add :dir fallback (#1223)
Browse files Browse the repository at this point in the history
  • Loading branch information
liamdebeasi authored May 30, 2023
1 parent 3992b01 commit 06fa4a5
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 3 deletions.
39 changes: 39 additions & 0 deletions src/components/icon/icon.css
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,54 @@ svg {
/* Icon RTL
* -----------------------------------------------------------
*/

/**
* Safari <16.4 incorrectly reports
* that it supports :dir(rtl) when it does not.
* This @supports statement lets us target
* WebKit browsers to apply the RTL fallback.
* -webkit-named-image only exists on WebKit.
* For WebKit browsers that do support :dir(rtl)
* (i.e. Safari >= 16.4) then the :dir(rtl)
* code farther down on the page will take
* effect and override this fallback.
*/
@supports (background: -webkit-named-image(i)) {
:host(.icon-rtl) .icon-inner {
transform: scaleX(-1);
}
}

/**
* Fallback for browsers that support
* neither :host-context nor :dir.
* The icon will not react to dir
* changes, but it will at least
* respect the dir on component load.
*/
@supports not selector(:dir(rtl)) and selector(:host-context([dir='rtl'])) {
:host(.icon-rtl) .icon-inner {
transform: scaleX(-1);
}
}

/* :host-context is supported in chromium; :dir is supported in safari & firefox */
:host(.flip-rtl):host-context([dir='rtl']) .icon-inner {
transform: scaleX(-1);
}

@supports selector(:dir(rtl)) {
:host(.flip-rtl:dir(rtl)) .icon-inner {
transform: scaleX(-1);
}
/**
* This is needed for WebKit otherwise the fallback
* will always cause the icon to be flipped if the document
* loads in RTL.
*/
:host(.flip-rtl:dir(ltr)) .icon-inner {
transform: scaleX(1);
}
}

/* Icon Sizes
Expand Down
5 changes: 3 additions & 2 deletions src/components/icon/icon.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Build, Component, Element, Host, Prop, State, Watch, h } from '@stencil/core';
import { getSvgContent, ioniconContent } from './request';
import { getName, getUrl, inheritAttributes } from './utils';
import { getName, getUrl, inheritAttributes, isRTL } from './utils';

@Component({
tag: 'ion-icon',
Expand Down Expand Up @@ -145,7 +145,7 @@ export class Icon {
}

render() {
const { flipRtl, iconName, inheritedAttributes } = this;
const { flipRtl, iconName, inheritedAttributes, el } = this;
const mode = this.mode || 'md';
// we have designated that arrows & chevrons should automatically flip (unless flip-rtl is set to false) because "back" is left in ltr and right in rtl, and "forward" is the opposite
const shouldAutoFlip = iconName
Expand All @@ -162,6 +162,7 @@ export class Icon {
...createColorClasses(this.color),
[`icon-${this.size}`]: !!this.size,
'flip-rtl': shouldBeFlippable,
'icon-rtl': shouldBeFlippable && isRTL(el)
}}
{...inheritedAttributes}
>
Expand Down
2 changes: 1 addition & 1 deletion src/components/icon/test/icon.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('icon', () => {
});

expect(root).toEqualHtml(`
<ion-icon class="md flip-rtl" name="chevron-forward" role="img" aria-hidden="true">
<ion-icon class="md flip-rtl icon-rtl" name="chevron-forward" role="img" aria-hidden="true">
<mock:shadow-root>
<div class="icon-inner"></div>
</mock:shadow-root>
Expand Down
14 changes: 14 additions & 0 deletions src/components/icon/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,17 @@ export const inheritAttributes = (el: HTMLElement, attributes: string[] = []) =>

return attributeObject;
}

/**
* Returns `true` if the document or host element
* has a `dir` set to `rtl`. The host value will always
* take priority over the root document value.
*/
export const isRTL = (hostEl?: Pick<HTMLElement, 'dir'>) => {
if (hostEl) {
if (hostEl.dir !== '') {
return hostEl.dir.toLowerCase() === 'rtl';
}
}
return document?.dir.toLowerCase() === 'rtl';
};

0 comments on commit 06fa4a5

Please sign in to comment.