feat(runtime): support the clonable shadow root option - #6837
Open
Arul1998 wants to merge 2 commits into
Open
Conversation
Expose the native `clonable` shadow root option so it can be set via the
`@Component()` decorator, e.g. `shadow: { clonable: true }`. When enabled, the
component's shadow root is attached with `{ clonable: true }`, allowing the
shadow root and its contents to be preserved when the host element is
deep-cloned (`Node.cloneNode(true)`). Libraries such as AG Grid rely on this
when cloning DOM subtrees that contain shadow components; without it the clone
is an empty shell.
This follows the existing `delegatesFocus` / `slotAssignment` pipeline end to
end:
- add `clonable` to the public `ShadowRootOptions` type
- add the `shadowClonable` flag to `CMP_FLAGS` (1 << 11)
- emit a `clonable` static getter from the decorator, parse it onto component
compiler meta (`shadowClonable`), pack it into the runtime flags in
`formatComponentRuntimeMeta`, and add the `shadowClonable` build conditional
- set `opts.clonable` in `createShadowRoot` behind the `BUILD.shadowClonable`
build flag
Carry `clonable` through the mock-doc / declarative shadow DOM path so the
option is not lost across SSR + hydrate, where the shadow root is reused rather
than re-attached: `attachShadow` records `clonable` on the mock shadow root and
serialization emits the `shadowrootclonable` boolean attribute, mirroring
`shadowrootdelegatesfocus`.
`ShadowRootInit` in the current TypeScript DOM lib does not yet include
`clonable`, so the option type is widened locally where it is read. Add
`clonable` and `shadowrootclonable` to the cspell wordlist.
Tests:
- parse `shadow: { clonable: true }` into component meta, incl. scoped / no
encapsulation / alongside delegatesFocus (parse-clonable.spec)
- pack the `shadowClonable` flag into runtime meta (format-component-runtime-meta.spec)
- `createShadowRoot` passes `{ clonable: true }` to `attachShadow` (shadow-root.spec)
- DSD serialization emits `shadowrootclonable`, incl. a toEqualHtml round-trip
and a combined delegatesFocus + clonable case (serialize-node.spec)
Fixes stenciljs#6833
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Expose the native
clonableshadow root option so it can be set via the@Component()decorator, e.g.shadow: { clonable: true }. When enabled, the component's shadow root is attached with{ clonable: true }, allowing the shadow root and its contents to be preserved when the host element is deep-cloned (Node.cloneNode(true)). Libraries such as AG Grid rely on this when cloning DOM subtrees that contain shadow components; without it the clone is an empty shell.This follows the existing
delegatesFocus/slotAssignmentpipeline end to end:clonableto the publicShadowRootOptionstypeshadowClonableflag toCMP_FLAGS(1 << 11)clonablestatic getter from the decorator, parse it onto component compiler meta (shadowClonable), pack it into the runtime flags informatComponentRuntimeMeta, and add theshadowClonablebuild conditionalopts.clonableincreateShadowRootbehind theBUILD.shadowClonablebuild flagCarry
clonablethrough the mock-doc / declarative shadow DOM path so the option is not lost across SSR + hydrate, where the shadow root is reused rather than re-attached:attachShadowrecordsclonableon the mock shadow root and serialization emits theshadowrootclonableboolean attribute, mirroringshadowrootdelegatesfocus.ShadowRootInitin the current TypeScript DOM lib does not yet includeclonable, so the option type is widened locally where it is read. Addclonableandshadowrootclonableto the cspell wordlist.Tests:
shadow: { clonable: true }into component meta, incl. scoped / no encapsulation / alongside delegatesFocus (parse-clonable.spec)shadowClonableflag into runtime meta (format-component-runtime-meta.spec)createShadowRootpasses{ clonable: true }toattachShadow(shadow-root.spec)shadowrootclonable, incl. a toEqualHtml round-trip and a combined delegatesFocus + clonable case (serialize-node.spec)Fixes #6833
What is the current behavior?
GitHub Issue Number: #6833
Stencil has no way to enable the native
clonableoption on a component's shadow root.shadowacceptsdelegatesFocusandslotAssignment, but notclonable, socreateShadowRootalways callsattachShadowwithout it. As a result, when a host element containing a Stencil shadow component is deep-cloned (Node.cloneNode(true)), the shadow root is not preserved and the clone is an empty shell. Libraries such as AG Grid that deep-clone DOM subtrees cannot clone Stencil shadow components. There is no per-component opt-in and no way to carry the option through SSR/hydrate.What is the new behavior?
clonablecan now be set on the shadow options object: