diff --git a/src/theme/helpers/ionic.components.mixins.scss b/src/theme/helpers/ionic.components.mixins.scss index 529dfb75a..c3c9009b1 100644 --- a/src/theme/helpers/ionic.components.mixins.scss +++ b/src/theme/helpers/ionic.components.mixins.scss @@ -2,8 +2,7 @@ * Imported ionic mixins for SCSS from different components * ---------------------------------------------------------------------------- * Extracted from - * https://github.com/ionic-team/ionic-framework/blob/master/core/src/components/grid/grid.mixins.scss - * https://github.com/ionic-team/ionic-framework/blob/master/core/src/components/item/item.mixins.scss + * https://github.com/ionic-team/ionic-framework/blob/main/core/src/components/grid/grid.mixins.scss */ // Responsive Mixins @@ -36,13 +35,3 @@ } } } - - -// Item Mixins -// -------------------------------------------------- - -@mixin item-push-svg-url($fill) { - $item-detail-push-svg: ""; - - @include svg-background-image($item-detail-push-svg, true); -} diff --git a/src/theme/helpers/ionic.functions.color.scss b/src/theme/helpers/ionic.functions.color.scss index a6b9060a7..07d258fff 100644 --- a/src/theme/helpers/ionic.functions.color.scss +++ b/src/theme/helpers/ionic.functions.color.scss @@ -2,7 +2,7 @@ * Imported ionic color functions for SCSS * ---------------------------------------------------------------------------- * Extracted from - * https://github.com/ionic-team/ionic-framework/blob/master/core/src/themes/ionic.functions.color.scss + * https://github.com/ionic-team/ionic-framework/blob/main/core/src/themes/ionic.functions.color.scss */ // Gets the active color's css variable from a variation. Alpha is optional. diff --git a/src/theme/helpers/ionic.functions.string.scss b/src/theme/helpers/ionic.functions.string.scss index 6b411ef28..0d41e1fee 100644 --- a/src/theme/helpers/ionic.functions.string.scss +++ b/src/theme/helpers/ionic.functions.string.scss @@ -2,7 +2,7 @@ * Imported ionic string functions for SCSS * ---------------------------------------------------------------------------- * Extracted from - * https://github.com/ionic-team/ionic-framework/blob/master/core/src/themes/ionic.functions.string.scss + * https://github.com/ionic-team/ionic-framework/blob/main/core/src/themes/ionic.functions.string.scss */ @@ -93,9 +93,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: (); @@ -103,14 +109,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, " "); @@ -125,19 +138,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); } } @@ -148,24 +170,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); } } @@ -176,9 +212,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/src/theme/helpers/ionic.mixins.scss b/src/theme/helpers/ionic.mixins.scss index d74f2011c..dd727e9b8 100644 --- a/src/theme/helpers/ionic.mixins.scss +++ b/src/theme/helpers/ionic.mixins.scss @@ -2,9 +2,43 @@ * Imported ionic mixins for SCSS * ---------------------------------------------------------------------------- * Extracted from - * https://github.com/ionic-team/ionic-framework/blob/master/core/src/themes/ionic.mixins.scss + * https://github.com/ionic-team/ionic-framework/blob/main/core/src/themes/ionic.mixins.scss */ +/** + * A heuristic that applies CSS to tablet + * viewports. + * + * Usage: + * @include tablet-viewport() { + * :host { + * background-color: green; + * } + * } + */ + @mixin tablet-viewport() { + @media screen and (min-width: 768px) { + @content; + } +} + +/** + * A heuristic that applies CSS to mobile + * viewports (i.e. phones, not tablets). + * + * Usage: + * @include mobile-viewport() { + * :host { + * background-color: blue; + * } + * } + */ +@mixin mobile-viewport() { + @media screen and (max-width: 767px) { + @content; + } +} + @mixin input-cover() { @include position(0, null, null, 0); @include margin(0); @@ -240,28 +274,24 @@ } // If browser can support `:dir()`, then add the `:dir()` selectors. - // @supports selector(:dir(rtl)) { // @ IMPOTANT NOTE: This has been removed because selector function is not supported in current SCSS - // Adding :dir() in case the browser doesn't support `:host-context()` and does support `:dir()`. - // `:host-context()` is added: - // - through the `add-root-selector()` function. - // - first so that it takes precedence over `:dir()`. - // For example, - // - 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); - } + @supports selector(:dir(rtl)) { + // Adding :dir() in case the browser doesn't support `:host-context()` and does support `:dir()`. + // `:host-context()` is added: + // - through the `add-root-selector()` function. + // - first so that it takes precedence over `:dir()`. + // For example, + // - 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/ + // -- 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} { + // Supported by Firefox. + @at-root #{add-root-selector($root, ":dir(rtl)", false)} { @content; } } - //} } @mixin ltr() {