Browse Source

Integrate list-item-icon component for improved icon rendering

- Replaced existing icon rendering logic with the new list-item-icon component across multiple files, including editor, select, cmdk/list_item, and property/value.
- Enhanced layout consistency by adjusting flex properties and spacing in item-render functions.
- Updated icon handling to support different variants based on context, improving visual coherence.
scheinriese 6 days ago
parent
commit
113d7cf993

+ 21 - 12
src/main/frontend/components/cmdk/list_item.cljs

@@ -3,6 +3,7 @@
    ["remove-accents" :as remove-accents]
    [clojure.string :as string]
    [goog.string :as gstring]
+   [frontend.components.list-item-icon :as list-item-icon]
    [logseq.shui.hooks :as hooks]
    [logseq.shui.ui :as shui]
    [rum.core :as rum]))
@@ -50,12 +51,22 @@
 
 (rum/defc root [{:keys [group icon icon-theme query text info shortcut value-label value
                         title highlighted on-highlight on-highlight-dep header on-click hls-page?
-                        hoverable compact rounded on-mouse-enter component-opts source-page] :as _props
+                        hoverable compact rounded on-mouse-enter component-opts source-page source-create] :as _props
                  :or {hoverable true rounded true}}
                 {:keys [app-config]}]
   (let [ref (hooks/create-ref)
         highlight-query (partial highlight-query* app-config query)
-        [hover? set-hover?] (rum/use-state false)]
+        [hover? set-hover?] (rum/use-state false)
+        ;; Determine icon variant
+        icon-variant (cond
+                      source-create :create
+                      (#{:gradient} icon-theme) :default  ;; gradient handled with inline styles
+                      (#{:gray :color} icon-theme) :default
+                      :else :default)
+        ;; For gradient, we need to keep inline styles
+        gradient-style (when (#{:gradient} icon-theme)
+                         {:background "linear-gradient(-65deg, #8AE8FF, #5373E7, #369EFF, #00B1CC)"
+                          :box-shadow "inset 0 0 0 1px rgba(255,255,255,0.3)"})]
     (hooks/use-effect!
      (fn []
        (when (and highlighted on-highlight)
@@ -83,16 +94,14 @@
         (highlight-query header)])
      ;; main row
      [:div.flex.items-start.gap-3
-      [:div.w-5.h-5.rounded.flex.items-center.justify-center
-       {:style {:background (when (#{:gradient} icon-theme) "linear-gradient(-65deg, #8AE8FF, #5373E7, #369EFF, #00B1CC)")
-                :box-shadow (when (#{:gradient} icon-theme) "inset 0 0 0 1px rgba(255,255,255,0.3) ")}
-        :class (cond-> "w-5 h-5 rounded flex items-center justify-center"
-                 (= icon-theme :color) (str
-                                        " "
-                                        (if highlighted "bg-accent-07-alpha" "bg-gray-05")
-                                        " dark:text-white")
-                 (= icon-theme :gray) (str " bg-gray-05 dark:text-white"))}
-       (shui/tabler-icon icon {:size "14" :class ""})]
+      (if gradient-style
+        ;; Special handling for gradient theme with inline styles
+        [:div.w-5.h-5.rounded.flex.items-center.justify-center
+         {:style gradient-style}
+         (shui/tabler-icon icon {:size "14" :class ""})]
+        ;; Use new list-item-icon component for all other cases
+        (list-item-icon/root {:variant icon-variant
+                              :icon icon}))
       [:div.flex.flex-1.flex-col
        (when title
          [:div.text-sm.pb-2.font-bold.text-gray-11 (highlight-query title)])

+ 51 - 51
src/main/frontend/components/editor.cljs

@@ -4,6 +4,7 @@
             [frontend.commands :as commands :refer [*matched-commands]]
             [frontend.components.combobox :as combobox]
             [frontend.components.file-based.datetime :as datetime-comp]
+            [frontend.components.list-item-icon :as list-item-icon]
             [frontend.components.search :as search]
             [frontend.components.svg :as svg]
             [frontend.config :as config]
@@ -76,7 +77,7 @@
                icon-name (some-> (if (map? options) (:icon options) options) (name))
                command-name (if icon-name
                               [:span.flex.items-center.gap-1
-                               (shui/tabler-icon icon-name)
+                               (list-item-icon/root {:variant :raw :icon icon-name})
                                [:strong.font-normal command-name]]
                               command-name)]
            (cond
@@ -201,56 +202,55 @@
          :on-chosen   (page-on-chosen-handler embed? input id q pos format)
          :on-enter    (fn []
                         (page-handler/page-not-exists-handler input id q current-pos))
-         :item-render (fn [block _chosen?]
-                        (let [block' (if-let [id (:block/uuid block)]
-                                       (if-let [e (db/entity [:block/uuid id])]
-                                         (assoc e
-                                                :block/title (:block/title block)
-                                                :alias (:alias block))
-                                         block)
-                                       block)]
-                          [:div.flex.flex-col
-                           (when (and (:block/uuid block') (or (:block/parent block') (not (:page? block))))
-                             (when-let [breadcrumb (state/get-component :block/breadcrumb)]
-                               [:div.text-xs.opacity-70.mb-1 {:style {:margin-left 3}}
-                                (breadcrumb {:search? true} (state/get-current-repo) (:block/uuid block') {})]))
-                           [:div.flex.flex-row.items-start
-                            (when-not (or db-tag? (not db-based?))
-                              [:div.flex.items-center.h-5.mr-1.opacity-50
-                               (cond
-                                 (:nlp-date? block')
-                                 (ui/icon "calendar" {:size 14})
-
-                                 (ldb/class? block')
-                                 (ui/icon "hash" {:size 14})
-
-                                 (ldb/property? block')
-                                 (ui/icon "letter-p" {:size 14})
-
-                                 (db-model/whiteboard-page? block')
-                                 (ui/icon "writing" {:size 14})
-
-                                 (or (ldb/page? block') (:page? block))
-                                 (ui/icon "file" {:size 14})
-
-                                 (or (string/starts-with? (str (:block/title block')) (t :new-tag))
-                                     (string/starts-with? (str (:block/title block')) (t :new-page)))
-                                 (ui/icon "plus" {:size 14})
-
-                                 :else
-                                 (ui/icon "letter-n" {:size 14}))])
-
-                            (let [title (let [alias (get-in block' [:alias :block/title])
-                                              title (if (and db-based? (not (ldb/built-in? block')))
-                                                      (block-handler/block-unique-title block')
-                                                      (:block/title block'))]
-                                          (if alias
-                                            (str title " -> alias: " alias)
-                                            title))]
-                              (if (or (string/starts-with? title (t :new-tag))
-                                      (string/starts-with? title (t :new-page)))
-                                title
-                                (search-handler/highlight-exact-query title q)))]]))
+         :item-render
+        (fn [block _chosen?]
+          (let [block' (if-let [id (:block/uuid block)]
+                        (if-let [e (db/entity [:block/uuid id])]
+                          (assoc e
+                                  :block/title (:block/title block)
+                                  :alias (:alias block))
+                          block)
+                        block)]
+            [:div.flex.flex-col
+            (when (and (:block/uuid block')
+                        (or (:block/parent block')
+                            (not (:page? block))))
+              (when-let [breadcrumb (state/get-component :block/breadcrumb)]
+                [:div.text-xs.opacity-70.mb-1 {:style {:margin-left 3}}
+                  (breadcrumb {:search? true}
+                              (state/get-current-repo)
+                              (:block/uuid block')
+                              {})]))
+            [:div.flex.flex-row.items-start.gap-3
+              (when-not (or db-tag? (not db-based?))
+                (let [is-new? (or (string/starts-with? (str (:block/title block'))
+                                                      (t :new-tag))
+                                  (string/starts-with? (str (:block/title block'))
+                                                      (t :new-page)))
+                      icon-name (cond
+                                  (:nlp-date? block') "calendar"
+                                  (ldb/class? block') "hash"
+                                  (ldb/property? block') "letter-p"
+                                  (db-model/whiteboard-page? block') "writing"
+                                  (or (ldb/page? block') (:page? block)) "file"
+                                  is-new? "plus"
+                                  :else "letter-n")
+                      variant (if is-new? :create :default)]
+                  (list-item-icon/root {:variant variant
+                                        :icon icon-name})))
+              (let [title (let [alias (get-in block' [:alias :block/title])
+                                title (if (and db-based?
+                                              (not (ldb/built-in? block')))
+                                        (block-handler/block-unique-title block')
+                                        (:block/title block'))]
+                            (if alias
+                              (str title " -> alias: " alias)
+                              title))]
+                (if (or (string/starts-with? title (t :new-tag))
+                        (string/starts-with? title (t :new-page)))
+                  title
+                  (search-handler/highlight-exact-query title q)))]]))
+
          :empty-placeholder [:div.text-gray-500.text-sm.px-4.py-2 (if db-tag?
                                                                     "Search for a tag"
                                                                     "Search for a node")]

+ 53 - 0
src/main/frontend/components/list_item_icon.cljs

@@ -0,0 +1,53 @@
+(ns frontend.components.list-item-icon
+  (:require
+   [logseq.shui.ui :as shui]
+   [rum.core :as rum]))
+
+(rum/defc root
+  "List item icon component with 4 variants:
+   - :default - Dark gray background for regular search results
+   - :create - Blue background with border for create actions
+   - :raw - No visible background, icon with opacity for slash commands
+   - :checkbox - Checkbox variant for multi-select
+   
+   Props:
+   - variant - one of :default, :create, :raw, :checkbox
+   - icon - icon name (for non-checkbox variants)
+   - checked? - boolean for checkbox variant
+   - on-checked-change - callback for checkbox variant
+   - size - optional icon size override
+   - class - optional additional classes"
+  [{:keys [variant icon checked? on-checked-change size class]
+    :or {variant :default}}]
+  (case variant
+    :default
+    [:div.list-item-icon.list-item-icon--default
+     {:class (str "w-5 h-5 rounded flex items-center justify-center " (or class ""))}
+     (when icon
+       (shui/tabler-icon icon {:size (or size "14") :class ""}))]
+
+    :create
+    [:div.list-item-icon.list-item-icon--create
+     {:class (str "w-5 h-5 rounded flex items-center justify-center " (or class ""))}
+     (when icon
+       (shui/tabler-icon icon {:size (or size "14") :class ""}))]
+
+    :raw
+    [:div.list-item-icon.list-item-icon--raw
+     {:class (str "w-5 h-5 flex items-center justify-center " (or class ""))}
+     (when icon
+       (shui/tabler-icon icon {:size (or size "16") :class ""}))]
+
+    :checkbox
+    [:div.list-item-icon.list-item-icon--checkbox
+     {:class (str "w-5 h-5 flex items-center justify-center " (or class ""))}
+     (shui/checkbox {:checked checked?
+                     :on-checked-change on-checked-change
+                     :class "w-4 h-4"})]
+
+    ;; fallback to default
+    [:div.list-item-icon.list-item-icon--default
+     {:class (str "w-5 h-5 rounded flex items-center justify-center " (or class ""))}
+     (when icon
+       (shui/tabler-icon icon {:size (or size "14") :class ""}))]))
+

+ 34 - 0
src/main/frontend/components/list_item_icon.css

@@ -0,0 +1,34 @@
+.list-item-icon {
+  flex-shrink: 0;
+}
+
+/* Default variant - Dark gray background */
+.list-item-icon--default {
+  background-color: #2B2F31;
+  padding: 4px;
+  border-radius: 4px;
+}
+
+/* Create variant - Blue background with border */
+.list-item-icon--create {
+  background-color: rgba(5, 126, 255, 0.6);
+  border: 1px solid #369EFF;
+  padding: 4px;
+  border-radius: 4px;
+}
+
+/* Raw variant - No visible background, icon with opacity */
+.list-item-icon--raw {
+  /* Container is 20px (w-5 h-5), icon is 16px with opacity-50 */
+}
+
+.list-item-icon--raw .ui__icon {
+  opacity: 0.5;
+}
+
+/* Checkbox variant - Container for checkbox */
+.list-item-icon--checkbox {
+  /* Container is 20px (w-5 h-5), checkbox is 16px (w-4 h-4) */
+  /* The checkbox component from shui handles its own styling */
+}
+

+ 4 - 2
src/main/frontend/components/property/value.cljs

@@ -6,6 +6,7 @@
             [clojure.string :as string]
             [dommy.core :as d]
             [frontend.components.icon :as icon-component]
+            [frontend.components.list-item-icon :as list-item-icon]
             [frontend.components.select :as select]
             [frontend.config :as config]
             [frontend.date :as date]
@@ -749,10 +750,11 @@
                                                              (when-let [breadcrumb (state/get-component :block/breadcrumb)]
                                                                [:div.text-xs.opacity-70
                                                                 (breadcrumb {:search? true} (state/get-current-repo) (:block/uuid node) {})]))
-                                                    label [:div.flex.flex-row.items-center.gap-1
+                                                    label [:div.flex.flex-row.items-center.gap-3
                                                            (when-not (or (:logseq.property/classes property)
                                                                          (contains? #{:class :property} (:logseq.property/type property)))
-                                                             (ui/icon icon {:size 14}))
+                                                             (list-item-icon/root {:variant :default
+                                                                                   :icon icon}))
                                                            [:div title]]]
                                                 [header label])
                                               [nil (:block/title node)])]

+ 4 - 9
src/main/frontend/components/select.cljs

@@ -5,6 +5,7 @@
   select-type. See the :graph/open command for a full example."
   (:require [clojure.string :as string]
             [frontend.components.combobox :as combobox]
+            [frontend.components.list-item-icon :as list-item-icon]
             [frontend.config :as config]
             [frontend.context.i18n :refer [t]]
             [frontend.handler.common.developer :as dev-common-handler]
@@ -30,15 +31,9 @@
         value-content (if is-new-option?
                        (let [parts (string/split value #"New option: " 2)
                              input-text (second parts)]
-                         [:div.flex.flex-row.items-center.gap-2
-                          [:span.inline-flex.items-center.justify-center
-                           {:style {:width "16px"
-                                    :height "16px"
-                                    :background-color "#057EFF"
-                                    :border "1px solid #369EFF"
-                                    :border-radius "4px"
-                                    :flex-shrink 0}}
-                           (ui/icon "plus" {:size 12 :style {:color "white"}})]
+                         [:div.flex.flex-row.items-center.gap-3
+                          (list-item-icon/root {:variant :create
+                                                :icon "plus"})
                           [:span.text-gray-12 "New option:"]
                           (when input-text
                             [:span.text-gray-11 (str "\"" input-text "\"")])])