;; ---------------------------------------------------------------------------
;; L5: Keyed Lists
;; ---------------------------------------------------------------------------
(defcomp ()
  (~docs/page :title "Layer 5: Keyed List Reconciliation"

    (p (~tw :tokens "text-stone-500 text-sm italic mb-8")
      "Enhances the existing reactive-list with explicit key extraction callbacks "
      "for stable identity tracking across updates.")

    (~docs/section :title "Live Demo" :id "demo"
      (p "Items with stable " (code ":key") " identities. Reverse and rotate reorder the signal list — the reconciler moves existing DOM nodes instead of recreating them. Add and remove demonstrate insertion and deletion.")
      (~reactive-runtime/demo-keyed-lists)
      (~docs/code :src (highlight "(defisland ~demo-keyed-lists ()\n  (let ((items (signal (list\n          (dict \"id\" 1 \"text\" \"Alpha\" \"color\" \"violet\")\n          (dict \"id\" 2 \"text\" \"Beta\" \"color\" \"blue\") ...)))\n        (next-id (signal 6)))\n    (button :on-click (fn (e) (swap! items reverse)) \"Reverse\")\n    (button :on-click (fn (e)\n      (swap! items (fn (old) (append (rest old) (first old)))))\n      \"Rotate\")\n    (ul (map (fn (item)\n      (li :key (str (get item \"id\"))\n        :class (str \"bg-\" (get item \"color\") \"-100 ...\")\n        (span (get item \"text\"))\n        (button :on-click (fn (e) (remove-item (get item \"id\"))) \"✕\")))\n      (deref items)))))" "lisp"))
      (p (code ":key") " on each " (code "li") " gives the reconciler stable identity. When " (code "reverse") " flips the list, the existing DOM nodes are moved — not destroyed and recreated. This preserves focus, scroll position, CSS transitions, and internal island state."))

    (~docs/section :title "API" :id "keyed-api"

      (~docs/code :src (highlight
        ";; Current: keys extracted from rendered DOM key attribute\n(map (fn (el) (~shape-handle :key (get el :id) el)) (deref items))\n\n;; Enhanced: explicit key function\n(map (fn (el) (~shape-handle el)) (deref items)\n  :key (fn (el) (get el :id)))"
        "lisp"))

      (p "The " (code ":key") " parameter provides a function that extracts a stable identity "
         "from each item " (em "before") " rendering. This is more efficient than extracting keys "
         "from rendered DOM nodes and handles cases where the rendered output doesn't have a "
         "natural key attribute."))

    (~docs/section :title "Changes" :id "keyed-changes"

      (p "Enhancement to existing " (code "adapter-dom.sx") ":")
      (ul (~tw :tokens "list-disc pl-6 mb-4 space-y-1")
        (li (code "render-dom-list") " detection — parse " (code ":key") " kwarg after " (code "(deref sig)"))
        (li (code "reactive-list") " — accept optional " (code "key-fn") ", use instead of " (code "extract-key") " when provided")
        (li "Fully backward compatible — without " (code ":key") ", behavior unchanged"))

      (p "~155 lines of changes. No new platform primitives — existing DOM ops suffice."))))
