[WICG/webcomponents] Shadow DOM mode as opt-in feature flags (Issue #1049)

The Shadow DOM was originally built as an all-or-nothing API to encapsulate a broad range of functionality. Since then, there have been many recommendations around selective means of working around that encapsulation, including `mode: "open"`, the `::part` and `::slotted` CSS features, a new [`open-styleable` mode](https://github.com/WICG/webcomponents/issues/909), and userland requests for such things as [Light DOM slots](https://github.com/lit/lit-element/issues/553). At the core of each of these requests is the thought, "The Shadow DOM does too much; how can we make it do less?"

What if, instead of debating how to allow people to opt out, we instead look at a way to make Shadow DOM features individually opt-in with feature flags? We could treat `mode` more akin to `<iframe>`’s `sandbox` attribute where multiple flags can be set (though even that API suffers from flags that opt out, instead of opting in).

JavaScript example:

```js
host.attachShadow({
  mode: 'encapsulate-ids encapsulate-events encapsulate-styles delegates-focus'
});
```

Declarative example:

```html
<template
  shadowdommode=“encapsulate-ids encapsulate-events encapsulate-styles delegates-focus”
>
```

I propose we change `mode` from being a single-value string to being a whitespace-delimited multi-value string with the following flags to start with (the names could change and the list could be longer or shorter):

- `encapsulate-ids`: Omitting this value is useful for allowing unique items on the page to exist in a declarative Shadow DOM to enable deep linking, id-referencing via aria attributes, id-referencing `for=""` attributes, etc. There is currently no alternative to this feature.
- `encapsulate-events`: Omitting this value is useful for web components that consist of several related but unique form fields and buttons, such as checklists, address fieldsets, credit card fieldsets, etc., as well as component libraries that wrap buttons and inputs with specific styling, but otherwise wish the Shadow DOM children to behave regularly. This would be a simpler alternative to the Form Associated API.
- `encapsulate-styles`: Omitting this value is useful for allowing Light DOM styles to apply to Shadow DOM children. This fulfills the intent of and could be an alternative solution to the `open-styleable` recommendation.
- `delegates-focus`: Allows for setting the `delegatesFocus` option of `.attachShadow()` declaratively which I don't believe is currently possible.
- `open`: Would be redeclared as a preset of the `encapsulate-ids`, `encapsulate-events`, and `encapsulate-styles` values.
- `closed`: (default value if `mode` is omitted) Would be redeclared as a preset of the `encapsulate-ids`, `encapsulate-events`, and `encapsulate-styles` values, but would also prevent the definition of the `.shadowRoot` property on the host element.
- `none`: A value that explicitly disables all other flags. This would solve the intent behind requests for "Light DOM, but with slots." I believe for slots to be effective a host of some kind is still needed. If users wish for slots throughout a page, this would be easy enough to implement by wrapping page contents in `<template shadowdommode="none">`.

I don't believe we need a flag as a means of toggling slots as that appears to be an intrinsic feature of Shadow DOM and it's "toggled" by the existence or non-existence of `<slot>` elements within the Shadow DOM markup.

This could allow for solving the current need for granular control of encapsulation while also opening the door for future additional Shadow DOM features without breaking backwards compatibility or declarative usage.

I realize each of these flags could generate a lot of questions that may need to be discussed in detail in separate threads. I'm happy to create those threads of the idea overall has merit.

_Originally posted by @shannonmoeller in https://github.com/WICG/webcomponents/issues/909#issuecomment-1937380036_
            

-- 
Reply to this email directly or view it on GitHub:
https://github.com/WICG/webcomponents/issues/1049
You are receiving this because you are subscribed to this thread.

Message ID: <WICG/webcomponents/issues/1049@github.com>

Received on Sunday, 11 February 2024 21:15:47 UTC