{"slug":"lists","title":"Lists","headings":["Try it"],"contentHtml":"<h1 id=\"lists\">Lists</h1><p><code>each</code> renders reactive lists with keyed reconciliation:</p><pre class=\"shiki github-dark\" style=\"background-color:#17171d;color:#e1e4e8\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#F97583\">import</span><span style=\"color:#E1E4E8\"> { each, tags } </span><span style=\"color:#F97583\">from</span><span style=\"color:#9ECBFF\"> \"ruri\"</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#F97583\">const</span><span style=\"color:#E1E4E8\"> { </span><span style=\"color:#79B8FF\">ul</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#79B8FF\">li</span><span style=\"color:#E1E4E8\"> } </span><span style=\"color:#F97583\">=</span><span style=\"color:#E1E4E8\"> tags</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">const</span><span style=\"color:#79B8FF\"> todos</span><span style=\"color:#F97583\"> =</span><span style=\"color:#F97583\"> new</span><span style=\"color:#B392F0\"> Signal</span><span style=\"color:#E1E4E8\">([{ id: </span><span style=\"color:#79B8FF\">1</span><span style=\"color:#E1E4E8\">, text: </span><span style=\"color:#9ECBFF\">\"one\"</span><span style=\"color:#E1E4E8\"> }])</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#B392F0\">ul</span><span style=\"color:#E1E4E8\">({}, </span><span style=\"color:#B392F0\">each</span><span style=\"color:#E1E4E8\">(todos, (</span><span style=\"color:#FFAB70\">todo</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#FFAB70\">index</span><span style=\"color:#E1E4E8\">) </span><span style=\"color:#F97583\">=></span><span style=\"color:#B392F0\"> li</span><span style=\"color:#E1E4E8\">({}, </span><span style=\"color:#9ECBFF\">`${</span><span style=\"color:#E1E4E8\">index</span><span style=\"color:#9ECBFF\">.</span><span style=\"color:#E1E4E8\">value</span><span style=\"color:#9ECBFF\">}: ${</span><span style=\"color:#E1E4E8\">todo</span><span style=\"color:#9ECBFF\">.</span><span style=\"color:#E1E4E8\">text</span><span style=\"color:#9ECBFF\">}`</span><span style=\"color:#E1E4E8\">), {</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">  key</span><span style=\"color:#E1E4E8\">: (</span><span style=\"color:#FFAB70\">todo</span><span style=\"color:#E1E4E8\">) </span><span style=\"color:#F97583\">=></span><span style=\"color:#E1E4E8\"> todo.id,</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">}))</span></span></code></pre><ul><li>rows keep their DOM nodes across reorders (minimal-move via longest</li></ul><p>  increasing subsequence)</p><ul><li>replacing an item object for an existing key re-renders <strong>only that row</strong></li><li>the render function receives a per-row index signal that tracks position</li><li>on the server rows render statically; hydration adopts them in place</li></ul><h2 id=\"try-it\">Try it</h2><p>Every second row toggles its label - watch the rows move without being rebuilt:</p><div class=\"playground\"><pre class=\"pg-code shiki github-dark\" style=\"background-color:#17171d;color:#e1e4e8\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#F97583\">import</span><span style=\"color:#E1E4E8\"> { each, Signal, tags } </span><span style=\"color:#F97583\">from</span><span style=\"color:#9ECBFF\"> \"ruri\"</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#F97583\">const</span><span style=\"color:#E1E4E8\"> { </span><span style=\"color:#79B8FF\">ol</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#79B8FF\">li</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#79B8FF\">button</span><span style=\"color:#E1E4E8\"> } </span><span style=\"color:#F97583\">=</span><span style=\"color:#E1E4E8\"> tags</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">const</span><span style=\"color:#79B8FF\"> rows</span><span style=\"color:#F97583\"> =</span><span style=\"color:#E1E4E8\"> [{ id: </span><span style=\"color:#79B8FF\">1</span><span style=\"color:#E1E4E8\">, text: </span><span style=\"color:#9ECBFF\">\"alpha\"</span><span style=\"color:#E1E4E8\"> }, { id: </span><span style=\"color:#79B8FF\">2</span><span style=\"color:#E1E4E8\">, text: </span><span style=\"color:#9ECBFF\">\"beta\"</span><span style=\"color:#E1E4E8\"> }, { id: </span><span style=\"color:#79B8FF\">3</span><span style=\"color:#E1E4E8\">, text: </span><span style=\"color:#9ECBFF\">\"gamma\"</span><span style=\"color:#E1E4E8\"> }]</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">const</span><span style=\"color:#79B8FF\"> items</span><span style=\"color:#F97583\"> =</span><span style=\"color:#F97583\"> new</span><span style=\"color:#B392F0\"> Signal</span><span style=\"color:#E1E4E8\">(rows)</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">let</span><span style=\"color:#E1E4E8\"> flipped </span><span style=\"color:#F97583\">=</span><span style=\"color:#79B8FF\"> false</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">output.</span><span style=\"color:#B392F0\">append</span><span style=\"color:#E1E4E8\">(</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">    ol</span><span style=\"color:#E1E4E8\">({}, </span><span style=\"color:#B392F0\">each</span><span style=\"color:#E1E4E8\">(items, (</span><span style=\"color:#FFAB70\">row</span><span style=\"color:#E1E4E8\">) </span><span style=\"color:#F97583\">=></span><span style=\"color:#B392F0\"> li</span><span style=\"color:#E1E4E8\">({}, row.text), { </span><span style=\"color:#B392F0\">key</span><span style=\"color:#E1E4E8\">: (</span><span style=\"color:#FFAB70\">row</span><span style=\"color:#E1E4E8\">) </span><span style=\"color:#F97583\">=></span><span style=\"color:#E1E4E8\"> row.id })),</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">    button</span><span style=\"color:#E1E4E8\">({</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">      onclick</span><span style=\"color:#E1E4E8\">: () </span><span style=\"color:#F97583\">=></span><span style=\"color:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">        flipped </span><span style=\"color:#F97583\">=</span><span style=\"color:#F97583\"> !</span><span style=\"color:#E1E4E8\">flipped</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">        items.value </span><span style=\"color:#F97583\">=</span><span style=\"color:#E1E4E8\"> flipped </span><span style=\"color:#F97583\">?</span><span style=\"color:#E1E4E8\"> [</span><span style=\"color:#F97583\">...</span><span style=\"color:#E1E4E8\">items.</span><span style=\"color:#B392F0\">peek</span><span style=\"color:#E1E4E8\">()].</span><span style=\"color:#B392F0\">reverse</span><span style=\"color:#E1E4E8\">() </span><span style=\"color:#F97583\">:</span><span style=\"color:#E1E4E8\"> [</span><span style=\"color:#F97583\">...</span><span style=\"color:#E1E4E8\">items.</span><span style=\"color:#B392F0\">peek</span><span style=\"color:#E1E4E8\">()]</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">      },</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    }, </span><span style=\"color:#9ECBFF\">\"reverse\"</span><span style=\"color:#E1E4E8\">),</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">)</span></span></code></pre><div class=\"pg-view\" id=\"pg-view-1\"><span class=\"pg-hint\">running...</span></div></div>"}