Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
f7b1a82
chore(): remove old snapshots
brandyscarney Aug 4, 2026
5821084
fix(select): support floating labels with slotted content
brandyscarney Aug 4, 2026
8a3df75
style: lint
brandyscarney Aug 4, 2026
108222a
refactor(select): remove inner part, add parts for new wrapper divs
brandyscarney Aug 5, 2026
5a47f9f
chore: build
brandyscarney Aug 5, 2026
939b029
copy editing
brandyscarney Aug 5, 2026
657ba03
test(select): rename tests and add fill and rtl coverage
brandyscarney Aug 5, 2026
9fdfc74
chore(): add updated snapshots
brandyscarney Aug 5, 2026
d5ecc50
fix(select): prevent the label click from propagating
brandyscarney Aug 5, 2026
4459f48
test(select): update to verify new parts can be customized
brandyscarney Aug 5, 2026
7a6f3ef
chore(): add updated snapshots
Ionitron Aug 5, 2026
feafbf2
chore: remove unrelated snapshot change
brandyscarney Aug 5, 2026
ecbe120
fix(select): properly group icon with the native select for justify
brandyscarney Aug 5, 2026
531ff9b
chore(): add updated snapshots
Ionitron Aug 5, 2026
b7de667
test(select): fix duplicate screenshot name
brandyscarney Aug 5, 2026
64c9cfb
chore(): revert unchanged snapshots
brandyscarney Aug 5, 2026
c822f1d
chore(): revert unrelated snapshots
brandyscarney Aug 5, 2026
a4ec7e8
test(select): add an example with dynamic slot content
brandyscarney Aug 5, 2026
b21f895
Merge branch 'major-9.0' into FW-6471-select
brandyscarney Aug 5, 2026
8610c19
chore(): add updated snapshots
brandyscarney Aug 5, 2026
a27ba41
style: remove extra function call
brandyscarney Aug 5, 2026
be5fdbb
chore(): add updated snapshots
Ionitron Aug 5, 2026
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
9 changes: 9 additions & 0 deletions BREAKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,15 @@ When using `interface="action-sheet"`, `ion-select` no longer assigns the `selec

Previously, the `selected` role was assigned only to the option matching the select's current value. Because the dismiss role mirrors the tapped button, this surfaced in just one case: re-selecting the already-selected option dismissed the action sheet with `role: "selected"` in `ionActionSheetDidDismiss`. Tapping any other option changed the value and dismissed with `role: ""`. Now that the role is no longer assigned, both cases dismiss with `role: undefined`. Apps that inspected this role to detect that a value was chosen, such as reading `role` from the underlying action sheet's `onDidDismiss` result, should listen for `ion-select`'s `ionChange` event instead, which emits the selected value when the selection changes.

**Internal DOM Structure Changes**

The component's internal DOM structure has been restructured to support floating labels with slotted start and end content. Additionally, the structure of the component has been reorganized, with some elements now grouped differently than before. The `inner` wrapper element has been removed, and its content has been split across separate wrapper elements for the start slot, control, and end slot. This may introduce breaking changes for developers who rely on the component's internal DOM structure or apply custom styling to internal elements.

Developers who previously styled `ion-select::part(inner)` should migrate to targeting the updated component structure using the following CSS parts instead:
- `ion-select::part(start)` - Target the start slot wrapper
- `ion-select::part(control)` - Target the control wrapper containing the label and native select. When the label is not floating or stacked, this part also contains the dropdown icon.
- `ion-select::part(end)` - Target the end slot wrapper. When the label is floating or stacked, this part also contains the dropdown icon.

<h2 id="version-9x-framework-specific">Framework Specific</h2>

<h4 id="version-9x-angular">Angular</h4>
Expand Down
4 changes: 3 additions & 1 deletion core/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1758,12 +1758,14 @@ 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,control
ion-select,part,end
ion-select,part,error-text
ion-select,part,helper-text
ion-select,part,icon
ion-select,part,inner
ion-select,part,label
ion-select,part,placeholder
ion-select,part,start
ion-select,part,supporting-text
ion-select,part,text
ion-select,part,wrapper
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 0 additions & 8 deletions core/src/components/select/select.ios.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,6 @@
color: #{$text-color-step-350};
}

// Select Inner Wrapper
// ----------------------------------------------------------------

:host(.select-label-placement-stacked) .select-wrapper-inner,
:host(.select-label-placement-floating) .select-wrapper-inner {
width: calc(100% - $select-ios-icon-size - $select-icon-margin-start);
}
Comment on lines -22 to -28

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I could not find anywhere this is necessary after changing the icon structure.


// Select: Disabled
// ----------------------------------------------------------------
// The select and label should use the
Expand Down
13 changes: 2 additions & 11 deletions core/src/components/select/select.md.outline.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
--border-radius: 4px;
--padding-start: 16px;
--padding-end: 16px;
--start-slot-adjustment: 0px;

min-height: 56px;
}
Expand Down Expand Up @@ -103,7 +104,7 @@
* This makes the label sit above the select.
*/
:host(.label-floating.select-fill-outline) .label-text-wrapper {
@include transform(translateY(-32%), scale(#{$form-control-label-stacked-scale}));
@include transform(translate(var(--start-slot-adjustment), -32%), scale(#{$form-control-label-stacked-scale}));
@include margin(0);

/**
Expand Down Expand Up @@ -197,13 +198,8 @@

:host(.select-fill-outline) .select-outline-start {
@include border(null, null, null, var(--border-width) var(--border-style) var(--border-color));
}

:host(.select-fill-outline) .select-outline-start {
@include border-radius(var(--border-radius), 0px, 0px, var(--border-radius));
}

:host(.select-fill-outline) .select-outline-start {
/**
* There should be spacing between the translated text
* and .select-outline-start. However, we can't add this
Expand All @@ -217,13 +213,8 @@

:host(.select-fill-outline) .select-outline-end {
@include border(null, var(--border-width) var(--border-style) var(--border-color), null, null);
}

:host(.select-fill-outline) .select-outline-end {
@include border-radius(0px, var(--border-radius), var(--border-radius), 0px);
}

:host(.select-fill-outline) .select-outline-end {
/**
* The ending outline fragment
* should take up the remaining free space.
Expand Down
8 changes: 0 additions & 8 deletions core/src/components/select/select.md.scss
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,6 @@
--border-radius: 16px;
}

// Select Inner Wrapper
// ----------------------------------------------------------------

:host(.select-label-placement-stacked) .select-wrapper-inner,
:host(.select-label-placement-floating) .select-wrapper-inner {
width: calc(100% - $select-md-icon-size - $select-icon-margin-start);
}
Comment on lines -121 to -127

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I could not find anywhere this is necessary after changing the icon structure.


// Select: Disabled
// ----------------------------------------------------------------
// The select and label should use the
Expand Down
110 changes: 45 additions & 65 deletions core/src/components/select/select.scss
Original file line number Diff line number Diff line change
Expand Up @@ -154,36 +154,6 @@ button {
color: inherit;
}

/**
* The select icon should be centered with
* the entire container not just the control
* with floating/stacked labels.
*/
:host(.select-label-placement-stacked) .select-icon,
:host(.select-label-placement-floating) .select-icon {
position: absolute;

height: 100%;
}

/**
* This positions the icon at the correct
* edge of the component with LTR and RTL
* text directions. The position mixin cannot be
* used here because the icon is in the Shadow DOM.
*/
:host(.select-ltr.select-label-placement-stacked) .select-icon,
:host(.select-ltr.select-label-placement-floating) .select-icon {
// stylelint-disable-next-line property-disallowed-list
right: var(--padding-end, 0);
}

:host(.select-rtl.select-label-placement-stacked) .select-icon,
:host(.select-rtl.select-label-placement-floating) .select-icon {
// stylelint-disable-next-line property-disallowed-list
left: var(--padding-start, 0);
}
Comment on lines -157 to -185

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is no longer necessary using flex properties to center the icon vertically.


// Select Text
// --------------------------------------------------
.select-text {
Expand Down Expand Up @@ -237,7 +207,7 @@ button {

flex-grow: 1;

align-items: center;
align-items: stretch;
justify-content: space-between;

height: inherit;
Expand Down Expand Up @@ -270,23 +240,28 @@ button {
transition: opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);
}

.select-wrapper-inner {
// The control must inherit specific flex properties
// so that it will be placed properly when justify
// or label-placement are set on the host
.select-control {
display: flex;

align-items: center;
position: relative;

overflow: hidden;
}
flex: 1;

flex-direction: inherit;

align-items: center;
justify-content: inherit;

:host(.select-label-placement-stacked) .select-wrapper-inner,
:host(.select-label-placement-floating) .select-wrapper-inner {
/**
* When using a stacked/floating label, the inner wrapper is
* stacked vertically under the label container. This line
* ensures that the inner wrapper fills all the remaining height
* of the component.
* The min-width is set to 0 to allow flex items to shrink below
* their content size. This enables the select text to collapse
* in width. We avoid overflow: hidden here because it will clip
* the floating label.
*/
flex-grow: 1;
min-width: 0;
}

// Select Highlight
Expand Down Expand Up @@ -554,9 +529,18 @@ button {
* down when the select is focused or has a value.
*
*/
:host(.select-label-placement-stacked) .select-wrapper,
:host(.select-label-placement-floating) .select-wrapper {
:host(.select-label-placement-stacked) .select-control,
:host(.select-label-placement-floating) .select-control {
flex-direction: column;

/**
* When using a stacked/floating label, the inner wrapper is
* stacked vertically under the label container. This line
* ensures that the inner wrapper fills all the remaining height
* of the component.
*/
flex-grow: 1;

align-items: start;
}

Expand All @@ -583,15 +567,11 @@ button {
}

/**
* Ensures the select does not
* overlap the label.
* Also ensure that the native wrapper
* takes up the remaining available height and width.
* Ensures that the native wrapper takes up the
* remaining available height and width.
*/
:host(.select-label-placement-stacked) .native-wrapper,
:host(.select-label-placement-floating) .native-wrapper {
@include margin(1px, 0, 0, 0);

flex-grow: 1;

width: 100%;
Expand All @@ -616,27 +596,16 @@ button {
* The placeholder should be hidden when the label
* is on top of the select. This prevents the label
* from overlapping any placeholder value.
*
* TODO(FW-5592): Remove :not(.label-floating) piece
*/
:host(.select-label-placement-floating:not(.label-floating)) .native-wrapper .select-placeholder {
:host(.select-label-placement-floating) .native-wrapper .select-placeholder {
opacity: 0;
}

/**
* We don't use .label-floating here because that would
* also include the case where the label is floating due
* to content in the start/end slot. We want the opacity
* to remain at the default in this case, since the select
* isn't being actively interacted with.
*
* TODO(FW-5592): Change entire selector to:
* :host(.label-floating.select-label-placement-floating) .native-wrapper .select-placeholder
* Show the placeholder when the label is floating.
*/
:host(.select-expanded.select-label-placement-floating) .native-wrapper .select-placeholder,
:host(.has-focus.select-label-placement-floating) .native-wrapper .select-placeholder,
:host(.has-value.select-label-placement-floating) .native-wrapper .select-placeholder {
opacity: 1;
:host(.label-floating.select-label-placement-floating) .native-wrapper .select-placeholder {
opacity: var(--placeholder-opacity);
}

/**
Expand All @@ -655,6 +624,17 @@ button {
// Start/End Slots
// ----------------------------------------------------------------

.select-start,
.select-end {
display: flex;

position: relative;

flex-shrink: 0;

align-items: center;
}

::slotted([slot="start"]), ::slotted([slot="end"]) {
/**
* Prevent the slots from shrinking when the label and/or
Expand Down
Loading
Loading