fix(runtime): hide slotted content with no destination in scoped components#5135
Conversation
It is possible for slotted content to still be invisible in the DOM if the slot was not rendered on the first render. This commit resets the `hidden` attribute of a node on successful relocation. STENCIL-1053
Hides any content that is projected through to a Stencil component that does not have a destination slot. Only for `scoped` components. Fixes #2877 STENCIL-938
|
| Path | Error Count |
|---|---|
| src/dev-server/index.ts | 37 |
| src/mock-doc/serialize-node.ts | 36 |
| src/dev-server/server-process.ts | 32 |
| src/compiler/style/test/optimize-css.spec.ts | 23 |
| src/compiler/output-targets/dist-lazy/generate-lazy-module.ts | 22 |
| src/compiler/prerender/prerender-main.ts | 22 |
| src/testing/puppeteer/puppeteer-element.ts | 22 |
| src/runtime/client-hydrate.ts | 20 |
| src/screenshot/connector-base.ts | 19 |
| src/runtime/vdom/vdom-render.ts | 18 |
| src/compiler/config/test/validate-paths.spec.ts | 16 |
| src/dev-server/request-handler.ts | 15 |
| src/compiler/prerender/prerender-optimize.ts | 14 |
| src/compiler/sys/stencil-sys.ts | 14 |
| src/compiler/transpile/transpile-module.ts | 14 |
| src/runtime/vdom/vdom-annotations.ts | 14 |
| src/sys/node/node-sys.ts | 14 |
| src/compiler/prerender/prerender-queue.ts | 13 |
| src/compiler/sys/in-memory-fs.ts | 13 |
| src/runtime/connected-callback.ts | 13 |
Our most common errors
| Typescript Error Code | Count |
|---|---|
| TS2345 | 399 |
| TS2322 | 374 |
| TS18048 | 286 |
| TS18047 | 101 |
| TS2722 | 37 |
| TS2532 | 30 |
| TS2531 | 23 |
| TS2454 | 14 |
| TS2352 | 13 |
| TS2790 | 10 |
| TS2769 | 8 |
| TS2538 | 8 |
| TS2416 | 6 |
| TS2344 | 5 |
| TS2493 | 3 |
| TS2488 | 2 |
| TS18046 | 2 |
| TS2684 | 1 |
| TS2430 | 1 |
Unused exports report
There are 14 unused exports on this PR. That's the same number of errors on main, so at least we're not creating new ones!
Unused exports
| File | Line | Identifier |
|---|---|---|
| src/runtime/bootstrap-lazy.ts | 21 | setNonce |
| src/screenshot/screenshot-fs.ts | 18 | readScreenshotData |
| src/testing/testing-utils.ts | 198 | withSilentWarn |
| src/utils/index.ts | 145 | CUSTOM |
| src/utils/index.ts | 269 | normalize |
| src/utils/index.ts | 7 | escapeRegExpSpecialCharacters |
| src/compiler/app-core/app-data.ts | 25 | BUILD |
| src/compiler/app-core/app-data.ts | 115 | Env |
| src/compiler/app-core/app-data.ts | 117 | NAMESPACE |
| src/compiler/fs-watch/fs-watch-rebuild.ts | 123 | updateCacheFromRebuild |
| src/compiler/types/validate-primary-package-output-target.ts | 61 | satisfies |
| src/compiler/types/validate-primary-package-output-target.ts | 61 | Record |
| src/testing/puppeteer/puppeteer-declarations.ts | 485 | WaitForEventOptions |
| src/compiler/sys/fetch/write-fetch-success.ts | 7 | writeFetchSuccessSync |
tanner-reits
left a comment
There was a problem hiding this comment.
Called out one thing
| // Store the initial value of `hidden` so we can reset it later when | ||
| // moving nodes around. | ||
| if (isInitialLoad) { | ||
| nodeToRelocate['s-ih'] = nodeToRelocate.hidden ?? false; |
There was a problem hiding this comment.
It might be possible to run into a situation where an element is programmatically hidden and we end up storing the incorrect state since this only captures the state on initial render. I figured that can be something we deal with as needed since the functionality is currently broken anyway so this is a step in the right direction
christian-bromann
left a comment
There was a problem hiding this comment.
One comment, but overall LGTM 👍
|
@tanner-reits I have a quick clarifying questions regarding the manual testing steps:
|
|
@rwaskiewicz Sorry bout that.
|
|
@tanner-reits my bad on question 2 - IDK what I was looking at 😓 |
Co-authored-by: Christian Bromann <git@bromann.dev>
|
Released in |
This commit adds a new extras flag, `experimentalScopedSlotChanges`, that is used to change logic in a few places to align Stencil's `scoped` encapsulation to work more like the native Shadow DOM when using slots. Changes in #5146 and #5135 are changed from being gated by the `experimentalSlotFixes` flag to this new flag so they can be toggled independently.
This commit adds a new extras flag, `experimentalScopedSlotChanges`, that is used to change logic in a few places to align Stencil's `scoped` encapsulation to work more like the native Shadow DOM when using slots. Changes in #5146 and #5135 are changed from being gated by the `experimentalSlotFixes` flag to this new flag so they can be toggled independently.
This commit adds a new extras flag, `experimentalScopedSlotChanges`, that is used to change logic in a few places to align Stencil's `scoped` encapsulation to work more like the native Shadow DOM when using slots. Changes in #5146 and #5135 are changed from being gated by the `experimentalSlotFixes` flag to this new flag so they can be toggled independently.
This commit adds a new extras flag, `experimentalScopedSlotChanges`, that is used to change logic in a few places to align Stencil's `scoped` encapsulation to work more like the native Shadow DOM when using slots. Changes in #5146 and #5135 are changed from being gated by the `experimentalSlotFixes` flag to this new flag so they can be toggled independently.
What is the current behavior?
Two current behaviors this solves:
slotis dynamically rendered in a component usingscopedor no encapsulation and is not rendered initially, the content that would go into this slot is marked ashidden. But, if the slot was rendered on a subsequent render, we would not remove thehiddenattribute, so the content would still be invisible in the DOM.slotlike how a component with a Shadow Root would hide any content in the light DOM not mapped to a slot.Fixes: #2877
What is the new behavior?
Solutions in order of the issues listed above:
hiddenattribute when content is successfully relocated to a "slot" location. This accounts for if a user manually set thehiddenattribute on an element so it would remain hidden after relocation. There may be issues with this value getting programmatically changed throughout a component's lifetime and reset to an incorrect value. We can address this in the future as needed.scopedcomponent that does not end up in a slot. If an appropriate "slot" is dynamically rendered later, the content will then be relocated and displayed accordingly.Does this introduce a breaking change?
Testing
Manual testing
experimentalSlotFixesin theextrasobject of the Stencil configmy-component.tsxandindex.htmlfiles as follows:divprojected through from theindex.htmlfile does appear in the DOM despite theslotnot being rendered.divis not visible until after clicking the button (which dynamically renders the slot).Automated testing
Existing unit & e2e tests continue to pass. Added e2e tests for the reproduction case in the associated issue.
Other information
Only available with the
experimentalSlotFixesextra flag enabled in a project's Stencil config.