Skip to content

Child Component Content Blocks Not Rendering in Parent Component #2157

@Eth3rnit3

Description

@Eth3rnit3

When rendering a parent component with multiple child components, the content blocks provided to each child are not displayed as expected. Instead of rendering the <p> content within each child component's container <div>, the child components appear empty in the HTML output. This issue suggests that the blocks passed to each child are not being processed or rendered correctly within the parent-child component structure.

Steps to reproduce

  1. Set up the component structure:

    • Create an AccordionComponent in app/components/accordion_component.rb to render multiple Accordion::ItemComponent components.
    # app/components/accordion_component.rb
    class AccordionComponent < ViewComponent::Base
      renders_many :items, Accordion::ItemComponent
    end
  2. Define the template for the AccordionComponent:

    • In app/components/accordion_component.html.erb, iterate over each item to render its content.
    <!-- app/components/accordion_component.html.erb -->
    <div class="accordion">
      <% items.each do |item| %>
        <%= render item %>
      <% end %>
    </div>
  3. Create the Accordion::ItemComponent:

    • Define the Accordion::ItemComponent with an initializer that accepts a title parameter.
    # app/components/accordion/item_component.rb
    class Accordion::ItemComponent < ViewComponent::Base
      def initialize(title:)
        @title = title
      end
    end
  4. Define the template for Accordion::ItemComponent:

    • In app/components/accordion/item_component.html.erb, render the title and the content passed to the item component.
    <!-- app/components/accordion/item_component.html.erb -->
    <h2>Item <%= @title %></h2>
    <div class="accordion-item">
      <%= content %>
    </div>
  5. Use the component in a view:

    • In app/views/application/home.html.erb, render the AccordionComponent with three items, each containing specific content in a block.
    <!-- app/views/application/home.html.erb -->
    <%= render(AccordionComponent.new) do |accordion| %>
      <% accordion.with_item title: :to_classify do %>
        <p>Items that need to be classified.</p>
      <% end %>
    
      <% accordion.with_item title: :classified do %>
        <p>Items that have been classified.</p>
      <% end %>
    
      <% accordion.with_item title: :rejected do %>
        <p>Items that have been rejected.</p>
      <% end %>
    <% end %>
  6. Render the page and check the HTML output:

    • Run the server and navigate to the view rendering home.html.erb.
    • Observe the generated HTML output in the browser or inspect it through the page source.

Expected behavior

The content within each Accordion::ItemComponent should be rendered inside the accordion-item <div>. Each item should display the title and the specified content:

<div class="accordion">
  <h2>Item to_classify</h2>
  <div class="accordion-item">
    <p>Items that need to be classified.</p>
  </div>
  
  <h2>Item classified</h2>
  <div class="accordion-item">
    <p>Items that have been classified.</p>
  </div>
  
  <h2>Item rejected</h2>
  <div class="accordion-item">
    <p>Items that have been rejected.</p>
  </div>
</div>

Actual behavior

The content inside each Accordion::ItemComponent is missing. The rendered HTML output does not contain the expected <p> content within each accordion-item <div>, resulting in an empty structure:

<body>
    <main class="container mx-auto mt-28 px-5 flex">
      <!-- BEGIN app/views/application/home.html.erb --><!-- BEGIN app/components/accordion_component.html.erb --><div class"accordion"="">
    <!-- BEGIN app/components/accordion/item_component.html.erb --><h2>Item to_classify </h2>
<div class"accordion-item"="">
  
</div><!-- END app/components/accordion/item_component.html.erb -->
    <!-- BEGIN app/components/accordion/item_component.html.erb --><h2>Item classified </h2>
<div class"accordion-item"="">
  
</div><!-- END app/components/accordion/item_component.html.erb -->
    <!-- BEGIN app/components/accordion/item_component.html.erb --><h2>Item rejected </h2>
<div class"accordion-item"="">
  
</div><!-- END app/components/accordion/item_component.html.erb -->
</div><!-- END app/components/accordion_component.html.erb --><!-- END app/views/application/home.html.erb -->
    </main>
</body>

This indicates that the content passed to each with_item block is not being rendered inside the component.

System configuration

Rails version: 7.2.2
Ruby version: 3.2.2
Gem version: view_component version 3.20

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions