0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-13 16:21:57 -05:00

Add open components, and scroll into view to show main component acction

This commit is contained in:
eva 2021-12-28 12:38:25 +01:00 committed by Alonso Torres
parent c69d7f50a3
commit 6dae420254
6 changed files with 148 additions and 85 deletions

View file

@ -5,6 +5,7 @@
### :boom: Breaking changes
### :sparkles: New features
- Add actions to go to main component context menu option [Taiga #2053](https://tree.taiga.io/project/penpot/us/2053).
- Add contrast between component select color and shape select color [Taiga #2121](https://tree.taiga.io/project/penpot/issue/2121).
- Add animations in interactions [Taiga #2244](https://tree.taiga.io/project/penpot/us/2244).

View file

@ -44,10 +44,12 @@
[app.main.repo :as rp]
[app.main.streams :as ms]
[app.main.worker :as uw]
[app.util.dom :as dom]
[app.util.globals :as ug]
[app.util.http :as http]
[app.util.i18n :as i18n]
[app.util.router :as rt]
[app.util.timers :as tm]
[app.util.webapi :as wapi]
[beicon.core :as rx]
[cljs.spec.alpha :as s]
@ -111,6 +113,10 @@
{:zoom 1
:flags #{}
:selected (d/ordered-set)
:selected-assets {:components #{}
:graphics #{}
:colors #{}
:typographies #{}}
:expanded {}
:tooltip nil
:options-mode :design
@ -1305,6 +1311,66 @@
qparams {:page-id page-id :layout (name layout)}]
(rx/of (rt/nav :workspace pparams qparams))))))
(defn check-in-asset
[set element]
(if (contains? set element)
(disj set element)
(conj set element)))
(defn toggle-selected-assets
[asset type]
(ptk/reify ::toggle-selected-assets
ptk/UpdateEvent
(update [_ state]
(update-in state [:workspace-local :selected-assets type] #(check-in-asset % asset)))))
(defn select-single-asset
[asset type]
(ptk/reify ::select-single-asset
ptk/UpdateEvent
(update [_ state]
(assoc-in state [:workspace-local :selected-assets type] #{asset}))))
(defn select-assets
[assets type]
(ptk/reify ::select-assets
ptk/UpdateEvent
(update [_ state]
(assoc-in state [:workspace-local :selected-assets type] (into #{} assets)))))
(defn unselect-all-assets
[]
(ptk/reify ::unselect-all-assets
ptk/UpdateEvent
(update [_ state]
(assoc-in state [:workspace-local :selected-assets] {:components #{}
:graphics #{}
:colors #{}
:typographies #{}}))))
(defn go-to-component
[objs]
(ptk/reify ::set-workspace-layout-component
IDeref
(-deref [_] {:layout :assets})
ptk/WatchEvent
(watch [_ state _]
(let [project-id (get-in state [:workspace-project :id])
file-id (get-in state [:workspace-file :id])
page-id (get state :current-page-id)
component-id (get (first objs) :component-id)
pparams {:file-id file-id :project-id project-id}
qparams {:page-id page-id :layout :assets}]
(rx/of (rt/nav :workspace pparams qparams)
(dwl/set-assets-box-open file-id :library true)
(dwl/set-assets-box-open file-id :components true)
(select-single-asset component-id :components))))
ptk/EffectEvent
(effect [_ _ _]
(let [component-id (get (first objs) :component-id)
wrapper-id (str "component-shape-id-" component-id)]
(tm/schedule-on-idle #(dom/scroll-into-view-if-needed! (dom/get-element wrapper-id)))))))
(def go-to-file
(ptk/reify ::go-to-file
ptk/WatchEvent

View file

@ -155,6 +155,9 @@
(def editors
(l/derived :editors workspace-local))
(def selected-assets
(l/derived :selected-assets workspace-local))
(def workspace-layout
(l/derived :workspace-layout st/state))

View file

@ -168,7 +168,7 @@
:accept-label (tr "modals.update-remote-component.accept")
:accept-style :primary
:on-accept confirm-update-remote-component}))
do-show-component (st/emitf (dw/go-to-layout :assets))
do-show-component (st/emitf (dw/go-to-component selected-objects))
do-navigate-component-file (st/emitf (dwl/nav-to-component-file
(:component-file shape)))

View file

@ -273,6 +273,7 @@
:selected (contains? selected-components (:id component))
:grid-cell @listing-thumbs?
:enum-item (not @listing-thumbs?))
:id (str "component-shape-id-" (:id component))
:draggable true
:on-click #(on-asset-click % (:id component) nil)
:on-context-menu (on-context-menu (:id component))
@ -1402,15 +1403,12 @@
reverse-sort? (mf/use-state false)
listing-thumbs? (mf/use-state true)
selected-assets (mf/use-state {:components #{}
:graphics #{}
:colors #{}
:typographies #{}})
selected-assets (mf/deref refs/selected-assets)
selected-count (+ (count (:components @selected-assets))
(count (:graphics @selected-assets))
(count (:colors @selected-assets))
(count (:typographies @selected-assets)))
selected-count (+ (count (:components selected-assets))
(count (:graphics selected-assets))
(count (:colors selected-assets))
(count (:typographies selected-assets)))
toggle-open (st/emitf (dwl/set-assets-box-open (:id file) :library (not open?)))
@ -1441,92 +1439,81 @@
(fn [_]
(swap! listing-thumbs? not)))
toggle-selected-asset
(mf/use-callback
(mf/deps @selected-assets)
(fn [asset-type asset-id]
(swap! selected-assets update asset-type
(fn [selected]
(if (contains? selected asset-id)
(disj selected asset-id)
(conj selected asset-id))))))
extend-selected-assets
(mf/use-callback
(mf/deps @selected-assets)
(fn [asset-type asset-groups asset-id]
(letfn [(flatten-groups
[groups]
(concat
(get groups "" [])
(reduce concat
[]
(->> (filter #(seq (first %)) groups)
(map second)
(map flatten-groups)))))]
(swap! selected-assets update asset-type
(fn [selected]
(let [all-assets (flatten-groups asset-groups)
clicked-idx (d/index-of-pred all-assets #(= (:id %) asset-id))
selected-idx (->> selected
(map (fn [id]
(d/index-of-pred all-assets
#(= (:id %) id)))))
min-idx (apply min (conj selected-idx clicked-idx))
max-idx (apply max (conj selected-idx clicked-idx))]
(mf/deps selected-assets)
(fn [asset-type asset-groups asset-id]
(letfn [(flatten-groups
[groups]
(concat
(get groups "" [])
(reduce concat
(into []
(->> (filter #(seq (first %)) groups)
(map second)
(mapcat flatten-groups))))))]
(let [selected-assets-type (get selected-assets asset-type)
count-assets (count selected-assets-type)]
(if (<= count-assets 0)
(st/emit! (dw/select-single-asset asset-id asset-type))
(let [all-assets (flatten-groups asset-groups)
clicked-idx (d/index-of-pred all-assets #(= (:id %) asset-id))
components (get selected-assets asset-type)
(->> all-assets
d/enumerate
(filter #(<= min-idx (first %) max-idx))
(map #(-> % second :id))
set)))))))
first-idx (first (sort (map (fn [asset] (d/index-of-pred all-assets #(= (:id %) asset))) components)))
selected-idx (vector first-idx clicked-idx)
min-idx (apply min (conj selected-idx clicked-idx))
max-idx (apply max (conj selected-idx clicked-idx))
values (->> all-assets
d/enumerate
(filter #(<= min-idx (first %) max-idx))
(map #(-> % second :id))
set)]
(st/emit! (dw/select-assets values asset-type))))))))
unselect-all
(mf/use-callback
(fn []
(swap! selected-assets {:components #{}
:graphics #{}
:colors #{}
:typographies #{}})))
(fn []
(st/emit! (dw/unselect-all-assets))))
on-asset-click
(mf/use-callback
(mf/deps toggle-selected-asset extend-selected-assets)
(fn [asset-type asset-groups event asset-id default-click]
(cond
(kbd/ctrl? event)
(do
(dom/stop-propagation event)
(toggle-selected-asset asset-type asset-id))
(mf/deps extend-selected-assets selected-assets)
(fn [asset-type asset-groups event asset-id default-click]
(cond
(kbd/ctrl? event)
(do
(dom/stop-propagation event)
(st/emit! (dw/toggle-selected-assets asset-id asset-type)))
(kbd/shift? event)
(do
(dom/stop-propagation event)
(extend-selected-assets asset-type asset-groups asset-id))
(kbd/shift? event)
(do
(dom/stop-propagation event)
(extend-selected-assets asset-type asset-groups asset-id))
:else
(when default-click
(default-click event)))))
:else
(when default-click
(default-click event)))))
on-assets-delete
(mf/use-callback
(mf/deps @selected-assets)
(fn []
(let [selected-assets @selected-assets]
(st/emit! (dwu/start-undo-transaction))
(apply st/emit! (map #(dwl/delete-component {:id %})
(:components selected-assets)))
(apply st/emit! (map #(dwl/delete-media {:id %})
(:graphics selected-assets)))
(apply st/emit! (map #(dwl/delete-color {:id %})
(:colors selected-assets)))
(apply st/emit! (map #(dwl/delete-typography %)
(:typographies selected-assets)))
(when (or (d/not-empty? (:components selected-assets))
(d/not-empty? (:colors selected-assets))
(d/not-empty? (:typographies selected-assets)))
(st/emit! (dwl/sync-file (:id file) (:id file))))
(st/emit! (dwu/commit-undo-transaction)))))]
(mf/deps selected-assets)
(fn []
(st/emit! (dwu/start-undo-transaction))
(apply st/emit! (map #(dwl/delete-component {:id %})
(:components selected-assets)))
(apply st/emit! (map #(dwl/delete-media {:id %})
(:graphics selected-assets)))
(apply st/emit! (map #(dwl/delete-color {:id %})
(:colors selected-assets)))
(apply st/emit! (map #(dwl/delete-typography %)
(:typographies selected-assets)))
(when (or (d/not-empty? (:components selected-assets))
(d/not-empty? (:colors selected-assets))
(d/not-empty? (:typographies selected-assets)))
(st/emit! (dwl/sync-file (:id file) (:id file))))
(st/emit! (dwu/commit-undo-transaction))))]
[:div.tool-window {:on-context-menu #(dom/prevent-default %)
:on-click unselect-all}
@ -1588,7 +1575,7 @@
:open? (open-box? :components)
:open-groups (open-groups :components)
:reverse-sort? @reverse-sort?
:selected-assets @selected-assets
:selected-assets selected-assets
:on-asset-click (partial on-asset-click :components)
:on-assets-delete on-assets-delete
:on-clear-selection unselect-all}])
@ -1601,7 +1588,7 @@
:open? (open-box? :graphics)
:open-groups (open-groups :graphics)
:reverse-sort? @reverse-sort?
:selected-assets @selected-assets
:selected-assets selected-assets
:on-asset-click (partial on-asset-click :graphics)
:on-assets-delete on-assets-delete
:on-clear-selection unselect-all}])
@ -1612,7 +1599,7 @@
:open? (open-box? :colors)
:open-groups (open-groups :colors)
:reverse-sort? @reverse-sort?
:selected-assets @selected-assets
:selected-assets selected-assets
:on-asset-click (partial on-asset-click :colors)
:on-assets-delete on-assets-delete
:on-clear-selection unselect-all}])
@ -1625,7 +1612,7 @@
:open? (open-box? :typographies)
:open-groups (open-groups :typographies)
:reverse-sort? @reverse-sort?
:selected-assets @selected-assets
:selected-assets selected-assets
:on-asset-click (partial on-asset-click :typographies)
:on-assets-delete on-assets-delete
:on-clear-selection unselect-all}])

View file

@ -354,6 +354,12 @@
([element scroll-top]
(.scrollIntoView ^js element scroll-top)))
(defn scroll-into-view-if-needed!
([element]
(.scrollIntoViewIfNeeded ^js element false))
([element scroll-top]
(.scrollIntoViewIfNeeded ^js element scroll-top)))
(defn is-in-viewport?
[element]
(let [rect (.getBoundingClientRect element)