stencil icon indicating copy to clipboard operation
stencil copied to clipboard

bug: Slotted Content Being Erroneously Hidden When Nested

Open dgibson666 opened this issue 1 year ago • 1 comments

Prerequisites

Stencil Version

4.22.1

Current Behavior

My understanding is that Stencil will place a hidden attribute on a node if it references a named slot that doesn't exist. I know there have been issues around this in the past, so I upgraded Stencil to the very latest and am testing/reporting on v4.22.1. And I am fairly certain you have a bug/regression here.

In my case, I have a component whose render lifecycle method renders a named slot within another component. My slotted content is rendering as hidden. I believe that this check is flagging the named slot as not existing inside of the nested/rendered component rather than the component in which the named slot is defined and belongs. When I updated my component to not render other components, just plain HTML, this issue went away.

I threw a console.log in to be sure the node did not have the hidden attribute on it prior to the render lifecycle hook and it was confirmed.

I am fairly certain that I've composed components that render other components in the past (with optional named slots) without running into this issue.

Expected Behavior

Do not add hidden to the slotted node.

System Info

System: node 18.18.2
    Platform: windows (10.0.22631)
   CPU Model: 13th Gen Intel(R) Core(TM) i7-13700F (24 cpus) 
    Compiler: C:\websites\_sandbox\cbp-design-system\node_modules\@stencil\core\compiler\stencil.js
       Build: 1728498324
     Stencil: 4.22.1
  TypeScript: 5.5.4
      Rollup: 2.56.3
      Parse5: 7.1.2
      jQuery: 4.0.0-pre
      Terser: 5.31.1

Steps to Reproduce

Case 1 (Original code, rendering slotted content as hidden):

  render() {
    console.log(this.host.querySelector('[slot=cbp-accordion-item-label]'));

    return (
      <Host>
        <cbp-flex
          class="cbp-accordion-item--control"
          align-items="center"
          onClick={() => this.handleClick()}
        >
        <slot name="cbp-accordion-item-label" />
          <cbp-flex-item>
            <cbp-button
              type="button"
              class="cbp-accordion-item--toggle"
              fill="ghost"
              color="secondary"
              controls={`${this.headingId}-content`}
              expanded={this.open}
              accessibilityText="Toggle Accordion Item"
              aria-describedby={this.headingId}
              ref={el => (this.control = el)}
            >
              <cbp-icon name="chevron-right"></cbp-icon>
            </cbp-button>
          </cbp-flex-item>

          <cbp-flex-item id={this.headingId} flex-grow="1">
            <slot name="cbp-accordion-item-label" />
            {this.label && <cbp-typography tag={this.headingLevel} variant="heading-sm">{this.label}</cbp-typography>}
          </cbp-flex-item>
        </cbp-flex>
      </Host>
    );
  }

Case 2 (rendering correctly):

  render() {
    console.log(this.host.querySelector('[slot=cbp-accordion-item-label]'));

    return (
      <Host>
        <div 
          class="cbp-accordion-item--control"
          onClick={() => this.handleClick()}
        >
          <cbp-button
            type="button"
            class="cbp-accordion-item--toggle"
            fill="ghost"
            color="secondary"
            controls={`${this.headingId}-content`}
            expanded={this.open}
            accessibilityText="Toggle Accordion Item"
            aria-describedby={this.headingId}
            ref={el => (this.control = el)}
          >
            <cbp-icon name="chevron-right"></cbp-icon>
          </cbp-button>

          <div id={this.headingId} class="cbp-accordion-item--heading">
            <slot name="cbp-accordion-item-label" />
            {this.label && <cbp-typography tag={this.headingLevel} variant="heading-sm">{this.label}</cbp-typography>}
          </div>
        </div>

        <div id={`${this.headingId}-content`} class="cbp-accordion-item--content">
          <slot />
        </div>
      </Host>
    );
  }

Code Reproduction URL

none yet

Additional Information

No response

dgibson666 avatar Oct 15 '24 18:10 dgibson666

Thanks for the issue! This issue has been labeled as needs reproduction. This label is added to issues that need a code reproduction.

Please reproduce this issue in an Stencil starter component library and provide a way for us to access it (GitHub repo, StackBlitz, etc). Without a reliable code reproduction, it is unlikely we will be able to resolve the issue, leading to it being closed.

If you have already provided a code snippet and are seeing this message, it is likely that the code snippet was not enough for our team to reproduce the issue.

For a guide on how to create a good reproduction, see our Contributing Guide.

ionitron-bot[bot] avatar Oct 15 '24 18:10 ionitron-bot[bot]

@dgibson666 any updates on the reproduction case?

christian-bromann avatar Oct 29 '24 20:10 christian-bromann

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[bot] avatar Nov 28 '24 21:11 ionitron-bot[bot]