enhance(ui): support custom colors for the icons picker

feat/asset-sync
charlie 2024-07-10 17:54:57 +08:00
parent c406cb2461
commit 2933e45694
6 changed files with 105 additions and 38 deletions

View File

@ -71,9 +71,9 @@
[items]
[:div.its.icons-row items])
(rum/defc pane-block
(rum/defc pane-section
[label items & {:keys [virtual-list?]}]
[:div.pane-block
[:div.pane-section
{:class (when virtual-list? "has-virtual-list")}
[:div.hd.px-1.pb-1.leading-none
[:strong.text-xs.font-medium.text-gray-07.dark:opacity-80 label]]
@ -109,7 +109,7 @@
(rum/defc emojis-cp < rum/static
[emojis opts]
(pane-block
(pane-section
(util/format "Emojis (%s)" (count emojis))
(for [emoji emojis]
(rum/with-key (emoji-cp emoji opts) (:id emoji)))
@ -135,7 +135,7 @@
(rum/defc icons-cp < rum/static
[icons opts]
(pane-block
(pane-section
(util/format "Icons (%s)" (count icons))
(for [icon icons]
(icon-cp icon opts))
@ -165,11 +165,11 @@
(emoji-cp d opts)))]
[:div.all-pane.pb-10
(when (count used-items)
(pane-block "Frequently used"
(pane-section "Frequently used"
(->> used-items (map item-cp))))
(pane-block (util/format "Emojis (%s)" (count emojis))
(pane-section (util/format "Emojis (%s)" (count emojis))
(->> emoji-items (map item-cp)))
(pane-block (util/format "Icons (%s)" (count (get-tabler-icons)))
(pane-section (util/format "Icons (%s)" (count (get-tabler-icons)))
(->> icon-items (map item-cp)))]))
(rum/defc tab-observer
@ -220,8 +220,8 @@
(rum/use-effect!
(fn []
;; calculate items
(let [^js blocks (.querySelectorAll (get-cnt) ".pane-block")
items (map #(some-> (.querySelectorAll % ".its > button") (js/Array.from) (js->clj)) blocks)
(let [^js sections (.querySelectorAll (get-cnt) ".pane-section")
items (map #(some-> (.querySelectorAll % ".its > button") (js/Array.from) (js->clj)) sections)
step 9
items (map #(let [count (count %)
m (mod count step)]
@ -236,24 +236,60 @@
[])
[:span.absolute.hidden {:ref *el-ref}]))
(rum/defc color-picker
[*color]
(let [[color, set-color!] (rum/use-state @*color)
*el (rum/use-ref nil)
content-fn (fn []
(let [colors ["#6e7b8b" "#5e69d2" "#00b5ed" "#00b55b"
"#f2be00" "#e47a00" "#f38e81" "#fb434c" nil]]
[:div.color-picker-presets
(for [c colors]
(shui/button
{:on-click (fn [] (set-color! c) (shui/popup-hide!))
:size :sm :variant :outline
:class "it" :style {:background-color c}}
(if c "" (shui/tabler-icon "minus" {:class "scale-75 opacity-70"}))))]))]
(rum/use-effect!
(fn []
(when-let [^js section (some-> (rum/deref *el) (.closest ".cp__emoji-icon-picker") (.querySelector ".pane-section"))]
(let [color (if (string/blank? color) "inherit" color)]
(set! (. (.-style section) -color) color)
(storage/set :ls-icon-color-preset color)))
(reset! *color color))
[color])
(shui/button {:size :sm
:ref *el
:class "color-picker"
:on-click (fn [^js e] (shui/popup-show! (.-target e) content-fn {:content-props {:side-offset 6}}))
:variant :outline}
[:strong {:style {:color (or color "inherit")}}
(shui/tabler-icon "palette")])))
(rum/defcs ^:large-vars/cleanup-todo icon-search <
(rum/local "" ::q)
(rum/local nil ::result)
(rum/local false ::select-mode?)
(rum/local :all ::tab)
(rum/local (storage/get :ls-icon-color-preset) ::color)
(rum/local nil ::hover)
[state {:keys [on-chosen] :as opts}]
(let [*q (::q state)
*result (::result state)
*tab (::tab state)
*color (::color state)
*hover (::hover state)
*input-ref (rum/create-ref)
*result-ref (rum/create-ref)
result @*result
opts (assoc opts :hover *hover
:on-chosen (fn [e m]
(and on-chosen (on-chosen e m))
(when (:type m) (add-used-item! m))))
(let [icon? (= (:type m) :tabler-icon)
m (if (and icon? (not (string/blank? @*color)))
(assoc m :color @*color) m)]
(and on-chosen (on-chosen e m))
(when (:type m) (add-used-item! m)))))
*select-mode? (::select-mode? state)
reset-q! #(when-let [^js input (rum/deref *input-ref)]
(reset! *q "")
@ -323,16 +359,19 @@
[:div.ft
(if-not @*hover
;; tabs
[:div.flex.flex-1.flex-row.items-center.gap-2
(let [tabs [[:all "All"] [:emoji "Emojis"] [:icon "Icons"]]]
(for [[id label] tabs
:let [active? (= @*tab id)]]
(shui/button
{:variant :ghost
:size :sm
:class (util/classnames [{:active active?} "tab-item"])
:on-click #(reset! *tab id)}
label)))]
[:<>
[:div.flex.flex-1.flex-row.items-center.gap-2
(let [tabs [[:all "All"] [:emoji "Emojis"] [:icon "Icons"]]]
(for [[id label] tabs
:let [active? (= @*tab id)]]
(shui/button
{:variant :ghost
:size :sm
:class (util/classnames [{:active active?} "tab-item"])
:on-click #(reset! *tab id)}
label)))]
(when (= :icon @*tab)
(color-picker *color))]
;; preview
[:div.hover-preview
@ -365,5 +404,6 @@
(shui/popup-show! (.-target %) content-fn
{:content-props {:class "ls-icon-picker"}}))}
(if has-icon?
(icon icon-value (merge {:size 18} icon-props))
[:span {:style {:color (or (:color icon-value) "inherit")}}
(icon icon-value (merge {:size 18} icon-props))]
"Empty")))))

View File

@ -1,6 +1,6 @@
.cp__emoji-icon-picker {
@apply w-[380px] max-h-[396px] relative flex flex-col overflow-hidden;
@apply pt-14 pb-12;
@apply pt-14 pb-[40px];
> .hd {
@apply absolute w-full pt-3 pb-1 px-3 top-0 left-0;
@ -51,7 +51,7 @@
}
}
.pane-block {
.pane-section {
@apply pl-2 overflow-y-scroll h-full;
> .its, .icons-row {
@ -85,12 +85,38 @@
overflow-ellipsis overflow-hidden mr-2;
}
}
.color-picker {
@apply rounded-full w-[24px] h-[24px] overflow-hidden flex relative p-0;
> strong {
@apply w-[18px] h-[18px] rounded-full absolute opacity-90
hover:opacity-100 font-normal text-sm;
.ui__icon {
@apply opacity-90 scale-90;
}
}
}
}
.color-picker-presets {
@apply flex flex-row gap-[2px];
.it {
@apply w-[18px] h-[18px] overflow-hidden p-0
opacity-90 hover:opacity-100 active:opacity-80;
}
}
.dropdown-wrapper .cp__emoji-icon-picker {
@apply -m-4;
}
.ui__dropdown-menu-content:has(> .cp__emoji-icon-picker) {
@apply flex;
}
.ui__dropdown-menu-content .cp__emoji-icon-picker {
@apply -m-1;
}

View File

@ -355,12 +355,12 @@
{:on-pointer-down util/stop-propagation}
(if (and (map? icon) db-based?)
(icon-component/icon-picker icon
{:on-chosen (fn [_e icon]
(db-property-handler/set-block-property!
(:db/id page)
(pu/get-pid :logseq.property/icon)
(select-keys icon [:id :type])))
:icon-props {:size 38}})
{:on-chosen (fn [_e icon]
(db-property-handler/set-block-property!
(:db/id page)
(pu/get-pid :logseq.property/icon)
(select-keys icon [:id :type :color])))
:icon-props {:size 38}})
icon)])
[:h1.page-title.flex-1.cursor-pointer.gap-1
{:class (when-not whiteboard-page? "title")

View File

@ -624,12 +624,13 @@
(shui/popup-hide! id))))}))]
(shui/trigger-as :button
(-> (when-not config/publishing?
{:on-click #(shui/popup-show! (.-target %) content-fn {:as-dropdown? true :auto-focus? true})})
(assoc :class "flex items-center"))
(if icon
(icon-component/icon icon {:size 15})
(property-icon property nil)))))
(-> (when-not config/publishing?
{:on-click #(shui/popup-show! (.-target %) content-fn {:as-dropdown? true :auto-focus? true})})
(assoc :class "flex items-center"))
(if-let [color (some-> icon :color)]
[:span.flex.items-center {:style {:color (or color "inherit")}}
(icon-component/icon icon {:size 15})]
(property-icon property nil)))))
(if config/publishing?
[:a.property-k.flex.select-none.jtrigger

View File

@ -174,7 +174,7 @@
:update-icon
(fn [icon]
(property-handler/set-block-property! (state/get-current-repo) (:block/uuid block) :logseq.property/icon
(select-keys icon [:id :type]))))
(select-keys icon [:id :type :color]))))
parent-opts))))
(rum/defc add-existing-values

View File

@ -46,7 +46,7 @@
(db-property-handler/set-block-property!
(:db/id block)
:logseq.property/icon
(select-keys icon [:type :id])))})
(select-keys icon [:type :id :color])))})
(when (and icon-value (not config/publishing?))
[:a.fade-link.flex {:on-click (fn [_e]
(db-property-handler/remove-block-property!