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

stylable select: What should we do about the multiple and size attributes? #977

Closed
josepharhar opened this issue Jan 11, 2024 · 15 comments
Closed
Labels
select These are issues that relate to the select component stale

Comments

@josepharhar
Copy link
Collaborator

The stylable select element as we are designing it right now is only for single-select with a popup listbox.
In the future, it would be great if we could extend these improvements to <select multiple> and <select size>. Here are my initial ideas:

  1. Adding a <button> as a child of a <select multiple> makes it replace the button to open the popup, and on desktop, makes it have a popup insead of the current in-page listbox thing.
  2. Adding a <datalist> as a child of a <select multiple> replaces the listbox, but makes it also have checkboxes in or next to the <option>s somehow.
  3. Adding both a <datalist> and a <button> to a <select multiple> makes it have a custom button to open the popup and lets you replace the contents of the listbox, like a combination of the last two options.
  4. Adding a <datalist> to a <select size> would replace the in-page listbox and keep it in-page without a button. If we end up using <datalist> for all this stuff instead of creating a <listbox> element, this could be a way to effectively get the <listbox> accessibility primitive that people have been asking me for. Putting a <button> inside a <select size> would not do anything, but would still be allowed by the parser. The value of the size attribute would likely not perfectly map to the number of options displayed in the height of the element due to layout issues.

In the initial version of single-select with a popup listbox, <select multiple> and <select size> would continue to render the same way as they already do.

@smaug---- I think that we can design and ship these things separately/iteratively. Do you agree?
@pxlcoder do you have any thoughts?

@josepharhar josepharhar added the select These are issues that relate to the select component label Jan 11, 2024
@gregwhitworth gregwhitworth added the agenda+ Use this label if you'd like the topic to be added to the meeting agenda label Jan 16, 2024
@josepharhar
Copy link
Collaborator Author

josepharhar commented Jan 18, 2024

To reiterate, here are the modes I am proposing supporting:

  1. single-select with a custom button and a custom popup listbox
<select>
  <button>custom button</button>
  <datalist>...</datalist>
</select>
  1. single-select with a native button and a custom popup listbox
<select>
  <datalist>...</datalist>
</select>
  1. single-select with a custom button and a native popup listbox
<select>
  <button>custom button</button>
  <option>one</option>
  ...
</select>
  1. single-select with no button and a custom in-page listbox
<select size=n>
  <datalist>...</datalist>
</select>
  1. multi-select with a custom button and a custom popup listbox
<select multiple>
  <button>custom button</button>
  <datalist>...</datalist>
</select>
  1. multi-select with a native button and a custom popup listbox
<select multiple>
  <datalist>...</datalist>
</select>
  1. multi-select with custom button and a native popup listbox
<select multiple>
  <button>button</button>
  <option>one</option>
  ...
</select>
  1. multi-select with no button and a custom in-page listbox
<select multiple size=n>
  <datalist>...</datalist>
</select>

I wrote this out based on the idea of extending the existing multiple and size attributes because there was a question raised in whatwg concerning what we should do with these attributes when you're opting in to the new behavior by providing a button or datalist element.

Alternatively, there could be some other way to opt in to making a custom+stylable in-page select or a custom+stylable multi-select, perhaps with an enumerated attribute that is put on the select element. I'd be curious to know what @smaug---- and @annevk think of this.

@una
Copy link
Collaborator

una commented Jan 18, 2024

@josepharhar -- in the existing (selectlist) implementation, button and datalist are optional. I.e. this example https://codepen.io/una/pen/vYPmyRM

<select class="account-select">
  <option value="" hidden>
    Select an account
  </option>
  <option value="001">
    <p class="name">Patrick Brosset</p>
    <p class="type">Personal Account</p>
  </option>
  <option value="002">
    <p class="name">Microsoft Edge</p>
    <p class="type">Team Account</p>
  </option>
</select>

Is it confusing that this would not be possible now? I would expect the above to "just work" as it does in the current prototype.

@lukewarlow
Copy link
Collaborator

lukewarlow commented Jan 18, 2024

The problem with the above example is the existing parser restrictions. So we'd need an attribute or datalist to enable the new parsing model (for back compat). Or a new element obviously.

@gregwhitworth
Copy link
Member

gregwhitworth commented Jan 19, 2024

Goodness that matrix hurts my head and trying to explain this in any meaningful sense to devs. But let's set that aside for now.

I'll break this up and address size and multiple on their own.

size

Can I ask an honest question, if datalist opts you into the new behavior why can't we make size a no-op where it does nothing? As we discussed in another meeting if parts and styles are standardized a developer should be able to achieve an inline select themselves.

For this example, let's assume that in order to have standardized styles we need to use the proposed appearance: base-select.

HTML

    <select>
        <button type=select>
        <datalist>
            <option>One</option>
        </datalist>
     </select>

CSS

    select {
        appearance: base-select;
    }

    select button {
     display: none;
    }

   select datalist {
       display: grid;
    }

As we discussed prior; the datalist will be display: none since their is a button present in the UA stylesheet; but by hiding it and making the datalist any other display type it now is inline. Granted we haven't standardized the UA stylesheet so there may be other things that a dev needs to do in order to accomplish this.

We could have an alias for size that makes it inline via attribute but actually makes intuitive sense. So maybe something like <select inline> will result in the styles above but using select[inline].

multiple

Adding a <datalist> as a child of a <select multiple> replaces the listbox, but makes it also have checkboxes in or next to the <option>s somehow.

This is my largest concern. I fear that we're going to rush this and put in type=checkbox when there are some more complex scenarios that have a hierarchy of options within a <select multiple>. We included an example of this in the checkbox findings.

image

While the easy path is to simply say to add in a place for input type=checkbox somewhere on the <option> and have that set an array for the value of select; given the use-cases I think we'll ultimately want an extensible checkbox and hierarchy solution for selecting all or deselecting all. I'm purposefully not prescribing a solution here as I think it warrants a separate issue.

@annevk
Copy link

annevk commented Jan 19, 2024

@josepharhar I don't think "native" vs "custom" should follow from markup. It should follow from CSS. There might well be limits to a "native" appearance, forcing a user agent to fallback to text or text and images, but that seems acceptable. If a developer wants full control over the appearance they can use appearance:base / appearance:base-select / bikeshed.

@josepharhar
Copy link
Collaborator Author

I don't think "native" vs "custom" should follow from markup. It should follow from CSS. There might well be limits to a "native" appearance, forcing a user agent to fallback to text or text and images, but that seems acceptable. If a developer wants full control over the appearance they can use appearance:base / appearance:base-select / bikeshed.

Sounds good to me, apologies for this or any future word choice to suggest otherwise.

Is it confusing that this would not be possible now? I would expect the above to "just work" as it does in the current prototype.

As Luke said, this can't work given the restrictions of the HTML parser. If we are going to reuse the select element, which it seems we must, then we can't make this work without making a large breaking change to websites.

Can I ask an honest question, if datalist opts you into the new behavior why can't we make size a no-op where it does nothing? As we discussed in another meeting if parts and styles are standardized a developer should be able to achieve an inline select themselves.

I don't think we can make datalist work as a standalone in-page listbox because it is currently always display:none. I suppose that we could add an attribute or something to it to opt into an in-page listbox thing, but if we also want to give it form semantics and stuff as a form-associated element then we would be better off reusing the select element I think.

I agree that size is kind of weird but I think its the most natural way to provide the in-page listbox that people were hoping that the <listbox> element would be.

As we discussed prior; the datalist will be display: none since their is a button present in the UA stylesheet; but by hiding it and making the datalist any other display type it now is inline. Granted we haven't standardized the UA stylesheet so there may be other things that a dev needs to do in order to accomplish this.

Yeah that could also work if there are no quirks. Maybe you could try it out soon when I finish the prototype in chromium.

We could have an alias for size that makes it inline via attribute but actually makes intuitive sense. So maybe something like <select inline> will result in the styles above but using select[inline].

Yeah that doesn't sound bad to me. Using a completely new attribute also reduces compatibility issues when we change the behavior of size or multiple in the future. I was just talking to @mfreed7 about how to make multiple work in the future, and if we ship single-select improvements before multi-select improvements then we need to provide some way to feature detect what state the improvements are in, and using completely separate attributes would be an easy way to do that.

@annevk
Copy link

annevk commented Jan 24, 2024

I could see offering a replacement for size, maybe, but multiple is the API across several controls for multiple values. Perhaps we can make the multiple getter return false or some such though.

@josepharhar
Copy link
Collaborator Author

I could see offering a replacement for size, maybe, but multiple is the API across several controls for multiple values.

Sounds good to me. Greg's suggestion of creating a new "inline" attribute sounds appealing to me

Perhaps we can make the multiple getter return false or some such though.

Could you elaborate? Should we make the getter return false if you are opted in to the new behavior but we havent implemented support for multiple yet?

@mfreed7
Copy link
Collaborator

mfreed7 commented Jan 25, 2024

For feature detection of support for multiple, what about if the presence of the multiple attribute, when not supported, triggers the "old" parser behavior of throwing out content? I.e.

function supportsMultiple() {
  const select = document.createElement('select');
  select.multiple = true;
  select.innerHTML = '<datalist><option>';
  return select.firstChild.localName === 'datalist';
}

@css-meeting-bot
Copy link

The Open UI Community Group just discussed stylable select: What should we do about the `multiple` and `size` attributes?, and agreed to the following:

  • RESOLVED: multiple and size will not be supported initially on singled select with datalist. If these attributes are detected the parser uses the original select logic
The full IRC log of that discussion <una> SGTM ^
<dbaron> ScribeNick: luke
<brecht_dr> jarhar: There are some questions risen about multiple and size. Let's just integrate this when doing the stylable select
<gregwhitworth> q+
<brecht_dr> jarhar: I layed out a few cases on how we could do that. Maybe we should not do something with size, and keep the multiple
<scotto> q+
<brecht_dr> jarhar: maybe we need a replacement for size, but we need an answer how the single select will work to work on the multi-select in the future
<masonf> q+
<dbaron> s/ScribeNick: luke/ScribeNick: brecht_dr/
<brecht_dr> gregwhitworth: what i am curious about: we want to ship this soon. With the new element we could use multiple. How do we ensure that the multiselect is backwards compatible
<brecht_dr> gregwhitworth: do we need the multiple to ship the single select
<brecht_dr> jarhar: no
<luke> q+
<brecht_dr> gregwhitworth: will we ship the stylable select with multiple and just pass the issue to a later date
<gregwhitworth> ack gregwhitworth
<brecht_dr> masonf: I agree we need to built this in a way to ship the single select first and multiple later
<brecht_dr> masonf: I like the multiple attribute, because people know it
<brecht_dr> masonf: for now we could render the old behavor when multiple is added as an attribute
<gregwhitworth> ack masonf
<gregwhitworth> ack scotto
<brecht_dr> masonf: so would be good to have a plan to ship single select first
<brecht_dr> scotto: Do we need to do anything with size? The primary point of this is people willing to style selects
<gregwhitworth> q+
<brecht_dr> scotto: It might be a good idea that you see a basic multiple select until it is shipped, this sound like a good reason to do this
<brecht_dr> jarhar: +1 this
<brecht_dr> masonf: The basic multiple looks aweful, and that's perfect, because it will still work. eventhough it's not a good looking element
<brecht_dr> scotto: give them the old aweful until multiple stylable select is implemented sounds good
<gregwhitworth> ack luke
<gregwhitworth> scribenick: gregwhitworth
<gregwhitworth> luke: if we go on the basis of the new parsing model and there is a dl or not a dl then you use the old/new behavior
<gregwhitworth> luke: it will use the options not within the datalist and they add multiple they will get thrown away
<jarhar> q+
<gregwhitworth> luke: if that's the case then it breaks obviously to the dev, I like that it's perfect
<gregwhitworth> masonf: it would actually go back to the old solution and so datalist wouldn't be in the DOM
<jarhar> the parser will still allow datalist in select multiple, but it might not be rendered because the old code expects the options to be direct children maybe - not sure but will have to look
<gregwhitworth> luke: the size attribute to have in page listboxes, having them inline is useful and common components and you can choose between two groups
<jarhar> having an in page listbox is something id like to support since people want it, but not sure if size is the right way to do it - maybe a new attribute like inline like greg mentioned would be cool. size attribute could just render the old thing
<gregwhitworth> luke: I think it's something worth doing in the future but I like size opting out of the old model
<gregwhitworth> scribenick: brecht_dr
<brecht_dr> gregwhitworth: I love the blowouts of the old parser approach. In the past, size was a way to change styles which you can do with css now with the popover
<brecht_dr> gregwhitworth: I think we should solve multiple, I like not taking forward size
<jarhar> i think we should still provide an explicit inline thing, but maybe not with the size attribute
<gregwhitworth> q?
<gregwhitworth> ack gregwhitworth
<gregwhitworth> ack jarhar
<brecht_dr> gregwhitworth: Personally, i wouldn't miss size
<brecht_dr> jarhar: Not sure if putting display block on the datalist is the way to go. Ideally with size we could just still render the old thing.
<brecht_dr> jarhar: for select multiple and you put datalist in it. I think the browser will still alow it, but if it will render the old view because we haven't implement it, i'm not completely sure
<masonf> q+
<gregwhitworth> Proposed Resolution: Re-use the multiple attribute for multi-select in the future and for now we render the current solution when it's present. For size we'll plan on creating a new attribute to produce an inline select but for now we'll leverage the current solution
<gregwhitworth> ack masonf
<gregwhitworth> q+
<scotto> q+
<brecht_dr> masonf: If having a multiple attribute on there triggers the parser to show the old way, sound better
<brecht_dr> jarhar: We're not doing new stuff for multiple yet, and this would force people not to use it and have a fallback
<brecht_dr> masonf: it should be a feature detect
<brecht_dr> gregwhitworth: I agree with going back to the old skool one.
<gregwhitworth> ack scotto
<gregwhitworth> ack gregwhitworth
<brecht_dr> gregwhitworth: It becomes obvious that this isn't supported and that's a good thing, seeing an old styling for size
<brecht_dr> gregwhitworth: for size attribute - see a broken select *
<brecht_dr> scotto: I agree with this
<gregwhitworth> Proposed Resolution: multiple and size will not be supported initially on singled select with datalist. If these attributes are detected the parser uses the original select logic
<flackr> q+
<luke> +1
<gregwhitworth> ack flackr
<masonf> q+
<brecht_dr> flackr: What does the feature detection look like?
<brecht_dr> masonf: I added an example in the issue
<gregwhitworth> ack masonf
<brecht_dr> flackr: might be better ways to feature detect, but we can think about that later on
<brecht_dr> masonf: I'm curious if we might ship support for a new version of size early on
<brecht_dr> masonf: I'd like to split that in a different issue after resolving on this
<brecht_dr> +1
<masonf> +1 to the resolution
<luke> +1
<gregwhitworth> Resolved: multiple and size will not be supported initially on singled select with datalist. If these attributes are detected the parser uses the original select logic
<masonf> RESOLVED: multiple and size will not be supported initially on singled select with datalist. If these attributes are detected the parser uses the original select logic
<gregwhitworth> Zakim, end topic
<Zakim> I don't understand 'end topic', gregwhitworth
<gregwhitworth> Zakim, end meeting

@lukewarlow lukewarlow removed the agenda+ Use this label if you'd like the topic to be added to the meeting agenda label Jan 25, 2024
josepharhar added a commit to josepharhar/open-ui that referenced this issue Jan 25, 2024
@annevk
Copy link

annevk commented Jan 26, 2024

Making the parser dependent upon attributes won't gain multi-implementer interest I'd bet. It's also better for downstream HTML parsers if we can do all the parser changes once instead of spreading them out. And yeah, I meant that the multiple getter would return false if you use a novel pattern where it's not yet supported.

@mfreed7
Copy link
Collaborator

mfreed7 commented Jan 26, 2024

Making the parser dependent upon attributes won't gain multi-implementer interest I'd bet.

Thanks - but can you say a bit more here? The <template shadowrootmode> element does exactly this: the parser changes behavior once it finds the shadowrootmode attribute.

It's also better for downstream HTML parsers if we can do all the parser changes once instead of spreading them out.

Makes total sense, I think.

And yeah, I meant that the multiple getter would return false if you use a novel pattern where it's not yet supported.

Ok, that can work too, and that makes the feature detection easy: select.hasAttribute('multiple') && !select.multiple.

josepharhar added a commit that referenced this issue Jan 31, 2024
* Add size and multiple to select explainer

This follow the resolution in
#977

* add space
Copy link

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.

@github-actions github-actions bot added the stale label Jul 25, 2024
@josepharhar
Copy link
Collaborator Author

Since we are committed to doing a CSS solution for the customizable select project, the answer here is simple: <select size=2> and <select multiple> will not support appearance:base/base-select for the initial launch of the feature. When that property is applied to selects with these attributes, they will just render as if they had appearance:auto.

@annevk
Copy link

annevk commented Aug 12, 2024

It's prolly cleaner to not support size at all. (As in, maybe we want size=1 to do something else at some point.)

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

7 participants