diff --git a/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs b/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs index 5a69b066b..1acf6657f 100644 --- a/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs @@ -9,16 +9,19 @@ (:require [app.common.data :as d] [app.common.data.macros :as dm] + [app.common.types.shape.radius :as ctsr] [app.main.data.events :as ev] [app.main.data.modal :as modal] [app.main.data.shortcuts :as scd] [app.main.data.tokens :as dt] [app.main.data.workspace :as dw] + [app.main.data.workspace.changes :as dch] [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.components.dropdown :refer [dropdown]] [app.main.ui.icons :as i] [app.main.ui.workspace.context-menu :refer [menu-entry prevent-default]] + [app.main.ui.workspace.tokens.core :as wtc] [app.util.dom :as dom] [app.util.timers :as timers] [okulary.core :as l] @@ -27,32 +30,68 @@ (def tokens-menu-ref (l/derived :token-context-menu refs/workspace-local)) +(defn update-shape-radius-single-corner [value shape-ids attribute] + (st/emit! + (dch/update-shapes shape-ids + (fn [shape] + (when (ctsr/has-radius? shape) + (ctsr/set-radius-4 shape (first attribute) value))) + {:reg-objects? true + :attrs [:rx :ry :r1 :r2 :r3 :r4]}))) + +(defn apply-border-radius-token [token-id token-type-props attribute selected-shapes] + (let [token (dt/get-token-data-from-token-id token-id) + updated-token-type-props (if (#{:r1 :r2 :r3 :r4} attribute) + (assoc token-type-props + :on-update-shape update-shape-radius-single-corner + :attributes #{attribute}) + token-type-props)] + (wtc/on-apply-token {:token token + :token-type-props updated-token-type-props + :selected-shapes selected-shapes}))) + +(defn additional-actions [{:keys [token-id token-type-props token-type selected-shapes] :as context-data}] + (case token-type + :border-radius [{:title "All" :action #(apply-border-radius-token token-id token-type-props :all selected-shapes)} + {:title "Top Left" :action #(apply-border-radius-token token-id token-type-props :r1 selected-shapes)} + {:title "Top Right" :action #(apply-border-radius-token token-id token-type-props :r2 selected-shapes)} + {:title "Bottom Right" :action #(apply-border-radius-token token-id token-type-props :r3 selected-shapes)} + {:title "Bottom Left" :action #(apply-border-radius-token token-id token-type-props :r4 selected-shapes)}] + [])) + +(defn generate-menu-entries [{:keys [token-id token-type-props token-type selected-shapes] :as context-data}] + (let [{:keys [modal]} token-type-props + default-actions [{:title "Delete Token" :action #(st/emit! (dt/delete-token token-id))} + {:title "Duplicate Token" :action #(st/emit! (dt/duplicate-token token-id))} + {:title "Edit Token" :action (fn [event] + (let [{:keys [key fields]} modal + token (dt/get-token-data-from-token-id token-id)] + (st/emit! dt/hide-token-context-menu) + (dom/stop-propagation event) + (modal/show! key {:x (.-clientX ^js event) + :y (.-clientY ^js event) + :position :right + :fields fields + :token token})))}] + specific-actions (additional-actions context-data) + all-actions (concat default-actions specific-actions)] + all-actions)) + (mf/defc token-pill-context-menu - [{:keys [token-id token-type-props]}] - (let [{:keys [modal attributes title]} token-type-props - do-delete #(st/emit! (dt/delete-token token-id)) - do-duplicate #(st/emit! (dt/duplicate-token token-id)) - do-edit (fn [event] - (let [{:keys [key fields]} modal - token (dt/get-token-data-from-token-id token-id)] - (st/emit! dt/hide-token-context-menu) - (dom/stop-propagation event) - (modal/show! key {:x (.-clientX ^js event) - :y (.-clientY ^js event) - :position :right - :fields fields - :token token})))] - [:* - [:& menu-entry {:title "Delete Token" :on-click do-delete}] - [:& menu-entry {:title "Duplicate Token" :on-click do-duplicate}] - [:& menu-entry {:title "Edit Token" :on-click do-edit}]])) + [{:keys [token-id token-type-props token-type selected-shapes] :as context-data}] + (let [menu-entries (generate-menu-entries context-data)] + (for [[index entry] (d/enumerate menu-entries)] + [:& menu-entry {:title (:title entry) :on-click (:action entry) :key index}]))) (mf/defc token-context-menu [] (let [mdata (mf/deref tokens-menu-ref) top (- (get-in mdata [:position :y]) 20) left (get-in mdata [:position :x]) - dropdown-ref (mf/use-ref)] + dropdown-ref (mf/use-ref) + objects (mf/deref refs/workspace-page-objects) + selected (mf/deref refs/selected-shapes) + selected-shapes (into [] (keep (d/getf objects)) selected)] (mf/use-effect (mf/deps mdata) @@ -76,4 +115,6 @@ (when (= :token (:type mdata)) [:ul {:class (stl/css :context-list)} [:& token-pill-context-menu {:token-id (:token-id mdata) - :token-type-props (:token-type-props mdata)}]])]])) \ No newline at end of file + :token-type-props (:token-type-props mdata) + :token-type (:token-type mdata) + :selected-shapes selected-shapes}]])]])) \ No newline at end of file diff --git a/frontend/src/app/main/ui/workspace/tokens/core.cljs b/frontend/src/app/main/ui/workspace/tokens/core.cljs index 0b972f61d..aa8d62a67 100644 --- a/frontend/src/app/main/ui/workspace/tokens/core.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/core.cljs @@ -83,7 +83,7 @@ (st/emit! (on-apply {:token-id (:id token) :shape-id (:id shape) :attributes attributes})) - (on-update-shape token-value shape-ids)))) + (on-update-shape token-value shape-ids attributes)))) (defn update-shape-radius [value shape-ids] (st/emit! diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index 64800f962..f0246b4a4 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -68,6 +68,7 @@ (st/emit! (dt/show-token-context-menu {:type :token :position (dom/get-client-position event) :token-type-props token-type-props + :token-type type :token-id (:id token)})))) on-toggle-open-click (mf/use-fn