fix(select): do not collapse to width: 0 when placed in flex container - #28631
Conversation
a8d240e to
a5a007e
Compare
390d1b2 to
aee7bc3
Compare
99561a4 to
ab11766
Compare
averyrousseau
left a comment
There was a problem hiding this comment.
Confirmed that this works with the extra ion-item 👍 Once this merges, I'll get a separate PR up to remove the min-width patch from the select slot playground.
| <ion-select-option value="apple">Apple</ion-select-option> | ||
| </ion-select> | ||
| </ion-item> | ||
| <ion-list> |
There was a problem hiding this comment.
Brandy and I discussed that it would be good to account for ion-list here too. Amanda had found an edge case where Brandy's previous fix did not work, so we wanted to test for that here.
brandyscarney
left a comment
There was a problem hiding this comment.
Talked through this with Liam - the change makes sense & we can always remove the CSS variable later since it is internal. Great job!
| // allowing the item to grow to fill the flex container. | ||
| // If the item is inside of a block container this | ||
| // property will be ignored. | ||
| flex: 1; |
There was a problem hiding this comment.
This is the old fix that brandy had that is no longer needed.
|
Note: The screenshot diffs in 07ab2fe are correct. I wrapped the item in a list as per #28631 (comment). As a result, items in a flex container no longer grow by default. This test is verifying that the select widths don't collapse to 0px. This behavior aligns with what's in main (v7.5.7 as of writing): https://codepen.io/liamdebeasi/pen/bGzOxjy |
Issue number: Internal
What is the current behavior?
We currently apply a workaround to
ion-selectso it can wrap correctly inside ofion-item:ionic-framework/core/src/components/select/select.scss
Lines 99 to 103 in 357b8b2
However, this causes issues when a parent element has
display: flexbecause theion-selectwidth becomes 0.What is the new behavior?
ion-select(and other elements in the default slot) to either truncate or wrap within its own container and then have the entire container (i.e. the entireion-select) wrap to the next line once the container is too small.To achieve this, I needed to set a min-width on
.item-innerto define the point at which the element should wrap to the next line. I also changed the flex basis fromautoto0which means the initial main size of the flex item will be 0px. In reality, this will be--inner-min-widthsince we also setmin-width: var(--inner-min-width). I used0for simplicity but I can change this to use the CSS variable if that's more clear. Since we also setflex-grow: 1we indicate that the element can grow from that basis (but it cannot shrink).I chose
--inner-min-width: 4remto minimize the number of diffs. We can certainly change this, but it may cause some diffs as certain elements will start wrapping sooner. I also chose to userembecause having a fixed min-width means that fewer characters are going to fit in the same space as text scales.I made this a CSS variable but left it undocumented. If developers need a way of changing this
min-widththey can request it and we can easily expose this variable. However, I think4remis small enough that this should be sufficient.Does this introduce a breaking change?
Other information
The visual diffs here are correct. The table below shows the screenshot group and an explanation for why the changes are correct.
disabledhighlight--inner-min-width.legacy/fill--inner-min-width.slotted-inputs--inner-min-width.slotted-inputsnote: I'd argue many of these examples are not best practices. For example, adding a range in the start slot and the end slot is a bit unusual. I'm not aware of any native apps that implement this pattern.popover note: I removed the
ion-itemfrom thepopover/test/asynctest. There was a diff because the min-width increased, but IMO that component should not be used in the popover test since we want to test the popover, not the item.Demo:
feature-7.6branchbefore-item.mov
after-item.mov
(In this demo I updated the
ion-selectto wrap within its own container first instead of truncate. We may want to consider doing this by default, but I think this is out of scope for this task)