diff --git a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-ios-rtl-Mobile-Firefox-linux.png b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-ios-rtl-Mobile-Firefox-linux.png index 509fc18de6..5911fa5e1c 100644 Binary files a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-ios-rtl-Mobile-Firefox-linux.png and b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-ios-rtl-Mobile-Firefox-linux.png differ diff --git a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-ios-rtl-Mobile-Safari-linux.png b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-ios-rtl-Mobile-Safari-linux.png index 655f4423bc..b1843a2b09 100644 Binary files a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-ios-rtl-Mobile-Safari-linux.png and b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-ios-rtl-Mobile-Safari-linux.png differ diff --git a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-md-rtl-Mobile-Firefox-linux.png b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-md-rtl-Mobile-Firefox-linux.png index 76b19a0830..9a1cb20106 100644 Binary files a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-md-rtl-Mobile-Firefox-linux.png and b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-md-rtl-Mobile-Firefox-linux.png differ diff --git a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-md-rtl-Mobile-Safari-linux.png b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-md-rtl-Mobile-Safari-linux.png index 7d64c60606..5f9f0e9aaa 100644 Binary files a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-md-rtl-Mobile-Safari-linux.png and b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-md-rtl-Mobile-Safari-linux.png differ diff --git a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-ios-rtl-Mobile-Firefox-linux.png b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-ios-rtl-Mobile-Firefox-linux.png index 3a3b396e0e..937d38ec8c 100644 Binary files a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-ios-rtl-Mobile-Firefox-linux.png and b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-ios-rtl-Mobile-Firefox-linux.png differ diff --git a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-ios-rtl-Mobile-Safari-linux.png b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-ios-rtl-Mobile-Safari-linux.png index f23b06ab64..29cc9bcb0f 100644 Binary files a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-ios-rtl-Mobile-Safari-linux.png and b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-ios-rtl-Mobile-Safari-linux.png differ diff --git a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-md-rtl-Mobile-Firefox-linux.png b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-md-rtl-Mobile-Firefox-linux.png index b9147d78ad..9a60e5f2b0 100644 Binary files a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-md-rtl-Mobile-Firefox-linux.png and b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-md-rtl-Mobile-Firefox-linux.png differ diff --git a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-md-rtl-Mobile-Safari-linux.png b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-md-rtl-Mobile-Safari-linux.png index 1a6d83bfad..875a045fff 100644 Binary files a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-md-rtl-Mobile-Safari-linux.png and b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-md-rtl-Mobile-Safari-linux.png differ diff --git a/core/src/themes/ionic.functions.string.scss b/core/src/themes/ionic.functions.string.scss index 098a2e9f73..ea3da90c5e 100644 --- a/core/src/themes/ionic.functions.string.scss +++ b/core/src/themes/ionic.functions.string.scss @@ -85,9 +85,15 @@ // Add Root Selector // -------------------------------------------------------------------------------- // Adds a root selector using host based on the selector passed +// $root: The selector that needs to be updated to include the $addHostSelector. +// - Example: ion-button +// $addHostSelector: The selector that is used to add the host to the $root selector. +// - Example: [dir=rtl] +// $useHostContext: Whether to use host-context or not. Defaults to true. // -------------------------------------------------------------------------------- -@function add-root-selector($root, $addHostSelector) { + +@function add-root-selector($root, $addHostSelector, $useHostContext: true) { $selectors: str-split($root, ","); $list: (); @@ -95,14 +101,21 @@ @each $selector in $selectors { // If the selector contains :host( it means it is targeting a class on the host // element so we need to change how we target it: + // Example with `useHostContext=true` // @include add-root-selector(":host(.fixed)", "[dir=rtl]") // --> :host-context([dir=rtl]):host(.fixed) // --> :host-context([dir=rtl]).fixed + // --- + // Example with `useHostContext=false` + // @include add-root(":host(.fixed)", ":dir(rtl)", false) + // --> :host(.fixed:dir(rtl)) @if str-contains($selector, ":host(") { - // @include add-root-selector(":host(.fixed)", "[dir=rtl]") - // --> :host-context([dir=rtl]):host(.fixed) - $shadow-element: str-replace($selector, ":host(", ":host-context(#{$addHostSelector}):host("); - $list: append($list, $shadow-element, comma); + @if $useHostContext { + // @include add-root-selector(":host(.fixed)", "[dir=rtl]") + // --> :host-context([dir=rtl]):host(.fixed) + $shadow-element: str-replace($selector, ":host(", ":host-context(#{$addHostSelector}):host("); + $list: append($list, $shadow-element, comma); + } $new-element: (); $elements: str-split($selector, " "); @@ -117,19 +130,28 @@ $scoped-element: str-replace($scoped-element, ")", ""); $scoped-element: str-replace($scoped-element, ":host(", ""); - // Add the class back inside of host with the rtl selector: - // .fixed -> :host-context([dir=rtl]).fixed - $scoped-element: str-replace($scoped-element, $scoped-element, ":host-context(#{$addHostSelector})#{$scoped-element}"); - + // Add the class back inside of host with the addHostSelector: + @if $useHostContext { + // .fixed -> :host-context([dir=rtl]).fixed + $scoped-element: str-replace($scoped-element, $scoped-element, ":host-context(#{$addHostSelector})#{$scoped-element}"); + } @else { + // .fixed -> :host(.fixed:dir(rtl)) + $scoped-element: str-replace($scoped-element, $scoped-element, ":host(#{$scoped-element}#{$addHostSelector})"); + } + // @include add-root-selector(":host(.fixed)", "[dir=rtl]") // --> :host-context([dir=rtl]).fixed + // @include add-root(":host(.fixed)", ":dir(rtl)", false) + // --> :host(.fixed:dir(rtl)) $new-element: append($new-element, $scoped-element, space); } @else { - // Add back any selectors that followed the host after transforming the - // first selector: - // :host(.fixed) ::slotted(ion-icon) + // Add back any selectors that followed the host + // after transforming the first selector: + // @include add-root-selector(":host(.fixed) ::slotted(ion-icon)", "[dir=rtl]") // --> :host-context([dir=rtl]):host(.fixed) ::slotted(ion-icon) // --> :host-context([dir=rtl]).fixed ::slotted(ion-icon) + // @include add-root(":host(.fixed) ::slotted(ion-icon)", ":dir(rtl)", false) + // --> :host(.fixed:dir(rtl)) ::slotted(ion-icon) $new-element: append($new-element, $element, space); } } @@ -140,24 +162,38 @@ // element so we can change it to look for host-context // @include add-root-selector(":host", "[dir=rtl]") // --> :host-context([dir=rtl]) - // --> :host:dir(rtl) + // @include add-root(":host", ":dir(rtl)", false) + // --> :host(:dir(rtl)) } @else if str-contains($selector, ":host") { $new-element: (); $elements: str-split($selector, " "); @each $element in $elements { @if str-contains($element, ":host") { + $updated-element: ''; + // Replace the :host with the addHostSelector: - // :host -> :host-context([dir=rtl]) - $updated-element: str-replace($element, ":host", ":host-context(#{$addHostSelector})"); + @if $useHostContext { + // :host -> :host-context([dir=rtl]) + $updated-element: str-replace($element, ":host", ":host-context(#{$addHostSelector})"); + } @else { + // :host -> :host(:dir(rtl)) + $updated-element: str-replace($element, ":host", ":host(#{$addHostSelector})"); + } // Add the final selector after all transformations: - // :host -> :host-context([dir=rtl]) + // @include add-root-selector(":host", "[dir=rtl]") + // --> :host-context([dir=rtl]) + // @include add-root(":host", ":dir(rtl)", false) + // --> :host(:dir(rtl)) $new-element: append($new-element, $updated-element, space); } @else { - // Add back any selectors that followed the host after transforming the - // first selector: - // :host ::slotted(ion-icon) -> :host-context([dir=rtl]) ::slotted(ion-icon) + // Add back any selectors that followed the host + // after transforming the first selector: + // @include add-root-selector(":host ::slotted(ion-icon)", "[dir=rtl]") + // --> :host-context([dir=rtl]) ::slotted(ion-icon) + // @include add-root(":host ::slotted(ion-icon)", ":dir(rtl)", false) + // --> :host(:dir(rtl)) ::slotted(ion-icon) $new-element: append($new-element, $element, space); } } @@ -168,9 +204,15 @@ // @include add-root-selector("ion-component", "[dir=rtl]") // --> :host-context([dir=rtl]) ion-component // --> [dir=rtl] ion-component + // @include add-root("ion-component", ":dir(rtl)", false) + // --> ion-component:dir(rtl) } @else { - $list: append($list, "#{$addHostSelector} #{$selector}", comma); - $list: append($list, ":host-context(#{$addHostSelector}) #{$selector}", comma); + @if ($useHostContext) { + $list: append($list, ":host-context(#{$addHostSelector}) #{$selector}", comma); + $list: append($list, "#{$addHostSelector} #{$selector}", comma); + } @else { + $list: append($list, "#{$selector}#{$addHostSelector}", comma); + } } } diff --git a/core/src/themes/ionic.mixins.scss b/core/src/themes/ionic.mixins.scss index 053a4627c6..0c8cdad9b7 100644 --- a/core/src/themes/ionic.mixins.scss +++ b/core/src/themes/ionic.mixins.scss @@ -242,17 +242,13 @@ // - Firefox doesn't support `:host-context()`, but does support `:dir()`. // - Safari doesn't support `:host-context()`, but Safari 16.4+ supports `:dir()` // @link https://webkit.org/blog/13966/webkit-features-in-safari-16-4/ - @each $selector in $rootSplit { - $dirSelector: "#{$selector}:dir(rtl)"; - // Group the selectors back into a single selector to optimize the output. - $dirSelectors: append($dirSelectors, $dirSelector, comma); - } + // -- However, there is a Webkit bug on v16 that prevents `:dir()` from working when + // -- the app direction is changed dynamically. v17+ works fine. + // -- @link https://bugs.webkit.org/show_bug.cgi?id=257133 // Supported by Firefox. - @if length($dirSelectors) > 0 { - @at-root #{$dirSelectors} { - @content; - } + @at-root #{add-root-selector($root, ":dir(rtl)", false)} { + @content; } } }