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] Don't reuse slot="" and ::part(); behavior="" is also strange #702

Closed
domenic opened this issue Mar 31, 2023 · 40 comments
Closed
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

@domenic
Copy link
Contributor

domenic commented Mar 31, 2023

slot="" and ::part() are used for custom elements. They are a separate namespace for authors to use.

Native HTML elements get customized via normal child elements and pseudo-elements:

Similarly, your use of a semi-generic behavior="" attribute, which only has meaning within a certain parent context but can be used on any arbitrary element, is not idiomatic to HTML either. Is there any way to replace that with an idiomatic child-element pattern?

@josepharhar
Copy link
Collaborator

Thanks for your feedback! I see what you mean, especially with your details and summary example.

What if we replaced all of the slot and behavior attributes with new elements?

  • <div popover=auto slot=listbox behavior=listbox> would become <listbox>
  • <button slot=button behavior=button> would become <selectmenubutton> or something. I don't think we can necessarily just use <button> because you might want to use <button> elements in other parts of the selectmenu.
  • <span slot=selected-value behavior=selected-value> would become <selectedvalue>
  • <span slot=marker behavior=marker> would become <marker>, or maybe we could replace it entirely with a pseudo-element...?

This would align better with the HTML spec, but may also reduce the customizability of selectmenu, for example by not providing a way to opt out of behaviors - not sure how important this actually is for customizability though.

I'm likely missing historical context on this. I'd like to talk about it at the next meeting

@josepharhar josepharhar added the agenda+ Use this label if you'd like the topic to be added to the meeting agenda label Apr 6, 2023
@domenic
Copy link
Contributor Author

domenic commented Apr 7, 2023

What if we replaced all of the slot and behavior attributes with new elements?

I think this would be ideal. I look forward to hearing back what others say at the meeting, but I think this should be the starting position, and any deviations from it should be considered quite carefully. (It feels like instead the current starting position was some sort of custom element library.)

@gregwhitworth
Copy link
Member

This would align better with the HTML spec, but may also reduce the customizability of selectmenu

I'll need to think about this a bit and run through a variety of use cases to determine the implications of this recommendation as this is actually my key concern and why we landed where we did. Looping in @jh3y since he's probably built the most selectmenu demos and would be able to determine if this would break his customizations or not.

@mfreed7
Copy link
Collaborator

mfreed7 commented Apr 10, 2023

slot="" and ::part() are used for custom elements. They are a separate namespace for authors to use.

Can you comment more on this? slot and part() aren’t just for custom elements, right? They’re for shadow DOM, which the <selectmenu> contains. Part of what I liked about this proposal was that it isn’t co-opting these attributes for a different purpose, it is directly using them. I.e. the slot attribute actually slots that element into the UA shadow root. And ::part() exposes the parts. This would be the first native element with a well defined shadow structure designed for direct part replacement like this. But I think the way this works is exactly the same “namespace” as custom elements that use shadow DOM.

A nice thing (IMHO) about using slotting attributes is that a semantically appropriate element such as a <button> or <input> can be used, rather than a new element that presumably always acts like a button?

@domenic
Copy link
Contributor Author

domenic commented Apr 11, 2023

Can you comment more on this? slot and part() aren’t just for custom elements, right? They’re for shadow DOM

Sorry, I mispoke, you're right. They're for shadow DOM. But, specifically by shadow DOM, I mean they're for DOM trees created by authors with attachShadow() (or declarative shadow DOM).

which the <selectmenu> contains.

<selectmenu> does not (or at least should not) contain shadow DOM, in the sense of "something accessed and created through the normal shadow DOM APIs". I expect that if it's a native HTML element, it might have a sort of "user agent shadow root", like various implementations have chosen to use when implementing controls like <input type=date>, <details>, or <select>. But this is just an implementation detail, and should not interfere with the normal web developer APIs. There should be no shadowRoot property; slot="" and ::part() should not get their meaning changed by the presence of these elements; etc.

This would be the first native element with a well defined shadow structure designed for direct part replacement like this.

<details> is arguably such an element, as is <select> itself. Maybe even <li>, with its ::marker being the replace-able part. The point is, the choice of underlying technology to implement those "replaceable slots" is an implementation detail. Chromium might have chosen to use shadow DOM for <selectmenu>, but that implementation-specific technology choice must not leak into the specification and start interfering with web-developer-facing technology like slot="" or ::part().

A nice thing (IMHO) about using slotting attributes is that a semantically appropriate element such as a <button> or <input> can be used, rather than a new element that presumably always acts like a button?

Again, I don't think existing examples bear this out. <summary> is not exactly like a button. <button>s can have arbitrary behavior, but <summary> always expands/collapses its <details> element. I think that's the same intention for <selectmenubutton> as explained in #702 (comment) .

@josepharhar
Copy link
Collaborator

I need more time to collect pros/cons and limitations of slots/behaviors vs elements in order to present in a meeting, so I am removing the agenda+ label and will re-add it when I am ready. Anyone can continue to discuss here in the meantime.

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

Just chiming in from a web developer perspective obviously I understand there's trade-offs with each API.

I think I prefer treating it as a customizable shadow root rather than like the old style html elements. The main concern seems to be this isn't how HTML behaves currently but isn't that the problem that open-ui is trying to solve in that there isn't a proper specification for structure and stylability?

Take the file input for example we can currently customise the selector button using a (only fairly recently) standard pseudo element but we can't for example remove the label entirely or customise its text even. This would be better as a more defined shadow root like selectmenu.

If a proper structural spec appears for HTML elements then the worries about exposing implementation details (presumably for forwards compatibility reasons) mostly go away?

Also adding a new CSS pseudo element or actual html element for every single customisable part of each html element doesn't seem like a great design to me. Even adding the search html element required accessibility tools to update and various other software changes. Adding loads more elements each with their own contextual semantics seems like it might end up in a place where those kinds of tools are constantly playing catch-up?

@keithamus
Copy link
Collaborator

keithamus commented May 10, 2023

I'm not sure there's a appreciable practical difference in favour of using ::part()/slot=. Domenic is talking about avoiding the ::part and slot syntax, as it should be free to live within the realm of user-authored ShadowDOM, and the browser shouldn't introduce built ins using this as it is yet another surface for potential webcompat issues. In other words ::part()/slot= should be like data- attributes, and - in element names; an effective safe ground for userland, with a handshake agreement from specs not to collide.

::part() is an ergonomic tradeoff between webcompat safety and CSS complexity at the cost of developer ergonomics. Those concerns aren't present when using "bare" pseudo selectors. Instead of ::part(foo), browsers can introduce syntax like ::foo without webcompat issues, without the ergonomic tradeoff of ::part() and without the same CSS complexity concerns (it will be a well defined extension to CSS rather than a custom userland one).

Likewise slot= is a declarative mechanism for ShadowDOM authors to allow re-arranging of nodes to fit within a template structure. The browser doesn't need this as it can construct these based on other serialisable steps, such as the tag name (which userland can do, but it requires JS).

The rest of the mechanics are identical; older elements (like <input>) lacking well defined structural markup needn't set a precedent. Newer elements like <details>/<summary> can instead.

The concerns of adding more pseudo selectors vs using part seem rather unimportant; pedagogically speaking webdevs will have to learn either one; if I want to style a marker learning to target either ::part(marker) or ::marker is essentially the same mental space, except for those who haven't had exposure to authoring ShadowDOM would need to learn new concepts like ::part().

The other concern of using ::part()/slot is that it makes it harder to differentiate, within a CSS file, which declarations drive userland and which drive the browser. A declaration of ::marker {} has certain guarantees about the elements it will style, and the safety & cadence of which new elements will end up being targeted by that selector. The same is not true for ::part(marker) {} which could conflict with arbitrary elements.

@josepharhar
Copy link
Collaborator

A few of us have been working on a doc which walks through some ideas for new elements, including selectmenu, to see how using slots/behaviors vs creating new elements works for each of them: https://docs.google.com/document/d/1b1wTaoNwUY4sFJQZE0V1nLA7pve16WnYRipbBdzXpVU/edit

Using ::part and slots is helpful because:

  • It is very clean for new elements which have a lot of sub-parts
  • They're existing standardized and implemented technologies
  • Enables web developers to learn web components while using native HTML elements

I see that ::part and slot collide with user-authored stuff, so what if we used a different names?
We actually already resolved to use "::behavior" instead of ::part in this issue: #645
As for slot, we could have another name like "part" or "component" or "module".

Having a separate behavior attribute also enables certain use cases - see the "split button" use case in the linked doc.

your use of a semi-generic behavior="" attribute, which only has meaning within a certain parent context but can be used on any arbitrary element, is not idiomatic to HTML either. Is there any way to replace that with an idiomatic child-element pattern?

We could sort of invert the structure in order to avoid having attributes which only have meaning within a certain parent context like this:

With behavior attribute:

<selectmenu>
  <button slot=button>
    <span behavior=selected-value></span>
  </button>
</selectmenu>

With specialized attribute to invert stucture:

<selectmenu selected-value=myselectedvalue>
  <button slot=button>
    <span id=myselectedvalue></span>
  </button>
</selectmenu>

I don't know if this makes it any more idiomatic, but it certainly doesn't seem very ergonomic to have to add an element ID and wire it up in two places instead of just having behavior=selected-value.

We are planning on using the next OpenUI meeting to discuss the use cases and recommend yall read the doc

@josepharhar josepharhar added the agenda+ Use this label if you'd like the topic to be added to the meeting agenda label Jul 14, 2023
@domenic
Copy link
Contributor Author

domenic commented Jul 14, 2023

Thanks for the analysis doc! However, I think I've come to the opposite conclusion based off of it. Everything in the analysis doc is: "here's a way of doing it that is the same as the rest of the platform, and is more ergonomic. Here is a way of doing it using some generic ::part/behavior/etc. thing, which is less ergonomic and mismatches the rest of the platform". And somehow you favor the latter?

It seems like maybe one crux is that you're viewing it as strange or problematic to have new elements or pseudo-element selectors which are only usable within certain parents. That is not problematic; that is just how HTML works. Examples include: dd/dt in dl; option in select; li in ul; track in video/audio; caption in table; figcaption in figure; etc. Indeed, if you look at https://html.spec.whatwg.org/#elements-3 's "Parents" column, you'll see that a large number of elements are only allowed in certain parent contexts.

Similarly, pseudo-elements like ::backdrop, ::cue, ::file-selector-button, ::marker, ::placeholder, etc. are element-specific. This is fine and is how the platform works.

Having a separate behavior attribute also enables certain use cases - see the "split button" use case in the linked doc.

I think the comparison in the linked doc there is a false one. For some reason you did <span behavior=button> and then you compared it to just <span>button</span>. The correct comparison is with something like <actualbutton>, or maybe <span actualbutton>. (That said, I think that design is pretty weird. It seems like the "actual button" should be the part getting the button name, and the non-clickable parts should not be labeled "selectmenubutton" in any way.)

There is one thing the doc mentions which goes beyond existing patterns in today's HTML elements, which is replacing UA elements. But this will be novel in either paradigm, whether you use some generic names/attributes or specific ones. Designing that new system will be very hard, either way! You have half-gestured at one new system with behavior + slot, and then said you can get some replacement by only using slot and not using behavior. That's a totally new system you've designed that's non-idiomatic for HTML. Now do the work to design a new system that's idiomatic for HTML, to compare it with! My suggested starting point is to figure out how you'd replace the file selector button in <input type="file">, or the video controls in <video>, or similar.

@keithamus
Copy link
Collaborator

My suggested starting point is to figure out how you'd replace the file selector button in <input type="file">

In order to have a button declaratively replace the button in <input type="file">, which takes no children, we may end up with a solution that relates to the existing work done on popovertarget and subsequent proposal for dialogmodaltarget which has requests to unify toward something more generic like invokertarget. Perhaps there's some space to explore here about giving buttons the general ability to declaratively invoke interactive elements on the page?

An invokertarget could also apply nicely to a video; where invokeraction could be on of the video control actions e.g. play/pause. <input type="range" invokertarget="video"> could also have an invokeraction=playbackrate|volume|time which would create an easy way to make sliders that act on a video.

@justinfagnani
Copy link

I came here looking to find or file this very issue after reading the explainer and coming away very confused about the use of ::part().

Native elements can just define their own pseudo-elements, so what's the advantage of using ::part(button) instead of ::button? I thought ::part() was specifically for userland code that cannot otherwise add a real pseudo-element.

There may be a valid answer, but I would expect the explainer to go into the rationale for diverging from all of the rest of the native elements that use named pseudo-elements.

@mfreed7
Copy link
Collaborator

mfreed7 commented Jul 26, 2023

Native elements can just define their own pseudo-elements, so what's the advantage of using ::part(button) instead of ::button? I thought ::part() was specifically for userland code that cannot otherwise add a real pseudo-element.

I think ::part() was suggested because we were trying to adopt Web Components tech. Of the three proposed "new things":

  1. Use the slot attribute to describe which part of the control you'd like to replace.
  2. Use the ::part() psuedo element to style parts of the control.
  3. Replace the entire shadow root with a developer-provided one.

...only #1 is really needed here. As has been pointed out, minting proper pseudo elements such as ::selectmenu-selected-value is easy, and easily scoped to the element using it. So #2 is not needed. As we found through developers experimenting with the <selectmenu> prototype, #3 is also not needed, as long as you have #1, which allows replacement of parts of the control from the light DOM.

The alternative to #1 is minting new elements for each sub-part of any new control. Here is a comparison of those two approaches, for the split button use case for <selectmenu>.

<selectmenu> split button, using slots:

<selectmenu>
  <div slot=button>
    <button onclick=splitButtonAction()>
      <span behavior=selected-value></span>
    </button>
    <button behavior=button> ⬇️ </button>
  </div>
  <option>Option 1</option>
  <option>Option 2</option>
  <option>Option 3</option>
</selectmenu>

<selectmenu> split button, using new elements:

<selectmenu>
  <selectmenubuttoncontainer>
    <button onclick=splitButtonAction()>
       <selectmenuselectedvalue></selectmenuselectedvalue>
    </button>
    <selectmenubutton> ⬇️  </selectmenubutton>
  </selectmenubuttoncontainer>
  <option>Option 1</option>
  <option>Option 2</option>
  <option>Option 3</option>
</selectmenu>

To highlight the differences:

  • <div slot=button> vs. <selectmenubuttoncontainer>
  • <span behavior=selected-value> vs. <selectmenuselectedvalue>
  • <button behavior=button> vs. <selectmenubutton>

Certainly any pattern that can be addressed by <element attribute> (an attribute on an element) can always be addressed by <elementattribute> (a new element minted for this one combination). So both examples above work. And almost any pattern that uses slots can also use new elements. But there are some questions I have about the "mint new elements" approach:

  • Doesn't this effectively prohibit composition? E.g. what if I have <custom-button> and I want to use that as the button inside my <selectmenu>. Is there a way to do that cleanly?
  • This will result in the addition of many new elements to the platform. For example, a date picker will need quite a few special purpose elements, most of which are icons and buttons. Isn't there a risk of confusion? E.g. there will be many elements that semantically and presentationally are the same as each other, and their only difference will be where you can use them. Will developers get confused? I think there's an existing expectation that if you want a "button", you use <button>.

In addition to the above developer-centric issues (which are paramount), there are also implementation and spec questions:

  • What do these new elements do in other contexts? Certainly the validator can report that you're not supposed to use <selectmenubutton> inside a <form>, but we'll have to define what happens when you do. Does it submit the form? Does it fire all of the same events as <button>? Is it styled in the same way?
  • Implementation-wise, things get more complicated. For example, there will now be a number of things that behave like buttons. And buttons have many button-specific code paths, such as in the HTML parser. These will all need to be expanded to handle all the various types of buttons. This is do-able, of course, but leads to extra complexity and bugs.

@domenic
Copy link
Contributor Author

domenic commented Jul 26, 2023

Doesn't this effectively prohibit composition?

It shouldn't. This is like asking, "what if I have a <custom-button> and I want to to use that as the summary inside my <details>. Is there a way to do that cleanly?" Yes, there is: <details><summary><custom-button>...</custom-button></summary>...</details>.

Note the issue with an attribute version is pretty much precisely that attributes are not made for composition. Attributes modify the behavior of existing elements. But what does <script behavior="button"> or <video behavior="button"> do? Or <a href="foo" behavior="button"> or <input type="text" behavior="button">? Whereas we have clearly-defined answers for what happens when you place each of those elements inside another element, like <summary> or <selectmenubutton>.

(This holds whether the design is slot=button or behavior=button or selectmenubuttoncontainer="" or any combination of those.)

  • This will result in the addition of many new elements to the platform. For example, a date picker will need quite a few special purpose elements, most of which are icons and buttons. Isn't there a risk of confusion?

I don't think so! Developers haven't gotten confused about the many examples I've already given of context-sensitive elements. To quantify, it looks like 35/109 elements have parent restrictions; this is a pretty well-established pattern.

If you're worried about developer confusion, I'd strongly urge not introducing a novel pattern like these attributes-that-are-actually-elements, or even worse, changing the meaning of something like slot="" whichh developers already have a mental model of.

E.g. there will be many elements that semantically and presentationally are the same as each other, and their only difference will be where you can use them. Will developers get confused? I think there's an existing expectation that if you want a "button", you use <button>.

This is something that came up in my conversation with @josepharhar this morning. If you're worried about creating too many identical elements... don't do that! Just reuse the ones you created beforehand!

For example, notice how <li> is reused by <ul>, <ol>, and <menu>; how <option> is reused by <select>, <datalist>, and <selectmenu>; how <source> is reused by <picture>, <video>, and <audio>; and so on.

Even <button> has differing behaviors depending on its ancestors. If nested inside a <form>, it behaves one way; if it has popover-related attributes on it, it behaves another way; and if it has neither of those conditions, it just fires the click event with no activation behavior. If you want to use <button> for your selectmenu buttons, that should work fine! (Just be sure you're clear on what is actually a "button", since it seems like so far much of the discussion has identified a "button" as something non-clickable---that's actually a "button container"?)

Another related point I mentioned to Joey was that you don't need these long namespaced names like <selectmenuselectedvalue>. Just <selectedvalue>, or maybe even <selected> or <value>, would be fine! HTML does not namespace in this way in general; it's <summary>, not <detailssummary>; it's <input>, not <forminput>; it's <option>, not <selectoption>; it's <track>, not <mediatrack>. This kind of simple naming scheme is part of what allows us to reuse and expand elements over time, per my previous list of examples!

To be fair, there are some namespaced names, like <tbody>, <figcaption>, and <rt>. I would say they're more the exception. But the lesson from them should be clear: if your element is truly specialized (like <rt> and friends are specialized to <ruby>), then keep the namespace short. <smvalue> would be my suggestion, in that vein, if you truly cannot imagine any future elements who might have some sort of "current value" or "selected value" that might get slotted into them.

  • What do these new elements do in other contexts? Certainly the validator can report that you're not supposed to use <selectmenubutton> inside a <form>, but we'll have to define what happens when you do. Does it submit the form? Does it fire all of the same events as <button>? Is it styled in the same way?

Again, please lean on precedent. That's what it's there for! What does <summary> do outside <details>? What does <option> do outside <datalist> / <select> / <selectmenu>? What does <track> do outside <video> / <audio>? These questions are pretty easy to answer, I think. If you need help deciphering the spec / implementation in that regard, let me know.

  • Implementation-wise, things get more complicated. For example, there will now be a number of things that behave like buttons. And buttons have many button-specific code paths, such as in the HTML parser. These will all need to be expanded to handle all the various types of buttons. This is do-able, of course, but leads to extra complexity and bugs.

If the intent is for them to behave exactly like buttons, including in the HTML parser, then just use <button>!

But IIUC the intent is not for them to behave exactly the same, similar to how <summary> does not behave exactly like <button>.

@keithamus
Copy link
Collaborator

In the spirit of @domenic's comment, would simply borrowing <summary> get us what we want?

<selectmenu>
  <summary>Currently selected value</summary><!--selectmenu>summary::marker exists for dropdown indicator-->
  <optgroup> <!-- optional -->
    <option></option>
  </optgroup>
</selectmenu>

@mfreed7
Copy link
Collaborator

mfreed7 commented Jul 26, 2023

I don't think so! Developers haven't gotten confused about the many examples I've already given of context-sensitive elements. To quantify, it looks like 35/109 elements have parent restrictions; this is a pretty well-established pattern.

This wasn't my point - there will be, e.g., 10 elements that are all "buttons". It sounds like you think that won't be confusing, because the documentation for each of them will say "only use this button within the <selectmenu> element", so ok.

or even worse, changing the meaning of something like slot="" whichh developers already have a mental model of.

I don't think we're proposing to change the meaning of slot - on the contrary, we're using it just like it is defined. But ok.

This is something that came up in my conversation with @josepharhar this morning. If you're worried about creating too many identical elements... don't do that! Just reuse the ones you created beforehand!

But we'll have to, as you can see in the split button example. Unless I'm missing something. In that example, we need one "normal" button and one "special" button that the UA hooks up to the selectmenu behaviors. We can't, therefore, just use <button> without an attribute to tell the UA which button is the special one. We also can't use something like "the first <button> is the special one" because in that use case the special button comes last. So we'll need <button> and <selectmenubutton>.

Another related point I mentioned to Joey was that you don't need these long namespaced names like <selectmenuselectedvalue>. Just <selectedvalue>, or maybe even <selected> or <value>, would be fine! HTML does not namespace in this way in general; it's <summary>, not <detailssummary>; it's <input>, not <forminput>; it's <option>, not <selectoption>; it's <track>, not <mediatrack>. This kind of simple naming scheme is part of what allows us to reuse and expand elements over time, per my previous list of examples!

Fair enough. Let's go with <sb> for the special/select menu button. That's very parallel to <tr>, <td>, <li>, <dt>, etc.

Again, please lean on precedent. That's what it's there for! What does <summary> do outside <details>? What does <option> do outside <datalist> / <select> / <selectmenu>? What does <track> do outside <video> / <audio>? These questions are pretty easy to answer, I think. If you need help deciphering the spec / implementation in that regard, let me know.

None of those are interactive elements, AFAIK, so this'll involve more. But ok.

If the intent is for them to behave exactly like buttons, including in the HTML parser, then just use <button>!

But IIUC the intent is not for them to behave exactly the same, similar to how <summary> does not behave exactly like <button>.

See the split-button example above. The intent is for them to behave exactly like buttons. We just need a way to denote which button is the special one that should get hooked up to the appropriate behaviors. Therefore, as mentioned above, we can't re-use <button> if attributes are prohibited, so we need <sb>.


So this is a big change in direction. I'm a bit hesitant due to the similar whiplash I suffered during the Popover effort, going from element to attribute to element to attribute. I want to ensure this new approach ("New elements for everything, no new global attributes") is WHATWG-approved. I assume you're speaking on behalf of WHATWG editors, and there won't be pushback to bringing a bunch of new elements to the platform, as needed to achieve the use cases we are targeting with <selectmenu>. Can you please confirm, @domenic?


@gregwhitworth I'm going to close this issue, and I don't think we need to discuss in OpenUI. There is (pending approval above) only one approved way to do this for WHATWG, so there's no point in discussing new/different ways to do things. There's only one way to do it, and that's what we'll need to do.

@mfreed7 mfreed7 closed this as completed Jul 26, 2023
@justinfagnani
Copy link

I don't think we're proposing to change the meaning of slot - on the contrary, we're using it just like it is defined.

With my user hat on, I think that using slot makes a lot of sense (my comment above is about ::part()). If I am placing an element into a specific spot for projection and even if that includes behavior as a result of event listeners. It just fits the concept well, and I think it could even reasonably apply to other built-ins like <video controls> as a way to replace or add just specific controls.

@jh3y
Copy link
Collaborator

jh3y commented Jul 26, 2023

But we'll have to, as you can see in the #702 (comment). Unless I'm missing something. In that example, we need one "normal" button and one "special" button that the UA hooks up to the selectmenu behaviors. We can't, therefore, just use without an attribute to tell the UA which button is the special one. We also can't use something like "the first is the special one" because in that use case the special button comes last. So we'll need and .

Dipping in here. But, couldn't you use a button inside selectmenu like you would a form? The typical scenario is one button that you anticipate will open the popover. But, if it has type=button you can do what you want with it and it doesn't have the popover trigger behavior. Instead of opting in the button, you explicitly opt-out the button because the number of cases with multiple buttons is anticipated to be fewer than those with?

@dbaron
Copy link
Collaborator

dbaron commented Jul 27, 2023

For what it's worth, I'm pretty sad about the conclusion that we're not going to use Web Components technologies to describe pieces of the web that are implemented in browsers. In my mind, this was one of the major goals of Web Components (and thinking that is not a new opinion for me). There was admittedly a very long history leading to Web Components (including HTML Components, XBL 1, RCC, and XBL 2), and I was involved more in some of the earlier parts and had gotten tired of it before the parts that actually succeeded in building the pieces that have become a part of the Web. But being able to describe builtin controls formally was, I think, the main reason I thought that work was important in the first place.

But one of the longstanding problems in CSS has been that developers want to be able to style form controls and similar things and CSS doesn't have a good way to do that. My understanding that the plan of record for decades for addressing that need was to (1) do what ended up being Web components and then (2) redefine (in so far as we can do that compatibly) complex controls in terms of Web components. I think we're now doing moving towards a plan that is more work -- but also one that didn't need to wait 20 years for Web Components to be a reality. (Though it may well have needed to wait most of that time before we'd be willing to tolerate the number of elements and the complexity and work of specifying them.)

@css-meeting-bot
Copy link

The Open UI Community Group just discussed [select] Don't reuse slot="" and ::part(); behavior="" is also strange.

The full IRC log of that discussion <gregwhitworth> Topic: [select] Don't reuse slot="" and ::part(); behavior="" is also strange
<bkardell_> there was previously a proposed thing called interest masonf , but it was related to something else :) I voted for interest fwiw
<gregwhitworth> github: https://github.com//issues/702
<hdv> gregwhitworth: when we were designing some of this in the Microsoft explainer at first, we thought initially that web components would solve this problem very well
<hdv> gregwhitworth: in this issue, Domenic says this is not really how HTML works
<hdv> gregwhitworth: also the idea of web components's features like slots and parts is that browsers should not leverage them, they are for authors to use
<hdv> gregwhitworth: the other thing is this notion of a certain element being only used inside of this other element, this is common in HTML, it's fine to just introduce elements like that
<una> q?
<hdv> gregwhitworth: my key concern with this was something masonf explained… my worry isn't really that we would add a lot of elements and pseudos, but more that it would be harder to slot
<una> q+
<hdv> gregwhitworth: this is important, because we started off defining the parts and then defining how to make them styleable. There are certain controls with a defined anotomy, like <select> and <optgroup>/<option>s
<hdv> gregwhitworth: in cases like split buttons, which can be complex, I'm not sure how we can make them work _without_ slotting
<hdv> masonf: I've asked for clarification on if we really can add a lot of elements, seems like the answer to that is that we can
<hdv> masonf: if we add behaviour with a value, that's pretty much the same as adding another element, all of that would allow us to do the same things
<gregwhitworth> q+
<bkardell_> `<smb>` :-p
<hdv> masonf: all of these things can be done, so it is pretty much an ergonomics question: is it prettier to write <selectmenubutton> or do it through an attribute
<scotto> q+
<hdv> masonf: as you can do the same things with elements vs the attribute, I don't really mind which one it ends up… but given it needs to land in WHATWG, and the editors there do have a preference so we may end up using that
<hdv> nicole: clarifying question… does it need to be selectmenubutton or could you add a regular button inside of a selectmenu and that would _become_ a selectmenubutton?
<hdv> masonf: in the issue I used split button as the example… in that example the two buttons inside of it do two different things, they have to be distinguishable in order for it to work
<bkardell_> I love it
<gregwhitworth> ack una
<bkardell_> <3 spicybutton
<hdv> una: I think we have a clear path forward… in short term, with things like selectmenu vs combobox we can figure out what the distinct components are
<hdv> una: but for things like datepicker, would we actually be able to list all the different components or know what they are, and end up with 30 different elements ?
<hdv> masonf: datepicker probably gives us most concern… eg with datepicker would we not necessarily need <datepickerday1> <datepickerday2>, it could be <datepicker day="x">
<hdv> una: but aren't we saying attributes wouldn't be right?
<hdv> masonf: mostly global attributes are seen as a problem, like attributes that work on any HTML elements but then don't do anything on most HTML elements. Attributes that are specific to one element are fine
<masonf> q?
<hdv> gregwhitworth: I appreciate you drive this, masonf
<bkardell_> q+
<hdv> gregwhitworth: to una's point, we have a doc where we discuss these
<hdv> gregwhitworth: we could quickly throw together anatomies
<hdv> s/anatomies/anatomies between us
<gregwhitworth> ack gregwhitworth
<hdv> una: one worry I have is if we have short two letter components like <sb> for selectmenu button… and then we end up shipping a lot of components, what if we have <sb> somewhere else too
<hdv> una: one way to avoid it is to have an attribute shared between the components
<hdv> masonf: we can bikeshed actual names, sb was partially joke
<hdv> xiaocheng: what can possibly go wrong if we add like a 100 new elements, eg will we run into namespace issues?
<hdv> masonf: not in name space issues per se, but probably naming issues
<gregwhitworth> ack scotto
<jarhar> we could likely reuse the existing button element for selectmenu. if we need to differentiate it, then we could call it <button type=selectmenu>
<keithamus> q+
<hdv> scotto: I am partial to the idea of actually defining these particular elements… thinking back to some of the early demos where you could replace a button part with nothing and then you end up with no button at all
<hdv> scotto: by saying there is a specific element for the triggering element, that can then be required in HTML that could be required and styled however people want, but they can't be replaced, that seems like a very good thing to me
<hdv> scotto: it does seem that in some cases it would be a good idea to make some of these new elements for the cases where elements can have nested interactive elements… these are very tricky and like with details/summary browsers are currently a mess where browers implement them differently
<hdv> scotto: if we can create new elements where it is know that they are interactive and they can have interactive content in them, we can _plan_ for that (rather than today, people can make non-working things and assume it's fine because HTML allows for it)
<hdv> scotto: there is the possibility where maybe we don't have to create all new elements everywhere, some could be shared like optgroup currently is
<hdv> nicole: big +1 to that
<gregwhitworth> ack bkardell_
<hdv> bkardell: scott said most I was going to say
<jarhar> i wonder if any of the selectmenu demos here would go against what scott just said about forcing selectmenu to be usable https://microsoftedge.github.io/Demos/selectmenu/
<hdv> bkardell_: one thing that might be confusing… I would like ot see a proposal of what it looks like if selectmenu becomes this… eg we probably also need to determine if they can have a shadowroot, I guess in most cases probably not?
<hdv> gregwhitworth: we can't have user agents destroying the purpose of why we are on this path to begin with
<hdv> bkardell_: I think we would need to see the complete proposal to know
<scotto> @jarhar - some of those demos are the problematic ones i was referring to. for instance the multi-select demo cannot be accessed by keyboard
<hdv> gregwhitworth: yes we probably should go into docs and start writing out
<hdv> masonf: I'd rather try and go prototype it for one element as we may into have time to do it on multiple
<hdv> masonf: and figure out what sort of elements we would need specifically for selectmenu
<gregwhitworth> ack keithamus
<hdv> keithamus: I want to try and interpret what Domenic is getting at… I think the point of avoiding the namespace of custom elements… we don't want to step on custom element author's toes, we don't want to introduce issues that are already there for custom elements
<hdv> keithamus: zeroing in on selectmenu may be a mistake… we may need a more holistic view for adding these kinds of behaviours
<hdv> keithamus: we probably need to discuss is we need all specific elements. Like, might there be a way to use <button> instead of <sb>, I know, a strawman, and make that work?
<hdv> keithamus: we got in the same kind of discussion with the `popovertarget` attribute discussion that has now become a discussion around using some kind of `invoker` attribute, maybe that discussion can help us understand this discussion better
<hdv> keithamus: like, for the split button… if that is opening a popover, why don't we say a split button can have any number of buttons, but if you want one that actually opens a selectmenu, you would do that with an attribute on the button
<hdv> masonf: I get what you're saying, but a counterpoint… there isn't a namespacing issue with `slot=''` I think, it's more of a taste issue I think (which I don't disagree with)
<gregwhitworth> q+
<bkardell_> masonf: how can we help flesh that out?
<hdv> masonf: the issue with the `invoker` attribute… it's really tricky to make such generic attributes that can do a lot of things work because they're so generic, it is likely to take a lot of time and end up not happening at all
<hdv> gregwhitworth: I'm basically hearing conflicting discussion
<hdv> gregwhitworth: I agree with trying to define how this work for selectmenu, but would also agree it could make sense to repurpose elements like datalist and make them styleable
<keithamus> q+
<hdv> gregwhitworth: these controls are remarkably complicated, the amount of parts across design systems, it's a lot of work
<hdv> ack greg
<hdv> gregwhitworth: and because it is not easy we could probably go and start sketching new components in parallel with working on selectmenu implementation
<hdv> nicole: it's hard that we're getting this feedback at this point, I wish we had heard about them earlier
<hdv> nicole: it does seem somewhat arbitrary
<hdv> nicole: I'm arguing for us to get a design resource for mapping out this sort of things
<gregwhitworth> Nicole just hit the nail on the head on how I think we'll increase dev engagement is Open UI having design principles for landing into WHATWG
<hdv> nicole: this mapping out is something that designers would be really good at, on a non technical level
<hdv> nicole: which we could then overlay
<gregwhitworth> ack keithamus
<hdv> keithamus: I don't think it's necessary to figure out every variation of a particular element, I think it's more about introducing looser verbage
<hdv> keithamus: I'm thinking about details/summary… the summary element is not called detailssummary… it only works in details but it acts as a word that could be used in other places too
<hdv> keithamus: we need to think about elements more abstractly than zeroed in on specific use cases, like li, like option
<gregwhitworth> q+
<hdv> keithamus: we could use the summary element in selectmenu to describe the button or series of buttons that invokes the popover menu
<hdv> keithamus: there is a sweet spot somewhere where there is a name or existing element that ticks the boxes for the loose behaviour we have now, but also doesn't scope anything with regards to what is useful in the future
<jarhar> q+
<una> q+
<hdv> gregwhitworth: I don't think we disagree with the spirit of what you're saying… but also want to avoid confusion of elements that have the same name but don't do the same thing
<gregwhitworth> ack greg
<gregwhitworth> ack jarhar
<hdv> jarhar: if we allow for using the button element but with some attribute, it may be tricky to get the rendering to work
<gregwhitworth> ack una
<hdv> jarhar: but with some restrictions it should be doable to use a button element without introducing a new element
<hdv> jarhar: if we wanted to
<hdv> una: it sounds to me like we need a work session
<keithamus> q?
<hdv> una: heard (a) using existing elements as much as pobbiel, (b) using new elements for all the things, (c) using attributes
<hdv> s/pobbiel/possible
<hdv> una: we could work on those and take it to the next working group meeting
<nicole> +1 Una
<hdv> s/working//
<hdv> una: I think the format works… we've also done this with anchor positioning
<gregwhitworth> Zakim, end meeting

@jarhar
Copy link

jarhar commented Jul 27, 2023 via email

@gregwhitworth
Copy link
Member

Re-opening since there was further discussion around this topic last week with specific actions.

For what it's worth, I'm pretty sad about the conclusion that we're not going to use Web Components technologies to describe pieces of the web that are implemented in browsers. In my mind, this was one of the major goals of Web Components

@dbaron I want to say thank you for sharing your thoughts candidly and I will say that I feel the same sentiments. However, I'm less concerned with the need for elements or pseudo elements but I do want to utilize slots. My larger frustration is that the document authored about our fundamental approach is roughly three years old at this point. I think it's worth us doing a mini-retro on how we avoid these types of things from occurring in the future (should we have presented the paradigm to the TAG prior to any engagement, WHATWG, etc??).

But if I take a step back, I am cautiously optimistic as they aren't saying no to solving the problem but our current solution to the problem. We ultimately want to solve the 85-90% usecase by enabling styleable and extensible components and controls. While they may not like our current solution, the solution has proven that the model is correct and we should ensure that we do not lose use-cases as that benefits no one.

I look forward to the initial draft update by @mfreed7 and @jarhar re-doing the <selectmenu> anatomy

@gregwhitworth gregwhitworth reopened this Jul 29, 2023
@EisenbergEffect
Copy link
Collaborator

My own opinion, for what it's worth, is that any new built-ins should endeavor to use as much Web Component technology as possible. I would like to see a more consistent model for HTML and less concepts for developers.

If a developer knows Web Components, then they shouldn't need to learn much new when learning selectmenu. If they don't know Web Components, and are learning selectmenu, then they should be learning Web Components transitively.

If we're creating a new built-in or improving an existing one, and we don't have the Web Component tech to properly represent the element, then I believe we should design and standardize the Web Component tech we need first, then build the new element on top of that.

I'd like to have one HTML platform that is as consistent as possible at this stage in the game. I really don't want to see two different worlds, one for built-ins and one for custom.

@gregwhitworth
Copy link
Member

My own opinion, for what it's worth, is that any new built-ins should endeavor to use as much Web Component technology as possible. I would like to see a more consistent model for HTML and less concepts for developers.

If a developer knows Web Components, then they shouldn't need to learn much new when learning selectmenu. If they don't know Web Components, and are learning selectmenu, then they should be learning Web Components transitively.

@EisenbergEffect this was our thinking as well and why we created selectmenu in the manner that we did. However, I presume that you've read this thread and you'll find that that is not desired by at least one editor of the HTML specification. We additionally heard some general push back to this notion during the F2F CSSWG held 1.5 weeks ago. Suffice it to say, it's a lot of paddling upstream for that vision to come to fruition.

@justinfagnani
Copy link

I doubt think it makes a ton of sense to have a specific goal of using web components features in new native elements, for two main reasons:

  1. Web components features are trying to explain how the platform works. It's not always possible to do this seamlessly, but at its best that means that there would be no web component feature for native to use - both new native features and web components work how previous native features have.

  2. Once a feature is used in non-web components contexts, is ceases to be a web components feature, and becomes just a DOM feature. The feature should be used on its own merits, and not used or excluded because of the web components association. Getting over the idea that feature is web components specific might be the biggest hurdle.

So I think each feature needs to be discussed independently, but as part of a web components alignment.

From that perspective, I think that ::part() and slot="" are two very different features and whether to use them should be determined completely separately.

For me, using ::part() doesn't make sense because native shady has the ability to define pseudo-elements. ::part() only exists to try to give shadow DOM that same ability, though it's obviously not completely seamless. The only new platform capability is that parts can by dynamic, but that's not being used here, so new native pseudo-elements should just be regular pseudo-elements.

The slot attribute is arguably very different. It allows any element to be projected into a specific slot, instead of just blessed elements. This is a new capability and I think it makes a lot of conceptual sense and has some nice ergonomic benefits from not having to introduce wrapper elements just to slot something. I don't see why this ability would need to be limited to just web components.

@EisenbergEffect
Copy link
Collaborator

I can get on board with that.

@gregwhitworth
Copy link
Member

gregwhitworth commented Jul 29, 2023

The slot attribute is arguably very different. It allows any element to be projected into a specific slot, instead of just blessed elements. This is a new capability and I think it makes a lot of conceptual sense and has some nice ergonomic benefits from not having to introduce wrapper elements just to slot something. I don't see why this ability would need to be limited to just web components.

This is @mfreed7 and mine, among others key feature we'd like to re-use. We have been informed that we should introduce wrapper elements to produce slots and this doesn't seem like the best path in our opinion. We're fine migrating away from part(). I also do prefer the behavior attribute as well for slotted content and possibly element/custom elements that replace the native equivalent. The one negative of behavior that we already discussed fixing was meaningful defaults to avoid authors that do slot to not have to author behavior unless they introduce something that complicates the magic.

@josepharhar
Copy link
Collaborator

Here is a proposal for a new structure/anatomy for selectmenu.

Example of old structure:

<selectmenu>
  <div slot=button>
    <span>split button</span>
    <button behavior=button>
      <span behavior=selected-value />
    </button>
  </div>
  <div slot=listbox behavior=listbox popover=auto>
    <option>one</option>
    <option>two</option>
  </div>
</selectmenu>

Example of new structure:

<selectmenu>
  <span>split button</span>
  <button type=selectmenu>
    <selectedvalue />
  </button>
  <listbox>
    <option>one</option>
    <option>two</option>
  </listbox>
</selectmenu>

Replacing behavior=selected-value

The <selectedvalue> element can act as this behavior. Other tag names could work too, I didn’t think this through very much.

Replacing slot=selected-value

The new anatomy does not have a replacement for slot=selected-value. None of the OpenUI selectmenu demos use slot=selected-value without also applying behavior=selected-value, so I think that <selectedvalue> can replace this. In fact, the use of slot=selected-value in those demos is actually erroneous because the two usages of it are on children of a slot=button element.

Replacing slot=button

<selectmenubuttoncontainer> element

We could create a <selectmenubuttoncontainer> element, or something similar, to be an entire element which solely exists to act as slot=button. This is the most powerful option.

First child <button> element

We could make the first child <button> of the <selectmenu> get slotted into the button slot and also get the behavior=button behavior. This is nice because it is easy to understand and doesn’t require any new elements or attributes, but is the least powerful because it requires that the entire slot=button opens the listbox when clicked, probably looks like a normal button, and doesn’t allow for split buttons or nested buttons.

Any first child element or child elements

We could try to slot all non-listbox and non-option child elements into the button slot without creating a new element at all. I’m not sure how feasible this is since I haven’t had the time to try implementing this yet, but I think it seems the nicest because it's basically the same as without a new element at all.
This is the option I want to go with, and is what I put in the example above.

Replacing behavior=button

If we did the "first child <button> element” option for replacing the button slot, then it would also be a replacement for behavior=button. In the other cases, we could make a new element called <selectmenubutton>. Perhaps it would be nicer to instead create a new value for the existing button’s type attribute: <button type=selectmenu>

Replacing slot=listbox

<listbox> element

We could create a <listbox> element which automatically gets slot=listbox and behavior=listbox and popover=auto. It could also be used outside of the selectmenu element as a standalone replacement for <select multiple>. This would be a lot of extra work to make it work standalone, but people sound very excited for this to be a possibility. We could also make it work standalone as a followup to selectmenu, but Mason told me that we shouldn’t change the behavior of the new tag name because authors will certainly erroneously use it outside of selectmenu before we can change the behavior.

<datalist>

We could reuse the datalist element and have it work the same as <listbox> would. The advantage here is that it doesn’t do anything outside of a <selectmenu>, and we would never plan for it to do so. This way we wouldn’t have to block <selectmenu> on making <listbox> a replacement for <select multiple>.
We could also ship <selectmenu> with <datalist> initially and work on <listbox> in parallel. When <listbox> is ready, we can then make <selectmenu> take either a <datalist> or a <listbox>.

Replacing behavior=listbox

We don’t need a separate behavior=listbox. None of the OpenUI selectmenu demos have separated slot=listbox and behavior=listbox elements, so whatever replaces slot=listbox can also function as behavior=listbox.

@domenic
Copy link
Contributor Author

domenic commented Aug 2, 2023

That proposal looks really great to me! Thanks for the concrete work.

It sounds like <listbox> vs. <datalist> might still be an open question? Or at least, I didn't understand the reasoning for using <listbox>. Is the idea to delay shipping selectmenu until standalone <listbox> is also designed and shipped? Maybe that was implied by your analysis but I don't think you came out and stated it.

@scottaohara
Copy link
Collaborator

the revised markup example actually has me questioning what the span with the text 'split button' is meant to represent. not a concern with the proposed revision, but an open question on what could be put there / how it would need to be exposed to browsers' accessibility trees.

i have some ideas, but probably a good idea to discuss them at some point soon.

@brechtDR
Copy link
Collaborator

brechtDR commented Aug 3, 2023

The proposal for taking over with custom HTML sounds good.

  1. Just to be sure, Will we still be able to use a "simple markup" as well?
<selectmenu>
<option>option 1</option>
<option>option 2</option>
</selectmenu>

and further on style with ::part(), ::behavior() or ::enter-css-pseudo-here()?

Because the short version looked very powerful to me.

  1. Sidenote about behavior -> bad thing about behavior is that it's written different en/us vs en/uk. Might be nitpicky but some people might struggle with this.

@mfreed7
Copy link
Collaborator

mfreed7 commented Aug 3, 2023

One other idea came up in discussion: the <selectmenu> should have typeahead behavior, like the <select> does on most platforms. It would seem nice to include a <typeaheadbuffer> element which the UA will fill with the current contents of the typeahead buffer. In that way, the control could display the typeahead buffer visibly, to make it easier to use. Something like this:

Screenshot 2023-08-03 at 10 29 21 AM

Just a thought.

@mfreed7
Copy link
Collaborator

mfreed7 commented Aug 3, 2023

the revised markup example actually has me questioning what the span with the text 'split button' is meant to represent.

I believe that's a mistake. For a split button, that <span> should really be another <button> that does something else. And that's the reason you need to add something like <button type=selectmenu> to tell the UA which of those two buttons triggers the listbox popover.

@css-meeting-bot
Copy link

The Open UI Community Group just discussed [select] Don't reuse slot="" and ::part(); behavior="" is also strange, and agreed to the following:

  • RESOLVED: move forward with the "elements" approach for `<selectlist>`, abandoning the "slots" approach. Open fresh issues for any new questions.
The full IRC log of that discussion <gregwhitworth> Topic: [select] Don't reuse slot="" and ::part(); behavior="" is also strange
<gregwhitworth> github: https://github.com//issues/702
<hdv> masonf: jarhar and I looked at selectmenu and what if everything that was currently a slot would be an eleemnt
<gregwhitworth> Comment by joey: https://github.com//issues/702#issuecomment-1662708138
<hdv> s/eleemnt/element
<hdv> masonf: after we did it, it feels like it would result in a lot less code… it turns out we'd only need 2 elements
<hdv> masonf: previously `button` could be replaced with a `span`… the nuance/discovery, we don't need a container for it, we use selectmenu as the container, don't need a new element for it
<hdv> masonf: if you want some text and then a button that opens the popover, you need _some_ way to establish which one is the button
<scotto> q+
<hdv> masonf: proposal would be to add an attribute to the button to say that should get the button behaviour
<hdv> masonf: as proposed there, there would also be a new listbox element… that would be to _customise_ the listbox. If you don't add a listbox element, you just provide <option>s that would also work, the browser would add the listbox for you
<flackr> q+
<brecht_dr> q+
<hdv> masonf: I'd like to split out the discussion about whether to use datalist or listbox to a separate issue
<hdv> masonf: another thing we still need to figure out… if there's no container for the button, you just put content inside of the listbox, we need to figure out which parts go into the button and which go into the listbox
<gregwhitworth> ack scotto
<westbrook_> q+
<hdv> scotto: my question was what the span represent in the markup example
<hdv> s/represent/represents
<bkardell_> q+
<hdv> scotto: reminds me of the `details `element, if you put arbitrary content in that, the details element is smart enough to know that you didn't put a summary element in and can put that in for you
<hdv> scotto: the button typically shows what the selected option is… makes me thing that the button is the part of the combobox that's always shown, and the selectmenu is almost like a fieldset
<nicole> q+
<hdv> scotto: sometimes there's like extra content like a list of previously selected elements or some text that says 'choose shoes' because you want to… we need to figure out what sort of arbitrary content we'd allow there
<hdv> masonf: re: “if you provide some text there,what happens?” my answer would be if there's no button, the whole thing would become the button… but then the open question is, where would the currently selected value go?
<hdv> masonf: that's the kinf of stuff we need to put rules down for
<hdv> scotto: I guess I'm leaning more towards that it'd be weird if arbitrary content becomes the button, but if you put a button + arbitrary content that arbitrary content suddenly doesn't become the button?
<hdv> masonf: you'd have to put a `<button type=selectmenu>`, you explicitly claim _this_ is the button that is going to trigger it to open and the rest is not
<una> q+
<gregwhitworth> ack flackr
<bkardell_> q-
<hdv> scotto: question is… is the selectmenu really the interactive element or is it the button inside of it? for me the side content could be anything you'd want, but we need to figure out how to differentiate it in a sensible way and help people do it accessibly
<hdv> flackr: question: if everything that is not an option goes into the list… does that mean if you have a listbox it can only contain optons?
<hdv> flackr: and another question: I think people would want to add button that do other things, like a button that clears the current selection
<hdv> flackr: I would think the top select list becomes an activatable item and when you click inside of it it consumes whatever the activation is?
<hdv> flackr: similar to form submission in a way
<gregwhitworth> ack brecht_dr
<hdv> brecht_dr: I want 'select value' itself a bit odd… is it a self closing element that doesn't do anything except for printing the selected value on the screen? Seems strange in HTML?
<hdv> [adam in chat: <output> ]
<hdv> masonf: if you have other ideas, don't want to put you on the spot, but we'd welcome them. It felt a little weird to us too but we had to pick something
<gregwhitworth> q+
<hdv> brecht_dr: maybe output event? it does seem a bit weird to have a new element to do just that thing
<gregwhitworth> ack westbrook_
<scotto> output is _supposed_ to be a live region by default. so might not want that, unless we specifically negate it's implicit semantics in context of a selectlist parent
<nicole> q-
<hdv> westbrook_: one important piece to keep in mind… if the path is to move away from shadow dom/shadowroot-like APIs, but it continues to support people who work in those contexts…how would that work?
<hdv> westbrook_: how would a custom element user be able to participate in this context given current state of affairs? currently some of this works with workarounds, but would expect a new API like this to not require such workarounds
<gregwhitworth> ack una
<hdv> masonf: excellent point, this should be compatible with Web Components
<hdv> una: want to +1 that it feels cleaner to have some kind of containing element for that preview… there is also placeholder… we talked about placeholder before to have this sort of role
<hdv> una: in something like a combobox you might have a text input you could type into
<hdv> una: in which case it woulnd't just be a button
<hdv> una: there is meaning shared between these components… it's not just a button or output, also placeholder
<hdv> una: and other possible inputs
<hdv> masonf: placeholder element?
<nicole> q+
<hdv> una: but it's not just placeholder… I'm thinking about something like 'preview container'
<hdv> gregwhitworth: I agree it's a much cleaner look… I do have qualms with us removing the slot that wraps the button, I think it introduces all of the problems that people started asking about, like the 'will you shove all of that in the button' question
<hdv> gregwhitworth: for selected value you definitely need a container… in 90% of cases it usually isn't _just_ the selected value… it isn't meant to be all that's in the output element
<hdv> gregwhitworth: maybe `selected-valuec-container` that contains an `output`… we need some kind of container because people will do fancy things with this
<hdv> gregwhitworth: my third point is I would like to run this through the @@@ to make sure nothing is missing that people want to do with this
<hdv> gregwhitworth: thanks for all the work you've been doing on this
<gregwhitworth> ack gregwhitworth
<scotto> +1 to the thank you
<hdv> masonf: you said you were not sure about the container element
<una> +100! I do like this approach more :)
<hdv> gregwhitworth: I'm confused by some of these questions… the removal of slot somewhat complicates things… within this new setup there is a button that toggles the listbox… if the slot is there, we teach people what is going to exist, that the hierarchy is there
<gregwhitworth> q?
<gregwhitworth> ack nicole
<hdv> nicole: one thing that came up in CSSWG a couple of weeks ago is styleability of built-in elements… one thing in particular that comes up… if we skip wrapper elements, we reduce the use cases something can be used for, because it becomes difficult to style things the way people want
<hdv> nicole: like buttons at the bottom that aren't options but support the use case of the component somehow
<hdv> nicole: if we want to support these use cases, we need extra wrappers
<hdv> nicole: also for the kind of use cases scotto mentioned, we would need wrappers there to make it possible
<hdv> masonf: this is our first time to show this… next step for us would probably to prototype and figure out how it would work. there is a lot more work to be done
<hdv> nicole: this is where I wish we had a designer
<hdv> nicole: so they could go through and prototype
<masonf> q?
<hdv> una: if you go to amazon dot com, there's a lot of popovers on the homepage, at least 6-7 types of popovers
<hdv> nicole: was thinking about Google docs as well, there's selectmenus for text alignment, in those cases the icon doesn't actually change… there are probably a lot of cases like that where components do very unexpected things
<masonf> - Proposed resolution: move forward with the "elements" approach for `<selectmenu>`, abandoning the "slots" approach. Open fresh issues for any new questions.
<brecht_dr> q+
<hdv> scotto: but those kind of popovers would be menus
<bkardell_> q+
<gregwhitworth> ack brecht_dr
<bkardell_> q-
<hdv> brecht_dr: does this mean styling with `::part()` that we could do in the prototype would disappear?
<hdv> masonf: yes you could do the same things
<hdv> gregwhitworth: it would improve the developer experience a bit as they're actual elements that you can select rather than parts
<flackr> q+
<hdv> gregwhitworth: the probability of pseudo els is getting smaller and smaller
<hdv> brecht_dr: the reason I'm asking is I thought that approach was pretty powerful
<hdv> brecht_dr: but now you'd have to add a listbox I think?
<hdv> masonf: no, this should have the same capabilities as the old approach
<gregwhitworth> ack flackr
<bkardell_> I keep getting in the queue to say that i'm not sure I understand and would like to see more examples before I can really form an opinion
<hdv> flackr: to clarify… I think this is like `table`, if you don't add a `tbody` it is implicitly created
<hdv> [various people nod]
<hdv> bkardell_: I think I don't actually understand the new structure… like if there's a span it can't be a split button?
<hdv> bkardell_: I feel like I can't meaningfully add to this conversation as I don't feel I understand it all
<hdv> una: maybe pseudo code examples would be good
<hdv> masonf: this is not the end, it is the beginning
<una> we can put some examples together
<hdv> masonf: and if we find out down the road that people find it confusing we could return
<hdv> bkardell_: I felt the question being asked was 'how do you feel about this?' and all I could think is 'I don't understand it yet…' but if the question was 'should we make more' my answer would be 'yes'… I don't have a concern
<masonf> RESOLVED: move forward with the "elements" approach for `<selectlist>`, abandoning the "slots" approach. Open fresh issues for any new questions.
<gregwhitworth> Zakim, end meeting

@mfreed7
Copy link
Collaborator

mfreed7 commented Aug 3, 2023

Alright, I'm closing this issue again. We'll get started updating the explainer with "rules" for how to implement the ideas from above, and we'll update the Chromium prototype. At that point, we can start hashing out how things can work, and making sure we've taken care of all of the use cases.

@mfreed7 mfreed7 closed this as completed Aug 3, 2023
@josepharhar
Copy link
Collaborator

Just to be sure, Will we still be able to use a "simple markup" as well?

Yes, that will still work. The imperative slotting for the new selectlist will look for a listbox element, and if there isn't one, it will use a fallback listbox and slot all descendant option elements into it.

@jpzwarte
Copy link

jpzwarte commented Aug 4, 2023

Just so I understand the new API (without slots), I've tried to imagine how I would use <selectmenu> inside a design system:

<x-selectmenu>
  <template shadowrootmode="open">
    <selectmenu>
      <selectmenubuttoncontainer>
        <x-button>....?</x-button>
      </selectmenubuttoncontainer>
      <slot name="listbox">
        <listbox>
          <slot></slot>
        </listbox>
      </slot>
    </selectmenu>
  </template>
</x-selectmenu>

Which would then allow me to use it and have it styled in line with the rest of the design system:

<x-selectmenu>
  <option>Option 1</option>
  <option>Option 2</option>
</x-selectmenu>

Questions:

  1. Can i use a custom element for the button or does it have to be a <button>? Or do we need Form-associated custom elements: being a submit button WICG/webcomponents#814 so a CE can be a button first?
  2. Can i replace the marker with an <svg> for styling? Or can i only use CSS for changing the marker (similar to <summary>)?
  3. Is it possible to have the selected value be more than just plain text? For example an <svg> + text?
  4. Can i replace the <listbox> element or is it required? What if you wanted to use a virtual list web component when you have lots of options?

@mfreed7
Copy link
Collaborator

mfreed7 commented Aug 4, 2023

<x-selectmenu>
  <template shadowrootmode="open">
    <selectmenu>
      <selectmenubuttoncontainer>

For now, we're trying an approach where there's no <selectmenubuttoncontainer> needed.

  1. Can i use a custom element for the button or does it have to be a <button>? Or do we need Form-associated custom elements: being a submit button WICG/webcomponents#814 so a CE can be a button first?

This was mentioned at the weekly call yesterday. We need to support custom buttons somehow. At a minimum, it should work if <x-button> contains a <button type=selectmenu>. But it'd be better if we just allow <x-button type=selectmenu>. As you mentioned, that likely requires an extension to FACE, due to the interop issue with customized builtins.

  1. Can i replace the marker with an <svg> for styling? Or can i only use CSS for changing the marker (similar to <summary>)?

Since you can replace the entire button with your own content, you're free to use an <svg>, <img> or whatever else you like.

  1. Is it possible to have the selected value be more than just plain text? For example an <svg> + text?

For now, we're looking at the selected value as text only. There are issues with "copy pasting" the rest of the content from options. See #571 (comment).

  1. Can i replace the <listbox> element or is it required? What if you wanted to use a virtual list web component when you have lots of options?

You should be able to omit the <listbox> unless you want to replace the contents of the listbox itself. In other words, this should work fine: <selectlist><option>foo<option>bar</selectlist>.

@jpzwarte
Copy link

jpzwarte commented Aug 4, 2023

For now, we're looking at the selected value as text only. There are issues with "copy pasting" the rest of the content from options. See #571 (comment).

So I understand the comment you linked to. However, inside my <x-selectmenu> web component I could write some JS that renders the svg + text for the selected value myself?

The <select> suffers from the inability to display anything other than plain text, forcing us to write our own select (because we need to support mathml for example). Just checking we won't be forced to do that with <selectmenu>.

@mfreed7
Copy link
Collaborator

mfreed7 commented Aug 4, 2023

For now, we're looking at the selected value as text only. There are issues with "copy pasting" the rest of the content from options. See #571 (comment).

So I understand the comment you linked to. However, inside my <x-selectmenu> web component I could write some JS that renders the svg + text for the selected value myself?

Yep, that's the idea! The <selectlist> should allow arbitrary content in the button area, rendered just like other DOM content.

The <select> suffers from the inability to display anything other than plain text, forcing us to write our own select (because we need to support mathml for example). Just checking we won't be forced to do that with <selectmenu>.

Mathml should be supported. Your use case is the motivating use case for <selectlist>. (BTW, see #773 (comment) for why I keep calling it that.)

josepharhar added a commit that referenced this issue Aug 22, 2023
* Use new selectmenu anatomy in explainer

This new anatomy was proposed and agreed on here:
#702

* remove comment

* rewrite first sentence of button (slot)

* wrap selectlist with backticks and angle brackets

* add clarification to pseudo elements

* remove ::part sentence
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