- From: Joe Pea <notifications@github.com>
- Date: Sat, 11 Jul 2020 15:45:50 -0700
- To: w3c/webcomponents <webcomponents@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <w3c/webcomponents/issues/883/657141777@github.com>
Ah
> Sure thing, what I'm thinking is that a light DOM author might want to give control to part of its markup to some parent. Imagine this being like a design system implementation:
>
> ```js
> // ... elided ...
> customElements.define('x-ds', DesignSystem);
> ```
>
> then in the HTML
>
> ```
> <x-ds>
> ...
> <input id="whatever" name="whatever" control="ds-input">
> </x-ds>
> ```
Hah! Funny! That's very similar to what I wanted to do and asked about on StackOverflow yesterday: https://stackoverflow.com/questions/62842418
The example from that question is
```html
<div>
<p><span>test</span></p>
<p><span>test</span></p>
<p><span>test</span></p>
<p><span>test</span></p>
<p><span>test</span></p>
</div>
<script>
const d = document.querySelector('div')
const r = d.attachShadow({mode: 'open'})
r.innerHTML = `
<style>
/* This doesn't work as I was hoping: */
::slotted(p) span {
border: 1px solid deeppink;
}
/* This doesn't work (and I wouldn't expect it to), but I tried it anyways: */
::slotted(span) {
border: 1px solid deeppink;
}
/* This doesn't work either: */
:host span {
border: 1px solid deeppink;
}
/* This works, but not what I'm trying to do. */
::slotted(p) {
background: #f9f9f9
}
</style>
<slot></slot>
`
</script>
```
But you can also imagine how it would work with a custom element that creates its own `ShadowRoot`.
I think I like the `::slotted(*) .foo` method that I attempted in my SO question (f.e. in your last example it may be `::slotted(*) .close-btn`) because it doesn't add a new pseudo element in CSS (though honestly I don't know that "pseudo element" is even a good description of what `slotted` is) and doesn't add a new attribute in the HTML (the `control` attribute in your example).
Here's what your example would look like if what I was asking about worked (as one would intuitively expect it to):
```js
const sheet = new CSSStyleSheet();
sheet.replace(`
::slotted(*) .ds-input {
border: 2px solid tomato;
background: gainsboro;
}
`);
class DesignSystem extends HTMLElement {
constructor() {
super();
const root = this.attachShadow({ mode: 'open' });
root.adoptedStyleSheets = [sheet];
root.innerHTML = `<slot></slot>`;
// other stuff maybe
}
}
customElements.define('x-ds', DesignSystem);
```
and the user would write
```html
<x-ds>
<h1>Whatever</h1>
<form>
<label for="whatever">
<input id="whatever" name="whatever" class="ds-input">
</form>
</x-ds>
```
This is interesting because the user can write familiar markup using `class` attributes like they already do.
What I find unintuitive is why `::slotted(*) .ds-input` does not work. One would expect that `::slotted(.foo)` targets some set of elements with class `foo`, and therefore one would expect that `::slotted(.foo) .bar` would target any elements with class `bar` that are descendants of the elements targeted by `::slotted(.foo)`.
Your idea with `this.controls['close-btn']` would be convenient, but I believe this should also be achieved with the shadow root like follows (extending from my `::slotted` selector idea):
```js
this.shadowRoot.querySelector('::slotted(*) .close-btn').addEventListener('click', this.close.bind(this));
```
I think these things should be on `shadowRoot` for encapsulation. For example, your idea would be
```js
this.shadowRoot.controls['close-btn'].addEventListener('click', this.close.bind(this));
```
This is especially important because if the shadow root mode is `closed`, then someone could still run a querySelector or access controls on the custom element. I think it's good to just keep it on `shadowRoot`.
`ShadowRoot` instances already have the `querySelector` method, so we could allow it to query for things like `::slotted(.foo) .bar` without adding any new properties.
--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/webcomponents/issues/883#issuecomment-657141777
Received on Saturday, 11 July 2020 22:46:04 UTC