Skip to content

Nested Slots render children components in the wrong order if children components are added dynamically at run time. #5449

@classicmike

Description

@classicmike

Prerequisites

Stencil Version

4.12.6

Current Behavior

I'm doing some prototyping where I have Stencil components to load in to Seek Playroom (Design Tool using existing components: https://github.com/seek-oss/playroom), using the generated React components from ReactOutputTarget.

I have a minimum reproducible repo that you can use to run your tests to confirm the bug, which is here: https://github.com/classicmike/stencil-slot-test.git

The end goal is I want to be able to enter code in the code editor and Playroom will render the final generated output for me to be able to preview the content with children elements rendered in the correct order. See screenshot below. Currently this works perfectly fine when I enter the code and reload the page.

Ideal State of using Seek Playroom with nested children

The problem actually comes in when we add multiple stencil components nested inside a parent stencil component on the fly at runtime like so:

<TestContainer>
    <TestBtn>Some button 1</TestBtn>
    <TestBtn>Some button 2</TestBtn>
</TestContainer>

Both TestContainer and TestBtn have <slot> to render their children and have scoped: true.

What happens is the children components that get instantiated and rendered will appear in reverse order. See screenshot below:
Current bug where children content  is being rendered in 'reverse order'.

Please look at the code editor at the bottom of the screen and the result and you'll probably understand.

Further investigation so far has revealed that this issue happens mainly on using the Stencil components with slots as a parent element and do not happen when using plain HTML tags such as a div. Please see below:

Rendering and ordering works correctly with a plain html tag as parent

More investigation revealed, that it seems like this issue was introduced after doing a the introduction of adding experimentalSlotFixes: true to resolve very similar issue I had with the following Github issue: React fails to manage children in Stencil · Issue #2259 · ionic-team/stencil · GitHub.

Without the experimentalSlotFixes: true, writing the same markup renders the children in their correct order, like the screen shot below:
Children content order renders correctly when experimentalSlotFixes is false or not declared

Remember all of these scenarios I am testing for is when these new components are added and rendered dynamically at runtime.

Unfortuantely, I need the experimentalSlotFixes: true in order for my buttons inside of TestBtn to render correctly.

Expected Behavior

The end goal is I want to be able to enter code in the code editor and Playroom will render the final generated output for me to be able to preview the content with children elements rendered in the correct order. See screenshot below. Currently this works perfectly fine when I enter the code and reload the page.

Ideal State of using Seek Playroom with nested children

System Info

System: node 20.6.1
    Platform: darwin (23.1.0)
   CPU Model: Apple M2 Pro (10 cpus)
    Compiler: /Users/michaeltran/Documents/prototype/stencil-slot-test/node_modules/@stencil/core/compiler/stencil.js
       Build: 1709576313
     Stencil: 4.12.5 💙
  TypeScript: 5.3.3
      Rollup: 2.56.3
      Parse5: 7.1.2
      jQuery: 4.0.0-pre
      Terser: 5.28.1

Steps to Reproduce

  1. Clone the following repo: https://github.com/classicmike/stencil-slot-test.git
  2. cd stencil-slot-test
  3. Run npm install
  4. Build stencil library by running cd packages/stencil-library from the root directory and npm run build
  5. Build react library by running cd packages/react-library from the root directory and npm run build
  6. Initialise Play room by running cd packages/stencil-library-playroom from the root directory and run npm run playroom:start
  7. Once the UI has loaded, write the following markup below character by character. Do not copy and paste.
<TestContainer>
  <TestBtn>Test Btn 1</TestBtn>
  <TestBtn>This should be AFTER 'TEST BUTTON 1'</TestBtn>
</TestContainer>

If instructions done as above, the you will see the bug as shown below:

Current bug where children content  is being rendered in 'reverse order'.

Note: If you decide to reload the page, since it uses some form of local storage I believe, the code that was previously written on the screen will be loaded in and everything will work fine. To replicate the issue again after reloading the page, delete all content in the code editor and rewrite it again.

Code Reproduction URL

https://github.com/classicmike/stencil-slot-test.git

Additional Information

No response

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions