Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Elements created with map added outside target slot #897

Closed
davidrleonard opened this issue Jul 2, 2018 · 19 comments
Closed

Elements created with map added outside target slot #897

davidrleonard opened this issue Jul 2, 2018 · 19 comments
Projects

Comments

@davidrleonard
Copy link

davidrleonard commented Jul 2, 2018

Stencil version:

@stencil/core@0.9.1

I'm submitting a:

[x ] bug report
[ ] feature request
[ ] support request => Please do not submit support requests here, use one of these channels: https://forum.ionicframework.com/ or https://stencil-worldwide.slack.com

Current behavior:

  1. Use map inside of a render() function to iterate over state data, create elements, and pass the elements into a slot
  2. When the component first mounts the resulting elements are correctly rendered in the slot, and have a parentElement of the slot's owner
  3. Add something to the state data so render runs again and the map runs again
  4. The new elements are not rendered into their slot, and have a parentElement of null. They new elements are weirdly appended to the end of the slot owner's shadow root, and do not appear in the slot owner's children list. The new elements appear visually after all of their slot owner's shadow root content. The elements that were created before stay in the same place and work as expected.

Expected behavior:

1-3: Same
4. The new elements are rendered into their slot just like the original elements. The new elements have a parentElement of the slot owner and appear visually in the correct place.

Steps to reproduce:

  1. Create a stencil-component-starter project with the following files:
src/components/
├── my-app/
│   └── my-app.tsx
├── friends-list/
│   └── friends-list.tsx
└── index.html
  1. Add source code for index.html:
<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0">
  <title>Stencil Component Starter</title>
  <script src="/build/mycomponent.js"></script>

</head>
<body>
  <my-app></my-app>
</body>
</html>
  1. Add source code for my-app.tsx:
import { Component, State } from '@stencil/core';

@Component({
  tag: 'my-app',
  shadow: true
})
export class MyApp {
  @State() friends: string[] = ['Maria', 'Jasmine', 'Juan'];

  addFriend = () => {
    this.friends = [
      ...this.friends,
      'Alexander'
    ];
  }

  render() {
    return (
      <div>
        <button onClick={this.addFriend}>Add a friend</button>
        <friends-list>
          {this.friends.map(friend => {
            return <p>{friend}</p>;
          })}
        </friends-list>
      </div>
    );
  }
}
  1. Add source code for friends-list.tsx:
import { Component } from '@stencil/core';

@Component({
  tag: 'friends-list',
  shadow: true
})
export class FriendsList {
  render() {
    return (
      <div>
        <h1>These are my friends:</h1>
        <div style={{ display: 'block', border: '1px solid red' }}>
          <slot></slot>
        </div>
        <p>That's it....</p>
      </div>
    );
  }
}
  1. Run the dev server: npm run dev and open the demo in Chrome
  2. Click the "Add Friend" button
  3. The new friend "Alexander" appears outside of the red-bordered slot area.

image

  1. Inspect element and check the "Alexander" p tag's parentElement. It is null.

image

Related code:
See above.

Other information:

OS: macOS Sierra 10.13.2
Browser: Chrome Stable Version 66.0.3359.181 (Official Build) (64-bit)

@ionitron-bot ionitron-bot bot added the triage label Jul 2, 2018
@davidrleonard
Copy link
Author

Potentially related bugs that are closed: #810, #757, #727

Test suite added in 2a1553f that I think should be failing right now based on my repro code above, but seems to be passing in the last CI build (0 failures for karma tests).

@sebastien-yoobic
Copy link

I have the same issue. When I try to replace shadow: true by scoped: true the problem is still here.

@kensodemann
Copy link
Member

@davidrleonard - I can use the sample code provided above to duplicate this issue when using Stencil 0.9.1 and 0.9.7, but not when using Stencil 0.10.0 (using the latest starter) or 0.10.7 (after upgrading the version used by the starter) so this appears to have been fixed.

Please try your sample app using the latest starter. If this is still an issue for you, please provide a simple application that reproduces the issue via GitHub and I will re-open it.

@kensodemann
Copy link
Member

Reopenning as this can be duplicated by using scoped: true rather than shadow: true in the container component (friends-list in the code @davidrleonard provided).

Example: https://github.com/kensodemann/test-slot
Another Example: https://github.com/sebastien-yoobic/scoped-map-slot-update

@kensodemann kensodemann reopened this Jul 17, 2018
@adamdbradley adamdbradley added bug and removed triage labels Jul 26, 2018
@ionitron-bot ionitron-bot bot added the ionitron: stale issue This issue has not seen any activity for a long period of time label Aug 25, 2018
@ionitron-bot
Copy link

ionitron-bot bot commented Aug 25, 2018

Thanks for the issue! This issue is being closed due to inactivity. If this is still an issue with the latest version of Stencil, please create a new issue and ensure the template is fully filled out.

Thank you for using Stencil!

@ionitron-bot ionitron-bot bot closed this as completed Aug 25, 2018
@ionitron-bot ionitron-bot bot locked and limited conversation to collaborators Aug 25, 2018
@kensodemann
Copy link
Member

reopening as this is still an issue with a community member I am working with.

@kensodemann kensodemann reopened this Aug 27, 2018
@ionic-team ionic-team unlocked this conversation Sep 10, 2018
@jthoms1 jthoms1 removed the ionitron: stale issue This issue has not seen any activity for a long period of time label Sep 10, 2018
@jthoms1 jthoms1 added this to Backlog 🤖 in Stencil via automation Sep 10, 2018
@kensodemann
Copy link
Member

A community member I am working with was asking about this so I freshened up my sample project (https://github.com/kensodemann/test-slot) a bit as follows:

Updated my sample project to Stencil 0.13.2 and removed all <p> tags.

The issue occurs with the following component configuration in friends-list.tsx:

@Component({
  tag: 'friends-list',
  // shadow: true
  scoped: true
})

Swapping from scoped: true to shadow: true causes the issue to go away. However, it is my understanding that even though scoped: true is likely going to be on the chopping block at some point it needs to work properly because the same strategy is used in certain polyfills (or at least that is my understanding from prior verbal conversations).

@kensodemann
Copy link
Member

Duplicated this without the use of scoped: true:

https://github.com/kensodemann/out-of-slot-rendering

Code is based on some real-life code from the community member I am working on but greatly simplified and without any of their custom code (just using our PWA toolkit with @ionic/core components).

@kensodemann
Copy link
Member

My repro repo is using ion-slides, but I believe I have a way to duplicate this without any Ionic components. This seems to occur because ion-slides is not using shadow DOM (or scoped). I will try to create a unit test to recreate.

@kensodemann
Copy link
Member

@adamdbradley - PR #1197 contains a karma test that can be used to duplicate this issue.

@kensodemann
Copy link
Member

Also simplified the sample app: https://github.com/kensodemann/out-of-slot-rendering and provided three conditions in the README.md file with different behaviors given different uses of shadow DOM and light DOM.

@davidrleonard
Copy link
Author

Not trying to pollute this thread with unrelated talk, but btw, thanks for spending the time to hunt this down. Look forward to seeing a patch land to address it. 🚀

@seifsay3d-zz
Copy link

any updates on this one? I am still facing this with 1.0.2

@petermikitsh
Copy link
Contributor

@seifsay3d I have reproduced this issue in version 1.7.5.

See #1997 (Demo repo: https://github.com/petermikitsh/stencil-vdom-bug)

@seifsay3d-zz
Copy link

For anyone who is struggling with this problem, one possible 'hack' is to provide the content as props for the data that will change, and use slots only for static data :/

@bschlenk
Copy link

I'm close to a workaround here...

If I include the webcomponents polyfills (<script src="https://unpkg.com/@webcomponents/webcomponentsjs/webcomponents-bundle.js"></script>) on the page, then stencil doesn't use the fallback, and the component insides only show the light dom.

The issue now is that it seems like whatever stencil does to detect if it needs to use scoped styles is tied together with what it uses to determine if it needs to do the slots fallback, so now styles are broken. This seems to be because older browsers don't understand the :host css selector. Replacing :host with my component's tag name makes this work in older browsers, but breaks it in newer ones.

If there was a way to configure shadow: true and scoped: true at the same time on a component, then I think I'd have a proper workaround.

Stencil automation moved this from Backlog 🤖 to Done 🎉 Nov 13, 2019
@NKBelousov
Copy link

Just encountered this problem, what should I do about it? I'm using custom element for table component and misplaced rows are really problematic

@NKBelousov
Copy link

NKBelousov commented Dec 25, 2019

btw I'm using:

├─┬ @stencil/core@1.8.1
│ └── typescript@3.7.2

@Gbuomprisco
Copy link

I'm also getting the same issue using @stencil/core v1.9.0-11

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Stencil
  
Done 🎉
Development

No branches or pull requests

10 participants