Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[select] Ability to style the selected-value part based on the selected option #435

Closed
captainbrosset opened this issue Jan 4, 2022 · 4 comments
Labels
select These are issues that relate to the select component stale

Comments

@captainbrosset
Copy link
Contributor

Let's imagine the case where I have a select where each option has its own background-image:

image

The select control will make this very easy. But now, what if I want the background image to also appear in the selected-value part?

My understanding is that when an option gets selected, only its textContent ends up in the selected-value part, and I can't figure out a way to style it based on the selected option

Using :has() could be a way, but it would be very verbose: .my-custom-select:has(option[value="foo"]:checked)::part(selected-value) { background-image: ... }.

It'd be great to think of ways to more deeply customize the selected-value part without have to necessarily use JavaScript.

@dandclark
Copy link
Collaborator

Thanks for raising this, I agree that it could be useful to have <selectmenu> handle this by default.

That said it's not clear how the control could do this in a way that will work in all scenarios without adding a nontrivial amount of complexity. The first solution that comes to mind is that when the selection changes, <selectmenu> simply clones the DOM contents of the new selected <option> into the selected-value part. For simple cases this works. But it could cause trouble for authors who only want some of the content cloned, e.g. if each <option> has an image, text, and a button, maybe the author only wants the first two shown in the selected-value. We could introduce a way to label the subset of content to be shown in the selected-value, but this starts to add more complexity than we probably want.

This could also run into trouble if the <option> contains nontrivial custom elements that don't expect to be cloned to arbitrary positions in the tree.

So I'm leaning towards this being a scenario that we'd expect the author to write a bit of JS to handle, rather than adding more complexity to the control for a use case that not all <selectmenu> users will run into. I could be wrong though and I'm open to other ideas on how this might be achieved.

@dandclark dandclark added the select These are issues that relate to the select component label Jan 6, 2022
@captainbrosset
Copy link
Contributor Author

captainbrosset commented Jan 7, 2022

That's fair, and the JavaScript for this would likely be pretty simple.
I definitely wouldn't want the browser to have to do this automatically.

I was more thinking along the lines of a CSS selector that would allow authors to do it themselves (the :has selector in my earlier comment).

Or maybe an attribute that gets copied onto the selected-value? That might be a bit weird. But right now the browser copies the textcontent from the option to the selected-value. What do you think about also copying one of the attributes from the option? So, say my options each have a data-type attribute:

<option value="chrome" data-type="chrome-logo">Chrome</option>
<option value="edge" data-type="edge-logo">Edge</option>
<option value="firefox" data-type="firefox-logo">Firefox</option>
<option value="safari" data-type="safari-logo">Safari</option>

Then upon selection, the selected value becomes:

<selected-value data-type="firefox-logo">Firefox</selected-value>

Which gives authors the option to do:

.my-custom-select [data-type="chrome-logo"] { background-image: .... }
.my-custom-select [data-type="edge-logo"] { background-image: .... }
.my-custom-select [data-type="firefox-logo"] { background-image: .... }
.my-custom-select [data-type="safari-logo"] { background-image: .... }

What I don't like about this is choosing an attribute name isn't going to be straightforward, and this feels a bit random as I'm not aware of any other platform feature that does this already.

But maybe this sparks ideas for others.

If this approach isn't really feasible or wanted, I'm totally fine with the JS approach. It's just that this icon use case is, I think, one of the most common reasons why people built custom selects today.

@github-actions
Copy link

github-actions bot commented Jul 7, 2022

There hasn't been any discussion on this issue for a while, so we're marking it as stale. If you choose to kick off the discussion again, we'll remove the 'stale' label.

@josepharhar
Copy link
Collaborator

I believe that using script to apply a the same class to both the selected option and selected value is the best way to do this. See this example I made for #571: https://jsfiddle.net/jarhar/83gpscra/

Since this use case has a lot of overlap with #571 I'm going to close this one in favor of #571

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
select These are issues that relate to the select component stale
Projects
None yet
Development

No branches or pull requests

3 participants