ionic-team / stencil

A toolchain for building scalable, enterprise-ready component systems on top of TypeScript and Web Component standards. Stencil components can be distributed natively to React, Angular, Vue, and traditional web developers from a single, framework-agnostic codebase.
https://stenciljs.com
Other
12.57k stars 787 forks source link

Slot in loop doesn't repeat #990

Closed dboscanv closed 3 years ago

dboscanv commented 6 years ago

Stencil version:

 @stencil/core@<0.11.0>

I'm submitting a:

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

Current behavior: I put two slots in a loop:

{this.data.map((e, idx) =>
                <div class={this.containerButtonsClass}>
                  {this.data.length == idx + 1 ? <button type="button" class={this.buttonClass} onClick={this.addItem.bind(this)}>
                    <slot name="btn-plus">  </slot> // HERE
                  </button> : null}
                  {this.data.length !== 1 ? <button type="button" class={this.buttonClass} onClick={_ => this.removeItem(idx)}>
                    <slot name="btn-minus">  </slot> // HERE
                  </button> : null}
                </div> : null}
            </div>
          )}

The first slot (btn-plus) appear, but only appear once (if I add a element in array, the slot doesn't appear). The other slot, doesn't appear never. For me it's a bug, but perhaps I'm wrong.

captura de pantalla 2018-08-03 00 06 02

Expected behavior: The slots should be repeat itself.

Other information:

Repository: https://github.com/dboscanv/multiple-values Link to the file: https://github.com/dboscanv/multiple-values/blob/master/src/components/multiple-values/multiple-values.tsx#L216

Thanks!

jthoms1 commented 6 years ago

What are you filling into the slot? I am not sure I understand the use case.

dboscanv commented 6 years ago

Hi @jthoms1

The web component allow to add many group of inputs, each group of inputs has its values, additionaly, there are two buttons, one for add and one for remove a group. So, what I try to do is that the buttons (add or delete) can be will change the innerHTML.

For example, writing in the HTML this:

<multiple-values>
       <i slot="btn-plus" class="icon ion-md-add"></i>
        <i slot="btn-minus" class="icon ion-md-remove"></i>
</multiple-values>

Should be:

captura de pantalla 2018-08-07 23 48 36

But has a wrong behavior: captura de pantalla 2018-08-07 23 49 49

brajnacs commented 5 years ago

I am also facing the same issue. I have 2 components todo-list and todo-item todo-item has 2 actions with icons, I want to provide these icons via slots from the todo-list component itself todo-items is being repeated inside todo-list and I want the action icon slots to be repeated inside every todo item, right now it shows up only on the first element.

zohon commented 5 years ago

I am also facing this issue.

Vinoth-LearningThings commented 4 years ago

Anyone found a solution for this issue? I am also facing the same issue!

gandhirahul commented 4 years ago

I am also facing the same issue. Though this workaround works for me, but would really appreciate doing it the right way.

// Inside the loop.
<span class="inner" innerHTML={elm.outerHTML}> 
ghost commented 4 years ago

Hello, any updates here? I have the same issue.

juliovedovatto commented 4 years ago

Still facing same issue 😔

I have a slider carousel component, with 1...N slides and it would be good to set the same content for each slide using a slot.

In the issue #2103, some folks deduced that slots are not for this type of use. Which is kinda bummer.

It would be better if @adamdbradley confirmed this or something in documentation pointing this fact https://stenciljs.com/docs/templating-jsx#slots

jhairau commented 4 years ago

For anyone stuck on this. I found myself creating a work around. Yes we can't use a slot in a loop.

So my solution was to use <slot/> to pass in some DOM, clone that DOM and then use some logic to inject values each loop. It's probably easier to view my code to understand.

https://webcomponents.dev/edit/oEPlhviSVrJMW94FinxW?sv=1

DmitryEfimenko commented 4 years ago

basically people (my-self included) are searching for an alternative of Angular's template references that can be defined expecting some context. and used in the component. Something like render-props, does not quite solve this problem because they don't integrate well with non-jsx things - like Angular. StencilJS does support render props, but I'm not even sure how well that would work when integrating a StencilJS component with React.

sidharthramesh commented 3 years ago

I am also facing the same issue. Though this workaround works for me, but would really appreciate doing it the right way.

// Inside the loop.
<span class="inner" innerHTML={elm.outerHTML}> 

Thank you @gandhirahul for this solution. It works, however it messes up the styling in some cases. Even the solution by @jhairau uses a div and then injects the innerHTML.

Is there any way to render just the contents of the node instead of using a span or a div? Searching for an equivalent of Vue's <template> tag that disappears in the DOM.

splitinfinities commented 3 years ago

Could someone help to create a simpler repro case? I think I understand the problem - passing slotted elements to a custom element with Shadow DOM where inside the parent element is a list of slots generated from an array?

Are you duplicating the slotted elements for each repeated element segment, and that causes a regression? Or, are you passing in only two nodes, expecting those to be rendered across each of the repeatedly named slots within the scope of the ShadowDOM?

If the latter is the case, that is not the expected behavior per the HTML spec for Shadow DOM Slots, meaning the way Stencil works today is accurate. One node can't be rendered across multiple slots - you can, however, duplicate the node like many people here have recommend with using innerHTML/outerHTML. Let me know if I'm off base, though.

If someone wanted to pitch the feature of slotted content that CAN be automatically duplicated into multiple slots with some semantic sugar, please don't hesitate to make a PR or write an issue out and share your idea. We'd love to see how you would approach this concept.

I'm going to close this next Tuesday if my assumption here is correct, please feel free to let me know your thoughts!

ionitron-bot[bot] commented 3 years ago

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!

rwaskiewicz commented 3 years ago

Hey ionitron-bot, we didn't mean to close this. Bad bot!