From 8b90e11fc34a8ebadef6e8b1a398432ec4adff67 Mon Sep 17 00:00:00 2001 From: scheinriese Date: Thu, 21 May 2026 12:28:37 +0200 Subject: [PATCH] fix(icon): restore has-virtual-list fixed height to prevent picker collapse MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous single-scroller commit (3364f7bdbf) removed `h-[358px]` from `.pane-section.has-virtual-list`, assuming `:custom-scroll-parent` alone would carry the layout. It doesn't: when the popup container provides no max-height (e.g., reaction picker under a block toolbar / comment thread, or full picker opened fresh on the Emojis/Icons tab), the chain collapses to zero — Virtuoso hasn't rendered yet → parent has no content → Virtuoso measures 0 viewport → renders 0 items → never resolves. The picker shrunk to ~86px tall with the entire grid missing. The fixed height and `:custom-scroll-parent` are complementary, not redundant: - `h-[358px]` anchors the flex chain so Virtuoso has something to measure on first render. - `:custom-scroll-parent` keeps Virtuoso from creating its own scrollbar, preserving the 9-column grid. Restoring `h-[358px] overflow-y-visible` with the `searching-result h-auto` override fixes every surface (All / Emojis / Icons / search / reaction picker) at 442 picker / 360 .bd / 9 cols / 1 scrollbar. Also adds defensive `(= :emoji (:type icon))` guards to the two remaining reaction-picker call sites (block.cljs and comments.cljs) for symmetry with content.cljs and ui.cljs. Required because comments.cljs didn't yet require `frontend.handler.notification`. Co-Authored-By: Claude Opus 4.7 --- src/main/frontend/components/block.cljs | 11 +++++++---- .../frontend/components/block/comments.cljs | 10 +++++++--- src/main/frontend/components/icon.css | 19 +++++++++++++------ 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/main/frontend/components/block.cljs b/src/main/frontend/components/block.cljs index a9d2c06acc..199539a67c 100644 --- a/src/main/frontend/components/block.cljs +++ b/src/main/frontend/components/block.cljs @@ -2852,9 +2852,12 @@ (:db/id (db/entity repo [:block/uuid user-id])))) summary (reaction/summarize reactions user-db-id) read-only? config/publishing? - on-pick (fn [popup-id emoji] - (reaction-handler/toggle-reaction! (:block/uuid block) (:id emoji)) - (shui/popup-hide! popup-id)) + on-pick (fn [popup-id icon] + (if (= :emoji (:type icon)) + (do + (reaction-handler/toggle-reaction! (:block/uuid block) (:id icon)) + (shui/popup-hide! popup-id)) + (notification/show! (t :block.reaction/emoji-required-warning) :warning))) open-picker! (fn [^js e] (util/stop e) (shui/popup-show! @@ -2862,7 +2865,7 @@ (fn [{:keys [id]}] (icon-component/icon-search (merge icon-component/reaction-picker-opts - {:on-chosen (fn [_emoji-event emoji _keep-popup?] (on-pick id emoji))}))) + {:on-chosen (fn [_e icon _keep-popup?] (on-pick id icon))}))) {:align :start :content-props {:class "ls-icon-picker"}}))] (when (seq summary) diff --git a/src/main/frontend/components/block/comments.cljs b/src/main/frontend/components/block/comments.cljs index eb2b542451..b945384861 100644 --- a/src/main/frontend/components/block/comments.cljs +++ b/src/main/frontend/components/block/comments.cljs @@ -9,6 +9,7 @@ [frontend.date :as date] [frontend.format.block :as block] [frontend.handler.comments :as comments-handler] + [frontend.handler.notification :as notification] [frontend.handler.paste :as paste-handler] [frontend.handler.reaction :as reaction-handler] [frontend.handler.user :as user-handler] @@ -272,9 +273,12 @@ (fn [{:keys [id]}] (icon-component/icon-search (merge icon-component/reaction-picker-opts - {:on-chosen (fn [_emoji-event emoji _keep-popup?] - (reaction-handler/toggle-reaction! (:block/uuid comment-block) (:id emoji)) - (shui/popup-hide! id))}))) + {:on-chosen (fn [_emoji-event icon _keep-popup?] + (if (= :emoji (:type icon)) + (do + (reaction-handler/toggle-reaction! (:block/uuid comment-block) (:id icon)) + (shui/popup-hide! id)) + (notification/show! (t :block.reaction/emoji-required-warning) :warning)))}))) {:align :end :content-props {:class "ls-icon-picker"}}))) diff --git a/src/main/frontend/components/icon.css b/src/main/frontend/components/icon.css index f42c3f5e72..8371b5f854 100644 --- a/src/main/frontend/components/icon.css +++ b/src/main/frontend/components/icon.css @@ -158,12 +158,19 @@ } &.has-virtual-list { - /* Single-scroller layout: pane-section grows to Virtuoso's - reported list height; the outer `.bd-scroll` is the only - scroll surface (Virtuoso uses `:custom-scroll-parent` to - defer scrolling to it). The class itself stays as a marker - hook for other rules / data attributes. */ - @apply h-auto; + /* Definite height gives Virtuoso something to measure on first + render. Without it, when the popup container provides no + max-height, the pane collapses to 0 (Virtuoso hasn't rendered + yet → parent has no content → Virtuoso measures 0 viewport → + renders 0 items → never resolves). Coexists with + `:custom-scroll-parent` in `pane-section`: Virtuoso scrolls + `.bd-scroll`, not its own wrapper, so the fixed height does + NOT create a nested scrollbar / column collapse. */ + @apply h-[358px] overflow-y-visible; + + &.searching-result { + @apply h-auto; + } } .virtuoso-item-list {