Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
df394f2
fix(select-option): add rich content styles
thetaPC May 12, 2026
ce322f5
fix(action-sheet): add ionic theme
thetaPC May 12, 2026
db262b5
fix(action-sheet): add ionic theme
thetaPC May 13, 2026
c4aff48
test(action-sheet): add states page
thetaPC May 13, 2026
01cbf63
test(action-sheet): update states page
thetaPC May 13, 2026
d4680c5
fix(alert): add ionic theme
thetaPC May 13, 2026
bf4bc97
fix(action-sheet): split imports
thetaPC May 13, 2026
b3bd9ec
fix(alert): strip out imports
thetaPC May 14, 2026
2d7c760
fix(select-modal): update ionic theme
thetaPC May 14, 2026
03eb8d2
fix(action-sheet, alert): update ionic theme
thetaPC May 14, 2026
efc38be
fix(select-modal): update ionic theme
thetaPC May 14, 2026
6d01165
fix(action-sheet, alert, item): update ionic theme
thetaPC May 14, 2026
2305fc4
fix(alert): update ionic theme
thetaPC May 14, 2026
dce202e
test(action-sheet): update snapshots
thetaPC May 14, 2026
865d9af
fix(select-modal): update ionic theme
thetaPC May 14, 2026
5fa29e5
fix(select-popover): update ionic theme
thetaPC May 14, 2026
73f270d
fix(select-modal): update styles
thetaPC May 14, 2026
c7e177d
test(select): update order
thetaPC May 14, 2026
360a911
test(app): update snapshots
thetaPC May 14, 2026
5fda2dd
fix(many): improving cloning and add slot styles
thetaPC May 16, 2026
634408c
feat(alert): use ion-radio and ion-checkbox
thetaPC May 19, 2026
e26824c
Revert "feat(alert): use ion-radio and ion-checkbox"
thetaPC May 20, 2026
9c534e6
feat(select-option): add labelPlacement and justify props
thetaPC May 21, 2026
9b0e9f0
fix(alert): correct spot for radio
thetaPC May 21, 2026
b93a4cc
test(select-modal): update snapshots
thetaPC May 21, 2026
c9e6444
test(select-popover): update snapshots
thetaPC May 21, 2026
f968c7b
test(select): update snapshots
thetaPC May 21, 2026
7a4b385
test(alert): add label placement tests
thetaPC May 21, 2026
666a9a4
test(select-option): add label placement and justify tests
thetaPC May 21, 2026
cfc9b48
Merge branch 'next' of github.com:ionic-team/ionic-framework into FW-…
thetaPC May 21, 2026
c1c46cb
test(select): update snapshots
thetaPC May 21, 2026
3ea2a08
test(many): update snapshots
thetaPC May 21, 2026
a483e09
fix(select): preserve ion-icon props when slotted from frameworks
thetaPC May 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions core/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 18 additions & 0 deletions core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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;
Expand Down
52 changes: 39 additions & 13 deletions core/src/components/action-sheet/action-sheet.common.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import "./action-sheet.vars";
@use "../../themes/mixins" as mixins;

// Action Sheet
// --------------------------------------------------
Expand Down Expand Up @@ -41,34 +41,31 @@
--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) {
display: none;
}

.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;
Expand All @@ -81,7 +78,6 @@
min-height: var(--min-height);
max-height: var(--max-height);

z-index: $z-index-overlay-wrapper;
pointer-events: none;
}

Expand Down Expand Up @@ -109,6 +105,10 @@
opacity: 0.4;
}

.action-sheet-button:disabled ion-icon {
color: currentColor;
}

.action-sheet-button-inner {
display: flex;

Expand Down Expand Up @@ -177,7 +177,7 @@
// --------------------------------------------------

.action-sheet-button::after {
@include button-state();
@include mixins.button-state();
}

// Action Sheet: Selected
Expand Down Expand Up @@ -209,14 +209,20 @@
// Action Sheet: Focused
// --------------------------------------------------

.action-sheet-button.ion-focused {
.action-sheet-button.ion-focused:not(.ion-activated) {
color: var(--button-color-focused);

&::after {
background: var(--button-background-focused);

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));
}
Comment on lines +212 to +225
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By restructuring it this way, we are making sure that this style will be just a copy and paste for the Modular Ionic migration.

}

// Action Sheet: Hover
Expand All @@ -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;
}
122 changes: 118 additions & 4 deletions core/src/components/action-sheet/action-sheet.ionic.scss
Original file line number Diff line number Diff line change
@@ -1,22 +1,136 @@
@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
// --------------------------------------------------

.action-sheet-button-label {
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;
}
13 changes: 13 additions & 0 deletions core/src/components/action-sheet/action-sheet.ios.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
3 changes: 3 additions & 0 deletions core/src/components/action-sheet/action-sheet.ios.vars.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on what I found through iOS code and that it scales up.

15 changes: 14 additions & 1 deletion core/src/components/action-sheet/action-sheet.md.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@import "./action-sheet.native";
@import "./action-sheet.md.vars";

// Material Design Action Sheet Title
// Material Design Action Sheet
// -----------------------------------------

:host {
Expand Down Expand Up @@ -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;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on MD3

}
Loading
Loading