;; ---------------------------------------------------------------------------
;; L5: Keyed Lists — reorderable items
;; ---------------------------------------------------------------------------
(defisland ()
  (let ((next-id (signal 1))
        (items (signal (list)))
        (colors (list "violet" "blue" "green" "amber" "red" "stone"))
        (add-item (fn (e)
          (let ((id (deref next-id))
                (old (deref items)))
            (do
              (reset! items (append old (dict "id" id
                                              "text" (str "Item " id)
                                              "color" (nth colors (mod (- id 1) 6)))))
              (reset! next-id (+ id 1))))))
        (remove-item (fn (id)
          (reset! items (filter (fn (item) (not (= (get item "id") id))) (deref items))))))
    (div (~tw :tokens "rounded border border-violet-200 bg-violet-50 p-4 my-4")
      (div (~tw :tokens "flex items-center gap-2 mb-3")
        (button (~tw :tokens "px-3 py-1 rounded bg-violet-600 text-white text-sm font-medium hover:bg-violet-700")
          :on-click add-item
          "Add Item")
        (button (~tw :tokens "px-3 py-1 rounded bg-violet-600 text-white text-sm font-medium hover:bg-violet-700")
          :on-click (fn (e) (reset! items (reverse (deref items))))
          "Reverse")
        (span (~tw :tokens "text-sm text-stone-500")
          (deref (computed (fn () (len (deref items))))) " items"))
      (ul (~tw :tokens "space-y-1")
        (map (fn (item)
          (li :key (str (get item "id"))
              :class (str "flex items-center justify-between rounded px-3 py-2 text-sm bg-" (get item "color") "-100 text-" (get item "color") "-800")
            (span (get item "text"))
            (button (~tw :tokens "text-stone-400 hover:text-red-500 text-xs ml-2")
              :on-click (fn (e) (remove-item (get item "id")))
              "✕")))
          (deref items))))))
