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

SelectMenu placeholder capability? #637

Closed
jh3y opened this issue Nov 16, 2022 · 30 comments
Closed

SelectMenu placeholder capability? #637

jh3y opened this issue Nov 16, 2022 · 30 comments
Labels
agenda+ Use this label if you'd like the topic to be added to the meeting agenda select These are issues that relate to the select component

Comments

@jh3y
Copy link
Collaborator

jh3y commented Nov 16, 2022

In some of the popular select menu offerings out there, it's often the case that you can have a default "clean" state where no value is selected: https://react-select.com/home#async

The button part tends to have some form of "placeholder" content and the options list doesn't have to contain that placeholder visually as an option.

I tried to implement this behavior with the current API: https://codepen.io/web-dot-dev/pen/qBKjYKy

The question is "How do we allow people to set a placeholder without weird hacks?"

I tried a couple of "hacks" but they break the current implementation.

Do we see this as a bug in the implementation? Or should we have some way to define a placeholder? Technically allowing a SelectMenu to be in a non-selected state.

cc @mfreed7

@scottaohara
Copy link
Collaborator

Agree this is a common thing people want to do, and should probably be supported. Problem with this though, and with the hacks people do to simulate it, is that it creates situations where a user cannot return to a no value selected state without resetting the form.

If supporting a placeholder for selectmenu, it'd be nice to also account for users wanting to return to an unselected state without them having to reset the form or refresh the web page to do so.

@jh3y
Copy link
Collaborator Author

jh3y commented Nov 16, 2022

Totally agree! 💯

Side note:: Why is there not a "💯" reaction for comments?! 😅

@scottaohara
Copy link
Collaborator

There are quite a number of reactions that I'd like to see as well... though, most of them fall into sarcastic/snark territory, and it's best I do not have easy access to them.

@mfreed7
Copy link
Collaborator

mfreed7 commented Nov 16, 2022

I agree that this feels like something we should handle with the new element. Are there standard ways that existing frameworks expose this functionality to developers? Just no <option selected> means no selection? And how is the ability to clear the selection exposed to users? It'd be good to follow cow paths for this.

@gregwhitworth gregwhitworth added the agenda+ Use this label if you'd like the topic to be added to the meeting agenda label Jan 3, 2023
@smhigley
Copy link
Collaborator

smhigley commented Jan 5, 2023

+1 to having a placeholder prop and ::placeholder style on selectmenu. I think it'd be good to separate out clearing selection to a different issue. While placeholder makes the lack of clearing selection more obvious, I don't think they're otherwise related.

@css-meeting-bot
Copy link

The Open UI Community Group just discussed SelectMenu placeholder capability?, and agreed to the following:

  • RESOLVED: Add placeholder functionality of some sort
  • RESOLVED: `<selectmenu>` should support placeholder functionality in some form
The full IRC log of that discussion <una> Sarah: in favor of this
<JonathanNeal> q+
<masonf> q+
<JonathanNeal> Scott is addressing my question.
<JonathanNeal> Decorations.
<una> scotto: you mention placeholder prop like placeholder attribute like selectmenu, makes me think this would just accept text, are we saying people wouldn't be abel to have placeholder icons?
<una> Sarah: was actually going to ask and discuss that, my personal opinion is text-only is fine
<una> masonf: we haven't resolved what we're doing with non-text-only options in button anyway
<una> masonf: that would affect how we support placeholder
<una> masonf: if we're going just text as current protoype does, then text-only seems fine to me
<una> JonathanNeal: the proposal has pseudo element that doesnt force you to make a descision. But on the attribute that's where we'd need to decide in the API
<dandclark> q?
<una> JonathanNeal: might end up with the issue that have an attribute that also needs to be a slot
<una> ack JonathanNeal
<JonathanNeal> ack JonathanNeal
<JonathanNeal> +1 to having placeholder functionality
<una> masonf: not only that we want to do this, but we need to also discuss how to do it
<JonathanNeal> +1 to allowing `::placeholder`, too.
<dandclark> +1 to supporting it in some way
<una> scotto: would be nice to come up with an actual solution instead of people faking it like they need to do now
<una> scotto: let's definitely do it, people want it
<una> Brecht: the only thing i'm thinking about is using the pseudo would complicate things for multiple languages
<una> dandclark: so far solution has been to make everything a part
<JonathanNeal> I’m hoping both selectmenu values and selectmenu placeholders can share a mostly symmetry API.
<JonathanNeal> s/selectmenu values/selectmenu options
<una> dandclark: seems like the natural way to solve this as well
<JonathanNeal> s/symmetry/symmetric
<una> dandclark: maybe we should move forward with a resolution on if we should support this somehow before we determine how we should do it
<una> scotto: _1
<JonathanNeal> Agreed with dandclark to support the concept, bikeshed the how separately.
<una> s/_1/+1
<JonathanNeal> +1 to keep talking about it after the initial resolution
<una> masonf: any objections to adding a placeholder functionality of some form?
<una> - no objections -
<una> RESOLVED: Add placeholder functionality of some sort
<dandclark> RESOLVED: `<selectmenu>` should support placeholder functionality in some form
<una> masonf: agree with dan re: using slots
<una> masonf: my guess is placeholder slot would be inside the button slot
<una> masonf: may be confusing if you replace the button element, all the placeholder functionality would go away, but maybe this isn't an issue
<JonathanNeal> My question about this is whether the `::part` targets the shadow `<slot>` or the thing I added the `slot` to. It’s the former, technically, I think. But it kinda feels like I would want the later.
<una> JonathanNeal: when i added slot attribute to my own button for decorations, when i add the attribute, it felt a little strange that the part API is not targetting the element that i've assigned
<una> JonathanNeal: i didn't want it to not work that way at first but when I was using it, I wanted the part to style my element and not the display-contents slot container
<una> masonf: this is the same issue in that the part is exposed in the shadow root and not on the slotted content itself - have done this manually in the implementation of selectmenu
<una> masonf: the part is technically targetting the slot
<masonf> q?
<masonf> ack masonf
<una> masonf: to push things along, any objections to move things along to design a slot-based placeholder functionality?
<una> scotto: I do question how someone would do this if they were completely replacing the button and needing to add everything on their own
<una> JonathanNeal: when im using this API and I'm using native attributes then its going to be a little confusing if i'm adding decorations but i'm hiding them by adding a text value to that, unless I use ARIA text-value?
<una> JonathanNeal: example - I have rich content technically, but i want to represent that with a value, i.e. hex code of blue or word "five", but i want the value to be the color or number 5. I want a way to express that in my slotted content
<una> JonathanNeal: would we expect that I use another global attribute like aria-value-text? Or another special prop
<una> Sarah: I think this goes to what I brought up before because options can take richtext and images, we still need a plaintext attribute for them
<una> Sarah: for stuff like type to jump to an option, we need to give options a way to define a plaintext alternative
<una> masonf: the current prototype keeps using option element
<una> Sarah: I don't thihnk we can do that with value - the form uses option value instead of human submitted value
<una> Sarah: i.e. team wanted non-human-readable value for the DB, but wanted a human-readable value string text that had to be different than DB value
<una> masonf: is there an issue open for that?
<JonathanNeal> q?
<una> Sarah: not sure if there's another issue open for that
<una> masonf: please look for or open that so we can discuss
<JonathanNeal> I want to set something like `aria-valuetext` but also the thing that would be `setFormValue`
<una> scotto: i can't navigate by options by typing any of the values (just stays on first option), so its not supported yet
<una> Sarah: the one other consideration is if we have an editable selectmenu, i.e. another element that has a typeable combobox or autofill capability, would require string-only values
<JonathanNeal> Is my audio working?
<una> Related issue: https://github.com//issues/571#issuecomment-1293921725
<una> JonathanNeal: we have a JS API for this with setFormValue
<una> JonathanNeal: I also want this bc the need has been recognized for custom elements in the JS API
<una> masonf: might copy paste that link into a new issue because this is related but it's a seperate topic
<una> masonf: agreed to move forward with some sort of placeholder, tentative to use parts and slots, any objection to move along that route?
<JonathanNeal> +1 to prototyping
<una> dandclark: intermediate step can be to explore some options in protoype
<una> masonf: i meant to comment in code snippets
<una> dandclark: sounds good, agree
<JonathanNeal> +1 to code snippets, too; armchair prototyping.
<una> - no objections to exploring code snippets -
<una> masonf: one more thing - we discussed issue #578 before - how the event works when popover shows and hides

@gregwhitworth gregwhitworth added needs edits This is ready for edits to be made and removed agenda+ Use this label if you'd like the topic to be added to the meeting agenda labels Jan 11, 2023
@mfreed7 mfreed7 added the select These are issues that relate to the select component label Jan 17, 2023
@josepharhar
Copy link
Collaborator

masonf: agreed to move forward with some sort of placeholder, tentative to use parts and slots, any objection to move along that route?

So it sounds like we should use parts and slots to put some elements in as a placeholder and style it, but how should the selectmenu know if you want to opt into having a default unselected state with a placeholder in the first place?

Agree this is a common thing people want to do, and should probably be supported. Problem with this though, and with the hacks people do to simulate it, is that it creates situations where a user cannot return to a no value selected state without resetting the form.

What about pressing backspace or escape? I suppose that wouldn't work on a phone when you don't have a keyboard though... perhaps an "x" button? Or an entry in the list?

@josepharhar
Copy link
Collaborator

The existing <select> element supports clearing the selected value by doing element.value = '' or element.value = null. I think this is something we could easily copy for selectmenu.

As for having a placeholder...
We currently set the selected value's textContent to an empty string when there is no selected value: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/html/forms/html_select_menu_element.cc;l=864-865;drc=1fa8c431e4d96c382156f7831e5246a427754705
This matches what <select> does, it just becomes empty when there is no selected value.
We could easily add an attribute like placeholder to replace that empty string with an actual string specified by the author. This attribute already exists for other elements and I think would be perfect for selectmenu: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#placeholder

If you want to do something really fancy like have the placeholder have a different style than the other selected options, I believe that falls into something that you could do with a custom placeholder element and script. It wouldn't be too different than the resolution we already made for deciding not to copy innerHTML of the selected option: #571

I propose that we support selectmenu.value = '' and selectmenu.value = null for clearing the selected value and add the placeholder attribute as a way of setting the textContent of the selected value element to something other than an empty string for this case.

I also propose that pressing the escape key on the button while the listbox is closed should clear the selected value because thats what aria practices says to do: https://www.w3.org/WAI/ARIA/apg/patterns/combobox/

@josepharhar josepharhar added the agenda+ Use this label if you'd like the topic to be added to the meeting agenda label Mar 24, 2023
@scottaohara
Copy link
Collaborator

I also propose that pressing the escape key on the button while the listbox is closed should clear the selected value because thats what aria practices says to do: https://www.w3.org/WAI/ARIA/apg/patterns/combobox/

that's only for text-editable comboboxes though. that'd be out of scope for selectmenu

@josepharhar
Copy link
Collaborator

Thanks for looking scott, I retract my proposal for the escape key behavior

@josepharhar
Copy link
Collaborator

I think my proposal still skips over an important use case where the author wants the initial state of the selectmenu to not have a selected value, which isn't possible with the current implementations of select or selectmenu.

Input elements have a "default value" concept, where you can specify a default value with the value attribute or the defaultValue script IDL. Maybe we could do a similar thing for selectmenu, where the string you pass in is the value of the option you want to be selected by default, and if its null or an empty string then it starts out unselected?

@css-meeting-bot
Copy link

The Open UI Community Group just discussed SelectMenu placeholder capability? #637.

The full IRC log of that discussion <hdv> topic: SelectMenu placeholder capability? #637
<hdv> github: https://github.com//issues/637
<dandclark> jarhar: THis was a request to be able to have a placeholder for selectmenu. By default, the first element is selected. But authors might want to have nothing selected, and show placeholder text.
<flackr> q+
<dandclark> ...: this would be pretty easy to implement. Propose that we add the placeholder attribute. More tricky is to make it not have t placeholder value to by default. Look at input text for a way to this. Add a value or default-value to selectmenu, have the value of the attr be the value that you want to be selected by default.
<una> q+
<dbaron> i/Agenda/ScribeNick: dandclark/
<hdv> ack flackr
<JakeA> q+
<dandclark> flackr: I think we have to decide what selectedIndex returns as well.
<dandclark> ...: At what point does the user get a value selected where they can no longer unselect a value?
<jarhar> q+
<dandclark> ...: Presumably opening the select doesn't select an optoin. There's some point where you get a selected value and can no longer be unselected
<hdv> ack una
<dandclark> JakeA: COuld also look at radio buttons
<dandclark> una: ??? The second is that you don't have a placeholder, show the value by default. Third is you have a placeholder that's not a selected value, it's only presentational. Fourth is that you have a placeholder that's also the selected value. What you send to the form might be different than what you show on the screen. Proposal should cover all 4 of these use cases.
<scotto> q+
<dandclark> una: First is you have no placeholder, but don't want to show anything in selectmenu.
<hdv> ack JakeA
<dandclark> ...: Do not have an initial value for that
<dandclark> JakeA: Part of the reason for this is you can put richer contetn in options. Would be weird to regress on that for placeholder. Sounds like we were looking at it as only text, not rich. Would it make more sense to tag an option as a placeholder? Just doesn't take place in index of options, and can't be selected.
<scotto> +1 to jake's comment
<dandclark> una: good point, placeholder needs to be rich content
<bkardell_> JakeA: so its selectedIndex is -1?
<bkardell_> that would be weird
<hdv> ack jarhar
<una> q+
<dandclark> jarhar: We've already talked about richer contnt in selected value, decided should only be text for auto showing of the selected value. If show richer content, or mirror the content of the selected option into the selected value, it has to be rendered in 2 places at once. Gets error prone.
<dandclark> JakeA: svg use already has concept of rendering content in 2 places at once
<dandclark> una: THis is something I've struggled with when using selectmenu, can't reflect options in placeholder easily
<una> q-
<dandclark> jarhar: I can look into svg use
<dandclark> flakr: when we decided not to reflect content, was because we wanted to wait until we come up with a way to do this. WOuld make sense to have a placeholder option even if now we can only copy the value and authorss have to use script to add rich content. Then later we can do the better thing.
<dandclark> ...: though placeholder is easier since it's not showing in 2 places at once. But we have a longer term plan to address that concern
<bkardell_> q+
<hdv> ack scotto
<bkardell_> q-
<dandclark> scotto: To echo some of that, one of the issues with reflection is that because anyone can add arbitrary content, links buttons and stuff, you don't want that reflected in the trigger for hte selectmenu. E.g. an option with a link, paragraph, delete button, don't want that reflected in the triggering element. Can't just whole-hog copy the innerHTML of the option back to the triggering option
<bkardell_> q+
<dandclark> ...: I like the idea of identifying particular option in the set as the placholder
<dandclark> ...: make the option you want to be the placeholder, and you have the safe default.
<dandclark> ...: question I have for this approach is that because triggering element can be swapped out, how do we make that accessible by default. Someone can take out the default combobox element and put something else there. Using a placeholder on selectmenu element, I don't know how that would go into any element that people put in there.
<dandclark> ...: I'm still not sure how we'd make that not create problems
<hdv> ack bk
<dandclark> bkardell: Have to flesh out the idea of tagging one of them with follow up questions. Is it still an option if it's a placeholder? By selecting it, do you have none selected? SelectedIndex is -1 then? It's weird because you have option, option, defaultOption, and the indexes of those feel like it hsould skip 1.
<dandclark> ...: For multiselect, can you select placeholder and then something else? That's what people do now with select, you just have to fake it. Should be able to do that. It's going to be highly styleable anyway.
<dandclark> ...: This part of select is particularly broken anyway, so feel like it's an ok solutionl.
<dandclark> s/solutionl/solution
<dandclark> hidde: Sounds like placeholder string would not work, want to have rich content, but not sure how
<bkardell_> s/This part of select is particularly broken/This part of select seems not particularly broken
<dandclark> una: We'd rely on placeholder value to be that string that's preserved, but rich content is important for this feature
<dandclark> ...: it's what separates it from current select
<dandclark> jarhar: Agree, fact that we decided on having a string in selectedValue is not good enough. Idea was if you want to display something more rich, use script. But if that's not good enough, having just the placeholder text isn't good enough.
<dandclark> ...: Also, rob talked about going from selected to non-selected state. Not sure if makes sense to have option for that, or use backspace etc.
<dandclark> ...: Any other ideas to clear selected value?
<flackr> q+
<dandclark> scotto: Worry is that escape key is used to close listbox, I would hate for someone to open it, close it, and lose the value
<dandclark> ...: get form error because it's not filled out, have to go back and find it and the work is lost
<dandclark> ...: Could come up with way to make this more intuitive, but why change the behavior?
<dandclark> jarhar: Could slot something into button to clear the selectedvalue
<dandclark> scotto: If placehodler option is still selectable, someone could return to that
<dandclark> s/placehodler/placeholder
<dandclark> scotto: Do we really need this? Placeholder in text inputs is also big a11y issue
<dandclark> scotto: Already have solution for this now, use an option, don't give it a value. In validation, reject if no value
<hdv> ack flackr
<dandclark> flackr: Wanted to say thing. If you want to allow users to go back to unselected state, make the placholder selectable
<hdv> /me input type=reset
<dandclark> ...: LIke with radio buttons, if you want a way to reset form, add a button with script to do that. But dont' normally have a way to unselect radio buttons, dont' see why we need one for select either
<dandclark> jarhar: Don't think we can resolve, need a better way to render options into the selectedvalue to make more progress.
<dandclark> flackr: Aren't we saying this can be done by having an option that doesn't show up, that serves as your placeholder?
<dandclark> ...: By default we render text of option in the button, that satisfies the requirement for now. When we have a better solution for showing rich content, we can use that
<dandclark> ...: It's the default by being first. Just need way to indicate that it's not in the dropdown.
<dandclark> JakeA: use the attribute
<bkardell_> q+
<dandclark> flakr: It could be that there's a placeholder attr on the select that targets the option, ensures there's only one
<hdv> ack bk
<dandclark> bkardell: Could we do something to say if the 1st option has value of emptystring, it's the placeholder?
<dandclark> JakeA: If you use attr to indicate placeholder, it only applies to the 1st option. Worried about empty value because that's not how it behaves on select.
<dandclark> bkardell: Not showing is already not the way it behaves on select
<dandclark> flackr: Need a way for option to not be selectable in list
<dandclark> jarhar: Want to either render or not in the dropdown list depending on what author wants
<dandclark> jarhar: seems like there's 2 different controls here. Ability to not render should be on the option, and placeholder should be on the selectmenu itself?
<dandclark> flackr: To not have it render, seems like using the placeholder attribute is sufficent for that
<bkardell_> so we add an attribute like "resettable"?
<scotto> this is how someone would do this today
<scotto> <select> <option selected hidden>foo</option> <option>boo</option> </select>
<dandclark> flackr: We dont' need a separate feature for placeholder, as long as we have feature to prevent it from being in selectable options when we expand the menu.
<bkardell_> oh wow, does that work?
<dandclark> ...: Authors can build the equivalent of a placeholder
<scotto> https://codepen.io/scottohara/pen/eYLaWbL
<flackr> I suspect option:first-child { display: none; } might work
<dandclark> jarhar: What if on option element you say slot=placeholder.
<dandclark> ...: then it doesn't get slotted into the list
<bkardell_> scotto: that doesn't seem to work for me on safari at least
<dandclark> hidde: seems magic
<dandclark> una: so it's not selectable?
<dandclark> jarhar: yes, it's not rendered
<scotto> safari thinks different then
<dandclark> una: don't hate it but does seem magic
<flackr> scotto: nice demo!
<dandclark> ...: unexpected DOM result. But see how it would work for dev ergonomics. But then why not have the value in where you put the placeholder. In the dropdown slot.
<flackr> q+ can we just use hidden like scotto's demo?
<dandclark> jarhar: Una was saying we could make a special string that would go in option's value attr to prevent it from being rendered
<dandclark> una: Why not have attr that could live where the slot is for the placeholder, if you don't want it to be a selectable option, but want to put rich content inside it. The value of the placeholder attr is the value for screenreaders, visible to AT.
<dandclark> jarhar: attr goes on which el?
<dandclark> una: goes in slot where you put the button
<flackr> q+
<dandclark> jarhar: ON button element or selected-value element
<dandclark> una: On one of those
<dandclark> jarhar: It targets an option, or it's just text
<dandclark> una: not option, because option isnt' selectable
<dandclark> una: *works on providing code sample*
<dandclark> flackr: Could we do the thing that works with select today?
<dandclark> scotto: Doesnt' work on safari
<dandclark> jarhar: If put hidden on it, makes it not shown in the list. In selectmenu it also removes it from list
<dandclark> s/hidden/hidden attribute
<dandclark> flackr: Not sure you'd copy the options content itself, but we can figure that out
<dandclark> hidde: Want to come back to this?
<dandclark> ...: Seems like we're not sure if we need something specific for this or can be done with existing stuff
<flackr> q-
<hdv> q?

@gregwhitworth gregwhitworth removed the agenda+ Use this label if you'd like the topic to be added to the meeting agenda label Apr 5, 2023
@josepharhar josepharhar added the agenda+ Use this label if you'd like the topic to be added to the meeting agenda label Apr 5, 2023
@josepharhar
Copy link
Collaborator

At the meeting last week, people pointed out that having a placeholder attribute with a text value isn't good enough because if we find a way to display richer values in the selected value slot then simply having a text value wouldn't be as good as having all the rich content that you could put in an option element.

Scott pointed out that if you display:none or set the hidden attribute on an option, it won't show up in the dropdown, so the placeholder could simply be the first option in the list:

<selectmenu>
  <option hidden>--choose an option--</option>
  <option>one</option>
  <option>two</option>
</selectmenu>

If you want the user to be able to go back to the unselected state, you could simply remove the hidden attribute on the first option.
Does everyone think this is a good enough solution?

@jh3y
Copy link
Collaborator Author

jh3y commented Apr 6, 2023

Hey 👋

Does this work though? Setting [hidden] kinda works. The issue is that the value of the selectmenu becomes whatever that indeterminate option's value is. Which could be fine. But, the DX side likely expects something along the lines of null, undefined, "", etc.

Also, a hidden option breaks the keyboard controls.

<selectmenu>
  <option value="indeterminate" hidden>Indeterminate</option>
  <option value="one" autofocus>One</option>
  <option value="two">Two</option>
  <option value="three">Three</option>
</selectmenu>

Overriding the selected-value isn't terrible depending on the design. You would check against the selectmenu value and if it's other than null, you update accordingly. This is purely based on the fact that selected-value rich content hasn't been settled on yet so assuming long term that it'll be down to the developer to manage this which isn't "terrible", jus' a little tedious.

With that said, because a selectmenu assumes a value of the first option, setting the value to null or something other than an option value breaks the browser in certain scenarios 😅

Check this demo and tab into the control and hit up/down. Figured this was a "fun" find ha. But, this happens I believe because we've broken the tabbing controls by setting the value.

Either of these two approaches break the keyboard tabbing. I'm all for the "indeterminate" value route as mentioned. But, the tabbing controls need to skip to the first available(visible) option 👍

@scottaohara
Copy link
Collaborator

scottaohara commented Apr 8, 2023

The point of showing that hidden is how someone can hack this now was not to imply that it’s a perfect solution -now-, but to show that it’s a way it could be done and if it was specified to work this way, then unwanted behaviors could be mitigated. But if there is a better idea for how to do this, then we should go with that.

@josepharhar
Copy link
Collaborator

But, the DX side likely expects something along the lines of null, undefined, "", etc.

If you set the value of the placeholder option to an empty string, then at least assigning to an empty string works: https://jsfiddle.net/jarhar/3boetfum/
Assigning to null or undefined makes it look like it has no selected value at all, which we could change to make select the first option instead.

Check this demo and tab into the control and hit up/down

Thanks for finding this, I filed a bug to get it fixed: https://bugs.chromium.org/p/chromium/issues/detail?id=1432986

The point of showing that hidden is how someone can hack this now was not to imply that it’s a perfect solution -now-, but to show that it’s a way it could be done and if it was specified to work this way, then unwanted behaviors could be mitigated. But if there is a better idea for how to do this, then we should go with that.

Ok, what if we put a "placeholder" attribute on the placeholder option? I forget if this was thought of during the last meeting. @jh3y do you have any ideas?

@css-meeting-bot
Copy link

The Open UI Community Group just discussed SelectMenu placeholder capability? #637.

The full IRC log of that discussion <hdv> topic: SelectMenu placeholder capability? #637
<hdv> github: https://github.com//issues/637
<hdv> jarhar: this is about having a placeholder for <selectmenu>
<hdv> jarhar: I suggested a placeholder attribute on <selectmenu> itself
<hdv> jarhar: then last time we discussed we talked about adding an attribute to the <option> element, but then we discussed last time that it could work today already if you have the first <option> element as a placeholder and add hidden attr to it
<hdv> jarhar: it seems like we need a better way to do it
<una> q+
<masonf> q?
<hdv> jarhar: maybe we can add a placeholder attribute to the <option> element? does anyone have thoughts?
<masonf> ack una
<hdv> una: it sounds like this could work with another attribute, but I'm not sure if `placeholder` is it, if it's not going to be a string of text
<hdv> una: but then we'd also need to find out what to submit
<scotto> q+
<hdv> una: would suggest something very specific like optionlist-placeholder, though that's a bit long
<masonf> ack scotto
<hdv> scotto: I agree, reusing placeholder attribute would not be good here.
<hdv> scotto: when I mentioned using the hidden attribute… it was more to show _how_ it could be done today, I didn't want to suggest it was an ideal solution to this problem
<masonf> q+
<hdv> scotto: maybe it could have some attribute on an option that can indicate that a specific option is the placeholder, or maybe even an element like <placeholderoption>
<hdv> scotto: if we could identify an option as being the placeholder, or create an element to allow authors to specify the placeholder they want, that would be a less hacky than my previous suggestion
<hdv> s/suggestion/suggestion of using the `hidden` attribute
<masonf> ack dbaron
<hdv> dbaron: last time I asked about it, i18n working group prefers presentable text to not be an attribute
<hdv> dbaron: for things like directionality
<hdv> ack mason
<dbaron> s/directionality/directionality or ruby/
<masonf> q?
<hdv> masonf: we already have a placeholder attribute that is familiar to people… using that word might be useful. What if we did use the `placeholder` attribute or something like it but have it contain the ID of an option, like placeholder="foo" to indicate `<option id="foo">` is the placeholder
<masonf> q?
<hdv> Keith: there are cases where you want the currently selected
<hdv> jarhar: so it sounds like we have multiple options… maybe we can post those on the GitHub issue and discuss more there?

@jh3y
Copy link
Collaborator Author

jh3y commented Apr 13, 2023

Ok, what if we put a "placeholder" attribute on the placeholder option? I forget if this was thought of during the last meeting. @jh3y do you have any ideas?

To be honest, if I was going with an explicit placeholder that isn't an option, then perhaps it becomes another optional piece associated with a behavior. I gather the slot, behavior, etc. part was being discussed again. But, it could make sense as its own designated element. That's how I've gone about implementing it in some demos where I've needed it. That way you could have some logic such as if a placeholder is present, don't set a default value of the :selected or first option. And once there is a selected value, the placeholder loses visibility or something. In some cases to get around this, I have to manually create a selected-value element and control it myself.

@josepharhar josepharhar removed agenda+ Use this label if you'd like the topic to be added to the meeting agenda needs edits This is ready for edits to be made labels Apr 18, 2023
@una
Copy link
Collaborator

una commented Aug 10, 2023

I chatted with @mfreed7 and @josepharhar about a potential placeholder solution which is relatively simple and solves a lot of open questions.

TLDR; Align with what select does for placeholders: put value="" on an option to indicate a placeholder

Here's what this might look like:

Text-only placeholder:

<selectlist>
  <option value="">
    Select a country
  </option>
  <option value="south-africa">
    <img src="s-a-flag.png" />
    <p>South Africa</p>
  </option>
  <option>
    ...
  </option>
</selectlist>

Placeholder with an image:

<selectlist>
  <option value="">
    <img src="placeholder-flag.png" />
    <p>Select a country</p>
  </option>
  <option value="south-africa">
    <img src="s-a-flag.png" />
    <p>South Africa</p>
  </option>
  <option>
    ...
  </option>
</selectlist>

@una una added the agenda+ Use this label if you'd like the topic to be added to the meeting agenda label Aug 10, 2023
@brechtDR
Copy link
Collaborator

brechtDR commented Aug 16, 2023

Interesting idea @una

Few questions come to mind

  1. does this mean that the empty valued option should also be the first option?

  2. what if multiple empty values are provided?

  3. should we consider the "selected" and "disabled" attributes for this as well? As I believe an empty value could potentially be a choice (seen this in the past with other selects(

Would love to hear your thoughts.

@una
Copy link
Collaborator

una commented Aug 16, 2023

  1. Yes, it should. Currently, select will show "Disco" as the placeholder here:
<select> 
  <option value="disco">Disco</option>
  <option value="">Select a value</option>
</select>
  1. Currently, select will choose the first option (if there isn't a selected attribute on it). I.e. the placeholder in the below example is "Select a value"
<select>
  <option value="">Select a value</option>
  <option value="">Select a value 2</option>
  <option value="disco">Disco</option>
</select>
  1. Yes, good call -- that would be the ideal, just like with select:
<select> 
  <option value="" selected disabled>Select a value</option>
  <option value="disco">Disco</option>
</select>

So to put it all together:

<selectlist>
  <option value="" selected disabled>
    <img src="placeholder-flag.png" />
    <p>Select a country</p>
  </option>
  <option value="south-africa">
    <img src="s-a-flag.png" />
    <p>South Africa</p>
  </option>
  <option>
    ...
  </option>
</selectlist>

@brechtDR
Copy link
Collaborator

@una sounds about right. 👍

It's consistent with the current select implementation. I do remember that in the past a question was raised in a telecon with "can we do better?"

The use case for that is that people might want to use a placeholder attribute on a select as well just as they can do with an input element.

However, this use case doesn't have the ability to use an image as in your proposal. Especially for custom styling, I'm more into what you are proposing.

It does make me wonder: should we also allow a placeholder attribute? And what would happen if we have a placeholder combined with the empty value solution, but maybe this is beside the question.

@una
Copy link
Collaborator

una commented Aug 17, 2023

@brechtDR I recall we've talked about a placeholder attribute before but it didn't really get anywhere. I wouldn't be against it, but would need to define its utility and if its worth adding a new attribute to HTML, plus how it would interact with the existing select options, etc. This solution also doesn't disallow placeholder in the future, it could work with it. i.e.

<selectlist>
  <option value="" placeholder>
    <img src="placeholder-flag.png" />
    <p>Select a country</p>
  </option>
  <option value="south-africa">
    <img src="s-a-flag.png" />
    <p>South Africa</p>
  </option>
  <option>
    ...
  </option>
</selectlist>

where placeholder would replace selected disabled

@josepharhar
Copy link
Collaborator

josepharhar commented Aug 17, 2023

Considering that option elements already support selected and disabled, I think that we can just keep using those instead of making placeholder replace them. Besides, what if someone wants to make a placeholder than the user can go back to and select again? In this case, they could use selected without disabled.

I'd like to propose these three behaviors, aligning with @una, all three of which are already match the existing <select> element:

  1. <option value=""> in a <selectlist required> prevents form submission when selected.
  2. <option disabled> prevents the option from being selected by the user. It can still be the default initially selected option.
  3. <option selected> makes the option the default initially selected option. If there is no <option selected>, then the first child option in the DOM is the default initially selected option. If there are multiple <option selected>s, then the first one in the DOM wins.

Given all these behaviors, I think that authors should be able to do any placeholder use case they want.

EDIT:

I just re-read the issue description and realized this is missing the point that jhey brought up - there should be a way to also hide the placeholder from the option list completely.

Have an option that's hidden to "trick" the button part. This works but breaks the functionality as expected. Opening the dropdown doesn't focus on an option in the dropdown.

If we could make <option hidden> not break focus, then would the hidden attribute be good enough?

EDIT 2:

imo <option hidden> should be fine. I don't see any reason why it should break focus because I just tested <button hidden> and verified that it isn't keyboard focusable. I'd like to propose making <option hidden> the preferred way of preventing an option from being shown in the listbox until there is a compelling reason to do otherwise.

I don't think that just signifying an option as a "placeholder" to opt into these four different behaviors is a good idea when we could instead let authors opt into them separately to build exactly what they want.

@brechtDR
Copy link
Collaborator

imo <option hidden> should be fine.

In combination with this, it sounds really powerful. Absolutely great idea!

@css-meeting-bot
Copy link

The Open UI Community Group just discussed SelectMenu placeholder capability?, and agreed to the following:

  • RESOLVED: Support the value="" attribute, selected attribute, disabled attribute, and hidden attribute on option elements in selectlist. For v2, consider a placeholder attribute or element that implies <option value="" disabled hidden>.
The full IRC log of that discussion <gregwhitworth> Topic: SelectMenu placeholder capability?
<gregwhitworth> github: https://github.com//issues/637#issuecomment-1673657555
<gregwhitworth> jarhar: we've arleady discussed this once before
<gregwhitworth> jarhar: libs allow placeholder and it won't show up in the options list
<gregwhitworth> jarhar: I discussed having another element and that was deemed not a good idea but una noted supporting value=""
<gregwhitworth> jarhar: I looked at what select already supports and I think that we should support four different behaviors on an option element
<gregwhitworth> jarhar: value="" it will be an empty string but it will make the list has a required attribute it will keep the form from being submitted
<gregwhitworth> jarhar: second thing, if it is disabled it won't be selected by the user but it will be in the list but not selectable
<gregwhitworth> jarhar: we support the selected attribute we'll select the default
<gregwhitworth> jarhar: fourth we should support the hidden attribute on the option that will make it so that it won't show up in the listmenu at all; but this may have some a11y issues
<gregwhitworth> jarhar: this is all currently supported in the current select element
<masonf> q?
<gregwhitworth> masonf and argyle +1
<gregwhitworth> argyle: if you want examples of this I use gradient styles to make this possible
<jarhar> Proposed resolution: Support the value="" attribute, selected attribute, disabled attribute, and hidden attribute on option elements in selectlist
<bkardell_> +1
<flackr> +1
<masonf> q+
<scotto_> q+
<brecht_dr> gregwhitworth: In the current select when i put the hidden attribute in the option, it renders it in the box, but not in the popup. That seems odd to me.
<gregwhitworth> ack masonf
<gregwhitworth> masonf: it gets exactly the behavior that we want and it achieves the goal
<gregwhitworth> masonf: please choose one of these options, so this is nice
<gregwhitworth> scotto_:
<gregwhitworth> since I was the one that mentioned hidden was an example of what you can do today not that what we should do
<argyle> hrm https://codepen.io/argyleink/pen/PoXowLb
<gregwhitworth> scotto_: this should come with author guidance; it would be the random middle option that is hidden and multiple value=""; which one of those becomes the placeholder
<gregwhitworth> scotto_: as long as what's resolved will get the placeholder
<flackr> +1 it should be the first option that shows up in the select which you can use to implement placeholder like behavior
<gregwhitworth> q+
<gregwhitworth> ack scotto_
<gregwhitworth> scotto_: I don't really follow the proposed resolution as it relates to the placeholder
<bkardell_> this was my understanding too
<gregwhitworth> masonf: these four things, when put together they can make a placeholder
<gregwhitworth> masonf: this allows it to be a placeholder with these four options and also we planned to add these support
<gregwhitworth> masonf: do some of those scenarios cause a11y issues?
<gregwhitworth> scotto_: if it's disabled then it shouldn't be selected
<gregwhitworth> scotto_: if something's disabled; there is a reason for that
<gregwhitworth> scotto_: on ebay for example; there will be X variants but it is sold out so it's disabled but you want it rendered to the user
<gregwhitworth> scotto_: is it the combination of these things, one of them, etc that makes it a placeholder?
<gregwhitworth> masonf: I guess maybe my point is this proposal there is no such thing that is a placeholder
<gregwhitworth> masonf: they can be hidden, disabled, selected, the first one of those it will show up in the button
<gregwhitworth> scotto_: sorry, the one of these it needs to be the first option in the list
<brecht_dr> q+
<gregwhitworth> flackr: not if it's selected
<gregwhitworth> masonf: if it's a selected disabled in the middle but it will not be submittable
<gregwhitworth> scotto_: interesting, unsure what hidden would be
<gregwhitworth> scotto_: I'm not opposed to this, but it seems like a lot to do
<gregwhitworth> scotto_: or do we just want to have a placeholder attribute
<gregwhitworth> flackr: if it's the first option then it's selected
<gregwhitworth> jarhar: if we have a placeholder option, then we need to be both in the list
<bkardell_> could we have a placeholder idref to get around the "dont be an attribute" issues?
<gregwhitworth> masonf: it also allows the other usecases, such as wanting to show a selected but not available usecase
<gregwhitworth> scotto_: I wouldn't have considered that a placeholder
<gregwhitworth> scotto_: thank you for taking me on that journey
<gregwhitworth> q?
<jarhar> ill scribe
<jarhar> greg: when i was asking are these things defined, but scotts confusion is what i want to ensure is defined somewhere
<jarhar> greg: heres what happens with hidden, selected, etc.
<jarhar> greg: so selectlist needs to have a definition with what its going to do with those
<jarhar> greg: i think that the DX is super weird to me
<jarhar> greg: theres value to all of them existing, when you bring up the "please choose an option", that is such a placeholder and reaching for hidden is odd to me but its not something im going to fight for
<jarhar> greg: as long as we go through heres how it goes and author guidance apply hidden and everyone will move forward with life
<gregwhitworth> ack gregwhitworth
<gregwhitworth> brecht_dr: from the prior convo, two things came to mind
<gregwhitworth> brecht_dr: the benefit of this is that you can use the complex content in the option element; beyond text
<gregwhitworth> brecht_dr: another thing is that selected option being a placeholder that may not be the first option
<gregwhitworth> brecht_dr: they maybe selected somewhere down the list, but these do happen and it's perfectly understandable that the "placeholder" should be supported
<gregwhitworth> ack brecht_dr
<gregwhitworth> argyle: shared a codepen in IRC and started making weird selects and added multiple and none of the placeholders show up
<bkardell_> q+
<gregwhitworth> argyle: I kind of agree with scott on this that it feels very hacky; it's not an option. It's a label
<gregwhitworth> argyle: seems odd to keep this going forward
<gregwhitworth> argyle: we can make it very explicit
<gregwhitworth> ack dbaron
<gregwhitworth> dbaron: one brief comment that is similar to brecht's first comment is that i18n will remind groups of presentable text in attributes so that you can handle localization
<gregwhitworth> ack bkardell_
<brecht_dr> q+
<dbaron> s/groups of/groups of avoiding/
<scotto_> q+
<gregwhitworth> bkardell_: wanted to double on a couple things that others have said, if this is how we need to do it then sure, it's odd and hacky and I understand the desire to fix selectlist?
<gregwhitworth> bkardell_: can we give something for both select and selectlist
<gregwhitworth> bkardell_: all the reasons why it's not great to have a single string, bidi, complex content etc
<gregwhitworth> bkardell_: could we do an idref for that?
<scotto_> <option placeholderoption>whatever you want here</option>
<gregwhitworth> bkardell_: what is really the placeholder element
<flackr> q+
<gregwhitworth> masonf: one thing to point out is a few alternatives and one is attribute and another element like <placeholder> and that would solve all of the issues. ID ref is a third but feels a bit odd
<gregwhitworth> ack brecht_dr
<gregwhitworth> brecht_dr: I was thinking of a third; someone speaking about a placeholder attribute on the options that would allow you to select which option denotes the option
<gregwhitworth> q+
<gregwhitworth> masonf: the idea would be the placeholder attribute on the option?
<gregwhitworth> brecht_dr: yes
<gregwhitworth> ack scotto_
<gregwhitworth> that's what I was going to say, when I was talking about placeholder that we would actually re-use the placeholder attribute with text string and arbitrary content and i18n issues
<masonf> So <option placeholder> is like syntactic sugar for <option value="" disabled hidden>.
<gregwhitworth> scotto_: I think there is value in doing this as it could take precedance over an initially selected option and they end up with selected onto a selected option and what happens due to hacky stuff occurring
<flackr> and default selection - if you don't have a selected option
<gregwhitworth> scotto_: bugs sneak in
<gregwhitworth> q?
<gregwhitworth> ack flackr
<gregwhitworth> flackr: I think the discussion has gotten to where I've been going
<gregwhitworth> flackr: we have to suppor this anyways but I do like the proposal as it solves what we want
<jarhar> ill scribe
<jarhar> greg: im really like placeholder element given the plethora of elements we are introducing. it feels like we are doing old school flash days actionscript where everything is concretely defined
<jarhar> greg: i dont disagree from an implementation perspective that is so fast
<jarhar> greg: in a utopia world, i would just have a placeholder element
<jarhar> greg: like other issues with errors that we are going to have to generally solve to ensure that people dont rebuild their old stuff
<jarhar> greg: +1 to what rob just summed up
<jarhar> greg: kind of reached consensus on yes just go solve all of them
<jarhar> greg: seems to be general support, addendum to supposed resolution - placeholder attribute equivalent to value=""
<jarhar> flackr: should we do an element instead of an attribute?
<jarhar> greg: i care more about implementation time than whether is an element or an attribute
<scotto_> +1 to either attribute or optionplaceholder element
<jarhar> greg: take the whatwg spec time. do we envision this being faster as an attribute vs an element? i dont want to get bogged down
<jarhar> masonf: one important point is that we need to support these attributes anyway
<jarhar> masonf: they make it look like a placeholder
<jarhar> masonf: maybe we could do this in two versions. start with the option attributes, then do the element later
<jarhar> flackr: thats what i was getting towards
<jarhar> flackr: you can still build a placeholder in the meantime
<jarhar> masonf: i can see standardization issues with placeholder element
<jarhar> greg: that latter part is exactly what i want to avoid
<jarhar> greg: it seems pretty straightforward, it only works in selectlist
<jarhar> greg: it could work later on other elements
<scotto_> also agree to the idea that this could be a version 2 feature
<masonf> Proposed resolution: Support the value="" attribute, selected attribute, disabled attribute, and hidden attribute on option elements in selectlist. For a v2, consider a placeholder attribute or element that implies <option value="" disabled hidden>.
<jarhar> greg: what you just said is fine rob, im just not passionate enough about the placeholder thing. worthwhile resolution
<scotto_> +1
<argyle> +1
<jarhar> brecht: shouldnt that be option value="" selected hidden?
<masonf> RESOLVED: Support the value="" attribute, selected attribute, disabled attribute, and hidden attribute on option elements in selectlist. For v2, consider a placeholder attribute or element that implies <option value="" disabled hidden>.

@gregwhitworth gregwhitworth removed the agenda+ Use this label if you'd like the topic to be added to the meeting agenda label Aug 23, 2023
@lukewarlow
Copy link
Collaborator

For the placeholder aspect (wouldn't cover the reset one).

Could we allow <selectedoption>Placeholder content goes in here<selectedoption> kinda like how a slot takes default content?

@josepharhar
Copy link
Collaborator

Could we allow <selectedoption>Placeholder content goes in here<selectedoption> kinda like how a slot takes default content?

If we end up cloning into the user-agent shadowroot of the selectedoption element then I suppose that's a possibility. However, the way its currently prototyped and the way that some of us are pushing for is to replace the light-dom contents of the selectedoption element when cloning the selected option element, meaning that the "Placeholder content goes ..." text child of the selectedoption element will always get removed by the browser.

@lukewarlow lukewarlow added the agenda+ Use this label if you'd like the topic to be added to the meeting agenda label Apr 24, 2024
@josepharhar
Copy link
Collaborator

Is all we need to discuss here the idea of putting content inside the selectedoption element? I still think it would be better to follow the paradigm that the existing select element has with its options to do placeholders, especially now that we are re-using the select element.

@css-meeting-bot
Copy link

The Open UI Community Group just discussed SelectMenu placeholder capability?, and agreed to the following:

  • RESOLVED: Keep the previous resolution which reuses the existing APIs for placeholders for select elements
The full IRC log of that discussion <masonf> q+
<brecht_dr> jarhar We discussed this in the past and we resolved on supporting the bahavior that the select element already has. Where we can use the disabled and selected, etc attributes
<brecht_dr> jarhar the issue was never closed
<dandclark> q+
<brecht_dr> Luke Thinking of the selectedopion as a slot. which it kinda is. Should we just put placeholder in there? then you would not need the empty options
<gregwhitworth> q+
<brecht_dr> q+
<gregwhitworth> ack masonf
<brecht_dr> masonf We are now re-using the select element, I think we should re-use those paradigms
<una> +1 to masonf
<gregwhitworth> ack gregwhitworth
<gregwhitworth> +1 to masonf
<brecht_dr> masonf as much as possible, It would get confusing otherwise
<gregwhitworth> ack dandclark
<gregwhitworth> ack brecht_dr
<brecht_dr> dandclark When we started from a clean slate that sounded good
<gregwhitworth> brecht_dr: I do agree that this was something we discussed with another element, but when I saw the <selectedoption> capability I do think it's really neat
<gregwhitworth> brecht_dr: it could be really powerful and it wouldn't be breaking for existing <select>s
<gregwhitworth> q+
<gregwhitworth> masonf: my fear would be that we just resolved on now makes this really brittle if we did that
<gregwhitworth> ack gregwhitworth
<brecht_dr> gregwhitworth I agree with the spirit of what you said brecht_dr
<brecht_dr> But now that we are using select, this is not a technological usecase battle we need to have
<una> +1
<brecht_dr> gregwhitworth But now that we are using select, this is not a technological usecase battle we need to have
<Luke> +1 that's a fair summary
<jarhar> Proposed resolution: Keep the previous resolution which reuses the existing APIs for placeholders for select elements
<Luke> +1
<brecht_dr> +1
<masonf> +1
<una> +1
<dandclark> +1
<flackr> +1
<dbaron> +1
<jarhar> RESOLVED: Keep the previous resolution which reuses the existing APIs for placeholders for select elements

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
agenda+ Use this label if you'd like the topic to be added to the meeting agenda select These are issues that relate to the select component
Projects
None yet
Development

No branches or pull requests

10 participants