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

How to implement and shape API for <selectedoption> element for <select>#10242

Open
josepharhar opened this issue Apr 23, 2024 · 3 comments
Open

Comments

@josepharhar
Copy link
Contributor

josepharhar commented Apr 23, 2024

In the proposed appearance:base improvements for <select>, we want to support the use case of rendering the full DOM contents of the currently selected <option> into the select's button and let the author style it differently from the way it is styled in the <option> without the use of script.

The currently proposed way to support this, as designed in OpenUI, is to have a <selectedoption> element which copies contents from the selected <option> and replaces its children with those contents every time that the selected <option> changes.

There have been two ways of doing this which have been discussed:

  1. Call cloneNode on the selected <option>, and replace the light DOM children of <selectedoption> with the result of cloneNode.
    • Authors can style the <option> and <selectedoption> separately by selecting for those elements in their selectors. Since the cloned contents are in the light DOM, there is no new syntax needed.
  2. <selectedoption> has a UA shadowroot. Call cloneNode on the selected <option>, and replace the contents of the <selecedoption>'s shadowroot with the cloneNode result. Since this could leak the shadowroot, we will use the proposed sanitizer API on the cloneNode result before appending it to the shadowroot. In order to let authors style all the content in the shadowroot, we will create a pseudo element which goes to the content of the UA shadowroot, and add new syntax to CSS to allow for these descendants of the pseudo element to be selected.

Here's a quick example which shows the usecase and what the API would be like in solution 1 vs solution 2. It is a country picker where we only want to render the picture of the country flag in the button without the text next to it in the dropdown.

<select>
  <button type=popover>
    <selectedoption></selectedoption>
  </button>
  <datalist>
    <option>
      <img src="country1.jpg">
      <span>Country 1</span>
    </option>
    <option>
      <img src="country2.jpg">
      <span>Country 2</span>
    </option>
  </datalist>
</select>

Solution 1 CSS:

selectedoption > span {
  display: none;
}

Solution 2 CSS:

selectedoption::selectedoption-content > span {
  display:none;
}

This topic was previously discussed here: #9284

@josepharhar josepharhar changed the title How to implement shape API for <selectedoption> element for <select> How to implement and shape API for <selectedoption> element for <select> Apr 23, 2024
@tabatkins
Copy link
Member

Just curious - is there a reason this was split from #9284? If it was just to reset the conversation given a more stable design from HTML/OpenUI, should we close #9284?


I don't have a strong opinion between these two. I'm happy that we seem to have settled on "copy the DOM over" in both solutions, and are just debating whether it should be visible in the light DOM or hidden by a UA shadow; that makes many potential questions much easier to answer.

The Selectors spec is already equipped to handle Option 2, if we want: see Pseudo-elements/internal structure and the <complex-selector> grammar. This would be the first pseudo-element to actually use that syntax.

I suspect we might want Option 2, not for CSS reasons, but just for DOM reasons - it avoids the need to answer questions about mutation events and the like (I think those are censored by shadows? especially UA shadows?)

@josepharhar
Copy link
Contributor Author

Just curious - is there a reason this was split from #9284? If it was just to reset the conversation given a more stable design from HTML/OpenUI, should we close #9284?

Yeah I think we can close #9284 in favor of this.

it avoids the need to answer questions about mutation events and the like (I think those are censored by shadows? especially UA shadows?)

We could just disable mutation events during the scope of this DOM copying. We are trying to disable mutation events entirely anyway, so disabling them in this case sounds very reasonable to me.

Another question I have if we go with option 2: The pseudo-element would have to target the ShadowRoot node in order to access all of its children independently. Is it possible to have a pseudo-element map to a ShadowRoot node which is technically not an element?

@tabatkins
Copy link
Member

We could just disable mutation events during the scope of this DOM copying. We are trying to disable mutation events entirely anyway, so disabling them in this case sounds very reasonable to me.

Ah, true, that makes sense. Then that's not a factor either way, I'd think.

Another question I have if we go with option 2: The pseudo-element would have to target the ShadowRoot node in order to access all of its children independently. Is it possible to have a pseudo-element map to a ShadowRoot node which is technically not an element?

Yes, that's conceptually fine. It's just an "element" that is prevented from ever generating a box.

But the inheritance story is a little funky in that case. Would the elements inherit from the pseudo-element? That hasn't happened before (only pseudo-to-pseudo), and I'm not sure if it's problematic in implementations or not. Just using light-DOM children instead avoids us having to answer any of these questions.

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

No branches or pull requests

3 participants