<repeat-list>

Repeats its content once per item of an array. Laid out with display: contents, so it adds no box. Used in component markup.

<repeat-list of="#ref" [as="item"] [index="i"] [key="id"]>
  …content per item…
</repeat-list>

Inside <ul>, <ol>, <table>, <tbody>, <tr> and <select>, the HTML parser does not allow unknown elements. Use the repeat attribute on the item element there.

Attributes

Attribute Type Default Meaning
of reference to an array required The list. Anything that is not an array renders nothing
as name item Variable name for the current item
index name none Variable name for the current position (0-based). Only defined when set
key property name position Property of each item that identifies it between updates

Inside each copy

Keys

With key, items are matched by that property when the array changes:

Change Result
Item still present Its nodes are kept and updated in place. Focus, typed text and transitions survive
Item moved Its nodes are moved, not re-created
Item removed Its nodes are removed and its listeners, observers and requests stop
New item New nodes are created

Without key, items are matched by position. A duplicate key logs repeat has a duplicate key "…" and the duplicate gets its own row.

Example

Previewindex.htmlfruit-list.html
Add to top

. Remove

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>repeat-list demo</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@realmorg/realm@alpha/dist/realm.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/dist/theme.css">
  <script type="module" src="https://cdn.jsdelivr.net/npm/@realmorg/realm@alpha/dist/realm.js"></script>
</head>
<body>
  <import-element from="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/components/button.html"></import-element>

  <import-element from="./fruit-list.html"></import-element>

  <fruit-list></fruit-list>
</body>
</html>
<custom-element name="fruit-list">
  <script>
    const basket = useState({
      next: 4,
      items: [
        { id: 1, name: "Apple" },
        { id: 2, name: "Banana" },
        { id: 3, name: "Cherry" },
      ],
    });

    function add() {
      basket.items.unshift({ id: basket.next, name: `Fruit ${basket.next}` });
      basket.next++;
    }

    function remove(fruit) {
      basket.items = basket.items.filter((item) => item.id !== fruit.id);
    }
  </script>

  <style>
    :host {
      display: grid;
      gap: calc(var(--spacing) * 2);
      justify-items: start;
    }
    p {
      display: flex;
      align-items: center;
      gap: calc(var(--spacing) * 2);
      margin: 0;
    }
  </style>

  <ui-button onclick="add()">Add to top</ui-button>
  <repeat-list of="#basket.items" as="fruit" index="i" key="id">
    <p>
      <slot name="#i"></slot>.
      <slot name="#fruit.name"></slot>
      <ui-button variant="ghost" size="sm" onclick="remove(fruit)">Remove</ui-button>
    </p>
  </repeat-list>
</custom-element>

Edit this page on GitHub · View as Markdown