mirror of https://github.com/logseq/logseq
enhance(ui): support custom colors for the icons picker
parent
c406cb2461
commit
2933e45694
|
@ -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")))))
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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!
|
||||
|
|
Loading…
Reference in New Issue