Skip to content

Commit e39449e

Browse files
authored
feat(select): allow HTML within options (#31072)
Issue number: resolves #29890
1 parent 69e5ee1 commit e39449e

41 files changed

Lines changed: 1912 additions & 207 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

core/api.txt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2327,6 +2327,27 @@ ion-select,css-prop,--placeholder-opacity,md
23272327
ion-select,css-prop,--ripple-color,ionic
23282328
ion-select,css-prop,--ripple-color,ios
23292329
ion-select,css-prop,--ripple-color,md
2330+
ion-select,css-prop,--select-text-gap,ionic
2331+
ion-select,css-prop,--select-text-gap,ios
2332+
ion-select,css-prop,--select-text-gap,md
2333+
ion-select,css-prop,--select-text-media-border-color,ionic
2334+
ion-select,css-prop,--select-text-media-border-color,ios
2335+
ion-select,css-prop,--select-text-media-border-color,md
2336+
ion-select,css-prop,--select-text-media-border-radius,ionic
2337+
ion-select,css-prop,--select-text-media-border-radius,ios
2338+
ion-select,css-prop,--select-text-media-border-radius,md
2339+
ion-select,css-prop,--select-text-media-border-style,ionic
2340+
ion-select,css-prop,--select-text-media-border-style,ios
2341+
ion-select,css-prop,--select-text-media-border-style,md
2342+
ion-select,css-prop,--select-text-media-border-width,ionic
2343+
ion-select,css-prop,--select-text-media-border-width,ios
2344+
ion-select,css-prop,--select-text-media-border-width,md
2345+
ion-select,css-prop,--select-text-media-height,ionic
2346+
ion-select,css-prop,--select-text-media-height,ios
2347+
ion-select,css-prop,--select-text-media-height,md
2348+
ion-select,css-prop,--select-text-media-width,ionic
2349+
ion-select,css-prop,--select-text-media-width,ios
2350+
ion-select,css-prop,--select-text-media-width,md
23302351
ion-select,part,bottom
23312352
ion-select,part,container
23322353
ion-select,part,error-text
@@ -2347,6 +2368,7 @@ ion-select-modal,prop,multiple,boolean | undefined,undefined,false,false
23472368
ion-select-modal,prop,options,SelectModalOption[],[],false,false
23482369

23492370
ion-select-option,shadow
2371+
ion-select-option,prop,description,string | undefined,undefined,false,false
23502372
ion-select-option,prop,disabled,boolean,false,false,false
23512373
ion-select-option,prop,mode,"ios" | "md",undefined,false,false
23522374
ion-select-option,prop,theme,"ios" | "md" | "ionic",undefined,false,false

core/src/components.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3823,6 +3823,10 @@ export namespace Components {
38233823
"options": SelectModalOption[];
38243824
}
38253825
interface IonSelectOption {
3826+
/**
3827+
* Text that is placed underneath the option text to provide additional details about the option.
3828+
*/
3829+
"description"?: string;
38263830
/**
38273831
* 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.
38283832
* @default false
@@ -9922,6 +9926,10 @@ declare namespace LocalJSX {
99229926
"options"?: SelectModalOption[];
99239927
}
99249928
interface IonSelectOption {
9929+
/**
9930+
* Text that is placed underneath the option text to provide additional details about the option.
9931+
*/
9932+
"description"?: string;
99259933
/**
99269934
* 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.
99279935
* @default false
@@ -11300,6 +11308,7 @@ declare namespace LocalJSX {
1130011308
interface IonSelectOptionAttributes {
1130111309
"disabled": boolean;
1130211310
"value": string;
11311+
"description": string;
1130311312
}
1130411313
interface IonSelectPopoverAttributes {
1130511314
"header": string;

core/src/components/action-sheet/action-sheet.scss renamed to core/src/components/action-sheet/action-sheet.common.scss

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,3 +233,20 @@
233233
}
234234
}
235235
}
236+
237+
// Action Sheet: Select Option
238+
// --------------------------------------------------
239+
240+
.action-sheet-button-label {
241+
display: flex;
242+
243+
align-items: center;
244+
}
245+
246+
.select-option-content {
247+
flex: 1;
248+
}
249+
250+
.select-option-description {
251+
display: block;
252+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
@use "../../themes/ionic/ionic.globals.scss" as globals;
2+
@use "./action-sheet.common";
3+
@use "./action-sheet.md" as action-sheet-md;
4+
5+
// Ionic Action Sheet
6+
// --------------------------------------------------
7+
8+
// Action Sheet: Select Option
9+
// --------------------------------------------------
10+
11+
.action-sheet-button-label {
12+
gap: globals.$ion-space-300;
13+
}
14+
15+
.select-option-description {
16+
@include globals.typography(globals.$ion-body-md-regular);
17+
@include globals.padding(0);
18+
19+
color: globals.$ion-text-subtle;
20+
21+
font-size: globals.$ion-font-size-350;
22+
}

core/src/components/action-sheet/action-sheet.ios.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@import "./action-sheet";
1+
@import "./action-sheet.native";
22
@import "./action-sheet.ios.vars";
33

44
// iOS Action Sheet

core/src/components/action-sheet/action-sheet.md.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@import "./action-sheet";
1+
@import "./action-sheet.native";
22
@import "./action-sheet.md.vars";
33

44
// Material Design Action Sheet Title
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
@use "../../themes/native/native.theme.default" as native;
2+
@use "../../themes/mixins" as mixins;
3+
@use "../../themes/functions.font" as font;
4+
@use "./action-sheet.common";
5+
6+
// Action Sheet: Native
7+
// --------------------------------------------------
8+
9+
.action-sheet-button-label {
10+
gap: 12px;
11+
}
12+
13+
.select-option-description {
14+
@include mixins.padding(5px, 0, 0, 0);
15+
16+
color: native.$text-color-step-300;
17+
18+
font-size: font.dynamic-font(12px);
19+
}

core/src/components/action-sheet/action-sheet.tsx

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ import {
1616
safeCall,
1717
setOverlayId,
1818
} from '@utils/overlays';
19+
import { renderOptionLabel } from '@utils/select-option-render';
1920
import { getClassMap } from '@utils/theme';
2021

2122
import { getIonMode, getIonTheme } from '../../global/ionic-global';
2223
import type { AnimationBuilder, CssClassMap, FrameworkDelegate, OverlayInterface } from '../../interface';
2324
import type { OverlayEventDetail } from '../../utils/overlays-interface';
25+
import type { SelectActionSheetButton } from '../select/select-interface';
2426

2527
import type { ActionSheetButton } from './action-sheet-interface';
2628
import { iosEnterAnimation } from './animations/ios.enter';
@@ -37,7 +39,7 @@ import { mdLeaveAnimation } from './animations/md.leave';
3739
styleUrls: {
3840
ios: 'action-sheet.ios.scss',
3941
md: 'action-sheet.md.scss',
40-
ionic: 'action-sheet.md.scss',
42+
ionic: 'action-sheet.ionic.scss',
4143
},
4244
scoped: true,
4345
})
@@ -559,6 +561,21 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
559561
htmlAttrs['aria-checked'] = isActiveRadio ? 'true' : 'false';
560562
}
561563

564+
/**
565+
* Cast to `SelectActionSheetButton` to access rich content
566+
* fields (`startContent`, `endContent`, `description`)
567+
* that are passed through from `ion-select` but not
568+
* part of the public `ActionSheetButton` interface.
569+
*/
570+
const richButton = b as SelectActionSheetButton;
571+
const optionLabelOptions = {
572+
id: buttonId,
573+
label: richButton.text,
574+
startContent: richButton.startContent,
575+
endContent: richButton.endContent,
576+
description: richButton.description,
577+
};
578+
562579
return (
563580
<button
564581
{...htmlAttrs}
@@ -580,7 +597,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
580597
>
581598
<span class="action-sheet-button-inner">
582599
{b.icon && <ion-icon icon={b.icon} aria-hidden="true" lazy={false} class="action-sheet-icon" />}
583-
{b.text}
600+
{renderOptionLabel(optionLabelOptions, 'action-sheet-button-label', true)}
584601
</span>
585602
{theme === 'md' && <ion-ripple-effect></ion-ripple-effect>}
586603
</button>

core/src/components/alert/alert.scss renamed to core/src/components/alert/alert.common.scss

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,21 @@ textarea.alert-input {
247247
min-height: $alert-input-min-height;
248248
resize: none;
249249
}
250+
251+
// Alert Button: Select Option
252+
// --------------------------------------------------
253+
254+
.alert-radio-label,
255+
.alert-checkbox-label {
256+
display: flex;
257+
258+
align-items: center;
259+
}
260+
261+
.select-option-content {
262+
flex: 1;
263+
}
264+
265+
.select-option-description {
266+
display: block;
267+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
@use "../../themes/ionic/ionic.globals.scss" as globals;
2+
@use "./alert.common";
3+
@use "./alert.md" as alert-md;
4+
5+
// Ionic Alert
6+
// --------------------------------------------------
7+
8+
// Alert: Select Option
9+
// --------------------------------------------------
10+
11+
.alert-radio-label,
12+
.alert-checkbox-label {
13+
gap: globals.$ion-space-300;
14+
}
15+
16+
.select-option-description {
17+
@include globals.typography(globals.$ion-body-md-regular);
18+
@include globals.padding(0);
19+
20+
color: globals.$ion-text-subtle;
21+
22+
font-size: globals.$ion-font-size-350;
23+
}

0 commit comments

Comments
 (0)