From 30c52f9907ed7833d00ed25239140a458e691c84 Mon Sep 17 00:00:00 2001 From: Mega Yu Date: Sat, 28 Feb 2026 21:24:42 +0800 Subject: [PATCH] refactor: simplify highlight handling in list item component --- src/main/frontend/components/cmdk/core.cljs | 21 ++++++++++--------- .../frontend/components/cmdk/list_item.cljs | 16 ++++---------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/src/main/frontend/components/cmdk/core.cljs b/src/main/frontend/components/cmdk/core.cljs index 7d8650e75c..1cf05686b6 100644 --- a/src/main/frontend/components/cmdk/core.cljs +++ b/src/main/frontend/components/cmdk/core.cljs @@ -776,9 +776,6 @@ :rounded true :hoverable mouse-mode? :highlighted highlighted? - ;; Pass the item itself when highlighted so the effect re-fires - ;; if the list reloads while this item stays highlighted. - :on-highlight-dep (when highlighted? item) :on-click (fn [e] (util/stop-propagation e) (reset! (::highlighted-item state) item) @@ -798,13 +795,7 @@ (when-not (= :mouse @(::focus-source state)) (reset! (::focus-source state) :mouse)) (when (not= item @(::highlighted-item state)) - (reset! (::highlighted-item state) item))))) - :on-highlight (fn [ref] - (when (and ref (.-current ref)) - (let [row-el (.-current ref)] - (when (and (= :keyboard @(::focus-source state)) - (= item @(::highlighted-item state))) - (scroll-to-highlight! state row-el)))))) + (reset! (::highlighted-item state) item)))))) nil)] [:div {:data-item-index item-idx} (if (= group :nodes) @@ -1092,6 +1083,16 @@ (js/clearTimeout timeout-id))))) []) (hooks/use-effect! (fn [] (load-results :default state)) []) + ;; fired when highlighted item changes (normal keyboard navigation) + (hooks/use-effect! + (fn [] + (when (and highlighted-item (= :keyboard @(::focus-source state))) + (when-let [container @(::scroll-container-ref state)] + (when-let [idx (:item-index highlighted-item)] + (when-let [el (.querySelector container (str "[data-item-index='" idx "']"))] + (scroll-to-highlight! state el))))) + nil) + [highlighted-item]) [:div {:class "bg-gray-02 border-b border-1 border-gray-07"} [:input.cp__cmdk-search-input {:class "text-xl bg-transparent border-none w-full outline-none px-3 py-3" diff --git a/src/main/frontend/components/cmdk/list_item.cljs b/src/main/frontend/components/cmdk/list_item.cljs index fe1ffc0a0c..bb48f51c2a 100644 --- a/src/main/frontend/components/cmdk/list_item.cljs +++ b/src/main/frontend/components/cmdk/list_item.cljs @@ -65,13 +65,11 @@ (when-not (string/blank? label) [:span.cp__cmdk-current-page-badge label])) -(rum/defc root [{:keys [icon icon-theme query text info shortcut value-label value - title highlighted on-highlight on-highlight-dep header on-click - hoverable compact rounded on-mouse-enter on-mouse-move source-block] :as props +(rum/defc root [{:keys [icon icon-theme query text info shortcut value-label value title highlighted + header on-click hoverable compact rounded on-mouse-enter on-mouse-move source-block] :as props :or {hoverable true rounded true}} {:keys [app-config]}] - (let [ref (hooks/create-ref) - highlight-query (partial highlight-query* app-config query) + (let [highlight-query (partial highlight-query* app-config query) badge-placement (current-page-badge-placement props) text-badge (current-page-badge-node (:text-badge badge-placement)) header-badge (current-page-badge-node (:header-badge badge-placement)) @@ -83,11 +81,6 @@ mouse-selected-border "var(--ls-border-color, var(--lx-gray-09, rgba(0,0,0,0.32)))" keyboard-ring "var(--lx-accent-09, #3b82f6)" keyboard-overlay "rgba(0,0,0,0.07)"] - (hooks/use-effect! - (fn [] - (when (and highlighted on-highlight) - (on-highlight ref))) - [highlighted on-highlight-dep]) [:div (merge {:style (cond-> {:opacity 1 :background-color "transparent" @@ -108,7 +101,6 @@ rounded (str " rounded-lg") (not compact) (str " py-4 px-6 gap-1") compact (str " py-1.5 px-3 gap-0.5")) - :ref ref :on-click (when on-click on-click) :on-mouse-enter (fn [e] (set-hover? true) @@ -119,7 +111,7 @@ ;; header (when header [:div.text-xs.pl-8.font-light.flex.items-center.gap-2.flex-wrap {:class "-mt-1" - :style {:color "var(--lx-gray-11)"}} + :style {:color "var(--lx-gray-11)"}} (highlight-query header) header-badge]) ;; main row