withastro/compiler

Rendering issue: variable in `th` or `caption` inside a Table component wrapped with another element

ArmandPhilippot opened this issue · 0 comments

Astro Info

Astro                    v4.11.5
Node                     v20.12.0
System                   Linux (x64)
Package Manager          pnpm
Output                   hybrid
Adapter                  @astrojs/node
Integrations             astro-icon
                         dev-only-pages
                         @astrojs/mdx
                         pagefind
                         @astrojs/sitemap

If this issue only occurs in one browser, which browser is a problem?

No response

Describe the Bug

Context

  • In HTML, we can use a <table> element inside a <figure> element.
  • To avoid repeating the same styles for th and td, I use a simple <Table> component with a slot and global styles.
  • I translate every UI strings with a translate() function.
  • I have a table with a fixed number of columns and fixed headings, so I want to use my translate function in the <th>.

Issue

The <tbody> of a <Table> component is not correctly rendered when the component is wrapped with another element and that a variable is present in a <th> (i.e. <thead><th>{myVariable}</th></thead>) or in a <caption> (i.e. <caption>{myVariable}</caption>).

For example:

---
import Table from "./base/table.astro";

const headingContent = "foo";
const cellContent = "bar";
---

<figure>
  <Table>
    <thead>
      <tr>
        <th>{headingContent}</th>
        <th>Cell 2</th>
        <th>Cell 3</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>{cellContent}</td>
        <td>Data 2</td>
        <td>Data 3</td>
      </tr>
    </tbody>
  </Table>
</figure>

Is rendered as below:

Astro table: incorrect rendering example

Instead of:

Astro table: correct rendering example

The rendering is correct only when:

  • I use a <table> element instead of the component,
  • I don't wrap the <Table> component with a <figure>,
  • I don't use a variable in the <th> elements (and I don't add a <caption> with a variable at the beginning of the table).

Yet the <Table> component is very simple, for example:

---
import type { HTMLAttributes } from 'astro/types';

type Props = HTMLAttributes<'table'>;

const {...attrs} = Astro.props;
---

<table {...attrs}><slot /></table>

<style>
  :global(table :where(th, td)) {
    border: 1px solid #000;
  }
</style>

Workaround

  • Use a <table> element (instead of a component) and repeat the styles...
  • Do not use variables in <th> and/or <caption> (this is very inconvenient...)

Reproduction

I put a Stackblitz link with a minimal reproduction.

  • The file src/pages/index.astro is used to provide 3 different examples. The last one is the problem.
  • src/components/base/table.astro contains the very minimal Table component (I just define some styles to help visualize the problem).
  • src/components/table-component-wrapped-in-figure.astro is the problematic file.
  • src/components/table-element-wrapped-in-figure.astro and src/components/table-using-table-component.astro are two examples where the rendering is correct using the same table (with variables).

In table-component-wrapped-in-figure.astro:

  • you can replace <th>{headingContent}</th> with <th>Foo</th> and you'll see that the table is now correctly rendered.
  • you can keep the replacement made above and add a <caption>{headingContent}</caption> at the beginning of the table and you'll see the table is not rendered correctly again.

Additional notes

I don't think the <figure> element is the problem here. While I was writing this issue, I tried to wrap the <Table> component with a custom element instead of a <figure>, and the same rendering issue occurs.

What's the expected result?

I expect the <tbody> to be correctly rendered when using a variable in a <th> inside <Table> component wrapped in a another element (<figure>, custom element, etc.).

Link to Minimal Reproducible Example

https://stackblitz.com/edit/astro-table-th-figure?file=src%2Fpages%2Findex.astro

Participation

  • I am willing to submit a pull request for this issue.