mirror of
https://github.com/penpot/penpot.git
synced 2025-08-07 14:38:33 +02:00
Add the final layouts drag and drop impl.
This commit is contained in:
parent
2b74c34c00
commit
d238166405
2 changed files with 105 additions and 60 deletions
|
@ -377,11 +377,18 @@
|
||||||
(rx/from-coll
|
(rx/from-coll
|
||||||
(map unlock-shape (:items shape))))))))
|
(map unlock-shape (:items shape))))))))
|
||||||
|
|
||||||
|
;; FIXME: the impl can be maybe simplified.
|
||||||
|
|
||||||
(defn transfer-shape
|
(defn transfer-shape
|
||||||
"Event used in drag and drop for transfer shape
|
"Event used in drag and drop for transfer shape
|
||||||
from one position to an other."
|
from one position to an other."
|
||||||
[sid tid type]
|
[sid tid type]
|
||||||
(letfn [(transfer-to-group [state target])
|
(letfn [(transfer-to-group [state {:keys [id] :as target}]
|
||||||
|
(let [shapes (get-in state [:shapes-by-id id :items])
|
||||||
|
shapes (conj shapes sid)]
|
||||||
|
(as-> state $
|
||||||
|
(assoc-in $ [:shapes-by-id id :items] shapes)
|
||||||
|
(update-in $ [:shapes-by-id sid] assoc :group id))))
|
||||||
|
|
||||||
(transfer-at [index shapes sid]
|
(transfer-at [index shapes sid]
|
||||||
(let [[fst snd] (split-at index shapes)]
|
(let [[fst snd] (split-at index shapes)]
|
||||||
|
@ -426,18 +433,24 @@
|
||||||
(reify
|
(reify
|
||||||
rs/UpdateEvent
|
rs/UpdateEvent
|
||||||
(-apply-update [_ state]
|
(-apply-update [_ state]
|
||||||
(let [target (get-in state [:shapes-by-id tid])
|
(if (= tid sid)
|
||||||
source (get-in state [:shapes-by-id sid])
|
state
|
||||||
state (remove-source state source)]
|
(let [target (get-in state [:shapes-by-id tid])
|
||||||
(cond
|
source (get-in state [:shapes-by-id sid])
|
||||||
(and (= type :inside) (:group target))
|
state (remove-source state source)]
|
||||||
(transfer-to-group state target)
|
(cond
|
||||||
|
(and (= type :inside)
|
||||||
|
(= (:type target) :builtin/group))
|
||||||
|
(transfer-to-group state target)
|
||||||
|
|
||||||
(= type :before)
|
(= type :before)
|
||||||
(transfer-before state target)
|
(transfer-before state target)
|
||||||
|
|
||||||
(= type :after)
|
(= type :after)
|
||||||
(transfer-after state target)))))))
|
(transfer-after state target)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(throw (ex-info "Invalid data" {})))))))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Events (for selected)
|
;; Events (for selected)
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
[uxbox.ui.workspace.base :as wb]
|
[uxbox.ui.workspace.base :as wb]
|
||||||
[uxbox.ui.icons :as i]
|
[uxbox.ui.icons :as i]
|
||||||
[uxbox.ui.mixins :as mx]
|
[uxbox.ui.mixins :as mx]
|
||||||
|
[uxbox.util.dom.dnd :as dnd]
|
||||||
[uxbox.util.dom :as dom])
|
[uxbox.util.dom :as dom])
|
||||||
(:import goog.events.EventType))
|
(:import goog.events.EventType))
|
||||||
|
|
||||||
|
@ -115,36 +116,30 @@
|
||||||
toggle-visibility #(toggle-visibility selected item %)
|
toggle-visibility #(toggle-visibility selected item %)
|
||||||
toggle-blocking #(toggle-blocking item %)
|
toggle-blocking #(toggle-blocking item %)
|
||||||
local (:rum/local own)
|
local (:rum/local own)
|
||||||
|
|
||||||
classes (classnames
|
classes (classnames
|
||||||
:selected selected?
|
:selected selected?
|
||||||
:drag-top (= :top (:over @local))
|
:drag-top (= :top (:over @local))
|
||||||
:drag-bottom (= :bottom (:over @local))
|
:drag-bottom (= :bottom (:over @local))
|
||||||
:drag-inside (= :middle (:over @local)))]
|
:drag-inside (= :middle (:over @local)))]
|
||||||
(letfn [(on-drag-start [event]
|
(letfn [(on-drag-start [event]
|
||||||
(let [target (.-target event)
|
(let [target (dom/event->target event)]
|
||||||
style (.-style target)
|
(dnd/set-allowed-effect! event "move")
|
||||||
dt (.-dataTransfer event)]
|
(dnd/set-data! event (:id item))
|
||||||
(set! (.-effectAllowed dt) "move")
|
|
||||||
(.setData dt "item/uuid" (pr-str (:id item)))
|
|
||||||
(swap! local assoc :dragging true)))
|
(swap! local assoc :dragging true)))
|
||||||
(on-drag-end [event]
|
(on-drag-end [event]
|
||||||
(swap! local assoc :dragging false :over nil))
|
(swap! local assoc :dragging false :over nil))
|
||||||
(on-drop [event]
|
(on-drop [event]
|
||||||
(let [dt (.-dataTransfer event)
|
(dom/stop-propagation event)
|
||||||
id (read-string (.getData dt "item/uuid"))
|
(let [id (dnd/get-data event)
|
||||||
over (:over @local)]
|
over (:over @local)]
|
||||||
(case (:over @local)
|
(case (:over @local)
|
||||||
:top (rs/emit! (dw/transfer-shape id (:id item) :before))
|
:top (rs/emit! (dw/transfer-shape id (:id item) :before))
|
||||||
:bottom (rs/emit! (dw/transfer-shape id (:id item) :after))
|
:bottom (rs/emit! (dw/transfer-shape id (:id item) :after)))
|
||||||
;; :middle (rs/emit! (dw/transfer-inside id (:id item)))
|
|
||||||
)
|
|
||||||
(swap! local assoc :dragging false :over nil)))
|
(swap! local assoc :dragging false :over nil)))
|
||||||
(on-drag-over [event]
|
(on-drag-over [event]
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(let [dt (.-dataTransfer event)
|
(dnd/set-drop-effect! event "move")
|
||||||
over (get-hover-position event false)]
|
(let [over (get-hover-position event false)]
|
||||||
(set! (.-dropEffect dt) "move")
|
|
||||||
(swap! local assoc :over over)))
|
(swap! local assoc :over over)))
|
||||||
(on-drag-enter [event]
|
(on-drag-enter [event]
|
||||||
(swap! local assoc :over true))
|
(swap! local assoc :over true))
|
||||||
|
@ -159,7 +154,6 @@
|
||||||
:on-drag-over on-drag-over
|
:on-drag-over on-drag-over
|
||||||
:on-drag-end on-drag-end
|
:on-drag-end on-drag-end
|
||||||
:on-drop on-drop
|
:on-drop on-drop
|
||||||
:data-over (str (:over @local))
|
|
||||||
:draggable true
|
:draggable true
|
||||||
:class (when selected? "selected")}
|
:class (when selected? "selected")}
|
||||||
[:div.element-list-body
|
[:div.element-list-body
|
||||||
|
@ -198,40 +192,78 @@
|
||||||
toggle-open (fn [event]
|
toggle-open (fn [event]
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(swap! local assoc :open (not open?)))
|
(swap! local assoc :open (not open?)))
|
||||||
shapes-by-id (rum/react wb/shapes-by-id-l)]
|
shapes-by-id (rum/react wb/shapes-by-id-l)
|
||||||
(html
|
classes (classnames
|
||||||
[:li.group {:class (when open? "open") :draggable true}
|
:selected selected?
|
||||||
[:div.element-list-body
|
:drag-top (= :top (:over @local))
|
||||||
{:class (when selected? "selected")
|
:drag-bottom (= :bottom (:over @local))
|
||||||
:on-click select}
|
:drag-inside (= :middle (:over @local)))]
|
||||||
[:div.element-actions
|
(letfn [(on-drag-start [event]
|
||||||
[:div.toggle-element
|
(let [target (dom/event->target event)]
|
||||||
{:class (when-not (:hidden item) "selected")
|
(dnd/set-allowed-effect! event "move")
|
||||||
:on-click toggle-visibility}
|
(dnd/set-data! event (:id item))
|
||||||
i/eye]
|
(swap! local assoc :dragging true)))
|
||||||
[:div.block-element
|
(on-drag-end [event]
|
||||||
{:class (when (:blocked item) "selected")
|
(swap! local assoc :dragging false :over nil))
|
||||||
:on-click toggle-blocking}
|
(on-drop [event]
|
||||||
i/lock]
|
(dom/stop-propagation event)
|
||||||
[:div.chain-element
|
(let [id (dnd/get-data event)
|
||||||
{:class (when (:locked item) "selected")
|
over (:over @local)]
|
||||||
:on-click toggle-locking}
|
(case (:over @local)
|
||||||
i/chain]]
|
:top (rs/emit! (dw/transfer-shape id (:id item) :before))
|
||||||
[:div.element-icon i/folder]
|
:bottom (rs/emit! (dw/transfer-shape id (:id item) :after))
|
||||||
[:span (:name item "Unnamed group")]
|
:middle (rs/emit! (dw/transfer-shape id (:id item) :inside)))
|
||||||
[:span.toggle-content
|
(swap! local assoc :dragging false :over nil)))
|
||||||
{:on-click toggle-open
|
(on-drag-over [event]
|
||||||
:class (when open? "inverse")}
|
(dom/prevent-default event)
|
||||||
i/arrow-slide]]
|
(dnd/set-drop-effect! event "move")
|
||||||
(if open?
|
(let [over (get-hover-position event true)]
|
||||||
[:ul
|
(swap! local assoc :over over)))
|
||||||
(for [shape (map #(get shapes-by-id %) (:items item))
|
(on-drag-enter [event]
|
||||||
:let [key (str (:id shape))]]
|
(swap! local assoc :over true))
|
||||||
(if (= (:type shape) :builtin/group)
|
(on-drag-leave [event]
|
||||||
(-> (layer-group shape selected)
|
(swap! local assoc :over false))]
|
||||||
(rum/with-key key))
|
(html
|
||||||
(-> (layer-element shape selected)
|
[:li.group {:class (when open? "open")
|
||||||
(rum/with-key key))))])])))
|
:key (str (:id item))
|
||||||
|
:draggable true}
|
||||||
|
[:div.element-list-body
|
||||||
|
{:class classes
|
||||||
|
:on-drag-start on-drag-start
|
||||||
|
:on-drag-enter on-drag-enter
|
||||||
|
:on-drag-leave on-drag-leave
|
||||||
|
:on-drag-over on-drag-over
|
||||||
|
:on-drag-end on-drag-end
|
||||||
|
:on-drop on-drop
|
||||||
|
:on-click select}
|
||||||
|
[:div.element-actions
|
||||||
|
[:div.toggle-element
|
||||||
|
{:class (when-not (:hidden item) "selected")
|
||||||
|
:on-click toggle-visibility}
|
||||||
|
i/eye]
|
||||||
|
[:div.block-element
|
||||||
|
{:class (when (:blocked item) "selected")
|
||||||
|
:on-click toggle-blocking}
|
||||||
|
i/lock]
|
||||||
|
[:div.chain-element
|
||||||
|
{:class (when (:locked item) "selected")
|
||||||
|
:on-click toggle-locking}
|
||||||
|
i/chain]]
|
||||||
|
[:div.element-icon i/folder]
|
||||||
|
[:span (:name item "Unnamed group")]
|
||||||
|
[:span.toggle-content
|
||||||
|
{:on-click toggle-open
|
||||||
|
:class (when open? "inverse")}
|
||||||
|
i/arrow-slide]]
|
||||||
|
(if open?
|
||||||
|
[:ul
|
||||||
|
(for [shape (map #(get shapes-by-id %) (:items item))
|
||||||
|
:let [key (str (:id shape))]]
|
||||||
|
(if (= (:type shape) :builtin/group)
|
||||||
|
(-> (layer-group shape selected)
|
||||||
|
(rum/with-key key))
|
||||||
|
(-> (layer-element shape selected)
|
||||||
|
(rum/with-key key))))])]))))
|
||||||
|
|
||||||
(def ^:static ^:private layer-group
|
(def ^:static ^:private layer-group
|
||||||
(mx/component
|
(mx/component
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue