diff --git a/text/0000-dual-light-shadow.md b/text/0000-dual-light-shadow.md new file mode 100644 index 00000000..356f1997 --- /dev/null +++ b/text/0000-dual-light-shadow.md @@ -0,0 +1,346 @@ +--- +title: Dual light/shadow components +status: DRAFTED +created_at: 2022-02-08 +updated_at: 2022-02-08 +champion: Nolan Lawson (nolanlawson) +pr: https://github.com/salesforce/lwc-rfcs/pull/77 +--- + +# Dual light/shadow components + +## Summary + +[Light DOM components](https://rfcs.lwc.dev/rfcs/lwc/0115-light-dom) are a useful feature in certain contexts. +However, LWC currently requires a component to be either light or shadow – it cannot be both at once. + +This RFC proposes a "dual" mode where the same component can run in either light DOM mode or shadow DOM mode. + +## Basic example + +A component can declare its `lwc:render-mode` to be `"dual"`: + +```html + + +``` + +```js +// component.js +export default class extends LightningElement { + static renderMode = 'dual'; +} +``` + +Then, a parent component can use `lwc:render-mode` to choose to render the child as either light DOM or shadow DOM: + +```html + +``` + +```html + +``` + +This will result in `` being rendered as either light DOM: + +```html + +

Hello world

+
+``` + +or shadow DOM: + +```html + + #shadow-root +

Hello world

+
+``` + +## Motivation + +Light DOM and shadow DOM have tradeoffs relative to each other. Each may be useful in certain cases. + +Also, the design of LWC lends itself to largely shadow-DOM-neutral component authoring. For instance, LWC supports scoped styles, light DOM ``s, and `lwc:ref` – all of which work roughly the same between shadow components and light components. So there is not a strong reason for a component to declare upfront whether it is light or shadow. + +So naturally, a request we've heard from component authors is that they would like to be able to author a single component and have it render as either light or shadow DOM. + +To be fair, there is already a workaround today: composition. I.e., a component could be authored in light DOM, and then a wrapper component could be authored in shadow DOM. + +However, this workaround has several downsides: + +1. All properties have to be reflected between the shadow parent and light child. +2. All slots have to be propagated from the parent to the child. +3. An extra wrapper component is required, which may be undesired for common base components (e.g. buttons, icons). +4. The two components have different external tag names (e.g. `my-button` and `my-button-shadow`). + +This RFC has none of these downsides. + +## Detailed design + +### Declaring a dual-mode component + +Currently the `lwc:render-mode` directive / `static renderMode` property only allows two values: `"light"` and `"shadow"`. + +This proposal adds a third value: `"dual"`. + +```html + + +``` + +```js +// component.js +export default class extends LightningElement { + static renderMode = 'dual'; +} +``` + +### Switching between light and shadow mode + +Currently, `lwc:render-mode` can only be applied to the top-level `