;; lib/host/sx/relate-picker.sx — the relate picker as a reusable, content-addressed
;; SX component. On a FULL load render-page expands it server-side (SEO / no-JS); on a
;; boosted SPA nav the edit body is serialized as `(~relate-picker :slug … :kind …)`
;; and the CLIENT expands it — the component module is loaded content-addressed via
;; the data-sx-manifest at boot, so its defcomp is registered before any fragment
;; referencing it arrives.
;;
;; Pure markup, no client JS: the form GETs /<slug>/relate-options serialising kind +
;; the filter q (a FORM is serialised on GET, a bare input is not), innerHTML-swapping
;; the results <ul> on "load" and on a debounced "input". Paging is server-driven —
;; each full page carries a "load more" sentinel (sx-trigger revealed) the endpoint
;; emits. sx-retry makes a dropped/offline fetch self-heal; the engine's .sx-error
;; class (styled by the host shell) surfaces a stuck retry. The engine re-binds these
;; triggers on swapped-in content, so it works on full load AND boosted nav.
(defcomp
  ~relate-picker
  (&key slug kind)
  (form
    :class "relate-picker"
    :data-slug slug
    :data-kind kind
    :sx-get (str "/" slug "/relate-options")
    :sx-trigger "input delay:200ms, load"
    :sx-target (str "#rp-" kind "-results")
    :sx-swap "innerHTML"
    :sx-retry "exponential:1000:30000"
    :style "margin:0"
    (input :type "hidden" :name "kind" :value kind)
    (input
      :type "text"
      :name "q"
      :class "rp-filter"
      :placeholder "filter…"
      :autocomplete "off"
      :style "width:100%;padding:0.4em;box-sizing:border-box")
    (ul
      :id (str "rp-" kind "-results")
      :class "rp-results"
      :style "list-style:none;padding:0;margin:0.5em 0;border:1px solid #ddd")))
