Consultancy - Research Lab - Incubator

based in beautiful Zürich, Switzerland

- 402 words - 3 min read
#riotjs

If you want to use RiotJS Custom Tags within a <table>, you might have stumbled upon something that looks like a bug. If you nest Custom Tags within a <table> element, they will not render within said element, but outside of it. Let me clarify with an example and how to fix it.

If you have code that nests elements like this:

<todoList>
    <table>
      <tbody>
        <todo each="{ allTodos() }">
        </todo>
    </table>
</todoList>

Where <todo> is defined as a totally legit table row, you will find that the result does not look like you imagined it. If you check your browsers developer tools, you will see that the browser renders your <todo> elements unexpectedly outside the <table> element. It might look like this:

<todolist>
    <todo></todo>
    <table>
    </table>
</todolist>

The reason for this phenomenon is that browsers require known HTML elements within a <table> and <tbody> elements. If anything else is issued to be rendered within, it is just ejected.

No worries, though! RiotJS has a proper way of handling this type of situation. Standard HTML elements can be used as Riot Tags when you use the data-is attribute. For the <todoList> example above, this is functional code:

<todoList>
    <table>
      <tbody >
        <tr each="{ allTodos() }" data-is="todo">
        </tr>
    </table>
</todoList>

In this example, the <tr> tag is a legit HTML tag which the browser expects to be within a <table>. However, since we want to write modular composable code, we tell RiotJS to actually use the <todo> component to compose the <tr>. For completeness, this would be valid code for a <todo> component:

<todo>
  <td>
    <input type="checkbox" checked={ done } />
    { name }
  </td>
</todo>

One last thing: A custom tag has to be lower-case only when used with data-is, otherwise Riot will not pick it up. This is likely a bug and will be fixed in a future version.