Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions core/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2326,6 +2326,24 @@ ion-select,css-prop,--placeholder-opacity,md
ion-select,css-prop,--ripple-color,ionic
ion-select,css-prop,--ripple-color,ios
ion-select,css-prop,--ripple-color,md
ion-select,css-prop,--select-text-media-border-color,ionic
ion-select,css-prop,--select-text-media-border-color,ios
ion-select,css-prop,--select-text-media-border-color,md
ion-select,css-prop,--select-text-media-border-radius,ionic
ion-select,css-prop,--select-text-media-border-radius,ios
ion-select,css-prop,--select-text-media-border-radius,md
ion-select,css-prop,--select-text-media-border-style,ionic
ion-select,css-prop,--select-text-media-border-style,ios
ion-select,css-prop,--select-text-media-border-style,md
ion-select,css-prop,--select-text-media-border-width,ionic
ion-select,css-prop,--select-text-media-border-width,ios
ion-select,css-prop,--select-text-media-border-width,md
ion-select,css-prop,--select-text-media-height,ionic
ion-select,css-prop,--select-text-media-height,ios
ion-select,css-prop,--select-text-media-height,md
ion-select,css-prop,--select-text-media-width,ionic
ion-select,css-prop,--select-text-media-width,ios
ion-select,css-prop,--select-text-media-width,md
ion-select,part,bottom
ion-select,part,container
ion-select,part,error-text
Expand All @@ -2345,6 +2363,7 @@ ion-select-modal,prop,multiple,boolean | undefined,undefined,false,false
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,mode,"ios" | "md",undefined,false,false
ion-select-option,prop,theme,"ios" | "md" | "ionic",undefined,false,false
Expand Down
9 changes: 9 additions & 0 deletions core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3813,6 +3813,10 @@ export namespace Components {
"options": SelectModalOption[];
}
interface IonSelectOption {
/**
* Text that is placed underneath the option text to provide additional details about the option.
*/
"description"?: string;
/**
* If `true`, the user cannot interact with the select option. This property does not apply when `interface="action-sheet"` as `ion-action-sheet` does not allow for disabled buttons.
* @default false
Expand Down Expand Up @@ -9897,6 +9901,10 @@ declare namespace LocalJSX {
"options"?: SelectModalOption[];
}
interface IonSelectOption {
/**
* Text that is placed underneath the option text to provide additional details about the option.
*/
"description"?: string;
/**
* If `true`, the user cannot interact with the select option. This property does not apply when `interface="action-sheet"` as `ion-action-sheet` does not allow for disabled buttons.
* @default false
Expand Down Expand Up @@ -11268,6 +11276,7 @@ declare namespace LocalJSX {
interface IonSelectOptionAttributes {
"disabled": boolean;
"value": string;
"description": string;
}
interface IonSelectPopoverAttributes {
"header": string;
Expand Down
5 changes: 4 additions & 1 deletion core/src/components/action-sheet/action-sheet-interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export interface ActionSheetOptions extends OverlayOptions {
}

export interface ActionSheetButton<T = any> {
text?: string;
text?: string | HTMLElement;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Widening text from string to string | HTMLElement here affects all action-sheet consumers, not just select-driven ones. Same with AlertInput.label. Anyone calling actionSheetController.create() who does button.text.toLowerCase() or passes text to a string-typed function will get TS errors. Since this targets next, breaking changes are expected, but would it be cleaner to add a separate property (e.g., richText or contentElement) for the HTMLElement case? That way existing string usage stays untouched.

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.

Great point! cc0af05 and 49e0e6c

role?: LiteralUnion<'cancel' | 'destructive' | 'selected', string>;
icon?: string;
cssClass?: string | string[];
Expand All @@ -30,4 +30,7 @@ export interface ActionSheetButton<T = any> {
* users to dismiss the action sheet.
*/
disabled?: boolean;
startContent?: HTMLElement;
endContent?: HTMLElement;
description?: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -233,3 +233,20 @@
}
}
}

// Action Sheet: Select Option
// --------------------------------------------------

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

align-items: center;
}

.select-option-content {
flex: 1;
}

.select-option-description {
display: block;
}
22 changes: 22 additions & 0 deletions core/src/components/action-sheet/action-sheet.ionic.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@use "../../themes/ionic/ionic.globals.scss" as globals;
@use "./action-sheet.common";
@use "./action-sheet.md" as action-sheet-md;

// Ionic Action Sheet
// --------------------------------------------------

// Action Sheet: Select Option
// --------------------------------------------------

.action-sheet-button-label {
gap: globals.$ion-space-300;
}

.select-option-description {
@include globals.typography(globals.$ion-body-md-regular);
@include globals.padding(0);

color: globals.$ion-text-subtle;

font-size: globals.$ion-font-size-350;
}
2 changes: 1 addition & 1 deletion core/src/components/action-sheet/action-sheet.ios.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import "./action-sheet";
@import "./action-sheet.native";
@import "./action-sheet.ios.vars";

// iOS Action Sheet
Expand Down
2 changes: 1 addition & 1 deletion core/src/components/action-sheet/action-sheet.md.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import "./action-sheet";
@import "./action-sheet.native";
@import "./action-sheet.md.vars";

// Material Design Action Sheet Title
Expand Down
19 changes: 19 additions & 0 deletions core/src/components/action-sheet/action-sheet.native.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@use "../../themes/native/native.theme.default" as native;
@use "../../themes/mixins" as mixins;
@use "../../themes/functions.font" as font;
@use "./action-sheet.common";

// Action Sheet: Native
// --------------------------------------------------

.action-sheet-button-label {
gap: 12px;
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.

I decided to use the same value that ionic uses.

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 it off ionic theme

}

.select-option-description {
@include mixins.padding(5px, 0, 0, 0);

color: native.$text-color-step-300;

font-size: font.dynamic-font(12px);
}
13 changes: 11 additions & 2 deletions core/src/components/action-sheet/action-sheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
safeCall,
setOverlayId,
} from '@utils/overlays';
import { renderOptionLabel } from '@utils/select-option-render';
import { getClassMap } from '@utils/theme';

import { getIonMode, getIonTheme } from '../../global/ionic-global';
Expand All @@ -37,7 +38,7 @@ import { mdLeaveAnimation } from './animations/md.leave';
styleUrls: {
ios: 'action-sheet.ios.scss',
md: 'action-sheet.md.scss',
ionic: 'action-sheet.md.scss',
ionic: 'action-sheet.ionic.scss',
},
scoped: true,
})
Expand Down Expand Up @@ -559,6 +560,14 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
htmlAttrs['aria-checked'] = isActiveRadio ? 'true' : 'false';
}

const optionLabelOptions = {
id: buttonId,
label: b.text,
startContent: b.startContent,
endContent: b.endContent,
description: b.description,
};

return (
<button
{...htmlAttrs}
Expand All @@ -580,7 +589,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
>
<span class="action-sheet-button-inner">
{b.icon && <ion-icon icon={b.icon} aria-hidden="true" lazy={false} class="action-sheet-icon" />}
{b.text}
{renderOptionLabel(optionLabelOptions, 'action-sheet-button-label')}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This changes the DOM structure for all action-sheet buttons, not just ones created through select. Previously {b.text} rendered directly inside .action-sheet-button-inner, now it's wrapped in <span class="action-sheet-button-label"><span>...</span></span>. Same thing happens in alert for radio/checkbox labels. Any app CSS targeting these internal elements will break. Should renderOptionLabel only wrap when rich content is actually present (when startContent/endContent/description exist), falling back to the original rendering for plain strings?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I do understand that breaking changes are acceptable here and this may be intended. Just double checking that's what you're going for.

Copy link
Copy Markdown
Contributor Author

@thetaPC thetaPC Apr 14, 2026

Choose a reason for hiding this comment

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

There's no need for the extra wrappers so it's now back to plain: 0c7e4d6 and 17e9e37

</span>
{theme === 'md' && <ion-ripple-effect></ion-ripple-effect>}
</button>
Expand Down
5 changes: 4 additions & 1 deletion core/src/components/alert/alert-interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export interface AlertInput {
/**
* The label text to display next to the input, if the input type is `radio` or `checkbox`.
*/
label?: string;
label?: string | HTMLElement;
checked?: boolean;
disabled?: boolean;
id?: string;
Expand All @@ -35,6 +35,9 @@ export interface AlertInput {
cssClass?: string | string[];
attributes?: { [key: string]: any };
tabindex?: number;
startContent?: HTMLElement;
endContent?: HTMLElement;
description?: string;
}

type AlertButtonOverlayHandler = boolean | void | { [key: string]: any };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,3 +247,21 @@ textarea.alert-input {
min-height: $alert-input-min-height;
resize: none;
}

// Alert Button: Select Option
// --------------------------------------------------

.alert-radio-label,
.alert-checkbox-label {
display: flex;

align-items: center;
}

.select-option-content {
flex: 1;
}

.select-option-description {
display: block;
}
23 changes: 23 additions & 0 deletions core/src/components/alert/alert.ionic.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@use "../../themes/ionic/ionic.globals.scss" as globals;
@use "./alert.common";
@use "./alert.md" as alert-md;

// Ionic Alert
// --------------------------------------------------

// Alert: Select Option
// --------------------------------------------------

.alert-radio-label,
.alert-checkbox-label {
gap: globals.$ion-space-300;
}

.select-option-description {
@include globals.typography(globals.$ion-body-md-regular);
@include globals.padding(0);

color: globals.$ion-text-subtle;

font-size: globals.$ion-font-size-350;
}
2 changes: 1 addition & 1 deletion core/src/components/alert/alert.ios.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import "./alert";
@import "./alert.native";
@import "./alert.ios.vars";

// iOS Alert
Expand Down
2 changes: 1 addition & 1 deletion core/src/components/alert/alert.md.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import "./alert";
@import "./alert.native";
@import "./alert.md.vars";

// Material Design Alert
Expand Down
20 changes: 20 additions & 0 deletions core/src/components/alert/alert.native.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@use "../../themes/native/native.theme.default" as native;
@use "../../themes/mixins" as mixins;
@use "../../themes/functions.font" as font;
@use "./alert.common";

// Alert: Native
// --------------------------------------------------

.alert-radio-label,
.alert-checkbox-label {
gap: 12px;
}

.select-option-description {
@include mixins.padding(5px, 0, 0, 0);

color: native.$text-color-step-300;

font-size: font.dynamic-font(12px);
}
Loading
Loading