Skip to content

Conversation

liamdebeasi
Copy link
Contributor

@liamdebeasi liamdebeasi commented Dec 4, 2023

Issue number: Internal


What is the current behavior?

We currently apply a workaround to ion-select so it can wrap correctly inside of ion-item:

:host(.in-item:not(.legacy-select)) {
flex: 1 1 0;
width: 0;
}

However, this causes issues when a parent element has display: flex because the ion-select width becomes 0.

What is the new behavior?

  • In order to get the desired behavior, we need the 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 entire ion-select) wrap to the next line once the container is too small.

To achieve this, I needed to set a min-width on .item-inner to define the point at which the element should wrap to the next line. I also changed the flex basis from auto to 0 which means the initial main size of the flex item will be 0px. In reality, this will be --inner-min-width since we also set min-width: var(--inner-min-width). I used 0 for simplicity but I can change this to use the CSS variable if that's more clear. Since we also set flex-grow: 1 we indicate that the element can grow from that basis (but it cannot shrink).

I chose --inner-min-width: 4rem to 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 use rem because 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-width they can request it and we can easily expose this variable. However, I think 4rem is small enough that this should be sufficient.

Does this introduce a breaking change?

  • Yes
  • No

Other information

The visual diffs here are correct. The table below shows the screenshot group and an explanation for why the changes are correct.

Path Example Details
disabled Link The searchbar is able to shrink slightly to fit on the same line as the checkbox at the bottom.
highlight Link We're changing how small the main content can get, so the input is only wrapping once it gets to --inner-min-width.
legacy/fill Link We're changing how small the main content can get, so the input is only wrapping once it gets to --inner-min-width.
slotted-inputs Link We're changing how small the main content can get, so the range is only wrapping once it gets to --inner-min-width.

slotted-inputs note: 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-item from the popover/test/async test. 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.6 branch
before-item.mov
after-item.mov

(In this demo I updated the ion-select to 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)

@liamdebeasi liamdebeasi changed the title fix(select): avoid width:0 usage fix(select): do not collapse to width: 0 when placed in flex container Dec 5, 2023
@liamdebeasi liamdebeasi marked this pull request as ready for review December 5, 2023 00:45
@liamdebeasi liamdebeasi requested review from a team and brandyscarney as code owners December 5, 2023 00:45
@github-actions github-actions bot added the package: core @ionic/core package label Dec 5, 2023
Copy link
Contributor

@averyjohnston averyjohnston left a comment

Choose a reason for hiding this comment

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

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>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

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.

Copy link
Member

@brandyscarney brandyscarney left a comment

Choose a reason for hiding this comment

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

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;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the old fix that brandy had that is no longer needed.

@liamdebeasi
Copy link
Contributor Author

liamdebeasi commented Dec 5, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

package: core @ionic/core package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants