mirror of
https://github.com/penpot/penpot.git
synced 2025-05-24 17:56:10 +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
3
frontend/resources/images/icons/tick.svg
Normal file
3
frontend/resources/images/icons/tick.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="500" height="500" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M7.99941 1.62266C8.01413 1.36698 7.74905 1.14313 7.49807 1.21294C7.35967 1.27903 7.02149 1.60601 7.02149 1.60601C7.02149 1.60601 3.82775 4.79865 2.80464 5.76808C2.68664 5.81588 2.6167 5.68421 2.54114 5.62249C1.48872 4.57167 1.68802 4.66986 0.628214 3.62654C0.403393 3.46589 0.0441303 3.61642 0.00630665 3.8924C-0.0278168 4.07137 0.0811424 4.23539 0.212762 4.34466C1.2602 5.45375 1.12484 5.34669 2.1814 6.44725C2.31167 6.56977 2.42611 6.71875 2.58163 6.80902C2.77403 6.89051 2.99255 6.79154 3.11096 6.63235C4.317 5.44398 6.72612 3.05828 7.90933 1.84723C7.96218 1.78479 8.00392 1.70675 7.99941 1.62266Z" fill="black"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 731 B |
|
@ -52,24 +52,30 @@
|
||||||
left: 280px;
|
left: 280px;
|
||||||
width: calc(100% - 280px);
|
width: calc(100% - 280px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& .context-menu-items {
|
||||||
|
bottom: 1.5rem;
|
||||||
|
top: initial;
|
||||||
|
min-width: 10rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.color-palette-actions {
|
.color-palette-actions {
|
||||||
display: flex;
|
align-self: stretch;
|
||||||
flex-direction: column;
|
border: 1px solid #1F1F1F;
|
||||||
flex-shrink: 0;
|
cursor: pointer;
|
||||||
margin-right: .5rem;
|
|
||||||
|
|
||||||
border: 1px solid #1F1F1F;
|
|
||||||
align-self: stretch;
|
|
||||||
padding: 0.5rem;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
.color-palette-buttons {
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-around;
|
flex-direction: column;
|
||||||
}
|
flex-shrink: 0;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: .5rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
|
||||||
|
.color-palette-buttons {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.color-palette-actions-button {
|
.color-palette-actions-button {
|
||||||
|
@ -115,6 +121,7 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
height: 4.8rem;
|
||||||
padding: 0.25rem;
|
padding: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,9 @@
|
||||||
border-radius: $br-small;
|
border-radius: $br-small;
|
||||||
box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.25);
|
box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.25);
|
||||||
left: -$size-4;
|
left: -$size-4;
|
||||||
|
max-height: 30rem;
|
||||||
min-width: 7rem;
|
min-width: 7rem;
|
||||||
|
overflow: auto;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: $size-3;
|
top: $size-3;
|
||||||
}
|
}
|
||||||
|
@ -27,9 +29,25 @@
|
||||||
display: block;
|
display: block;
|
||||||
font-size: $fs12;
|
font-size: $fs12;
|
||||||
padding: $size-2 $size-4;
|
padding: $size-2 $size-4;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: $color-black;
|
color: $color-black;
|
||||||
background: $color-primary-lighter;
|
background-color: $color-primary-lighter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.context-menu.is-selectable {
|
||||||
|
& .context-menu-action {
|
||||||
|
padding-left: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .context-menu-item.is-selected .context-menu-action {
|
||||||
|
background-image: url(/images/icons/tick.svg);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 5% 48%;
|
||||||
|
background-size: 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,8 @@
|
||||||
.settings-bar-inside {
|
.settings-bar-inside {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
grid-template-columns: 100%;
|
||||||
|
|
||||||
&[data-layout*='layers'] {
|
&[data-layout*='layers'] {
|
||||||
grid-template-rows: 30% 70%;
|
grid-template-rows: 30% 70%;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,11 @@
|
||||||
grid-template-columns: repeat(2, 50%);
|
grid-template-columns: repeat(2, 50%);
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
|
& .context-menu-items {
|
||||||
|
left: initial;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.libraries-window-bar-title {
|
.libraries-window-bar-title {
|
||||||
|
|
|
@ -266,4 +266,4 @@
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(-> 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]
|
(update [_ state]
|
||||||
(let [{:keys [id] :as item} (assoc item :type :icon)]
|
(let [{:keys [id] :as item} (assoc item :type :icon)]
|
||||||
(-> state
|
(-> state
|
||||||
(update-in [:library :selected-items library-id] #(into [item] %)))))))
|
(update-in [:library-items :icons library-id] #(into [item] %)))))))
|
||||||
|
|
||||||
;; ;; --- Icon Persisted
|
;; ;; --- Icon Persisted
|
||||||
;;
|
;;
|
||||||
|
|
|
@ -395,5 +395,5 @@
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(-> 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
|
:images :images
|
||||||
:palettes :colors)]
|
:palettes :colors)]
|
||||||
(->> (rp/query! method {:library-id library-id})
|
(->> (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
|
(defn retrieve-library-data-result
|
||||||
[library-id data]
|
[type library-id data]
|
||||||
(ptk/reify ::retrieve-library-data-result
|
(ptk/reify ::retrieve-library-data-result
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(-> state
|
(-> state
|
||||||
(assoc-in [:library :selected-items library-id] data)))))
|
(assoc-in [:library-items type library-id] data)))))
|
||||||
|
|
||||||
|
|
||||||
;; Create library
|
;; Create library
|
||||||
|
@ -178,7 +178,7 @@
|
||||||
(let [update-fn (fn [items]
|
(let [update-fn (fn [items]
|
||||||
(filterv #(not= item-id (:id %)) items))]
|
(filterv #(not= item-id (:id %)) items))]
|
||||||
(-> state
|
(-> state
|
||||||
(update-in [:library :selected-items library-id] update-fn))))))
|
(update-in [:library-items type library-id] update-fn))))))
|
||||||
|
|
||||||
;; Batch delete
|
;; Batch delete
|
||||||
|
|
||||||
|
@ -207,4 +207,4 @@
|
||||||
update-fn (fn [items]
|
update-fn (fn [items]
|
||||||
(filterv #(not (item-ids-set (:id %))) items))]
|
(filterv #(not (item-ids-set (:id %))) items))]
|
||||||
(-> state
|
(-> 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)
|
(declare initialize-alignment)
|
||||||
|
|
||||||
#_(def default-layout #{:sitemap :layers :element-options :rules})
|
(def default-layout #{:sitemap :layers :element-options :rules})
|
||||||
(def default-layout #{:libraries :rules :colorpalette})
|
|
||||||
|
|
||||||
|
|
||||||
(def workspace-default
|
(def workspace-default
|
||||||
{:zoom 1
|
{:zoom 1
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
[rumext.alpha :as mf]
|
[rumext.alpha :as mf]
|
||||||
[goog.object :as gobj]
|
[goog.object :as gobj]
|
||||||
[uxbox.main.ui.components.dropdown :refer [dropdown-container]]
|
[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/defc context-menu
|
||||||
{::mf/wrap-props false}
|
{::mf/wrap-props false}
|
||||||
|
@ -13,12 +14,17 @@
|
||||||
(assert (vector? (gobj/get props "options")) "missing `options` prop")
|
(assert (vector? (gobj/get props "options")) "missing `options` prop")
|
||||||
|
|
||||||
(let [open? (gobj/get props "show")
|
(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?
|
(when open?
|
||||||
[:> dropdown-container props
|
[:> 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
|
[:ul.context-menu-items
|
||||||
(for [[action-name action-handler] options]
|
(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}
|
[:a.context-menu-action {:on-click action-handler}
|
||||||
action-name]])]]])))
|
action-name]])]]])))
|
||||||
|
|
|
@ -305,8 +305,8 @@
|
||||||
(-> (comp (l/key :library) (l/key section) (l/key team-id))
|
(-> (comp (l/key :library) (l/key section) (l/key team-id))
|
||||||
(l/derive st/state)))
|
(l/derive st/state)))
|
||||||
|
|
||||||
(defn selected-items-ref [library-id]
|
(defn selected-items-ref [section library-id]
|
||||||
(-> (comp (l/key :library) (l/key :selected-items) (l/key library-id))
|
(-> (comp (l/key :library-items) (l/key section) (l/key library-id))
|
||||||
(l/derive st/state)))
|
(l/derive st/state)))
|
||||||
|
|
||||||
(def last-deleted-library-ref
|
(def last-deleted-library-ref
|
||||||
|
@ -317,7 +317,7 @@
|
||||||
[{:keys [team-id library-id section]}]
|
[{:keys [team-id library-id section]}]
|
||||||
(let [state (mf/use-state {:selected #{}})
|
(let [state (mf/use-state {:selected #{}})
|
||||||
libraries (mf/deref (libraries-ref section team-id))
|
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)
|
last-deleted-library (mf/deref last-deleted-library-ref)
|
||||||
selected-library (first (filter #(= (:id %) library-id) libraries))]
|
selected-library (first (filter #(= (:id %) library-id) libraries))]
|
||||||
|
|
||||||
|
|
|
@ -13,16 +13,26 @@
|
||||||
[uxbox.builtins.icons :as i]
|
[uxbox.builtins.icons :as i]
|
||||||
[uxbox.main.data.colors :as udc]
|
[uxbox.main.data.colors :as udc]
|
||||||
[uxbox.main.data.workspace :as udw]
|
[uxbox.main.data.workspace :as udw]
|
||||||
|
[uxbox.main.data.library :as dlib]
|
||||||
[uxbox.main.store :as st]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.main.ui.keyboard :as kbd]
|
[uxbox.main.ui.keyboard :as kbd]
|
||||||
[uxbox.util.color :refer [hex->rgb]]
|
[uxbox.util.color :refer [hex->rgb]]
|
||||||
[uxbox.util.data :refer [read-string seek]]
|
[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
|
;; --- Refs
|
||||||
|
|
||||||
(def collections-iref
|
(def project-ref
|
||||||
(-> (l/key :colors-collections)
|
(-> (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)))
|
(l/derive st/state)))
|
||||||
|
|
||||||
;; --- Components
|
;; --- Components
|
||||||
|
@ -30,8 +40,6 @@
|
||||||
(mf/defc palette-item
|
(mf/defc palette-item
|
||||||
[{:keys [color] :as props}]
|
[{:keys [color] :as props}]
|
||||||
(let [rgb-vec (hex->rgb color)
|
(let [rgb-vec (hex->rgb color)
|
||||||
rgb-color (apply str "" (interpose ", " rgb-vec))
|
|
||||||
|
|
||||||
select-color
|
select-color
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(if (kbd/shift? event)
|
(if (kbd/shift? event)
|
||||||
|
@ -41,93 +49,85 @@
|
||||||
[:div.color-cell {:key (str color)
|
[:div.color-cell {:key (str color)
|
||||||
:on-click select-color}
|
:on-click select-color}
|
||||||
[:span.color {:style {:background color}}]
|
[:span.color {:style {:background color}}]
|
||||||
[:span.color-text color]
|
[:span.color-text color]]))
|
||||||
#_[:span.color-text rgb-color]]))
|
|
||||||
|
|
||||||
(mf/defc palette
|
(mf/defc palette
|
||||||
[{:keys [colls left-sidebar?] :as props}]
|
[{:keys [libraries left-sidebar?] :as props}]
|
||||||
(let [local (mf/use-state {})
|
|
||||||
colls (->> colls
|
|
||||||
(filter :id)
|
|
||||||
(sort-by :name))
|
|
||||||
|
|
||||||
coll (or (:selected @local)
|
(when (and libraries (-> libraries count (> 0)))
|
||||||
(first colls))
|
(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)
|
on-left-arrow-click
|
||||||
width (:width @local (* doc-width 0.84))
|
(fn [event]
|
||||||
offset (:offset @local 0)
|
(when (> offset 0)
|
||||||
visible (/ width 86)
|
(let [element (mf/ref-val container-child)]
|
||||||
invisible (- (count (:colors coll)) visible)
|
(swap! state update :offset dec))))
|
||||||
close #(st/emit! (udw/toggle-layout-flag :colorpalette))
|
|
||||||
|
|
||||||
container (mf/use-ref nil)
|
on-right-arrow-click
|
||||||
container-child (mf/use-ref nil)
|
(fn [event]
|
||||||
|
(when (< offset invisible)
|
||||||
|
(let [element (mf/ref-val container-child)]
|
||||||
|
(swap! state update :offset inc))))
|
||||||
|
|
||||||
select-coll
|
on-scroll
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(let [id (read-string (dom/event->value event))
|
(if (pos? (.. event -nativeEvent -deltaY))
|
||||||
selected (seek #(= id (:id %)) colls)]
|
(on-right-arrow-click event)
|
||||||
(swap! local assoc :selected selected :position 0)))
|
(on-left-arrow-click event)))
|
||||||
|
|
||||||
on-left-arrow-click
|
after-render
|
||||||
(fn [event]
|
(fn []
|
||||||
(when (> offset 0)
|
(let [dom (mf/ref-val container)
|
||||||
(let [element (mf/ref-val container-child)]
|
width (.-clientWidth dom)]
|
||||||
(swap! local update :offset dec))))
|
(when (not= (:width @state) width)
|
||||||
|
(swap! state assoc :width width))))
|
||||||
|
|
||||||
on-right-arrow-click
|
handle-click
|
||||||
(fn [event]
|
(fn [library]
|
||||||
(when (< offset invisible)
|
(swap! state assoc :selected-library (:id library)))]
|
||||||
(let [element (mf/ref-val container-child)]
|
|
||||||
(swap! local update :offset inc))))
|
|
||||||
|
|
||||||
on-scroll
|
(mf/use-effect nil after-render)
|
||||||
(fn [event]
|
|
||||||
(if (pos? (.. event -nativeEvent -deltaY))
|
|
||||||
(on-right-arrow-click event)
|
|
||||||
(on-left-arrow-click event)))
|
|
||||||
|
|
||||||
after-render
|
[:div.color-palette {:class (when left-sidebar? "left-sidebar-open")}
|
||||||
(fn []
|
[:& context-menu {:selectable true
|
||||||
(let [dom (mf/ref-val container)
|
:selected (->> libraries (filter #(= (:id %) (:selected-library @state))) first :name)
|
||||||
width (.-clientWidth dom)]
|
:show (:show-menu @state)
|
||||||
(when (not= (:width @local) width)
|
:on-close #(swap! state assoc :show-menu false)
|
||||||
(swap! local assoc :width width))))]
|
: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-content {:ref container :on-wheel on-scroll}
|
||||||
[:div.color-palette-actions
|
[:div.color-palette-inside {:ref container-child
|
||||||
[:div.color-palette-actions-button i/actions]
|
:style {:position "relative"
|
||||||
#_[:select.input-select {:on-change select-coll
|
:width (str (* 86 (count items)) "px")
|
||||||
:default-value (pr-str (:id coll))}
|
:right (str (* 86 offset) "px")}}
|
||||||
(for [item colls]
|
(for [item items]
|
||||||
[:option {:key (:id item) :value (pr-str (:id item))}
|
[:& palette-item {:color (:content item) :key (:id item)}])]]
|
||||||
(:name item)])]
|
|
||||||
|
|
||||||
#_[:div.color-palette-buttons
|
[:span.right-arrow {:on-click on-right-arrow-click} i/arrow-slide]]))))
|
||||||
[: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]]))
|
|
||||||
|
|
||||||
(mf/defc colorpalette
|
(mf/defc colorpalette
|
||||||
[{:keys [left-sidebar?]}]
|
[{:keys [left-sidebar?]}]
|
||||||
(let [colls (mf/deref collections-iref)]
|
(let [team-id (-> project-ref mf/deref :team-id)
|
||||||
#_(mf/use-effect #(st/emit! (udc/fetch-collections)))
|
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?
|
[:& palette {:left-sidebar? left-sidebar?
|
||||||
:colls (vals colls)}]))
|
:libraries libraries}]))
|
||||||
|
|
|
@ -24,7 +24,8 @@
|
||||||
[uxbox.util.uuid :as uuid]
|
[uxbox.util.uuid :as uuid]
|
||||||
[uxbox.util.i18n :as i18n :refer [t]]
|
[uxbox.util.i18n :as i18n :refer [t]]
|
||||||
[uxbox.main.ui.components.tab-container :refer [tab-container tab-element]]
|
[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
|
(def project-ref
|
||||||
(-> (l/key :workspace-project)
|
(-> (l/key :workspace-project)
|
||||||
|
@ -34,29 +35,34 @@
|
||||||
(-> (comp (l/key :library) (l/key section))
|
(-> (comp (l/key :library) (l/key section))
|
||||||
(l/derive st/state)))
|
(l/derive st/state)))
|
||||||
|
|
||||||
(defn selected-items-ref [library-id]
|
(defn selected-items-ref [section library-id]
|
||||||
(-> (comp (l/key :library) (l/key :selected-items) (l/key library-id))
|
(-> (comp (l/key :library-items) (l/key section) (l/key library-id))
|
||||||
(l/derive st/state)))
|
(l/derive st/state)))
|
||||||
|
|
||||||
(mf/defc icons-tab [{:keys [libraries]}]
|
(mf/defc icons-tab [{:keys [libraries]}]
|
||||||
|
|
||||||
(when (and libraries (-> libraries count (> 0)))
|
(when (and libraries (-> libraries count (> 0)))
|
||||||
(let [state (mf/use-state {:selected-library (-> libraries first :id)})]
|
(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))
|
(mf/use-effect (mf/deps (:selected-library @state))
|
||||||
#(st/emit! (dlib/retrieve-library-data :icons (:selected-library @state))))
|
#(st/emit! (dlib/retrieve-library-data :icons (:selected-library @state))))
|
||||||
|
|
||||||
[:div.library-tab.icons-tab
|
[:div.library-tab.icons-tab
|
||||||
[:select.input-select.library-tab-libraries
|
[: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]
|
(for [library libraries]
|
||||||
[:option.library-tab-libraries-item
|
[:option.library-tab-libraries-item
|
||||||
{:key (:id library)
|
{:key (:id library)
|
||||||
:value (:id library)}
|
:value (:id library)}
|
||||||
(:name library)])]
|
(:name library)])]
|
||||||
[:div.library-tab-content
|
[: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]
|
(for [item items]
|
||||||
[:div.library-tab-element
|
[: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 " "))
|
[:svg {:view-box (->> item :metadata :view-box (str/join " "))
|
||||||
:width (-> item :metadata :width)
|
:width (-> item :metadata :width)
|
||||||
:height (-> item :metadat :height)
|
:height (-> item :metadat :height)
|
||||||
|
@ -78,19 +84,30 @@
|
||||||
:value (:id library)}
|
:value (:id library)}
|
||||||
(:name library)])]
|
(:name library)])]
|
||||||
[:div.library-tab-content
|
[: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]
|
(for [item items]
|
||||||
[:div.library-tab-element
|
[: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)}]
|
[:img {:src (:thumb-uri item)}]
|
||||||
[:span.library-tab-element-name (:name item)]]))]])))
|
[:span.library-tab-element-name (:name item)]]))]])))
|
||||||
|
|
||||||
(mf/defc libraries-toolbox
|
(mf/defc libraries-toolbox
|
||||||
[{:keys [key]}]
|
[{:keys [key]}]
|
||||||
(let [team-id (-> project-ref mf/deref :team-id)
|
(let [state (mf/use-state {:menu-open false
|
||||||
locale (i18n/use-locale)]
|
: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/use-effect
|
||||||
(mf/deps key)
|
|
||||||
#(do
|
#(do
|
||||||
(st/emit! (dlib/retrieve-libraries :icons))
|
(st/emit! (dlib/retrieve-libraries :icons))
|
||||||
(st/emit! (dlib/retrieve-libraries :images))))
|
(st/emit! (dlib/retrieve-libraries :images))))
|
||||||
|
@ -104,17 +121,27 @@
|
||||||
[:div.libraries-window-bar
|
[:div.libraries-window-bar
|
||||||
[:div.libraries-window-bar-title "Libraries"]
|
[:div.libraries-window-bar-title "Libraries"]
|
||||||
[:div.libraries-window-bar-options
|
[:div.libraries-window-bar-options
|
||||||
"All libraries"
|
{:on-click #(swap! state assoc :menu-open true)}
|
||||||
[:button {:type "button"}
|
(key-to-str (:selected @state))
|
||||||
i/arrow-slide]]]
|
[: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
|
[:div.tool-window-content
|
||||||
[:& tab-container {}
|
[:& tab-container {}
|
||||||
[:& tab-element
|
[:& tab-element
|
||||||
{:id :icons :title "Icons"}
|
{: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
|
[:& tab-element
|
||||||
{:id :images :title "Images"}
|
{: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