mirror of
https://github.com/penpot/penpot.git
synced 2025-05-29 22:26:13 +02:00
👾 changes libraries types, reworked color palette
This commit is contained in:
parent
decd3e3443
commit
5cd8e85034
14 changed files with 193 additions and 128 deletions
|
@ -266,4 +266,4 @@
|
|||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(update-in [:library :selected-items library-id] #(into [item] %) )))))
|
||||
(update-in [:library-items :palettes library-id] #(into [item] %) )))))
|
||||
|
|
|
@ -203,7 +203,7 @@
|
|||
(update [_ state]
|
||||
(let [{:keys [id] :as item} (assoc item :type :icon)]
|
||||
(-> state
|
||||
(update-in [:library :selected-items library-id] #(into [item] %)))))))
|
||||
(update-in [:library-items :icons library-id] #(into [item] %)))))))
|
||||
|
||||
;; ;; --- Icon Persisted
|
||||
;;
|
||||
|
|
|
@ -395,5 +395,5 @@
|
|||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(update-in [:library :selected-items library-id] #(into [item] %))))))
|
||||
(update-in [:library-items :images library-id] #(into [item] %))))))
|
||||
|
||||
|
|
|
@ -56,15 +56,15 @@
|
|||
:images :images
|
||||
:palettes :colors)]
|
||||
(->> (rp/query! method {:library-id library-id})
|
||||
(rx/map (partial retrieve-library-data-result library-id)))))))
|
||||
(rx/map (partial retrieve-library-data-result type library-id)))))))
|
||||
|
||||
(defn retrieve-library-data-result
|
||||
[library-id data]
|
||||
[type library-id data]
|
||||
(ptk/reify ::retrieve-library-data-result
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(assoc-in [:library :selected-items library-id] data)))))
|
||||
(assoc-in [:library-items type library-id] data)))))
|
||||
|
||||
|
||||
;; Create library
|
||||
|
@ -178,7 +178,7 @@
|
|||
(let [update-fn (fn [items]
|
||||
(filterv #(not= item-id (:id %)) items))]
|
||||
(-> state
|
||||
(update-in [:library :selected-items library-id] update-fn))))))
|
||||
(update-in [:library-items type library-id] update-fn))))))
|
||||
|
||||
;; Batch delete
|
||||
|
||||
|
@ -207,4 +207,4 @@
|
|||
update-fn (fn [items]
|
||||
(filterv #(not (item-ids-set (:id %))) items))]
|
||||
(-> state
|
||||
(update-in [:library :selected-items library-id] update-fn))))))
|
||||
(update-in [:library-items type library-id] update-fn))))))
|
||||
|
|
|
@ -270,9 +270,7 @@
|
|||
|
||||
(declare initialize-alignment)
|
||||
|
||||
#_(def default-layout #{:sitemap :layers :element-options :rules})
|
||||
(def default-layout #{:libraries :rules :colorpalette})
|
||||
|
||||
(def default-layout #{:sitemap :layers :element-options :rules})
|
||||
|
||||
(def workspace-default
|
||||
{:zoom 1
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
[rumext.alpha :as mf]
|
||||
[goog.object :as gobj]
|
||||
[uxbox.main.ui.components.dropdown :refer [dropdown-container]]
|
||||
[uxbox.util.uuid :as uuid]))
|
||||
[uxbox.util.uuid :as uuid]
|
||||
[uxbox.util.data :refer [classnames]]))
|
||||
|
||||
(mf/defc context-menu
|
||||
{::mf/wrap-props false}
|
||||
|
@ -13,12 +14,17 @@
|
|||
(assert (vector? (gobj/get props "options")) "missing `options` prop")
|
||||
|
||||
(let [open? (gobj/get props "show")
|
||||
options (gobj/get props "options")]
|
||||
options (gobj/get props "options")
|
||||
is-selectable (gobj/get props "selectable")
|
||||
selected (gobj/get props "selected")]
|
||||
(println "selected" selected)
|
||||
(when open?
|
||||
[:> dropdown-container props
|
||||
[:div.context-menu {:class (when open? "is-open")}
|
||||
[:div.context-menu {:class (classnames :is-open open?
|
||||
:is-selectable is-selectable)}
|
||||
[:ul.context-menu-items
|
||||
(for [[action-name action-handler] options]
|
||||
[:li.context-menu-item {:key action-name}
|
||||
[:li.context-menu-item {:class (classnames :is-selected (and selected (= action-name selected)))
|
||||
:key action-name}
|
||||
[:a.context-menu-action {:on-click action-handler}
|
||||
action-name]])]]])))
|
||||
|
|
|
@ -305,8 +305,8 @@
|
|||
(-> (comp (l/key :library) (l/key section) (l/key team-id))
|
||||
(l/derive st/state)))
|
||||
|
||||
(defn selected-items-ref [library-id]
|
||||
(-> (comp (l/key :library) (l/key :selected-items) (l/key library-id))
|
||||
(defn selected-items-ref [section library-id]
|
||||
(-> (comp (l/key :library-items) (l/key section) (l/key library-id))
|
||||
(l/derive st/state)))
|
||||
|
||||
(def last-deleted-library-ref
|
||||
|
@ -317,7 +317,7 @@
|
|||
[{:keys [team-id library-id section]}]
|
||||
(let [state (mf/use-state {:selected #{}})
|
||||
libraries (mf/deref (libraries-ref section team-id))
|
||||
items (mf/deref (selected-items-ref library-id))
|
||||
items (mf/deref (selected-items-ref section library-id))
|
||||
last-deleted-library (mf/deref last-deleted-library-ref)
|
||||
selected-library (first (filter #(= (:id %) library-id) libraries))]
|
||||
|
||||
|
|
|
@ -13,16 +13,26 @@
|
|||
[uxbox.builtins.icons :as i]
|
||||
[uxbox.main.data.colors :as udc]
|
||||
[uxbox.main.data.workspace :as udw]
|
||||
[uxbox.main.data.library :as dlib]
|
||||
[uxbox.main.store :as st]
|
||||
[uxbox.main.ui.keyboard :as kbd]
|
||||
[uxbox.util.color :refer [hex->rgb]]
|
||||
[uxbox.util.data :refer [read-string seek]]
|
||||
[uxbox.util.dom :as dom]))
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.main.ui.components.context-menu :refer [context-menu]]))
|
||||
|
||||
;; --- Refs
|
||||
|
||||
(def collections-iref
|
||||
(-> (l/key :colors-collections)
|
||||
(def project-ref
|
||||
(-> (l/key :workspace-project)
|
||||
(l/derive st/state)))
|
||||
|
||||
(def libraries-ref
|
||||
(-> (comp (l/key :library) (l/key :palettes))
|
||||
(l/derive st/state)))
|
||||
|
||||
(defn selected-items-ref [library-id]
|
||||
(-> (comp (l/key :library-items) (l/key :palettes) (l/key library-id))
|
||||
(l/derive st/state)))
|
||||
|
||||
;; --- Components
|
||||
|
@ -30,8 +40,6 @@
|
|||
(mf/defc palette-item
|
||||
[{:keys [color] :as props}]
|
||||
(let [rgb-vec (hex->rgb color)
|
||||
rgb-color (apply str "" (interpose ", " rgb-vec))
|
||||
|
||||
select-color
|
||||
(fn [event]
|
||||
(if (kbd/shift? event)
|
||||
|
@ -41,93 +49,85 @@
|
|||
[:div.color-cell {:key (str color)
|
||||
:on-click select-color}
|
||||
[:span.color {:style {:background color}}]
|
||||
[:span.color-text color]
|
||||
#_[:span.color-text rgb-color]]))
|
||||
[:span.color-text color]]))
|
||||
|
||||
(mf/defc palette
|
||||
[{:keys [colls left-sidebar?] :as props}]
|
||||
(let [local (mf/use-state {})
|
||||
colls (->> colls
|
||||
(filter :id)
|
||||
(sort-by :name))
|
||||
[{:keys [libraries left-sidebar?] :as props}]
|
||||
|
||||
coll (or (:selected @local)
|
||||
(first colls))
|
||||
(when (and libraries (-> libraries count (> 0)))
|
||||
(let [state (mf/use-state {:show-menu false
|
||||
:selected-library (-> libraries first :id)})]
|
||||
(mf/use-effect (mf/deps (:selected-library @state))
|
||||
#(st/emit! (dlib/retrieve-library-data :palettes (:selected-library @state))))
|
||||
|
||||
(let [items (-> (:selected-library @state) selected-items-ref mf/deref)
|
||||
doc-width (.. js/document -documentElement -clientWidth)
|
||||
width (:width @state (* doc-width 0.84))
|
||||
offset (:offset @state 0)
|
||||
visible (/ width 86)
|
||||
invisible (- (count items) visible)
|
||||
close #(st/emit! (udw/toggle-layout-flag :colorpalette))
|
||||
container (mf/use-ref nil)
|
||||
container-child (mf/use-ref nil)
|
||||
|
||||
doc-width (.. js/document -documentElement -clientWidth)
|
||||
width (:width @local (* doc-width 0.84))
|
||||
offset (:offset @local 0)
|
||||
visible (/ width 86)
|
||||
invisible (- (count (:colors coll)) visible)
|
||||
close #(st/emit! (udw/toggle-layout-flag :colorpalette))
|
||||
on-left-arrow-click
|
||||
(fn [event]
|
||||
(when (> offset 0)
|
||||
(let [element (mf/ref-val container-child)]
|
||||
(swap! state update :offset dec))))
|
||||
|
||||
container (mf/use-ref nil)
|
||||
container-child (mf/use-ref nil)
|
||||
on-right-arrow-click
|
||||
(fn [event]
|
||||
(when (< offset invisible)
|
||||
(let [element (mf/ref-val container-child)]
|
||||
(swap! state update :offset inc))))
|
||||
|
||||
select-coll
|
||||
(fn [event]
|
||||
(let [id (read-string (dom/event->value event))
|
||||
selected (seek #(= id (:id %)) colls)]
|
||||
(swap! local assoc :selected selected :position 0)))
|
||||
on-scroll
|
||||
(fn [event]
|
||||
(if (pos? (.. event -nativeEvent -deltaY))
|
||||
(on-right-arrow-click event)
|
||||
(on-left-arrow-click event)))
|
||||
|
||||
on-left-arrow-click
|
||||
(fn [event]
|
||||
(when (> offset 0)
|
||||
(let [element (mf/ref-val container-child)]
|
||||
(swap! local update :offset dec))))
|
||||
after-render
|
||||
(fn []
|
||||
(let [dom (mf/ref-val container)
|
||||
width (.-clientWidth dom)]
|
||||
(when (not= (:width @state) width)
|
||||
(swap! state assoc :width width))))
|
||||
|
||||
on-right-arrow-click
|
||||
(fn [event]
|
||||
(when (< offset invisible)
|
||||
(let [element (mf/ref-val container-child)]
|
||||
(swap! local update :offset inc))))
|
||||
handle-click
|
||||
(fn [library]
|
||||
(swap! state assoc :selected-library (:id library)))]
|
||||
|
||||
on-scroll
|
||||
(fn [event]
|
||||
(if (pos? (.. event -nativeEvent -deltaY))
|
||||
(on-right-arrow-click event)
|
||||
(on-left-arrow-click event)))
|
||||
(mf/use-effect nil after-render)
|
||||
|
||||
after-render
|
||||
(fn []
|
||||
(let [dom (mf/ref-val container)
|
||||
width (.-clientWidth dom)]
|
||||
(when (not= (:width @local) width)
|
||||
(swap! local assoc :width width))))]
|
||||
[:div.color-palette {:class (when left-sidebar? "left-sidebar-open")}
|
||||
[:& context-menu {:selectable true
|
||||
:selected (->> libraries (filter #(= (:id %) (:selected-library @state))) first :name)
|
||||
:show (:show-menu @state)
|
||||
:on-close #(swap! state assoc :show-menu false)
|
||||
:options (mapv #(vector (:name %) (partial handle-click %)) libraries)} ]
|
||||
[:div.color-palette-actions
|
||||
{:on-click #(swap! state assoc :show-menu true)}
|
||||
[:div.color-palette-actions-button i/actions]]
|
||||
|
||||
(mf/use-effect nil after-render)
|
||||
[:span.left-arrow {:on-click on-left-arrow-click} i/arrow-slide]
|
||||
|
||||
[:div.color-palette {:class (when left-sidebar? "left-sidebar-open")}
|
||||
[:div.color-palette-actions
|
||||
[:div.color-palette-actions-button i/actions]
|
||||
#_[:select.input-select {:on-change select-coll
|
||||
:default-value (pr-str (:id coll))}
|
||||
(for [item colls]
|
||||
[:option {:key (:id item) :value (pr-str (:id item))}
|
||||
(:name item)])]
|
||||
[:div.color-palette-content {:ref container :on-wheel on-scroll}
|
||||
[:div.color-palette-inside {:ref container-child
|
||||
:style {:position "relative"
|
||||
:width (str (* 86 (count items)) "px")
|
||||
:right (str (* 86 offset) "px")}}
|
||||
(for [item items]
|
||||
[:& palette-item {:color (:content item) :key (:id item)}])]]
|
||||
|
||||
#_[:div.color-palette-buttons
|
||||
[:div.btn-palette.edit.current i/pencil]
|
||||
[:div.btn-palette.create i/close]]]
|
||||
|
||||
[:span.left-arrow {:on-click on-left-arrow-click} i/arrow-slide]
|
||||
|
||||
[:div.color-palette-content {:ref container :on-wheel on-scroll}
|
||||
[:div.color-palette-inside {:ref container-child
|
||||
:style {:position "relative"
|
||||
:width (str (* 86 (count (:colors coll))) "px")
|
||||
:right (str (* 86 offset) "px")}}
|
||||
#_(for [color (:colors coll)]
|
||||
[:& palette-item {:color color :key color}])
|
||||
(for [color (range 0 20)]
|
||||
[:& palette-item {:color "#FFFF00" :key color}])]]
|
||||
|
||||
[:span.right-arrow {:on-click on-right-arrow-click} i/arrow-slide]
|
||||
#_[:span.close-palette {:on-click close} i/close]]))
|
||||
[:span.right-arrow {:on-click on-right-arrow-click} i/arrow-slide]]))))
|
||||
|
||||
(mf/defc colorpalette
|
||||
[{:keys [left-sidebar?]}]
|
||||
(let [colls (mf/deref collections-iref)]
|
||||
#_(mf/use-effect #(st/emit! (udc/fetch-collections)))
|
||||
(let [team-id (-> project-ref mf/deref :team-id)
|
||||
libraries (-> libraries-ref mf/deref vals flatten)]
|
||||
(mf/use-effect #(st/emit! (dlib/retrieve-libraries :palettes)))
|
||||
(mf/use-effect #(st/emit! (dlib/retrieve-libraries :palettes team-id)))
|
||||
[:& palette {:left-sidebar? left-sidebar?
|
||||
:colls (vals colls)}]))
|
||||
:libraries libraries}]))
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
[uxbox.util.uuid :as uuid]
|
||||
[uxbox.util.i18n :as i18n :refer [t]]
|
||||
[uxbox.main.ui.components.tab-container :refer [tab-container tab-element]]
|
||||
[uxbox.main.data.library :as dlib]))
|
||||
[uxbox.main.data.library :as dlib]
|
||||
[uxbox.main.ui.components.context-menu :refer [context-menu]]))
|
||||
|
||||
(def project-ref
|
||||
(-> (l/key :workspace-project)
|
||||
|
@ -34,29 +35,34 @@
|
|||
(-> (comp (l/key :library) (l/key section))
|
||||
(l/derive st/state)))
|
||||
|
||||
(defn selected-items-ref [library-id]
|
||||
(-> (comp (l/key :library) (l/key :selected-items) (l/key library-id))
|
||||
(defn selected-items-ref [section library-id]
|
||||
(-> (comp (l/key :library-items) (l/key section) (l/key library-id))
|
||||
(l/derive st/state)))
|
||||
|
||||
(mf/defc icons-tab [{:keys [libraries]}]
|
||||
|
||||
(when (and libraries (-> libraries count (> 0)))
|
||||
(let [state (mf/use-state {:selected-library (-> libraries first :id)})]
|
||||
(mf/use-effect (mf/deps libraries)
|
||||
#(when (not (some (fn [it] (= (:selected-library @state) (-> it :id))) libraries))
|
||||
(swap! state assoc :selected-library (-> libraries first :id))))
|
||||
(mf/use-effect (mf/deps (:selected-library @state))
|
||||
#(st/emit! (dlib/retrieve-library-data :icons (:selected-library @state))))
|
||||
|
||||
[:div.library-tab.icons-tab
|
||||
[:select.input-select.library-tab-libraries
|
||||
{:on-change #(swap! state assoc :selected-library (-> % dom/get-target dom/get-value))}
|
||||
{:on-change #(swap! state assoc :selected-library (-> % dom/get-target dom/get-value uuid))}
|
||||
(for [library libraries]
|
||||
[:option.library-tab-libraries-item
|
||||
{:key (:id library)
|
||||
:value (:id library)}
|
||||
(:name library)])]
|
||||
[:div.library-tab-content
|
||||
(let [items (mf/deref (selected-items-ref (:selected-library @state)))]
|
||||
(let [items (mf/deref (selected-items-ref :icons (:selected-library @state)))]
|
||||
(for [item items]
|
||||
[:div.library-tab-element
|
||||
{:key (:id item)}
|
||||
{:key (:id item)
|
||||
:on-click #(st/emit! (dw/select-for-drawing :icon item))}
|
||||
[:svg {:view-box (->> item :metadata :view-box (str/join " "))
|
||||
:width (-> item :metadata :width)
|
||||
:height (-> item :metadat :height)
|
||||
|
@ -78,19 +84,30 @@
|
|||
:value (:id library)}
|
||||
(:name library)])]
|
||||
[:div.library-tab-content
|
||||
(let [items (mf/deref (selected-items-ref (:selected-library @state)))]
|
||||
(let [items (mf/deref (selected-items-ref :images (:selected-library @state)))]
|
||||
(for [item items]
|
||||
[:div.library-tab-element
|
||||
{:key (:id item)}
|
||||
{:key (:id item)
|
||||
:on-click #(st/emit! (dw/select-for-drawing :image item))}
|
||||
[:img {:src (:thumb-uri item)}]
|
||||
[:span.library-tab-element-name (:name item)]]))]])))
|
||||
|
||||
(mf/defc libraries-toolbox
|
||||
[{:keys [key]}]
|
||||
(let [team-id (-> project-ref mf/deref :team-id)
|
||||
locale (i18n/use-locale)]
|
||||
(let [state (mf/use-state {:menu-open false
|
||||
:selected :all})
|
||||
team-id (-> project-ref mf/deref :team-id)
|
||||
locale (i18n/use-locale)
|
||||
key-to-str {:all "All libraries"
|
||||
:own "My libraries"
|
||||
:store "Store libraries"}
|
||||
select-option (fn [option] (swap! state assoc :selected option))
|
||||
|
||||
filter-libraries (fn [libraries] (case (:selected @state)
|
||||
:all (-> libraries vals flatten)
|
||||
:own (libraries team-id)
|
||||
:store (libraries uuid/zero)))]
|
||||
(mf/use-effect
|
||||
(mf/deps key)
|
||||
#(do
|
||||
(st/emit! (dlib/retrieve-libraries :icons))
|
||||
(st/emit! (dlib/retrieve-libraries :images))))
|
||||
|
@ -104,17 +121,27 @@
|
|||
[:div.libraries-window-bar
|
||||
[:div.libraries-window-bar-title "Libraries"]
|
||||
[:div.libraries-window-bar-options
|
||||
"All libraries"
|
||||
[:button {:type "button"}
|
||||
i/arrow-slide]]]
|
||||
{:on-click #(swap! state assoc :menu-open true)}
|
||||
(key-to-str (:selected @state))
|
||||
[:button
|
||||
{
|
||||
:type "button"}
|
||||
i/arrow-slide
|
||||
[:& context-menu {:selectable true
|
||||
:show (:menu-open @state)
|
||||
:selected (key-to-str (:selected @state))
|
||||
:on-close #(swap! state assoc :menu-open false)
|
||||
:options (mapv (fn [[key val]] [val #(select-option key)]) key-to-str)}]]
|
||||
|
||||
]]
|
||||
[:div.tool-window-content
|
||||
[:& tab-container {}
|
||||
[:& tab-element
|
||||
{:id :icons :title "Icons"}
|
||||
[:& icons-tab {:libraries (-> (libraries-ref :icons) mf/deref vals flatten) }]]
|
||||
[:& icons-tab {:libraries (-> (libraries-ref :icons) mf/deref filter-libraries) }]]
|
||||
|
||||
[:& tab-element
|
||||
{:id :images :title "Images"}
|
||||
[:& images-tab {:libraries (-> (libraries-ref :images) mf/deref vals flatten)}]]]]]))
|
||||
[:& images-tab {:libraries (-> (libraries-ref :images) mf/deref filter-libraries)}]]]]]))
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue