@@ -91,7 +95,8 @@ configs({ modes: ['ionic-md'], directions: ['ltr'] }).forEach(({ title, screensh
test('should apply the utility classes for font display', async ({ page }) => {
await page.setContent(
`
-
Utility class 'ionic-display-s'
Utility class 'ionic-display-m'
diff --git a/core/src/css/test/typography/basic/typography.e2e.ts-snapshots/ionic-utility-classes-semantic-tags-ionic-md-ltr-light-Mobile-Chrome-linux.png b/core/src/css/test/typography/basic/typography.e2e.ts-snapshots/ionic-utility-classes-semantic-tags-ionic-md-ltr-light-Mobile-Chrome-linux.png
index 03ec9560ba..776261b6e9 100644
Binary files a/core/src/css/test/typography/basic/typography.e2e.ts-snapshots/ionic-utility-classes-semantic-tags-ionic-md-ltr-light-Mobile-Chrome-linux.png and b/core/src/css/test/typography/basic/typography.e2e.ts-snapshots/ionic-utility-classes-semantic-tags-ionic-md-ltr-light-Mobile-Chrome-linux.png differ
diff --git a/core/src/css/test/typography/basic/typography.e2e.ts-snapshots/ionic-utility-classes-semantic-tags-ionic-md-ltr-light-Mobile-Firefox-linux.png b/core/src/css/test/typography/basic/typography.e2e.ts-snapshots/ionic-utility-classes-semantic-tags-ionic-md-ltr-light-Mobile-Firefox-linux.png
index f61392e440..95ced965b9 100644
Binary files a/core/src/css/test/typography/basic/typography.e2e.ts-snapshots/ionic-utility-classes-semantic-tags-ionic-md-ltr-light-Mobile-Firefox-linux.png and b/core/src/css/test/typography/basic/typography.e2e.ts-snapshots/ionic-utility-classes-semantic-tags-ionic-md-ltr-light-Mobile-Firefox-linux.png differ
diff --git a/core/src/css/test/typography/basic/typography.e2e.ts-snapshots/ionic-utility-classes-semantic-tags-ionic-md-ltr-light-Mobile-Safari-linux.png b/core/src/css/test/typography/basic/typography.e2e.ts-snapshots/ionic-utility-classes-semantic-tags-ionic-md-ltr-light-Mobile-Safari-linux.png
index e6304aa31b..a129f344c1 100644
Binary files a/core/src/css/test/typography/basic/typography.e2e.ts-snapshots/ionic-utility-classes-semantic-tags-ionic-md-ltr-light-Mobile-Safari-linux.png and b/core/src/css/test/typography/basic/typography.e2e.ts-snapshots/ionic-utility-classes-semantic-tags-ionic-md-ltr-light-Mobile-Safari-linux.png differ
diff --git a/core/src/css/text-alignment.scss b/core/src/css/text-alignment.scss
index 20f8184f2e..2917ab2e78 100644
--- a/core/src/css/text-alignment.scss
+++ b/core/src/css/text-alignment.scss
@@ -1,5 +1,5 @@
-@import "../themes/ionic.globals";
-@import "../themes/ionic.mixins";
+@import "../themes/native/native.globals";
+@import "../themes/mixins";
// Text Alignment
// --------------------------------------------------
diff --git a/core/src/css/text-transformation.scss b/core/src/css/text-transformation.scss
index 631e9a0fb4..f08d51ca7c 100644
--- a/core/src/css/text-transformation.scss
+++ b/core/src/css/text-transformation.scss
@@ -1,5 +1,5 @@
-@import "../themes/ionic.globals";
-@import "../themes/ionic.mixins";
+@import "../themes/native/native.globals";
+@import "../themes/mixins";
// Text Transformation
// --------------------------------------------------
diff --git a/core/src/css/typography.ionic.scss b/core/src/css/typography.ionic.scss
deleted file mode 100644
index 238a9a4a2e..0000000000
--- a/core/src/css/typography.ionic.scss
+++ /dev/null
@@ -1,90 +0,0 @@
-@use "../foundations/ionic.vars.scss" as tokens;
-/* This import below is temporary, to make sure basic tests have access to all utility-classes */
-@import "../foundations/ionic.utility.scss";
-
-html {
- font-family: #{tokens.$ionic-font-family};
- font-size: #{tokens.$ionic-font-size-m};
- font-weight: #{tokens.$ionic-font-weight-regular};
-
- line-height: #{tokens.$ionic-font-line-height-m};
-}
-
-/* Composite utility classes for html headings and font classes, that aggregate size and weight, based on tokens*/
-h1,
-.ionic-heading1,
-h2,
-.ionic-heading2,
-h3,
-.ionic-heading3,
-h4,
-.ionic-heading4,
-h5,
-.ionic-heading5,
-h6,
-.ionic-heading6 {
- color: #{tokens.$ionic-color-neutral-900};
-
- font-weight: #{tokens.$ionic-font-weight-semi-bold};
-}
-
-h1,
-.ionic-heading1 {
- font-size: #{tokens.$ionic-font-size-h1};
-
- line-height: #{tokens.$ionic-font-line-height-xxl};
-}
-
-h2,
-.ionic-heading2 {
- font-size: #{tokens.$ionic-font-size-h2};
-
- line-height: #{tokens.$ionic-font-line-height-xl};
-}
-
-h3,
-.ionic-heading3 {
- font-size: #{tokens.$ionic-font-size-h3};
-
- line-height: #{tokens.$ionic-font-line-height-xl};
-}
-
-h4,
-.ionic-heading4 {
- font-size: #{tokens.$ionic-font-size-h4};
-
- line-height: #{tokens.$ionic-font-line-height-l};
-}
-
-h5,
-.ionic-heading5 {
- font-size: #{tokens.$ionic-font-size-h5};
-
- line-height: #{tokens.$ionic-font-line-height-l};
-}
-
-h6,
-.ionic-heading6 {
- font-size: #{tokens.$ionic-font-size-h6};
-
- line-height: #{tokens.$ionic-font-line-height-m};
-}
-
-.ionic-display-s {
- font-size: #{tokens.$ionic-font-size-display-s};
- font-weight: #{tokens.$ionic-font-weight-regular};
-
- line-height: #{tokens.$ionic-font-line-height-s};
-}
-
-.ionic-display-m {
- font-size: #{tokens.$ionic-font-size-display-m};
- font-weight: #{tokens.$ionic-font-weight-regular};
-
- line-height: #{tokens.$ionic-font-line-height-m};
-}
-
-/* Common */
-.ionic-font-italic {
- font-style: italic;
-}
diff --git a/core/src/css/typography.scss b/core/src/css/typography.scss
index d1474a38d9..ce6347d9df 100644
--- a/core/src/css/typography.scss
+++ b/core/src/css/typography.scss
@@ -1,32 +1,32 @@
-@import "../themes/ionic.globals";
-@import "../themes/ionic.mixins";
+@import "../themes/native/native.globals";
+@import "../themes/mixins";
// Typography
// --------------------------------------------------
/// @prop - Font weight of all headings
-$headings-font-weight: 500 !default;
+$headings-font-weight: 500 !default;
/// @prop - Line height of all headings
-$headings-line-height: 1.2 !default;
+$headings-line-height: 1.2 !default;
/// @prop - Font size of heading level 1
-$h1-font-size: dynamic-font(26px) !default;
+$h1-font-size: dynamic-font(26px) !default;
/// @prop - Font size of heading level 2
-$h2-font-size: dynamic-font(24px) !default;
+$h2-font-size: dynamic-font(24px) !default;
/// @prop - Font size of heading level 3
-$h3-font-size: dynamic-font(22px) !default;
+$h3-font-size: dynamic-font(22px) !default;
/// @prop - Font size of heading level 4
-$h4-font-size: dynamic-font(20px) !default;
+$h4-font-size: dynamic-font(20px) !default;
/// @prop - Font size of heading level 5
-$h5-font-size: dynamic-font(18px) !default;
+$h5-font-size: dynamic-font(18px) !default;
/// @prop - Font size of heading level 6
-$h6-font-size: dynamic-font(16px) !default;
+$h6-font-size: dynamic-font(16px) !default;
html {
font-family: var(--ion-font-family);
@@ -107,9 +107,9 @@ sup {
}
sup {
- top: -.5em;
+ top: -0.5em;
}
sub {
- bottom: -.25em;
+ bottom: -0.25em;
}
diff --git a/core/src/foundations/README.md b/core/src/foundations/README.md
index 4cb3b51002..b0de539fe2 100644
--- a/core/src/foundations/README.md
+++ b/core/src/foundations/README.md
@@ -89,12 +89,16 @@ It's very important to highlight that only the Ionic Theme supports these tokens
Within the component scope, variables from these global tokens should always be used. There should be no hardcoded values on component scope that relate to any of the existing tokens.
-Example (Chip Component):
+To prevent differences between components implementation, a global partial was created - `ionic.globals.scss` - that forwards all the necessary foundations, functions and mixins, relevant to the Ionic Theme.
+
+Usage example (Chip Component):
```scss
-@use '../../foundations/ionic.vars.scss' as tokens;
+@use '../../themes/ionic/ionic.globals.scss' as globals;
:host {
- --background: #{tokens.$ionic-color-neutral-10};
+ --background: #{globals.$ionic-color-neutral-10};
+ color: globals.$ionic-color-neutral-900;
+ @include globals.font-smoothing;
}
```
diff --git a/core/src/foundations/ionic.utility.scss b/core/src/foundations/ionic.utility.scss
index 1e5c302127..ea5c51aaed 100644
--- a/core/src/foundations/ionic.utility.scss
+++ b/core/src/foundations/ionic.utility.scss
@@ -3,8 +3,8 @@
* Ionic Design System
*/
-
@import "./ionic.vars";
+@import "../themes/mixins";
.ionic-color-primary-10 {
color: $ionic-color-primary-10;
@@ -530,83 +530,239 @@
font-weight: $ionic-font-weight-bold;
}
.ionic-margin-space-none {
- margin: $ionic-space-none;
-};
+ --margin-start: #{$ionic-space-none};
+ --margin-end: #{$ionic-space-none};
+ --margin-top: #{$ionic-space-none};
+ --margin-bottom: #{$ionic-space-none};
+
+ @include margin(0);
+}
+
.ionic-padding-space-none {
- padding: $ionic-space-none;
+ --padding-start: #{$ionic-space-none};
+ --padding-end: #{$ionic-space-none};
+ --padding-top: #{$ionic-space-none};
+ --padding-bottom: #{$ionic-space-none};
+
+ @include padding(0);
}
+
.ionic-margin-space-xxxxs {
- margin: $ionic-space-xxxxs;
-};
+ --margin-start: #{$ionic-space-xxxxs};
+ --margin-end: #{$ionic-space-xxxxs};
+ --margin-top: #{$ionic-space-xxxxs};
+ --margin-bottom: #{$ionic-space-xxxxs};
+
+ @include margin(2px);
+}
+
.ionic-padding-space-xxxxs {
- padding: $ionic-space-xxxxs;
+ --padding-start: #{$ionic-space-xxxxs};
+ --padding-end: #{$ionic-space-xxxxs};
+ --padding-top: #{$ionic-space-xxxxs};
+ --padding-bottom: #{$ionic-space-xxxxs};
+
+ @include padding(2px);
}
+
.ionic-margin-space-xxxs {
- margin: $ionic-space-xxxs;
-};
+ --margin-start: #{$ionic-space-xxxs};
+ --margin-end: #{$ionic-space-xxxs};
+ --margin-top: #{$ionic-space-xxxs};
+ --margin-bottom: #{$ionic-space-xxxs};
+
+ @include margin(4px);
+}
+
.ionic-padding-space-xxxs {
- padding: $ionic-space-xxxs;
+ --padding-start: #{$ionic-space-xxxs};
+ --padding-end: #{$ionic-space-xxxs};
+ --padding-top: #{$ionic-space-xxxs};
+ --padding-bottom: #{$ionic-space-xxxs};
+
+ @include padding(4px);
}
+
.ionic-margin-space-xxs {
- margin: $ionic-space-xxs;
-};
+ --margin-start: #{$ionic-space-xxs};
+ --margin-end: #{$ionic-space-xxs};
+ --margin-top: #{$ionic-space-xxs};
+ --margin-bottom: #{$ionic-space-xxs};
+
+ @include margin(6px);
+}
+
.ionic-padding-space-xxs {
- padding: $ionic-space-xxs;
+ --padding-start: #{$ionic-space-xxs};
+ --padding-end: #{$ionic-space-xxs};
+ --padding-top: #{$ionic-space-xxs};
+ --padding-bottom: #{$ionic-space-xxs};
+
+ @include padding(6px);
}
+
.ionic-margin-space-xs {
- margin: $ionic-space-xs;
-};
+ --margin-start: #{$ionic-space-xs};
+ --margin-end: #{$ionic-space-xs};
+ --margin-top: #{$ionic-space-xs};
+ --margin-bottom: #{$ionic-space-xs};
+
+ @include margin(8px);
+}
+
.ionic-padding-space-xs {
- padding: $ionic-space-xs;
+ --padding-start: #{$ionic-space-xs};
+ --padding-end: #{$ionic-space-xs};
+ --padding-top: #{$ionic-space-xs};
+ --padding-bottom: #{$ionic-space-xs};
+
+ @include padding(8px);
}
+
.ionic-margin-space-s {
- margin: $ionic-space-s;
-};
+ --margin-start: #{$ionic-space-s};
+ --margin-end: #{$ionic-space-s};
+ --margin-top: #{$ionic-space-s};
+ --margin-bottom: #{$ionic-space-s};
+
+ @include margin(12px);
+}
+
.ionic-padding-space-s {
- padding: $ionic-space-s;
+ --padding-start: #{$ionic-space-s};
+ --padding-end: #{$ionic-space-s};
+ --padding-top: #{$ionic-space-s};
+ --padding-bottom: #{$ionic-space-s};
+
+ @include padding(12px);
}
+
.ionic-margin-space-base {
- margin: $ionic-space-base;
-};
+ --margin-start: #{$ionic-space-base};
+ --margin-end: #{$ionic-space-base};
+ --margin-top: #{$ionic-space-base};
+ --margin-bottom: #{$ionic-space-base};
+
+ @include margin(16px);
+}
+
.ionic-padding-space-base {
- padding: $ionic-space-base;
+ --padding-start: #{$ionic-space-base};
+ --padding-end: #{$ionic-space-base};
+ --padding-top: #{$ionic-space-base};
+ --padding-bottom: #{$ionic-space-base};
+
+ @include padding(16px);
}
+
.ionic-margin-space-m {
- margin: $ionic-space-m;
-};
+ --margin-start: #{$ionic-space-m};
+ --margin-end: #{$ionic-space-m};
+ --margin-top: #{$ionic-space-m};
+ --margin-bottom: #{$ionic-space-m};
+
+ @include margin(20px);
+}
+
.ionic-padding-space-m {
- padding: $ionic-space-m;
+ --padding-start: #{$ionic-space-m};
+ --padding-end: #{$ionic-space-m};
+ --padding-top: #{$ionic-space-m};
+ --padding-bottom: #{$ionic-space-m};
+
+ @include padding(20px);
}
+
.ionic-margin-space-l {
- margin: $ionic-space-l;
-};
+ --margin-start: #{$ionic-space-l};
+ --margin-end: #{$ionic-space-l};
+ --margin-top: #{$ionic-space-l};
+ --margin-bottom: #{$ionic-space-l};
+
+ @include margin(24px);
+}
+
.ionic-padding-space-l {
- padding: $ionic-space-l;
+ --padding-start: #{$ionic-space-l};
+ --padding-end: #{$ionic-space-l};
+ --padding-top: #{$ionic-space-l};
+ --padding-bottom: #{$ionic-space-l};
+
+ @include padding(24px);
}
+
.ionic-margin-space-xl {
- margin: $ionic-space-xl;
-};
+ --margin-start: #{$ionic-space-xl};
+ --margin-end: #{$ionic-space-xl};
+ --margin-top: #{$ionic-space-xl};
+ --margin-bottom: #{$ionic-space-xl};
+
+ @include margin(28px);
+}
+
.ionic-padding-space-xl {
- padding: $ionic-space-xl;
+ --padding-start: #{$ionic-space-xl};
+ --padding-end: #{$ionic-space-xl};
+ --padding-top: #{$ionic-space-xl};
+ --padding-bottom: #{$ionic-space-xl};
+
+ @include padding(28px);
}
+
.ionic-margin-space-xxl {
- margin: $ionic-space-xxl;
-};
+ --margin-start: #{$ionic-space-xxl};
+ --margin-end: #{$ionic-space-xxl};
+ --margin-top: #{$ionic-space-xxl};
+ --margin-bottom: #{$ionic-space-xxl};
+
+ @include margin(32px);
+}
+
.ionic-padding-space-xxl {
- padding: $ionic-space-xxl;
+ --padding-start: #{$ionic-space-xxl};
+ --padding-end: #{$ionic-space-xxl};
+ --padding-top: #{$ionic-space-xxl};
+ --padding-bottom: #{$ionic-space-xxl};
+
+ @include padding(32px);
}
+
.ionic-margin-space-xxxl {
- margin: $ionic-space-xxxl;
-};
+ --margin-start: #{$ionic-space-xxxl};
+ --margin-end: #{$ionic-space-xxxl};
+ --margin-top: #{$ionic-space-xxxl};
+ --margin-bottom: #{$ionic-space-xxxl};
+
+ @include margin(36px);
+}
+
.ionic-padding-space-xxxl {
- padding: $ionic-space-xxxl;
+ --padding-start: #{$ionic-space-xxxl};
+ --padding-end: #{$ionic-space-xxxl};
+ --padding-top: #{$ionic-space-xxxl};
+ --padding-bottom: #{$ionic-space-xxxl};
+
+ @include padding(36px);
}
+
.ionic-margin-space-xxxxl {
- margin: $ionic-space-xxxxl;
-};
-.ionic-padding-space-xxxxl {
- padding: $ionic-space-xxxxl;
+ --margin-start: #{$ionic-space-xxxxl};
+ --margin-end: #{$ionic-space-xxxxl};
+ --margin-top: #{$ionic-space-xxxxl};
+ --margin-bottom: #{$ionic-space-xxxxl};
+
+ @include margin(40px);
}
+
+.ionic-padding-space-xxxxl {
+ --padding-start: #{$ionic-space-xxxxl};
+ --padding-end: #{$ionic-space-xxxxl};
+ --padding-top: #{$ionic-space-xxxxl};
+ --padding-bottom: #{$ionic-space-xxxxl};
+
+ @include padding(40px);
+}
+
.ionic-border-radius-square {
border-radius: $ionic-border-radius-square;
}
@@ -648,4 +804,4 @@
}
.ionic-elevation-4 {
box-shadow: $ionic-elevation-4;
-}
\ No newline at end of file
+}
diff --git a/core/src/foundations/ionic.vars.scss b/core/src/foundations/ionic.vars.scss
index 0b07beab54..2c1f098ad1 100644
--- a/core/src/foundations/ionic.vars.scss
+++ b/core/src/foundations/ionic.vars.scss
@@ -203,5 +203,13 @@ $ionic-border-size-large: var(--ionic-border-size-large, 3px);
$ionic-elevation-0: var(--ionic-elevation-0, none);
$ionic-elevation-1: var(--ionic-elevation-1, 0px 3px 9px 0px rgba(0, 0, 0, 0.07), 0px 0px 4px 0px rgba(0, 0, 0, 0.04));
$ionic-elevation-2: var(--ionic-elevation-2, 0px 8px 25px 0px rgba(0, 0, 0, 0.08), 0px 1px 5px 0px rgba(0, 0, 0, 0.05));
-$ionic-elevation-3: var(--ionic-elevation-3, 0px 2px 7px 0px rgba(0, 0, 0, 0.05), 0px 15px 32px 0px rgba(0, 0, 0, 0.09));
-$ionic-elevation-4: var(--ionic-elevation-4, 0px 3px 14px 0px rgba(0, 0, 0, 0.12), 0px 20px 48px 0px rgba(0, 0, 0, 0.12));
+$ionic-elevation-3: var(
+ --ionic-elevation-3,
+ 0px 2px 7px 0px rgba(0, 0, 0, 0.05),
+ 0px 15px 32px 0px rgba(0, 0, 0, 0.09)
+);
+$ionic-elevation-4: var(
+ --ionic-elevation-4,
+ 0px 3px 14px 0px rgba(0, 0, 0, 0.12),
+ 0px 20px 48px 0px rgba(0, 0, 0, 0.12)
+);
diff --git a/core/src/themes/ionic.functions.color.scss b/core/src/themes/functions.color.scss
similarity index 97%
rename from core/src/themes/ionic.functions.color.scss
rename to core/src/themes/functions.color.scss
index 1d78bbe131..f3cc87a90d 100644
--- a/core/src/themes/ionic.functions.color.scss
+++ b/core/src/themes/functions.color.scss
@@ -30,8 +30,10 @@
@if ($alpha) {
$value: color-to-rgb-list($value);
+
@return rgba(var(#{$variable}-rgb, $value), $alpha);
}
+
@if ($rgb) {
$value: color-to-rgb-list($value);
$variable: #{$variable}-rgb;
@@ -55,5 +57,5 @@
// Converts a color to a comma separated rgb.
// --------------------------------------------------------------------------------------------
@function color-to-rgb-list($color) {
- @return #{red($color)},#{green($color)},#{blue($color)};
+ @return #{red($color)}, #{green($color)}, #{blue($color)};
}
diff --git a/core/src/themes/ionic.functions.font.scss b/core/src/themes/functions.font.scss
similarity index 100%
rename from core/src/themes/ionic.functions.font.scss
rename to core/src/themes/functions.font.scss
diff --git a/core/src/themes/ionic.functions.sizes.scss b/core/src/themes/functions.sizes.scss
similarity index 100%
rename from core/src/themes/ionic.functions.sizes.scss
rename to core/src/themes/functions.sizes.scss
diff --git a/core/src/themes/ionic.functions.string.scss b/core/src/themes/functions.string.scss
similarity index 84%
rename from core/src/themes/ionic.functions.string.scss
rename to core/src/themes/functions.string.scss
index ea3da90c5e..cc4358f37c 100644
--- a/core/src/themes/ionic.functions.string.scss
+++ b/core/src/themes/functions.string.scss
@@ -8,7 +8,8 @@
$index: str-index($string, $search);
@if $index {
- @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
+ @return str-slice($string, 1, $index - 1) + $replace +
+ str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
}
@return $string;
@@ -17,7 +18,6 @@
// String Split Function
// --------------------------------------------------------------------------------
-
@function str-split($string, $separator) {
// empty array/list
$split-arr: ();
@@ -40,7 +40,6 @@
@return $split-arr;
}
-
// String Extract Function
// --------------------------------------------------------------------------------
@@ -59,7 +58,6 @@
@return null;
}
-
// String Contains Function
// --------------------------------------------------------------------------------
@@ -71,17 +69,16 @@
@return false;
}
-
// URL Encode Function
// --------------------------------------------------------------------------------
@function url-encode($val) {
$spaces: str-replace($val, " ", "%20");
$encoded: str-replace($spaces, "#", "%23");
+
@return $encoded;
}
-
// Add Root Selector
// --------------------------------------------------------------------------------
// Adds a root selector using host based on the selector passed
@@ -92,7 +89,6 @@
// $useHostContext: Whether to use host-context or not. Defaults to true.
// --------------------------------------------------------------------------------
-
@function add-root-selector($root, $addHostSelector, $useHostContext: true) {
$selectors: str-split($root, ",");
@@ -133,12 +129,20 @@
// 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}");
+ $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})");
+ $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)
@@ -157,20 +161,20 @@
}
$list: append($list, $new-element, comma);
- // If the selector contains :host without a parantheses
- // it means it is targeting just the host
- // element so we can change it to look for host-context
- // @include add-root-selector(":host", "[dir=rtl]")
- // --> :host-context([dir=rtl])
- // @include add-root(":host", ":dir(rtl)", false)
- // --> :host(:dir(rtl))
+ // If the selector contains :host without a parantheses
+ // it means it is targeting just the host
+ // element so we can change it to look for host-context
+ // @include add-root-selector(":host", "[dir=rtl]")
+ // --> :host-context([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: '';
+ $updated-element: "";
// Replace the :host with the addHostSelector:
@if $useHostContext {
@@ -197,15 +201,15 @@
$new-element: append($new-element, $element, space);
}
}
-
+
$list: append($list, $new-element, comma);
- // If the selector does not contain host at all it is either a shadow
- // or normal element so append both the addHostSelector and host-context
- // @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)
+ // If the selector does not contain host at all it is either a shadow
+ // or normal element so append both the addHostSelector and host-context
+ // @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 {
@if ($useHostContext) {
$list: append($list, ":host-context(#{$addHostSelector}) #{$selector}", comma);
diff --git a/core/src/themes/ionic.globals.ionic.scss b/core/src/themes/ionic.globals.ionic.scss
deleted file mode 100644
index d8a54973f7..0000000000
--- a/core/src/themes/ionic.globals.ionic.scss
+++ /dev/null
@@ -1,2 +0,0 @@
-// Core Globals
-@import "./ionic.globals";
diff --git a/core/src/themes/ionic.globals.ios.scss b/core/src/themes/ionic.globals.ios.scss
deleted file mode 100644
index d9aca20c4f..0000000000
--- a/core/src/themes/ionic.globals.ios.scss
+++ /dev/null
@@ -1,6 +0,0 @@
-
-// Global Core
-@import "./ionic.globals";
-
-// Global iOS
-@import "./ionic.theme.default.ios";
diff --git a/core/src/themes/ionic.globals.md.scss b/core/src/themes/ionic.globals.md.scss
deleted file mode 100644
index 6c0d558d01..0000000000
--- a/core/src/themes/ionic.globals.md.scss
+++ /dev/null
@@ -1,6 +0,0 @@
-
-// Core Globals
-@import "./ionic.globals";
-
-// Material Design Globals
-@import "./ionic.theme.default.md";
diff --git a/core/src/themes/ionic.theme.default.ios.scss b/core/src/themes/ionic.theme.default.ios.scss
deleted file mode 100644
index c5c5e7045a..0000000000
--- a/core/src/themes/ionic.theme.default.ios.scss
+++ /dev/null
@@ -1,39 +0,0 @@
-// Ionic iOS Theme
-// -------------------------------------------------------------------------------------------
-// This file contains the theme variables shared
-// between modes. This should only include variables
-// used to theme the application colors for iOS.
-
-// iOS General Colors
-// --------------------------------------------------
-$backdrop-ios-color: var(--ion-backdrop-color, #000) !default;
-$overlay-ios-background-color: var(--ion-overlay-background-color, var(--ion-color-step-100, var(--ion-background-color-step-100, #f9f9f9))) !default;
-
-// iOS Tabs & Tab bar
-// --------------------------------------------------
-$tabbar-ios-background: var(--ion-tab-bar-background, var(--ion-color-step-50, var(--ion-background-color-step-50, #f7f7f7))) !default;
-$tabbar-ios-background-focused: var(--ion-tab-bar-background-focused, get-color-shade(#fff)) !default;
-$tabbar-ios-border-color: var(--ion-tab-bar-border-color, var(--ion-border-color, var(--ion-color-step-150, var(--ion-background-color-step-150, rgba(0, 0, 0, .2)))) )!default;
-$tabbar-ios-color: var(--ion-tab-bar-color, $text-color-step-400) !default;
-$tabbar-ios-color-selected: var(--ion-tab-bar-color-selected, ion-color(primary, base)) !default;
-
-// iOS Toolbar
-// --------------------------------------------------
-$toolbar-ios-background: var(--ion-toolbar-background, var(--ion-color-step-50, var(--ion-background-color-step-50, #f7f7f7))) !default;
-$toolbar-ios-border-color: var(--ion-toolbar-border-color, var(--ion-border-color, var(--ion-color-step-150, var(--ion-background-color-step-150, rgba(0, 0, 0, .2))))) !default;
-$toolbar-ios-color: var(--ion-toolbar-color, $text-color) !default;
-
-// iOS List & List Items
-// --------------------------------------------------
-$item-ios-background: var(--ion-item-background, $background-color) !default;
-$item-ios-border-color: var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-250, var(--ion-background-color-step-250, #c8c7cc)))) !default;
-$item-ios-color: var(--ion-item-color, $text-color) !default;
-
-// iOS Card
-// --------------------------------------------------
-$card-ios-background: var(--ion-card-background, $item-ios-background) !default;
-$card-ios-color: var(--ion-card-color, var(--ion-item-color, $text-color-step-400)) !default;
-
-// iOS Form Controls
-// --------------------------------------------------
-$form-control-ios-disabled-opacity: 0.3;
diff --git a/core/src/themes/ionic.theme.default.md.scss b/core/src/themes/ionic.theme.default.md.scss
deleted file mode 100644
index 14f1f34c7a..0000000000
--- a/core/src/themes/ionic.theme.default.md.scss
+++ /dev/null
@@ -1,43 +0,0 @@
-
-// Material Design Default Theme
-// --------------------------------------------------
-// This file should only contain variables that are
-// used to theme the application colors for Material
-// Design.
-
-// Material Design General Colors
-// --------------------------------------------------
-$backdrop-md-color: var(--ion-backdrop-color, #000) !default;
-$border-md-color: var(--ion-border-color, var(--ion-color-step-150, var(--ion-background-color-step-150, #c1c4cd))) !default;
-$overlay-md-background-color: var(--ion-overlay-background-color, var(--ion-background-color, #fff)) !default;
-
-// Material Design Tabs & Tab bar
-// --------------------------------------------------
-$tabbar-md-background: var(--ion-tab-bar-background, $background-color) !default;
-$tabbar-md-background-focused: var(--ion-tab-bar-background-focused, get-color-shade(#fff)) !default;
-$tabbar-md-border-color: var(--ion-tab-bar-border-color, var(--ion-border-color, var(--ion-color-step-150, var(--ion-background-color-step-150, rgba(0, 0, 0, .07))))) !default;
-$tabbar-md-color: var(--ion-tab-bar-color, $text-color-step-350) !default;
-$tabbar-md-color-selected: var(--ion-tab-bar-color-selected, ion-color(primary, base)) !default;
-
-// Material Design Toolbar
-// --------------------------------------------------
-$toolbar-md-background: var(--ion-toolbar-background, $background-color) !default;
-$toolbar-md-border-color: var(--ion-toolbar-border-color, $border-md-color) !default;
-$toolbar-md-color: var(--ion-toolbar-color, var(--ion-text-color, #424242)) !default;
-
-// Material Design List & List Items
-// --------------------------------------------------
-$item-md-background: var(--ion-item-background, $background-color) !default;
-$item-md-border-color: var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-150, var(--ion-background-color-step-150, rgba(0, 0, 0, .13))))) !default;
-$item-md-color: var(--ion-item-color, $text-color) !default;
-
-// Material Design Card
-// --------------------------------------------------
-$card-md-background: var(--ion-card-background, $item-md-background) !default;
-$card-md-color: var(--ion-card-color, var(--ion-item-color, $text-color-step-450)) !default;
-
-// Material Design Form Controls
-// --------------------------------------------------
-/// This value comes from the Material Design spec:
-/// https://m3.material.io/components/text-fields/specs
-$form-control-md-disabled-opacity: 0.38;
diff --git a/core/src/themes/ionic.theme.default.scss b/core/src/themes/ionic.theme.default.scss
deleted file mode 100644
index 8a7c4c6013..0000000000
--- a/core/src/themes/ionic.theme.default.scss
+++ /dev/null
@@ -1,145 +0,0 @@
-// Ionic Theme
-// -------------------------------------------------------------------------------------------
-// This file contains the theme variables shared
-// between modes. This should only include variables
-// used to theme the application colors.
-
-// Default Ionic Colors
-// -------------------------------------------------------------------------------------------
-// Color map should provide
-// - base: main color to be used.
-// - contrast: Color that will provide readable text against the base color
-// - shade: 12% darker version of the base color (mix with black)
-// - tint: 10% lighter version of the base color (mix with white)
-
-$primary: #0054e9 !default;
-$secondary: #0163aa !default;
-$tertiary: #6030ff !default;
-$success: #2dd55b !default;
-$warning: #ffc409 !default;
-$danger: #c5000f !default;
-$light: #f4f5f8 !default;
-$medium: #636469 !default;
-$dark: #222428 !default;
-
-$colors: (
- primary: (
- base: $primary,
- contrast: #fff,
- shade: get-color-shade($primary),
- tint: get-color-tint($primary)
- ),
- secondary: (
- base: $secondary,
- contrast: #fff,
- shade: get-color-shade($secondary),
- tint: get-color-tint($secondary)
- ),
- tertiary: (
- base: $tertiary,
- contrast: #fff,
- shade: get-color-shade($tertiary),
- tint: get-color-tint($tertiary)
- ),
- success: (
- base: $success,
- contrast: #000,
- shade: get-color-shade($success),
- tint: get-color-tint($success)
- ),
- warning: (
- base: $warning,
- contrast: #000,
- shade: get-color-shade($warning),
- tint: get-color-tint($warning)
- ),
- danger: (
- base: $danger,
- contrast: #fff,
- shade: get-color-shade($danger),
- tint: get-color-tint($danger)
- ),
- light: (
- base: $light,
- contrast: #000,
- shade: get-color-shade($light),
- tint: get-color-tint($light)
- ),
- medium: (
- base: $medium,
- contrast: #fff,
- shade: get-color-shade($medium),
- tint: get-color-tint($medium)
- ),
- dark: (
- base: $dark,
- contrast: #fff,
- shade: get-color-shade($dark),
- tint: get-color-tint($dark)
- )
-) !default;
-
-// Default Foreground and Background Colors
-// -------------------------------------------------------------------------------------------
-// Used internally to calculate the default steps
-
-$background-color-value: #fff !default;
-$background-color-rgb-value: 255, 255, 255 !default;
-
-$text-color-value: #000 !default;
-$text-color-rgb-value: 0, 0, 0 !default;
-
-$background-color: var(--ion-background-color, $background-color-value) !default;
-$background-color-rgb: var(--ion-background-color-rgb, $background-color-rgb-value) !default;
-$text-color: var(--ion-text-color, $text-color-value) !default;
-$text-color-rgb: var(--ion-text-color-rgb, $text-color-rgb-value) !default;
-
-// Default Foreground and Background Step Colors
-// -------------------------------------------------------------------------------------------
-// Color Steps are used to provide variations in text and background colors of elements.
-// Steps move towards their contrasting color.
-// For example, $text-color-step-XXX will be $text-color stepping towards $background-color,
-// but a $background-color-step-XXX will be $background-color stepping towards $text-color.
-
-$background-color-step-50: var(--ion-color-step-50, var(--ion-background-color-step-50, mix($text-color-value, $background-color-value, 5%))) !default;
-$background-color-step-100: var(--ion-color-step-100, var(--ion-background-color-step-100, mix($text-color-value, $background-color-value, 10%))) !default;
-$background-color-step-150: var(--ion-color-step-150, var(--ion-background-color-step-150, mix($text-color-value, $background-color-value, 15%))) !default;
-$background-color-step-200: var(--ion-color-step-200, var(--ion-background-color-step-200, mix($text-color-value, $background-color-value, 20%))) !default;
-$background-color-step-250: var(--ion-color-step-250, var(--ion-background-color-step-250, mix($text-color-value, $background-color-value, 25%))) !default;
-$background-color-step-300: var(--ion-color-step-300, var(--ion-background-color-step-300, mix($text-color-value, $background-color-value, 30%))) !default;
-$background-color-step-350: var(--ion-color-step-350, var(--ion-background-color-step-350, mix($text-color-value, $background-color-value, 35%))) !default;
-$background-color-step-400: var(--ion-color-step-400, var(--ion-background-color-step-400, mix($text-color-value, $background-color-value, 40%))) !default;
-$background-color-step-450: var(--ion-color-step-450, var(--ion-background-color-step-450, mix($text-color-value, $background-color-value, 45%))) !default;
-$background-color-step-500: var(--ion-color-step-500, var(--ion-background-color-step-500, mix($text-color-value, $background-color-value, 50%))) !default;
-$background-color-step-550: var(--ion-color-step-550, var(--ion-background-color-step-550, mix($text-color-value, $background-color-value, 55%))) !default;
-$background-color-step-600: var(--ion-color-step-600, var(--ion-background-color-step-600, mix($text-color-value, $background-color-value, 60%))) !default;
-$background-color-step-650: var(--ion-color-step-650, var(--ion-background-color-step-650, mix($text-color-value, $background-color-value, 65%))) !default;
-$background-color-step-700: var(--ion-color-step-700, var(--ion-background-color-step-700, mix($text-color-value, $background-color-value, 70%))) !default;
-$background-color-step-750: var(--ion-color-step-750, var(--ion-background-color-step-750, mix($text-color-value, $background-color-value, 75%))) !default;
-$background-color-step-800: var(--ion-color-step-800, var(--ion-background-color-step-800, mix($text-color-value, $background-color-value, 80%))) !default;
-$background-color-step-850: var(--ion-color-step-850, var(--ion-background-color-step-850, mix($text-color-value, $background-color-value, 85%))) !default;
-$background-color-step-900: var(--ion-color-step-900, var(--ion-background-color-step-900, mix($text-color-value, $background-color-value, 90%))) !default;
-$background-color-step-950: var(--ion-color-step-950, var(--ion-background-color-step-950, mix($text-color-value, $background-color-value, 95%))) !default;
-$text-color-step-50: var(--ion-color-step-950, var(--ion-text-color-step-50, mix($background-color-value, $text-color-value, 5%))) !default;
-$text-color-step-100: var(--ion-color-step-900, var(--ion-text-color-step-100, mix($background-color-value, $text-color-value, 10%))) !default;
-$text-color-step-150: var(--ion-color-step-850, var(--ion-text-color-step-150, mix($background-color-value, $text-color-value, 15%))) !default;
-$text-color-step-200: var(--ion-color-step-800, var(--ion-text-color-step-200, mix($background-color-value, $text-color-value, 20%))) !default;
-$text-color-step-250: var(--ion-color-step-750, var(--ion-text-color-step-250, mix($background-color-value, $text-color-value, 25%))) !default;
-$text-color-step-300: var(--ion-color-step-700, var(--ion-text-color-step-300, mix($background-color-value, $text-color-value, 30%))) !default;
-$text-color-step-350: var(--ion-color-step-650, var(--ion-text-color-step-350, mix($background-color-value, $text-color-value, 35%))) !default;
-$text-color-step-400: var(--ion-color-step-600, var(--ion-text-color-step-400, mix($background-color-value, $text-color-value, 40%))) !default;
-$text-color-step-450: var(--ion-color-step-550, var(--ion-text-color-step-450, mix($background-color-value, $text-color-value, 45%))) !default;
-$text-color-step-500: var(--ion-color-step-500, var(--ion-text-color-step-500, mix($background-color-value, $text-color-value, 50%))) !default;
-$text-color-step-550: var(--ion-color-step-450, var(--ion-text-color-step-550, mix($background-color-value, $text-color-value, 55%))) !default;
-$text-color-step-600: var(--ion-color-step-400, var(--ion-text-color-step-600, mix($background-color-value, $text-color-value, 60%))) !default;
-$text-color-step-650: var(--ion-color-step-350, var(--ion-text-color-step-650, mix($background-color-value, $text-color-value, 65%))) !default;
-$text-color-step-700: var(--ion-color-step-300, var(--ion-text-color-step-700, mix($background-color-value, $text-color-value, 70%))) !default;
-$text-color-step-750: var(--ion-color-step-250, var(--ion-text-color-step-750, mix($background-color-value, $text-color-value, 75%))) !default;
-$text-color-step-800: var(--ion-color-step-200, var(--ion-text-color-step-800, mix($background-color-value, $text-color-value, 80%))) !default;
-$text-color-step-850: var(--ion-color-step-150, var(--ion-text-color-step-850, mix($background-color-value, $text-color-value, 85%))) !default;
-$text-color-step-900: var(--ion-color-step-100, var(--ion-text-color-step-900, mix($background-color-value, $text-color-value, 90%))) !default;
-$text-color-step-950: var(--ion-color-step-50, var(--ion-text-color-step-950, mix($background-color-value, $text-color-value, 95%))) !default;
-
-// Default General Colors
-// --------------------------------------------------
-$placeholder-text-color: var(--ion-placeholder-color, $text-color-step-600) !default;
diff --git a/core/src/themes/ionic/ionic.globals.scss b/core/src/themes/ionic/ionic.globals.scss
new file mode 100644
index 0000000000..4eaf0bcd62
--- /dev/null
+++ b/core/src/themes/ionic/ionic.globals.scss
@@ -0,0 +1,12 @@
+// Design System scss vars based on Design Tokens
+@forward "../../foundations/ionic.vars.scss";
+
+// Global Mixins
+@forward "../mixins";
+
+// Global Utility Functions
+@forward "../functions.sizes";
+@forward "../functions.string";
+
+// Global Font Functions
+@forward "../functions.font";
diff --git a/core/src/themes/ionic.mixins.scss b/core/src/themes/mixins.scss
similarity index 98%
rename from core/src/themes/ionic.mixins.scss
rename to core/src/themes/mixins.scss
index da174046be..3cc5dc1537 100644
--- a/core/src/themes/ionic.mixins.scss
+++ b/core/src/themes/mixins.scss
@@ -1,4 +1,3 @@
-
/**
* A heuristic that applies CSS to tablet
* viewports.
@@ -43,11 +42,14 @@
height: 100%;
border: 0;
+
+ outline: none;
+
background: transparent;
+
cursor: pointer;
appearance: none;
- outline: none;
&::-moz-focus-inner {
border: 0;
@@ -58,40 +60,46 @@
position: absolute;
top: 0;
- left: 0;
right: 0;
bottom: 0;
+ left: 0;
width: 100%;
height: 100%;
margin: 0;
+
padding: 0;
border: 0;
+
outline: 0;
- clip: rect(0 0 0 0);
opacity: 0;
overflow: hidden;
+ clip: rect(0 0 0 0);
-webkit-appearance: none;
-moz-appearance: none;
}
@mixin text-inherit() {
+ color: inherit;
+
font-family: inherit;
font-size: inherit;
font-style: inherit;
font-weight: inherit;
+
letter-spacing: inherit;
+
+ text-align: inherit;
text-decoration: inherit;
text-indent: inherit;
text-overflow: inherit;
text-transform: inherit;
- text-align: inherit;
+
white-space: inherit;
- color: inherit;
}
@mixin button-state() {
@@ -119,7 +127,6 @@
@return nth($keys, $index);
}
-
// Breakpoint Mixins
// ---------------------------------------------------------------------------------
@@ -158,6 +165,7 @@
// Makes the @content apply to the given breakpoint and wider.
@mixin media-breakpoint-up($name, $breakpoints: $screen-breakpoints) {
$min: breakpoint-min($name, $breakpoints);
+
@if $min {
@media (min-width: $min) {
@content;
@@ -177,6 +185,7 @@
// md
@function breakpoint-next($name, $breakpoints: $screen-breakpoints, $breakpoint-names: map-keys($breakpoints)) {
$n: index($breakpoint-names, $name);
+
@return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);
}
@@ -192,13 +201,15 @@
// 767.98px
@function breakpoint-max($name, $breakpoints: $screen-breakpoints) {
$max: map-get($breakpoints, $name);
- @return if($max and $max > 0, $max - .02, null);
+
+ @return if($max and $max > 0, $max - 0.02, null);
}
// Media of at most the maximum breakpoint width. No query for the largest breakpoint.
// Makes the @content apply to the given breakpoint and narrower.
@mixin media-breakpoint-down($name, $breakpoints: $screen-breakpoints) {
$max: breakpoint-max($name, $breakpoints);
+
@if $max {
@media (max-width: $max) {
@content;
@@ -208,7 +219,6 @@
}
}
-
// Text Direction - ltr / rtl
//
// CSS defaults to use the ltr css, and adds [dir=rtl] selectors
@@ -292,7 +302,6 @@
@content;
}
-
// SVG Background Image Mixin
// @param {string} $svg
// ----------------------------------------------------------
@@ -312,9 +321,10 @@
$flipped-url: str-replace($flipped-url, "
@@ -369,7 +380,7 @@ $screen-breakpoints: (
sm: 576px,
md: 768px,
lg: 992px,
- xl: 1200px
+ xl: 1200px,
) !default;
```
@@ -418,7 +429,7 @@ $chip-avatar-size: math.div(24em, $chip-base-font-size);
// alert.vars.scss
/// @prop - Font size of the alert button
-$alert-button-font-size: dynamic-font(14px) !default;
+$alert-button-font-size: dynamic-font(14px) !default;
```
@@ -445,7 +456,7 @@ For example, the color of the label changes when focused in `md` mode. However,
// label.md.vars.scss
/// @prop - Text color of the stacked/floating label when it is focused
-$label-md-text-color-focused: ion-color(primary, base) !default;
+$label-md-text-color-focused: ion-color(primary, base) !default;
```
```scss
@@ -474,7 +485,7 @@ $label-md-text-color-focused: ion-color(primary, base) !default;
// label.ios.vars.scss
/// @prop - Text color of the stacked/floating label when it is focused
-$label-ios-text-color-focused: null !default;
+$label-ios-text-color-focused: null !default;
```
```scss
@@ -526,7 +537,7 @@ A text alignment property should not be stored in a Sass variable, even if it is
// action-sheet.ios.vars.scss
/// @prop - Text align of the action sheet
-$action-sheet-ios-text-align: center !default;
+$action-sheet-ios-text-align: center !default;
```
```scss
@@ -545,7 +556,6 @@ $action-sheet-ios-text-align: center !default;
-
#### 🚫 Structural Changes
Variables should not be used when they are structural changes of an element. This includes `display` properties, `flex` properties, `grid` properties, and more.
@@ -583,15 +593,14 @@ Variables should not be used when they are structural changes of an element. Thi
-
```scss
// alert.ios.vars.scss
/// @prop - Flex wrap of the alert button group
-$alert-ios-button-group-flex-wrap: wrap !default;
+$alert-ios-button-group-flex-wrap: wrap !default;
/// @prop - Flex of the alert button
-$alert-ios-button-flex: 1 1 auto !default;
+$alert-ios-button-flex: 1 1 auto !default;
```
```scss
@@ -653,13 +662,13 @@ We shouldn't use variables for changing things such as `font-size` or `font-weig
// action-sheet.ios.vars.scss
/// @prop - Font size of the action sheet title
-$action-sheet-ios-title-font-size: dynamic-font-min(1, 13px) !default;
+$action-sheet-ios-title-font-size: dynamic-font-min(1, 13px) !default;
/// @prop - Font weight of the action sheet title
-$action-sheet-ios-title-font-weight: 400 !default;
+$action-sheet-ios-title-font-weight: 400 !default;
/// @prop - Font size of the action sheet sub title
-$action-sheet-ios-sub-title-font-size: dynamic-font-min(1, 13px) !default;
+$action-sheet-ios-sub-title-font-size: dynamic-font-min(1, 13px) !default;
```
```scss
@@ -681,5 +690,4 @@ $action-sheet-ios-sub-title-font-size: dynamic-font-min(1, 13px) !default;
[^1]: Sass Documentation, https://sass-lang.com/documentation/
-
[^2]: Ionic Framework v3 Documentation - Theming - Overriding Ionic Variables, https://ionicframework.com/docs/v3/theming/overriding-ionic-variables/
diff --git a/packages/vue/src/vue-component-lib/utils.ts b/packages/vue/src/vue-component-lib/utils.ts
index 136041073e..492ee5d410 100644
--- a/packages/vue/src/vue-component-lib/utils.ts
+++ b/packages/vue/src/vue-component-lib/utils.ts
@@ -91,8 +91,17 @@ export const defineContainer = (
const eventsNames = Array.isArray(modelUpdateEvent) ? modelUpdateEvent : [modelUpdateEvent];
eventsNames.forEach((eventName: string) => {
el.addEventListener(eventName.toLowerCase(), (e: Event) => {
- modelPropValue = (e?.target as any)[modelProp];
- emit(UPDATE_VALUE_EVENT, modelPropValue);
+ /**
+ * Only update the v-model binding if the event's target is the element we are
+ * listening on. For example, Component A could emit ionChange, but it could also
+ * have a descendant Component B that also emits ionChange. We only want to update
+ * the v-model for Component A when ionChange originates from that element and not
+ * when ionChange bubbles up from Component B.
+ */
+ if (e.target.tagName === el.tagName) {
+ modelPropValue = (e?.target as any)[modelProp];
+ emit(UPDATE_VALUE_EVENT, modelPropValue);
+ }
});
});
},
|