diff --git a/core/api.txt b/core/api.txt
index dafa0080ccf..d6ab0738408 100644
--- a/core/api.txt
+++ b/core/api.txt
@@ -2378,6 +2378,8 @@ ion-select-modal,prop,options,SelectModalOption[],[],false,false
ion-select-option,shadow
ion-select-option,prop,description,string | undefined,undefined,false,false
ion-select-option,prop,disabled,boolean,false,false,false
+ion-select-option,prop,justify,"end" | "space-between" | "start" | undefined,undefined,false,false
+ion-select-option,prop,labelPlacement,"end" | "start" | undefined,undefined,false,false
ion-select-option,prop,mode,"ios" | "md",undefined,false,false
ion-select-option,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-select-option,prop,value,any,undefined,false,false
diff --git a/core/src/components.d.ts b/core/src/components.d.ts
index c47221f63cb..787caa378d4 100644
--- a/core/src/components.d.ts
+++ b/core/src/components.d.ts
@@ -3863,6 +3863,14 @@ export namespace Components {
* @default false
*/
"disabled": boolean;
+ /**
+ * How to pack the label and the option's selection control within a line. `"start"`: The label and radio will appear on the left in LTR and on the right in RTL. `"end"`: The label and radio will appear on the right in LTR and on the left in RTL. `"space-between"`: The label and radio will appear on opposite ends of the line with space between the two elements. Applies to the `alert`, `popover`, and `modal` interfaces, but has no visible effect on radio options in `popover` or `modal` on the `md` and `ionic` themes (the radio control is hidden there). When unset, the interface picks a default based on theme and control type.
+ */
+ "justify"?: 'start' | 'end' | 'space-between';
+ /**
+ * Where the label is placed relative to the option's selection control (radio circle or checkbox box) when the option is rendered in an `alert`, `popover`, or `modal` interface. `"start"`: The label will appear to the left of the radio in LTR and to the right in RTL. `"end"`: The label will appear to the right of the radio in LTR and to the left in RTL. Applies to the `alert`, `popover`, and `modal` interfaces, but has no visible effect on radio options in `popover` or `modal` on the `md` and `ionic` themes (the radio control is hidden there). When unset, the interface picks a default based on theme and control type.
+ */
+ "labelPlacement"?: 'start' | 'end';
/**
* The mode determines the platform behaviors of the component.
*/
@@ -10002,6 +10010,14 @@ declare namespace LocalJSX {
* @default false
*/
"disabled"?: boolean;
+ /**
+ * How to pack the label and the option's selection control within a line. `"start"`: The label and radio will appear on the left in LTR and on the right in RTL. `"end"`: The label and radio will appear on the right in LTR and on the left in RTL. `"space-between"`: The label and radio will appear on opposite ends of the line with space between the two elements. Applies to the `alert`, `popover`, and `modal` interfaces, but has no visible effect on radio options in `popover` or `modal` on the `md` and `ionic` themes (the radio control is hidden there). When unset, the interface picks a default based on theme and control type.
+ */
+ "justify"?: 'start' | 'end' | 'space-between';
+ /**
+ * Where the label is placed relative to the option's selection control (radio circle or checkbox box) when the option is rendered in an `alert`, `popover`, or `modal` interface. `"start"`: The label will appear to the left of the radio in LTR and to the right in RTL. `"end"`: The label will appear to the right of the radio in LTR and to the left in RTL. Applies to the `alert`, `popover`, and `modal` interfaces, but has no visible effect on radio options in `popover` or `modal` on the `md` and `ionic` themes (the radio control is hidden there). When unset, the interface picks a default based on theme and control type.
+ */
+ "labelPlacement"?: 'start' | 'end';
/**
* The mode determines the platform behaviors of the component.
*/
@@ -11382,6 +11398,8 @@ declare namespace LocalJSX {
"disabled": boolean;
"value": string;
"description": string;
+ "labelPlacement": 'start' | 'end';
+ "justify": 'start' | 'end' | 'space-between';
}
interface IonSelectPopoverAttributes {
"header": string;
diff --git a/core/src/components/action-sheet/action-sheet.common.scss b/core/src/components/action-sheet/action-sheet.common.scss
index 7e857346ac9..0dfa5f3a29e 100644
--- a/core/src/components/action-sheet/action-sheet.common.scss
+++ b/core/src/components/action-sheet/action-sheet.common.scss
@@ -1,4 +1,4 @@
-@import "./action-sheet.vars";
+@use "../../themes/mixins" as mixins;
// Action Sheet
// --------------------------------------------------
@@ -41,25 +41,22 @@
--button-color-hover: var(--button-color);
--button-color-selected: var(--button-color);
--min-width: auto;
- --width: #{$action-sheet-width};
- --max-width: #{$action-sheet-max-width};
+ --width: 100%;
+ --max-width: 500px;
--min-height: auto;
--height: auto;
--max-height: calc(100% - (var(--ion-safe-area-top) + var(--ion-safe-area-bottom)));
- @include font-smoothing();
- @include position(0, 0, 0, 0);
+ @include mixins.font-smoothing();
+ @include mixins.position(0, 0, 0, 0);
display: block;
position: fixed;
outline: none;
- font-family: $font-family-base;
-
touch-action: none;
user-select: none;
- z-index: $z-index-overlay;
}
:host(.overlay-hidden) {
@@ -67,8 +64,8 @@
}
.action-sheet-wrapper {
- @include position(null, 0, 0, 0);
- @include transform(translate3d(0, 100%, 0));
+ @include mixins.position(null, 0, 0, 0);
+ @include mixins.transform(translate3d(0, 100%, 0));
display: block;
position: absolute;
@@ -81,7 +78,6 @@
min-height: var(--min-height);
max-height: var(--max-height);
- z-index: $z-index-overlay-wrapper;
pointer-events: none;
}
@@ -109,6 +105,10 @@
opacity: 0.4;
}
+.action-sheet-button:disabled ion-icon {
+ color: currentColor;
+}
+
.action-sheet-button-inner {
display: flex;
@@ -177,7 +177,7 @@
// --------------------------------------------------
.action-sheet-button::after {
- @include button-state();
+ @include mixins.button-state();
}
// Action Sheet: Selected
@@ -209,7 +209,7 @@
// Action Sheet: Focused
// --------------------------------------------------
-.action-sheet-button.ion-focused {
+.action-sheet-button.ion-focused:not(.ion-activated) {
color: var(--button-color-focused);
&::after {
@@ -217,6 +217,12 @@
opacity: var(--button-background-focused-opacity);
}
+
+ &.action-sheet-selected::after {
+ background: var(--button-background-focused, var(--button-background-selected));
+
+ opacity: var(--button-background-focused-opacity, var(--button-background-selected-opacity));
+ }
}
// Action Sheet: Hover
@@ -243,10 +249,30 @@
align-items: center;
}
+.action-sheet-button-label-has-rich-content,
.select-option-content {
flex: 1;
}
+.select-option-start,
+.select-option-end {
+ display: flex;
+
+ align-items: center;
+}
+
+/**
+ * Cap slotted children so they can't stretch the option
+ * row out of proportion, keeping rows visually uniform
+ * regardless of the content. ion-icon is excluded because
+ * its `contain: strict` makes intrinsic sizes resolve to 0,
+ * which would collapse the icon to zero width.
+ */
+.select-option-start > *:not(ion-icon),
+.select-option-end > *:not(ion-icon) {
+ max-width: fit-content;
+}
+
.select-option-description {
display: block;
}
diff --git a/core/src/components/action-sheet/action-sheet.ionic.scss b/core/src/components/action-sheet/action-sheet.ionic.scss
index b2c749d4e0a..b2877c9ce6e 100644
--- a/core/src/components/action-sheet/action-sheet.ionic.scss
+++ b/core/src/components/action-sheet/action-sheet.ionic.scss
@@ -1,10 +1,111 @@
@use "../../themes/ionic/ionic.globals.scss" as globals;
+@use "../../themes/mixins" as mixins;
@use "./action-sheet.common";
-@use "./action-sheet.md" as action-sheet-md;
// Ionic Action Sheet
// --------------------------------------------------
+:host {
+ --background: #{globals.$ion-bg-surface-default};
+ --backdrop-opacity: 0.7;
+ --button-background: transparent;
+ --button-background-selected: #{globals.$ion-semantics-primary-100};
+ --button-background-selected-opacity: 1;
+ --button-background-activated: #{globals.$ion-semantics-primary-100};
+ --button-background-activated-opacity: 1;
+ --button-background-hover: #{globals.$ion-semantics-primary-100};
+ --button-background-hover-opacity: 1;
+ --button-color: #{globals.$ion-text-default};
+ --button-color-disabled: #{globals.$ion-text-disabled};
+ --color: #{globals.$ion-text-default};
+
+ z-index: 1001;
+}
+
+.action-sheet-wrapper {
+ z-index: 10;
+}
+
+.action-sheet-button.ion-focused::after {
+ @include globals.focused-state(
+ globals.$ion-border-size-050,
+ globals.$ion-border-style-solid,
+ globals.$ion-border-focus-default
+ );
+
+ outline-offset: calc(globals.$ion-border-size-050 * -1);
+}
+
+// Action Sheet Wrapper
+// -----------------------------------------
+
+.action-sheet-wrapper {
+ @include mixins.margin(var(--ion-safe-area-top, 0), auto, 0, auto);
+}
+
+.action-sheet-title {
+ @include mixins.padding(globals.$ion-space-400);
+ @include globals.typography(globals.$ion-heading-h6-medium);
+
+ color: var(--color);
+
+ text-align: start;
+}
+
+.action-sheet-sub-title {
+ @include globals.typography(globals.$ion-body-md-regular);
+
+ color: globals.$ion-text-subtlest;
+}
+
+// Action Sheet Group
+// -----------------------------------------
+
+.action-sheet-group:first-child {
+ @include mixins.padding(globals.$ion-space-400, null, null, null);
+}
+
+.action-sheet-group:last-child {
+ @include mixins.padding(null, null, globals.$ion-space-400, null);
+}
+
+// Action Sheet Buttons
+// -----------------------------------------
+
+.action-sheet-button {
+ @include mixins.padding(
+ globals.$ion-space-300,
+ globals.$ion-space-400,
+ globals.$ion-space-300,
+ globals.$ion-space-400
+ );
+ @include globals.typography(globals.$ion-body-md-regular);
+
+ position: relative;
+
+ min-height: 52px;
+
+ text-align: start;
+
+ contain: content;
+ overflow: hidden;
+}
+
+.action-sheet-icon {
+ @include mixins.margin(globals.$ion-space-0, globals.$ion-space-600, globals.$ion-space-0, globals.$ion-space-0);
+ @include globals.typography(globals.$ion-body-md-regular);
+
+ color: var(--color, globals.$ion-text-default);
+}
+
+.action-sheet-button-inner {
+ justify-content: flex-start;
+}
+
+.action-sheet-selected {
+ font-weight: bold;
+}
+
// Action Sheet: Select Option
// --------------------------------------------------
@@ -12,11 +113,24 @@
gap: globals.$ion-space-300;
}
+.select-option-start,
+.select-option-end {
+ gap: globals.$ion-space-200;
+}
+
+/**
+ * Cap slotted children so they can't stretch the option
+ * row out of proportion, keeping rows visually uniform
+ * regardless of the content.
+ */
+.select-option-start > *,
+.select-option-end > * {
+ max-height: globals.$ion-scale-1200;
+}
+
.select-option-description {
@include globals.typography(globals.$ion-body-md-regular);
- @include globals.padding(0);
+ @include globals.padding(globals.$ion-space-0);
color: globals.$ion-text-subtle;
-
- font-size: globals.$ion-font-size-350;
}
diff --git a/core/src/components/action-sheet/action-sheet.ios.scss b/core/src/components/action-sheet/action-sheet.ios.scss
index 94b98447981..04485fe95c3 100644
--- a/core/src/components/action-sheet/action-sheet.ios.scss
+++ b/core/src/components/action-sheet/action-sheet.ios.scss
@@ -215,3 +215,16 @@
color: $action-sheet-ios-button-destructive-text-color;
}
}
+
+// Action Sheet: Select Option
+// --------------------------------------------------
+
+/**
+ * Cap slotted children so they can't stretch the option
+ * row out of proportion, keeping rows visually uniform
+ * regardless of the content.
+ */
+.select-option-start > *,
+.select-option-end > * {
+ max-height: $action-sheet-ios-select-option-slot-size;
+}
diff --git a/core/src/components/action-sheet/action-sheet.ios.vars.scss b/core/src/components/action-sheet/action-sheet.ios.vars.scss
index 0d2302b7183..6c301624c53 100644
--- a/core/src/components/action-sheet/action-sheet.ios.vars.scss
+++ b/core/src/components/action-sheet/action-sheet.ios.vars.scss
@@ -161,3 +161,6 @@ $action-sheet-ios-group-translucent-filter: saturate(280%) blur(20px);
/// @prop - Filter of the translucent action-sheet button
$action-sheet-ios-button-translucent-filter: saturate(120%);
+
+/// @prop - Maximum size of slotted children rendered in a select option's start/end slot
+$action-sheet-ios-select-option-slot-size: dynamic-font-max(24px, 2);
diff --git a/core/src/components/action-sheet/action-sheet.md.scss b/core/src/components/action-sheet/action-sheet.md.scss
index e46f06085b3..ef4134c2c63 100644
--- a/core/src/components/action-sheet/action-sheet.md.scss
+++ b/core/src/components/action-sheet/action-sheet.md.scss
@@ -1,7 +1,7 @@
@import "./action-sheet.native";
@import "./action-sheet.md.vars";
-// Material Design Action Sheet Title
+// Material Design Action Sheet
// -----------------------------------------
:host {
@@ -110,3 +110,16 @@
.action-sheet-selected {
font-weight: bold;
}
+
+// Action Sheet: Select Option
+// --------------------------------------------------
+
+/**
+ * Cap slotted children so they can't stretch the option
+ * row out of proportion, keeping rows visually uniform
+ * regardless of the content.
+ */
+.select-option-start > *,
+.select-option-end > * {
+ max-height: 24px;
+}
diff --git a/core/src/components/action-sheet/action-sheet.native.scss b/core/src/components/action-sheet/action-sheet.native.scss
index affa6aeb126..cdd91732bc6 100644
--- a/core/src/components/action-sheet/action-sheet.native.scss
+++ b/core/src/components/action-sheet/action-sheet.native.scss
@@ -1,4 +1,4 @@
-@use "../../themes/native/native.theme.default" as native;
+@use "../../themes/native/native.globals" as native;
@use "../../themes/mixins" as mixins;
@use "../../themes/functions.font" as font;
@use "./action-sheet.common";
@@ -6,10 +6,28 @@
// Action Sheet: Native
// --------------------------------------------------
+:host {
+ font-family: native.$font-family-base;
+
+ z-index: native.$z-index-overlay;
+}
+
+.action-sheet-wrapper {
+ z-index: native.$z-index-overlay-wrapper;
+}
+
+// Action Sheet: Select Option
+// --------------------------------------------------
+
.action-sheet-button-label {
gap: 12px;
}
+.select-option-start,
+.select-option-end {
+ gap: 8px;
+}
+
.select-option-description {
@include mixins.padding(5px, 0, 0, 0);
diff --git a/core/src/components/action-sheet/action-sheet.vars.scss b/core/src/components/action-sheet/action-sheet.vars.scss
deleted file mode 100644
index d81812ae23e..00000000000
--- a/core/src/components/action-sheet/action-sheet.vars.scss
+++ /dev/null
@@ -1,10 +0,0 @@
-@import "../../themes/native/native.globals";
-
-// Action Sheet
-// --------------------------------------------------
-
-/// @prop - Width of the action sheet
-$action-sheet-width: 100%;
-
-/// @prop - Maximum width of the action sheet
-$action-sheet-max-width: 500px;
diff --git a/core/src/components/action-sheet/test/basic/index.html b/core/src/components/action-sheet/test/basic/index.html
index b95d43b42c7..e7ec4e819ba 100644
--- a/core/src/components/action-sheet/test/basic/index.html
+++ b/core/src/components/action-sheet/test/basic/index.html
@@ -46,6 +46,8 @@
.my-color-class {
--background: #292929;
--button-background-selected: #222222;
+ --button-background-activated: #393838;
+ --button-background-activated-opacity: 1;
--color: #dfdfdf;
--button-color: #dfdfdf;
diff --git a/core/src/components/action-sheet/test/states/action-sheet.e2e.ts b/core/src/components/action-sheet/test/states/action-sheet.e2e.ts
new file mode 100644
index 00000000000..6929878f12b
--- /dev/null
+++ b/core/src/components/action-sheet/test/states/action-sheet.e2e.ts
@@ -0,0 +1,40 @@
+import { configs, test } from '@utils/test/playwright';
+
+import { ActionSheetFixture } from '../basic/fixture';
+
+/**
+ * This behavior does not vary across directions.
+ */
+configs({ directions: ['ltr'], modes: ['ios', 'md', 'ionic-md'] }).forEach(({ config, screenshot, title }) => {
+ test.describe(title('action sheet: states'), () => {
+ /**
+ * `(any-hover: hover)` evaluates to "none" in all three mobile-emulated
+ * projects, suppressing the hover rules:
+ *
+ * - Chromium and WebKit suppress it because of hasTouch and isMobile.
+ * - Headless Firefox doesn't detect input devices and reports no hover
+ * capability regardless of context options, so override it via
+ * launchOptions.firefoxUserPrefs. Bit values: 4 = FINE (mouse),
+ * 8 = HOVER, 12 = FINE | HOVER.
+ *
+ * Viewport, userAgent, and scale factor remain mobile-sized.
+ */
+ test.use({
+ hasTouch: false,
+ isMobile: false,
+ });
+
+ test('should render all button states', async ({ page }) => {
+ await page.goto(`/src/components/action-sheet/test/states`, config);
+
+ const actionSheetFixture = new ActionSheetFixture(page, screenshot);
+
+ await actionSheetFixture.open('#basic');
+
+ const defaultButton = page.locator('ion-action-sheet button.action-sheet-button').first();
+ await defaultButton.hover();
+
+ await actionSheetFixture.screenshot('states');
+ });
+ });
+});
diff --git a/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-ionic-md-ltr-light-Mobile-Chrome-linux.png b/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-ionic-md-ltr-light-Mobile-Chrome-linux.png
new file mode 100644
index 00000000000..756e33a6700
Binary files /dev/null and b/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-ionic-md-ltr-light-Mobile-Chrome-linux.png differ
diff --git a/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-ionic-md-ltr-light-Mobile-Firefox-linux.png b/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-ionic-md-ltr-light-Mobile-Firefox-linux.png
new file mode 100644
index 00000000000..8251dc17fe4
Binary files /dev/null and b/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-ionic-md-ltr-light-Mobile-Firefox-linux.png differ
diff --git a/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-ionic-md-ltr-light-Mobile-Safari-linux.png b/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-ionic-md-ltr-light-Mobile-Safari-linux.png
new file mode 100644
index 00000000000..00ab8017235
Binary files /dev/null and b/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-ionic-md-ltr-light-Mobile-Safari-linux.png differ
diff --git a/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-ios-ltr-Mobile-Chrome-linux.png b/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-ios-ltr-Mobile-Chrome-linux.png
new file mode 100644
index 00000000000..cf2d63235bb
Binary files /dev/null and b/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-ios-ltr-Mobile-Chrome-linux.png differ
diff --git a/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-ios-ltr-Mobile-Firefox-linux.png
new file mode 100644
index 00000000000..5ae3278c1b2
Binary files /dev/null and b/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-ios-ltr-Mobile-Firefox-linux.png differ
diff --git a/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-ios-ltr-Mobile-Safari-linux.png b/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-ios-ltr-Mobile-Safari-linux.png
new file mode 100644
index 00000000000..d03447bdf25
Binary files /dev/null and b/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-ios-ltr-Mobile-Safari-linux.png differ
diff --git a/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-md-ltr-Mobile-Chrome-linux.png b/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-md-ltr-Mobile-Chrome-linux.png
new file mode 100644
index 00000000000..290dd400493
Binary files /dev/null and b/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-md-ltr-Mobile-Chrome-linux.png differ
diff --git a/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-md-ltr-Mobile-Firefox-linux.png b/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-md-ltr-Mobile-Firefox-linux.png
new file mode 100644
index 00000000000..0b2cd5cb038
Binary files /dev/null and b/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-md-ltr-Mobile-Firefox-linux.png differ
diff --git a/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-md-ltr-Mobile-Safari-linux.png b/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-md-ltr-Mobile-Safari-linux.png
new file mode 100644
index 00000000000..1d3bc166290
Binary files /dev/null and b/core/src/components/action-sheet/test/states/action-sheet.e2e.ts-snapshots/action-sheet-states-diff-md-ltr-Mobile-Safari-linux.png differ
diff --git a/core/src/components/action-sheet/test/states/index.html b/core/src/components/action-sheet/test/states/index.html
new file mode 100644
index 00000000000..5d5339d5d1b
--- /dev/null
+++ b/core/src/components/action-sheet/test/states/index.html
@@ -0,0 +1,97 @@
+
+
+
+
+ Action Sheet - States
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Action Sheet - States
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/src/components/alert/alert.common.scss b/core/src/components/alert/alert.common.scss
index 84e35eca5c3..8ced6234f39 100644
--- a/core/src/components/alert/alert.common.scss
+++ b/core/src/components/alert/alert.common.scss
@@ -1,4 +1,5 @@
-@import "./alert.vars";
+@use "../../themes/functions.font" as font;
+@use "../../themes/mixins" as mixins;
// Alert
// --------------------------------------------------
@@ -17,14 +18,14 @@
*
* @prop --backdrop-opacity: Opacity of the backdrop
*/
- --min-width: #{$alert-min-width};
+ --min-width: 250px;
--width: auto;
--min-height: auto;
--height: auto;
- --max-height: #{$alert-max-height};
+ --max-height: 90%;
- @include font-smoothing();
- @include position(0, 0, 0, 0);
+ @include mixins.font-smoothing();
+ @include mixins.position(0, 0, 0, 0);
display: flex;
position: absolute;
@@ -34,12 +35,9 @@
outline: none;
- font-family: $font-family-base;
-
contain: strict;
touch-action: none;
user-select: none;
- z-index: $z-index-overlay;
}
:host(.overlay-hidden) {
@@ -47,7 +45,7 @@
}
:host(.alert-top) {
- @include padding(50px, null, null, null);
+ @include mixins.padding(50px, null, null, null);
align-items: flex-start;
}
@@ -69,17 +67,16 @@
contain: content;
opacity: 0;
- z-index: $z-index-overlay-wrapper;
}
.alert-title {
- @include margin(0);
- @include padding(0);
+ @include mixins.margin(0);
+ @include mixins.padding(0);
}
.alert-sub-title {
- @include margin(5px, 0, 0);
- @include padding(0);
+ @include mixins.margin(5px, 0, 0);
+ @include mixins.padding(0);
font-weight: normal;
}
@@ -140,7 +137,7 @@
}
.alert-input {
- @include padding(10px, 0);
+ @include mixins.padding(10px, 0);
width: 100%;
@@ -166,24 +163,19 @@
}
.alert-button {
- @include margin(0);
+ @include mixins.margin(0);
display: block;
border: 0;
- font-size: $alert-button-font-size;
+ font-size: font.dynamic-font(14px);
- line-height: $alert-button-line-height;
+ line-height: font.dynamic-font(20px);
z-index: 0;
}
-.alert-button.ion-focused,
-.alert-tappable.ion-focused {
- background: $background-color-step-100;
-}
-
.alert-button-inner {
display: flex;
@@ -198,6 +190,45 @@
min-height: inherit;
}
+// Alert Option: Label Placement
+// --------------------------------------------------
+
+/**
+ * Label is on the right of the radio in LTR and
+ * on the left in RTL.
+ */
+.radio-label-placement-start,
+.checkbox-label-placement-start {
+ flex-direction: row-reverse;
+}
+
+/**
+ * Label is on the left of the radio in LTR and
+ * on the right in RTL.
+ */
+.radio-label-placement-end,
+.checkbox-label-placement-end {
+ flex-direction: row;
+}
+
+// Alert Option: Justify
+// --------------------------------------------------
+
+.radio-justify-start,
+.checkbox-justify-start {
+ justify-content: start;
+}
+
+.radio-justify-end,
+.checkbox-justify-end {
+ justify-content: end;
+}
+
+.radio-justify-space-between,
+.checkbox-justify-space-between {
+ justify-content: space-between;
+}
+
// Alert Button: Disabled
// --------------------------------------------------
.alert-input-disabled,
@@ -209,8 +240,8 @@
}
.alert-tappable {
- @include margin(0);
- @include padding(0);
+ @include mixins.margin(0);
+ @include mixins.padding(0);
display: flex;
@@ -244,7 +275,7 @@
}
textarea.alert-input {
- min-height: $alert-input-min-height;
+ min-height: 37px;
resize: none;
}
@@ -258,10 +289,38 @@ textarea.alert-input {
align-items: center;
}
+/**
+ * Rich-content rows have inner pieces (start, content, description, end)
+ * that need the label to span the available row width.
+ */
+.alert-radio-label-has-rich-content,
+.alert-checkbox-label-has-rich-content {
+ flex: 1;
+}
+
.select-option-content {
flex: 1;
}
+.select-option-start,
+.select-option-end {
+ display: flex;
+
+ align-items: center;
+}
+
+/**
+ * Cap slotted children so they can't stretch the option
+ * row out of proportion, keeping rows visually uniform
+ * regardless of the content. ion-icon is excluded because
+ * its `contain: strict` makes intrinsic sizes resolve to 0,
+ * which would collapse the icon to zero width.
+ */
+.select-option-start > *:not(ion-icon),
+.select-option-end > *:not(ion-icon) {
+ max-width: fit-content;
+}
+
.select-option-description {
display: block;
}
diff --git a/core/src/components/alert/alert.ionic.scss b/core/src/components/alert/alert.ionic.scss
index 3c54136b477..1e493afc787 100644
--- a/core/src/components/alert/alert.ionic.scss
+++ b/core/src/components/alert/alert.ionic.scss
@@ -1,10 +1,373 @@
@use "../../themes/ionic/ionic.globals.scss" as globals;
+@use "../../themes/mixins" as mixins;
@use "./alert.common";
-@use "./alert.md" as alert-md;
// Ionic Alert
// --------------------------------------------------
+:host {
+ --background: #{globals.$ion-bg-surface-default};
+ --max-width: #{globals.$ion-scale-7400};
+ --backdrop-opacity: 0.7;
+
+ z-index: 1001;
+}
+
+.alert-wrapper {
+ @include globals.border-radius(globals.$ion-border-radius-200);
+
+ box-shadow: globals.$ion-elevation-4;
+
+ z-index: 10;
+}
+
+.alert-button.ion-focused {
+ @include globals.focused-state(
+ globals.$ion-border-size-050,
+ globals.$ion-border-style-solid,
+ globals.$ion-border-focus-default
+ );
+}
+
+.alert-tappable.ion-focused {
+ @include globals.focused-state(
+ globals.$ion-border-size-050,
+ globals.$ion-border-style-solid,
+ globals.$ion-border-focus-default
+ );
+
+ outline-offset: calc(globals.$ion-border-size-050 * -1);
+}
+
+.alert-tappable.ion-activated,
+.alert-tappable:not(:disabled):hover,
+.alert-tappable[aria-checked="true"] {
+ background: globals.$ion-semantics-primary-100;
+}
+
+// Ionic Alert Header
+// --------------------------------------------------
+
+.alert-head {
+ @include mixins.padding(globals.$ion-space-400);
+
+ text-align: start;
+}
+
+.alert-title {
+ @include globals.typography(globals.$ion-heading-h6-medium);
+
+ color: globals.$ion-text-default;
+}
+
+.alert-sub-title {
+ @include globals.typography(globals.$ion-body-md-regular);
+
+ color: globals.$ion-text-subtlest;
+}
+
+// Ionic Alert Message
+// --------------------------------------------------
+
+.alert-message,
+.alert-input-group {
+ @include globals.typography(globals.$ion-body-md-regular);
+ @include mixins.padding(globals.$ion-space-400);
+
+ color: globals.$ion-text-default;
+}
+
+/**
+ * Ionic Alerts on tablets can expand vertically up to
+ * a total maximum height. We only want to set a max-height
+ * on mobile phones.
+ */
+@include globals.mobile-viewport() {
+ .alert-message {
+ max-height: globals.$ion-scale-6200;
+ }
+}
+
+.alert-message:empty {
+ @include mixins.padding(globals.$ion-space-0);
+}
+
+.alert-head + .alert-message {
+ padding-top: globals.$ion-space-0;
+}
+
+// Ionic Alert Input
+// --------------------------------------------------
+
+.alert-input {
+ @include mixins.margin(globals.$ion-space-150, 0);
+
+ border-bottom: globals.$ion-border-size-025 globals.$ion-border-style-solid globals.$ion-border-input-default;
+
+ color: globals.$ion-text-default;
+
+ &::placeholder {
+ color: globals.$ion-text-subtlest;
+
+ font-family: inherit;
+ font-weight: inherit;
+ }
+
+ &::-ms-clear {
+ display: none;
+ }
+}
+
+.alert-input:focus {
+ @include mixins.margin(null, null, globals.$ion-scale-100, null);
+
+ border-bottom: globals.$ion-border-size-050 globals.$ion-border-style-solid globals.$ion-border-focus-default;
+}
+
+// Ionic Alert Radio/Checkbox Group
+// --------------------------------------------------
+
+.alert-radio-group,
+.alert-checkbox-group {
+ position: relative;
+
+ border-top: globals.$ion-border-size-025 globals.$ion-border-style-solid globals.$ion-border-default;
+ border-bottom: globals.$ion-border-size-025 globals.$ion-border-style-solid globals.$ion-border-default;
+
+ overflow: auto;
+}
+
+/**
+ * Ionic Alerts on tablets can expand vertically up to
+ * a total maximum height. We only want to set a max-height
+ * on mobile phones.
+ */
+@include globals.mobile-viewport() {
+ .alert-radio-group,
+ .alert-checkbox-group {
+ max-height: globals.$ion-scale-6200;
+ }
+}
+
+.alert-tappable {
+ position: relative;
+
+ min-height: globals.$ion-scale-1200;
+}
+
+// Ionic Alert Radio
+// --------------------------------------------------
+
+.alert-radio-label {
+ @include globals.typography(globals.$ion-body-md-regular);
+ @include mixins.padding(
+ globals.$ion-space-300,
+ globals.$ion-space-700,
+ globals.$ion-space-300,
+ globals.$ion-scale-1400
+ );
+
+ // Required for the radio icon to stay on the screen without
+ // being squished when the font size scales up.
+ max-width: calc(100% - globals.$ion-space-700);
+
+ color: globals.$ion-text-default;
+}
+
+.radio-label-placement-start .alert-radio-label {
+ /**
+ * The label's inline padding clears space for the icon on the
+ * icon's side. When the label is placed at the start, the icon
+ * is at the end, so swap the inline paddings to mirror that geometry.
+ */
+ @include mixins.padding-horizontal(globals.$ion-space-700, globals.$ion-scale-1400);
+}
+
+// Ionic Alert Radio Outer Circle: Unchecked
+// ---------------------------------------------------
+
+.alert-radio-icon {
+ @include globals.position(globals.$ion-space-0, null, null, null);
+ @include globals.border-radius(globals.$ion-border-radius-full);
+
+ display: flex;
+ position: relative;
+
+ align-items: center;
+ justify-content: center;
+
+ width: globals.$ion-scale-600;
+ height: globals.$ion-scale-600;
+
+ border-width: globals.$ion-border-size-025;
+ border-style: globals.$ion-border-style-solid;
+ border-color: globals.$ion-border-input-default;
+
+ background-color: globals.$ion-bg-input-default;
+
+ box-sizing: border-box;
+}
+
+// The icon's inline offset gives it a gap from whichever edge the icon
+// sits on, which depends on label placement
+.radio-label-placement-start .alert-radio-icon {
+ @include globals.position-horizontal(null, globals.$ion-space-700);
+}
+
+.radio-label-placement-end .alert-radio-icon {
+ @include globals.position-horizontal(globals.$ion-space-700, null);
+}
+
+// Ionic Alert Radio Inner Dot
+// ---------------------------------------------------
+
+.alert-radio-inner {
+ @include globals.border-radius(50%);
+
+ width: calc(32% + globals.$ion-border-size-025);
+ height: calc(32% + globals.$ion-border-size-025);
+
+ background-color: globals.$ion-bg-surface-inverse;
+
+ box-sizing: border-box;
+}
+
+// Ionic Alert Radio Outer Circle: Checked
+// ---------------------------------------------------
+
+[aria-checked="true"] .alert-radio-icon {
+ border-color: globals.$ion-bg-primary-base-default;
+
+ background-color: globals.$ion-bg-primary-base-default;
+}
+
+// Ionic Alert Checkbox Label
+// --------------------------------------------------
+
+.alert-checkbox-label {
+ @include globals.typography(globals.$ion-body-md-regular);
+ @include mixins.padding(
+ globals.$ion-space-300,
+ globals.$ion-space-700,
+ globals.$ion-space-300,
+ globals.$ion-scale-1400
+ );
+
+ // Required for the checkbox icon to stay on the screen without
+ // being squished when the font size scales up.
+ max-width: calc(100% - globals.$ion-space-700);
+
+ color: globals.$ion-text-default;
+}
+
+.checkbox-label-placement-start .alert-checkbox-label {
+ /**
+ * The label's inline padding clears space for the icon on the
+ * icon's side. When the label is placed at the start, the icon
+ * is at the end, so swap the inline paddings to mirror that geometry.
+ */
+ @include mixins.padding-horizontal(globals.$ion-space-700, globals.$ion-scale-1400);
+}
+
+// Ionic Alert Checkbox Outline: Unchecked
+// --------------------------------------------------
+
+.alert-checkbox-icon {
+ @include globals.position(globals.$ion-space-0, null, null, null);
+ @include globals.border-radius(globals.$ion-border-radius-100);
+
+ display: flex;
+ position: relative;
+
+ align-items: center;
+ justify-content: center;
+
+ width: globals.$ion-scale-600;
+ height: globals.$ion-scale-600;
+
+ border-width: globals.$ion-border-size-025;
+ border-style: globals.$ion-border-style-solid;
+ border-color: globals.$ion-primitives-neutral-800;
+
+ background-color: globals.$ion-bg-input-default;
+
+ box-sizing: border-box;
+}
+
+// The icon's inline offset gives it a gap from whichever edge the icon
+// sits on, which depends on label placement
+.checkbox-label-placement-end .alert-checkbox-icon {
+ @include globals.position-horizontal(globals.$ion-space-700, null);
+}
+
+.checkbox-label-placement-start .alert-checkbox-icon {
+ @include globals.position-horizontal(null, globals.$ion-space-700);
+}
+
+.alert-checkbox-inner {
+ width: globals.$ion-scale-400;
+ height: globals.$ion-scale-400;
+}
+
+.alert-checkbox-inner path {
+ fill: globals.$ion-bg-surface-default;
+}
+
+// Ionic Alert Checkbox Checkmark: Checked
+// --------------------------------------------------
+
+[aria-checked="true"] .alert-checkbox-icon {
+ border-color: globals.$ion-semantics-primary-base;
+
+ background-color: globals.$ion-bg-primary-base-default;
+}
+
+// Ionic Alert Button
+// --------------------------------------------------
+
+.alert-button-group {
+ @include mixins.padding(8px);
+
+ box-sizing: border-box;
+
+ flex-wrap: wrap-reverse;
+ justify-content: flex-end;
+}
+
+.alert-button {
+ @include globals.border-radius(globals.$ion-border-size-050);
+ @include mixins.margin(globals.$ion-space-0, globals.$ion-space-200, globals.$ion-space-0, globals.$ion-space-0);
+ @include mixins.padding(globals.$ion-space-250);
+
+ // necessary for ripple to work properly
+ position: relative;
+
+ background-color: transparent;
+ color: globals.ion-color(primary, base);
+
+ font-weight: globals.$ion-font-weight-medium;
+
+ text-align: end;
+ text-transform: uppercase;
+
+ overflow: hidden;
+}
+
+.alert-button .alert-button-inner {
+ justify-content: flex-end;
+}
+
+/**
+ * Ionic alerts should scale up to 560px x 560px
+ * on tablet dimensions.
+ */
+@include globals.tablet-viewport() {
+ :host {
+ --max-width: #{min(calc(100vw - 96px), 560px)};
+ --max-height: #{min(calc(100vh - 96px), 560px)};
+ }
+}
+
// Alert: Select Option
// --------------------------------------------------
@@ -13,9 +376,24 @@
gap: globals.$ion-space-300;
}
+.select-option-start,
+.select-option-end {
+ gap: globals.$ion-space-200;
+}
+
+/**
+ * Cap slotted children so they can't stretch the option
+ * row out of proportion, keeping rows visually uniform
+ * regardless of the content.
+ */
+.select-option-start > *,
+.select-option-end > * {
+ max-height: globals.$ion-scale-1200;
+}
+
.select-option-description {
@include globals.typography(globals.$ion-body-md-regular);
- @include globals.padding(0);
+ @include mixins.padding(globals.$ion-space-0);
color: globals.$ion-text-subtle;
diff --git a/core/src/components/alert/alert.ios.scss b/core/src/components/alert/alert.ios.scss
index 2671dc0940b..091b9caf69c 100644
--- a/core/src/components/alert/alert.ios.scss
+++ b/core/src/components/alert/alert.ios.scss
@@ -166,9 +166,6 @@
$alert-ios-radio-label-padding-start
);
- flex: 1;
- order: 0;
-
color: $alert-ios-radio-label-text-color;
}
@@ -185,7 +182,7 @@
.alert-radio-icon {
position: relative;
- order: 1;
+ flex-shrink: 0;
min-width: $alert-ios-radio-min-width;
}
@@ -194,7 +191,7 @@
// -----------------------------------------
[aria-checked="true"] .alert-radio-inner {
- @include position($alert-ios-radio-icon-top, null, null, $alert-ios-radio-icon-start);
+ @include position($alert-ios-radio-icon-top, null, null, null);
position: absolute;
@@ -210,6 +207,16 @@
border-color: $alert-ios-radio-icon-border-color;
}
+// The icon's inline offset gives it a gap from whichever edge the icon
+// sits on, which depends on label placement
+[aria-checked="true"] .radio-label-placement-end .alert-radio-inner {
+ @include position-horizontal(null, $alert-ios-radio-icon-start);
+}
+
+[aria-checked="true"] .radio-label-placement-start .alert-radio-inner {
+ @include position-horizontal($alert-ios-radio-icon-start, null);
+}
+
// iOS Alert Checkbox Label
// --------------------------------------------------
@@ -221,8 +228,6 @@
$alert-ios-checkbox-label-padding-start
);
- flex: 1;
-
color: $alert-ios-checkbox-label-text-color;
}
@@ -231,15 +236,12 @@
.alert-checkbox-icon {
@include border-radius($alert-ios-checkbox-border-radius);
- @include margin(
- $alert-ios-checkbox-margin-top,
- $alert-ios-checkbox-margin-end,
- $alert-ios-checkbox-margin-bottom,
- $alert-ios-checkbox-margin-start
- );
+ @include margin($alert-ios-checkbox-margin-top, null, $alert-ios-checkbox-margin-bottom, null);
position: relative;
+ flex-shrink: 0;
+
width: $alert-ios-checkbox-size;
height: $alert-ios-checkbox-size;
@@ -252,6 +254,17 @@
contain: strict;
}
+// The icon's inline margins are asymmetric (larger gap from the row
+// edge, smaller gap toward the label), so they swap with label
+// placement.
+.checkbox-label-placement-end .alert-checkbox-icon {
+ @include margin-horizontal($alert-ios-checkbox-margin-start, $alert-ios-checkbox-margin-end);
+}
+
+.checkbox-label-placement-start .alert-checkbox-icon {
+ @include margin-horizontal($alert-ios-checkbox-margin-end, $alert-ios-checkbox-margin-start);
+}
+
// iOS Alert Checkbox Outer Circle: Checked
// -----------------------------------------
@@ -265,7 +278,7 @@
// -----------------------------------------
[aria-checked="true"] .alert-checkbox-inner {
- @include position($alert-ios-checkbox-icon-top, null, null, $alert-ios-checkbox-icon-start);
+ @include position($alert-ios-checkbox-icon-top, null, null, null);
position: absolute;
@@ -281,6 +294,16 @@
border-color: $alert-ios-checkbox-icon-border-color;
}
+// The icon's inline offset gives it a gap from whichever edge the icon
+// sits on, which depends on label placement
+[aria-checked="true"] .checkbox-label-placement-end .alert-checkbox-inner {
+ @include position-horizontal($alert-ios-checkbox-icon-start, null);
+}
+
+[aria-checked="true"] .checkbox-label-placement-start .alert-checkbox-inner {
+ @include position-horizontal(null, $alert-ios-checkbox-icon-start);
+}
+
// iOS Alert Button
// --------------------------------------------------
@@ -352,7 +375,7 @@
background-color: $alert-ios-button-background-color-activated;
}
-// iOS Action Sheet Button: Destructive
+// iOS Alert Button: Destructive
// ---------------------------------------------------
.alert-button-role-destructive,
@@ -360,3 +383,16 @@
.alert-button-role-destructive.ion-focused {
color: $alert-ios-button-destructive-text-color;
}
+
+// Alert: Select Option
+// --------------------------------------------------
+
+/**
+ * Cap slotted children so they can't stretch the option
+ * row out of proportion, keeping rows visually uniform
+ * regardless of the content.
+ */
+.select-option-start > *,
+.select-option-end > * {
+ max-height: $alert-ios-select-option-slot-size;
+}
diff --git a/core/src/components/alert/alert.ios.vars.scss b/core/src/components/alert/alert.ios.vars.scss
index 2cb4fca98af..c1d0539278c 100644
--- a/core/src/components/alert/alert.ios.vars.scss
+++ b/core/src/components/alert/alert.ios.vars.scss
@@ -316,3 +316,6 @@ $alert-ios-translucent-filter: saturate(180%) blur(20px);
/// @prop - Height of the tappable inputs in the checkbox alert
$alert-ios-tappable-height: $item-ios-min-height;
+
+/// @prop - Maximum size of slotted children rendered in a select option's start/end slot
+$alert-ios-select-option-slot-size: dynamic-font-max(24px, 2);
diff --git a/core/src/components/alert/alert.md.scss b/core/src/components/alert/alert.md.scss
index 2fbd0fd8775..185f9671193 100644
--- a/core/src/components/alert/alert.md.scss
+++ b/core/src/components/alert/alert.md.scss
@@ -164,18 +164,29 @@
$alert-md-radio-label-padding-start
);
- flex: 1;
+ // Required for the radio icon to stay on the screen without
+ // being squished when the font size scales up.
+ max-width: calc(100% - $alert-md-radio-left);
color: $alert-md-radio-label-text-color;
font-size: $alert-md-radio-label-font-size;
}
+.radio-label-placement-start .alert-radio-label {
+ /**
+ * The label's inline padding clears space for the icon on the
+ * icon's side. When the label is placed at the start, the icon
+ * is at the end, so swap the inline paddings to mirror that geometry.
+ */
+ @include padding-horizontal($alert-md-radio-label-padding-end, $alert-md-radio-label-padding-start);
+}
+
// Material Design Alert Radio Unchecked Circle
// ---------------------------------------------------
.alert-radio-icon {
- @include position($alert-md-radio-top, null, null, $alert-md-radio-left);
+ @include position($alert-md-radio-top, null, null, null);
@include border-radius($alert-md-radio-border-radius);
display: block;
@@ -189,6 +200,16 @@
border-color: $alert-md-radio-border-color-off;
}
+// The icon's inline offset gives it a gap from whichever edge the icon
+// sits on, which depends on label placement
+.radio-label-placement-end .alert-radio-icon {
+ @include position-horizontal($alert-md-radio-left, null);
+}
+
+.radio-label-placement-start .alert-radio-icon {
+ @include position-horizontal(null, $alert-md-radio-left);
+}
+
// Material Design Alert Radio Checked Dot
// ---------------------------------------------------
@@ -234,22 +255,29 @@
$alert-md-checkbox-label-padding-start
);
- flex: 1;
-
// Required for the checkbox icon to stay on the screen without
// being squished when the font size scales up.
- width: calc(100% - $alert-md-checkbox-label-padding-start);
+ max-width: calc(100% - $alert-md-checkbox-left);
color: $alert-md-checkbox-label-text-color;
font-size: $alert-md-checkbox-label-font-size;
}
+.checkbox-label-placement-start .alert-checkbox-label {
+ /**
+ * The label's inline padding clears space for the icon on the
+ * icon's side. When the label is placed at the start, the icon
+ * is at the end, so swap the inline paddings to mirror that geometry.
+ */
+ @include padding-horizontal($alert-md-checkbox-label-padding-end, $alert-md-checkbox-label-padding-start);
+}
+
// Material Design Alert Checkbox Outline: Unchecked
// --------------------------------------------------
.alert-checkbox-icon {
- @include position($alert-md-checkbox-top, null, null, $alert-md-checkbox-left);
+ @include position($alert-md-checkbox-top, null, null, null);
@include border-radius($alert-md-checkbox-border-radius);
position: relative;
@@ -264,6 +292,16 @@
contain: strict;
}
+// The icon's inline offset gives it a gap from whichever edge the icon
+// sits on, which depends on label placement
+.checkbox-label-placement-end .alert-checkbox-icon {
+ @include position-horizontal($alert-md-checkbox-left, null);
+}
+
+.checkbox-label-placement-start .alert-checkbox-icon {
+ @include position-horizontal(null, $alert-md-checkbox-left);
+}
+
// Material Design Alert Checkbox Checkmark: Checked
// --------------------------------------------------
@@ -331,7 +369,7 @@
overflow: hidden;
}
-.alert-button-inner {
+.alert-button .alert-button-inner {
justify-content: $alert-md-button-group-justify-content;
}
@@ -345,3 +383,16 @@
--max-height: #{$alert-md-max-height-tablet};
}
}
+
+// Alert: Select Option
+// --------------------------------------------------
+
+/**
+ * Cap slotted children so they can't stretch the option
+ * row out of proportion, keeping rows visually uniform
+ * regardless of the content.
+ */
+.select-option-start > *,
+.select-option-end > * {
+ max-height: 24px;
+}
diff --git a/core/src/components/alert/alert.native.scss b/core/src/components/alert/alert.native.scss
index e2d5a87b8a5..d7cf5c086d3 100644
--- a/core/src/components/alert/alert.native.scss
+++ b/core/src/components/alert/alert.native.scss
@@ -1,4 +1,4 @@
-@use "../../themes/native/native.theme.default" as native;
+@use "../../themes/native/native.globals" as native;
@use "../../themes/mixins" as mixins;
@use "../../themes/functions.font" as font;
@use "./alert.common";
@@ -6,11 +6,34 @@
// Alert: Native
// --------------------------------------------------
+:host {
+ font-family: native.$font-family-base;
+
+ z-index: native.$z-index-overlay;
+}
+
+.alert-wrapper {
+ z-index: native.$z-index-overlay-wrapper;
+}
+
+.alert-button.ion-focused,
+.alert-tappable.ion-focused {
+ background: native.$background-color-step-100;
+}
+
+// Alert: Select Option
+// --------------------------------------------------
+
.alert-radio-label,
.alert-checkbox-label {
gap: 12px;
}
+.select-option-start,
+.select-option-end {
+ gap: 8px;
+}
+
.select-option-description {
@include mixins.padding(5px, 0, 0, 0);
diff --git a/core/src/components/alert/alert.tsx b/core/src/components/alert/alert.tsx
index e44077d0f86..44adc065aa9 100644
--- a/core/src/components/alert/alert.tsx
+++ b/core/src/components/alert/alert.tsx
@@ -6,6 +6,7 @@ import { createButtonActiveGesture } from '@utils/gesture/button-active';
import { raf } from '@utils/helpers';
import { createLockController } from '@utils/lock-controller';
import { printIonWarning } from '@utils/logging';
+import { getOverlayLabelJustify, getOverlayLabelPlacement } from '@utils/overlay-control-label';
import {
createDelegateController,
createTriggerController,
@@ -603,6 +604,8 @@ export class Alert implements ComponentInterface, OverlayInterface {
endContent: richInput.endContent,
description: richInput.description,
};
+ const defaultLabelPlacement = getOverlayLabelPlacement(theme, 'checkbox');
+ const defaultJustify = getOverlayLabelJustify(theme, 'checkbox');
return (