From 24f1693684fcf74693d94b6dba61e3c61e24c57a Mon Sep 17 00:00:00 2001 From: Akshay Gupta Date: Tue, 14 May 2024 18:10:13 +0530 Subject: [PATCH 1/7] Add Context Menu for tokens and simple placeholder functions --- frontend/src/app/main/refs.cljs | 3 + frontend/src/app/main/ui/workspace.cljs | 2 + .../app/main/ui/workspace/tokens/common.cljs | 19 +++ .../ui/workspace/tokens/context_menu.cljs | 153 ++++++++++++++++++ .../ui/workspace/tokens/context_menu.scss | 126 +++++++++++++++ .../app/main/ui/workspace/tokens/sidebar.cljs | 21 ++- 6 files changed, 319 insertions(+), 5 deletions(-) create mode 100644 frontend/src/app/main/ui/workspace/tokens/context_menu.cljs create mode 100644 frontend/src/app/main/ui/workspace/tokens/context_menu.scss diff --git a/frontend/src/app/main/refs.cljs b/frontend/src/app/main/refs.cljs index 969bb43a6..33e558446 100644 --- a/frontend/src/app/main/refs.cljs +++ b/frontend/src/app/main/refs.cljs @@ -196,6 +196,9 @@ (def context-menu (l/derived :context-menu workspace-local)) +(def token-context-menu + (l/derived :token-context-menu workspace-local)) + ;; page item that it is being edited (def editing-page-item (l/derived :page-item workspace-local)) diff --git a/frontend/src/app/main/ui/workspace.cljs b/frontend/src/app/main/ui/workspace.cljs index 8b4ee10c1..420e722a2 100644 --- a/frontend/src/app/main/ui/workspace.cljs +++ b/frontend/src/app/main/ui/workspace.cljs @@ -29,6 +29,7 @@ [app.main.ui.workspace.sidebar :refer [left-sidebar right-sidebar]] [app.main.ui.workspace.sidebar.collapsable-button :refer [collapsed-button]] [app.main.ui.workspace.sidebar.history :refer [history-toolbox]] + [app.main.ui.workspace.tokens.context-menu :refer [token-context-menu]] [app.main.ui.workspace.tokens.modals] [app.main.ui.workspace.viewport :refer [viewport]] [app.util.debug :as dbg] @@ -204,6 +205,7 @@ :style {:background-color background-color :touch-action "none"}} [:& context-menu] + [:& token-context-menu] (if ^boolean file-ready? [:& workspace-page {:page-id page-id diff --git a/frontend/src/app/main/ui/workspace/tokens/common.cljs b/frontend/src/app/main/ui/workspace/tokens/common.cljs index 0ecd7c505..bf4c29c5e 100644 --- a/frontend/src/app/main/ui/workspace/tokens/common.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/common.cljs @@ -7,6 +7,9 @@ (ns app.main.ui.workspace.tokens.common (:require-macros [app.main.style :as stl]) (:require + [app.common.data.macros :as dm] + [app.common.geom.point :as gpt] + [potok.v2.core :as ptk] [rumext.v2 :as mf])) ;; Helpers --------------------------------------------------------------------- @@ -39,3 +42,19 @@ :default-value default-value :autoFocus auto-focus? :on-change on-change}]]) + +;; Token Context Menu Functions ------------------------------------------------- + +(defn show-token-context-menu + [{:keys [position token-id] :as params}] + (dm/assert! (gpt/point? position)) + (ptk/reify ::show-token-context-menu + ptk/UpdateEvent + (update [_ state] + (assoc-in state [:workspace-local :token-context-menu] params)))) + +(def hide-token-context-menu + (ptk/reify ::hide-token-context-menu + ptk/UpdateEvent + (update [_ state] + (assoc-in state [:workspace-local :token-context-menu] nil)))) \ No newline at end of file diff --git a/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs b/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs new file mode 100644 index 000000000..424e56c91 --- /dev/null +++ b/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs @@ -0,0 +1,153 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) KALEIDOS INC + +(ns app.main.ui.workspace.tokens.context-menu + (:require-macros [app.main.style :as stl]) + (:require + [app.common.data :as d] + [app.common.data.macros :as dm] + [app.main.data.events :as ev] + [app.main.data.shortcuts :as scd] + [app.main.data.workspace :as dw] + [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.tokens.common :refer [hide-token-context-menu]] + [app.util.dom :as dom] + [app.util.i18n :refer [tr]] + [app.util.timers :as timers] + [okulary.core :as l] + [rumext.v2 :as mf])) + +(def tokens-menu-ref + (l/derived :token-context-menu refs/workspace-local)) + +(defn- prevent-default + [event] + (dom/prevent-default event) + (dom/stop-propagation event)) + +(mf/defc token-menu-entry + {::mf/props :obj} + [{:keys [title shortcut on-click on-pointer-enter on-pointer-leave + on-unmount children selected? icon disabled value]}] + (let [submenu-ref (mf/use-ref nil) + hovering? (mf/use-ref false) + on-pointer-enter + (mf/use-callback + (fn [] + (mf/set-ref-val! hovering? true) + (let [submenu-node (mf/ref-val submenu-ref)] + (when (some? submenu-node) + (dom/set-css-property! submenu-node "display" "block"))) + (when on-pointer-enter (on-pointer-enter)))) + + on-pointer-leave + (mf/use-callback + (fn [] + (mf/set-ref-val! hovering? false) + (let [submenu-node (mf/ref-val submenu-ref)] + (when (some? submenu-node) + (timers/schedule + 200 + #(when-not (mf/ref-val hovering?) + (dom/set-css-property! submenu-node "display" "none"))))) + (when on-pointer-leave (on-pointer-leave)))) + + set-dom-node + (mf/use-callback + (fn [dom] + (let [submenu-node (mf/ref-val submenu-ref)] + (when (and (some? dom) (some? submenu-node)) + (dom/set-css-property! submenu-node "top" (str (.-offsetTop dom) "px"))))))] + + (mf/use-effect + (mf/deps on-unmount) + (constantly on-unmount)) + + (if icon + [:li {:class (stl/css :icon-menu-item) + :disabled disabled + :data-value value + :ref set-dom-node + :on-click on-click + :on-pointer-enter on-pointer-enter + :on-pointer-leave on-pointer-leave} + [:span + {:class (stl/css :icon-wrapper)} + (if selected? [:span {:class (stl/css :selected-icon)} + i/tick] + [:span {:class (stl/css :selected-icon)}]) + [:span {:class (stl/css :shape-icon)} icon]] + [:span {:class (stl/css :title)} title]] + [:li {:class (stl/css :context-menu-item) + :disabled disabled + :ref set-dom-node + :data-value value + :on-click on-click + :on-pointer-enter on-pointer-enter + :on-pointer-leave on-pointer-leave} + [:span {:class (stl/css :title)} title] + (when shortcut + [:span {:class (stl/css :shortcut)} + (for [[idx sc] (d/enumerate (scd/split-sc shortcut))] + [:span {:key (dm/str shortcut "-" idx) + :class (stl/css :shortcut-key)} sc])]) + + (when (> (count children) 1) + [:span {:class (stl/css :submenu-icon)} i/arrow]) + + (when (> (count children) 1) + [:ul {:class (stl/css :token-context-submenu) + :ref submenu-ref + :style {:display "none" :left 250} + :on-context-menu prevent-default} + children])]))) + +(mf/defc menu-separator + [] + [:li {:class (stl/css :separator)}]) + +(mf/defc token-pill-context-menu + [{:keys [token-id]}] + (let [do-delete #(js/console.log "Deleting") + do-duplicate #(js/console.log "Duplicating") + do-edit #(js/console.log "Editing")] + [:ul.context-list + [:> token-menu-entry {:title (tr "Delete Token") :on-click do-delete}] + [:> token-menu-entry {:title (tr "Duplicate Token") :on-click do-duplicate}] + [:> token-menu-entry {:title (tr "Edit Token") :on-click do-edit}]])) + +(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)] + + (mf/use-effect + (mf/deps mdata) + #(let [dropdown (mf/ref-val dropdown-ref)] + (when dropdown + (let [bounding-rect (dom/get-bounding-rect dropdown) + window-size (dom/get-window-size) + delta-x (max (- (+ (:right bounding-rect) 250) (:width window-size)) 0) + delta-y (max (- (:bottom bounding-rect) (:height window-size)) 0) + new-style (str "top: " (- top delta-y) "px; " + "left: " (- left delta-x) "px;")] + (when (or (> delta-x 0) (> delta-y 0)) + (.setAttribute ^js dropdown "style" new-style)))))) + + [:& dropdown {:show (boolean mdata) + :on-close #(st/emit! hide-token-context-menu)} + [:div {:class (stl/css :token-context-menu) + :ref dropdown-ref + :style {:top top :left left} + :on-context-menu prevent-default} + (when (= :token (:type mdata)) + [:ul {:class (stl/css :context-list)} + [:& token-pill-context-menu {:token-id (:id mdata)}]])]])) \ No newline at end of file diff --git a/frontend/src/app/main/ui/workspace/tokens/context_menu.scss b/frontend/src/app/main/ui/workspace/tokens/context_menu.scss new file mode 100644 index 000000000..6a697ece0 --- /dev/null +++ b/frontend/src/app/main/ui/workspace/tokens/context_menu.scss @@ -0,0 +1,126 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// +// Copyright (c) KALEIDOS INC + +@import "refactor/common-refactor.scss"; + +.token-context-menu { + position: absolute; + top: $s-40; + left: $s-736; + z-index: $z-index-4; +} + +.context-list, +.token-context-submenu { + @include menuShadow; + display: grid; + width: $s-240; + padding: $s-4; + border-radius: $br-8; + border: $s-2 solid var(--panel-border-color); + background-color: var(--menu-background-color); + max-height: 100vh; + overflow-y: auto; +} + +.token-context-submenu { + position: absolute; +} + +.separator { + height: $s-12; +} + +.context-menu-item { + display: flex; + align-items: center; + justify-content: space-between; + height: $s-28; + width: 100%; + padding: $s-6; + border-radius: $br-8; + cursor: pointer; + + .title { + @include bodySmallTypography; + color: var(--menu-foreground-color); + } + .shortcut { + @include flexCenter; + gap: $s-2; + color: var(--menu-shortcut-foreground-color); + .shortcut-key { + @include bodySmallTypography; + @include flexCenter; + height: $s-20; + padding: $s-2 $s-6; + border-radius: $br-6; + background-color: var(--menu-shortcut-background-color); + } + } + + .submenu-icon svg { + @extend .button-icon-small; + stroke: var(--menu-foreground-color); + } + + &:hover { + background-color: var(--menu-background-color-hover); + .title { + color: var(--menu-foreground-color-hover); + } + .shortcut { + color: var(--menu-shortcut-foreground-color-hover); + } + } + &:focus { + border: 1px solid var(--menu-border-color-focus); + background-color: var(--menu-background-color-focus); + } +} + +.icon-menu-item { + display: flex; + justify-content: flex-start; + align-items: center; + height: $s-28; + padding: $s-6; + border-radius: $br-8; + &:hover { + background-color: var(--menu-background-color-hover); + } + + span.title { + margin-left: $s-6; + } + + .selected-icon { + svg { + @extend .button-icon-small; + stroke: var(--menu-foreground-color); + } + } + + .shape-icon { + margin-left: $s-2; + svg { + @extend .button-icon-small; + stroke: var(--menu-foreground-color); + } + } + + .icon-wrapper { + display: grid; + grid-template-columns: 1fr 1fr; + margin: 0; + } +} + +.icon-menu-item[disabled], +.context-menu-item[disabled] { + pointer-events: none; + opacity: 0.6; +} diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index 1aaaaf034..c1eba6e12 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -15,7 +15,7 @@ [app.main.ui.components.search-bar :refer [search-bar]] [app.main.ui.icons :as i] [app.main.ui.workspace.sidebar.assets.common :as cmm] - [app.main.ui.workspace.tokens.common :refer [workspace-shapes]] + [app.main.ui.workspace.tokens.common :as tcm] [app.main.ui.workspace.tokens.core :refer [tokens-applied?] :as wtc] [app.util.dom :as dom] [rumext.v2 :as mf])) @@ -36,18 +36,28 @@ (mf/defc token-pill {::mf/wrap-props false} - [{:keys [on-click token highlighted?]}] + [{:keys [on-click token highlighted? on-context-menu]}] (let [{:keys [name value]} token] [:div {:class (stl/css-case :token-pill true :token-pill-highlighted highlighted?) :title (str "Token value: " value) - :on-click on-click} + :on-click on-click + :on-context-menu on-context-menu} name])) (mf/defc token-component [{:keys [type file tokens selected-shapes token-type-props]}] (let [open? (mf/use-state false) {:keys [modal attributes title]} token-type-props + + on-context-menu (mf/use-fn + (fn [event token] + (dom/prevent-default event) + (dom/stop-propagation event) + (st/emit! (tcm/show-token-context-menu {:type :token + :position (dom/get-client-position event) + :token-id (:id token)})))) + on-toggle-open-click (mf/use-fn (mf/deps open? tokens) #(when (seq tokens) @@ -87,7 +97,8 @@ {:key (:id token) :token token :highlighted? (tokens-applied? token selected-shapes attributes) - :on-click #(on-token-pill-click % token)}])]])]])) + :on-click #(on-token-pill-click % token) + :on-context-menu #(on-context-menu % token)}])]])]])) (defn sorted-token-groups "Separate token-types into groups of `:empty` or `:filled` depending if tokens exist for that type. @@ -114,7 +125,7 @@ token-groups (mf/with-memo [tokens] (sorted-token-groups tokens)) selected-shape-ids (mf/deref refs/selected-shapes) - selected-shapes (workspace-shapes workspace-data current-page-id selected-shape-ids)] + selected-shapes (tcm/workspace-shapes workspace-data current-page-id selected-shape-ids)] [:article [:div.assets-bar (for [{:keys [token-key token-type-props tokens]} (concat (:filled token-groups) From 31b487ed869cd5532abcad49ebed4cd628b9cf4b Mon Sep 17 00:00:00 2001 From: Akshay Gupta Date: Tue, 14 May 2024 18:25:08 +0530 Subject: [PATCH 2/7] remoev translation function --- .../src/app/main/ui/workspace/tokens/context_menu.cljs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) 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 424e56c91..3808f1b0b 100644 --- a/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs @@ -18,7 +18,6 @@ [app.main.ui.icons :as i] [app.main.ui.workspace.tokens.common :refer [hide-token-context-menu]] [app.util.dom :as dom] - [app.util.i18n :refer [tr]] [app.util.timers :as timers] [okulary.core :as l] [rumext.v2 :as mf])) @@ -118,9 +117,9 @@ do-duplicate #(js/console.log "Duplicating") do-edit #(js/console.log "Editing")] [:ul.context-list - [:> token-menu-entry {:title (tr "Delete Token") :on-click do-delete}] - [:> token-menu-entry {:title (tr "Duplicate Token") :on-click do-duplicate}] - [:> token-menu-entry {:title (tr "Edit Token") :on-click do-edit}]])) + [:> token-menu-entry {:title "Delete Token" :on-click do-delete}] + [:> token-menu-entry {:title "Duplicate Token" :on-click do-duplicate}] + [:> token-menu-entry {:title "Edit Token" :on-click do-edit}]])) (mf/defc token-context-menu [] From 8cb9d9c3523139733b494c8744c9ded1987685a5 Mon Sep 17 00:00:00 2001 From: Akshay Gupta Date: Tue, 14 May 2024 18:48:48 +0530 Subject: [PATCH 3/7] Add delete token functionality in context menu --- .../app/main/ui/workspace/tokens/common.cljs | 17 +++++++++++++++- .../ui/workspace/tokens/context_menu.cljs | 20 ++++++++++++------- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/common.cljs b/frontend/src/app/main/ui/workspace/tokens/common.cljs index bf4c29c5e..d53805959 100644 --- a/frontend/src/app/main/ui/workspace/tokens/common.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/common.cljs @@ -8,7 +8,10 @@ (:require-macros [app.main.style :as stl]) (:require [app.common.data.macros :as dm] + [app.common.files.changes-builder :as pcb] [app.common.geom.point :as gpt] + [app.main.data.workspace.changes :as dch] + [beicon.v2.core :as rx] [potok.v2.core :as ptk] [rumext.v2 :as mf])) @@ -57,4 +60,16 @@ (ptk/reify ::hide-token-context-menu ptk/UpdateEvent (update [_ state] - (assoc-in state [:workspace-local :token-context-menu] nil)))) \ No newline at end of file + (assoc-in state [:workspace-local :token-context-menu] nil)))) + +(defn delete-token + [id] + (dm/assert! (uuid? id)) + (ptk/reify ::delete-token + ptk/WatchEvent + (watch [it state _] + (let [data (get state :workspace-data) + changes (-> (pcb/empty-changes it) + (pcb/with-library-data data) + (pcb/delete-token id))] + (rx/of (dch/commit-changes changes)))))) \ No newline at end of file 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 3808f1b0b..8233316aa 100644 --- a/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs @@ -10,13 +10,14 @@ [app.common.data :as d] [app.common.data.macros :as dm] [app.main.data.events :as ev] + [app.main.data.modal :as modal] [app.main.data.shortcuts :as scd] [app.main.data.workspace :as dw] [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.tokens.common :refer [hide-token-context-menu]] + [app.main.ui.workspace.tokens.common :as tcm] [app.util.dom :as dom] [app.util.timers :as timers] [okulary.core :as l] @@ -113,13 +114,18 @@ (mf/defc token-pill-context-menu [{:keys [token-id]}] - (let [do-delete #(js/console.log "Deleting") + (let [delete-fn #(st/emit! (tcm/delete-token token-id)) + do-delete #(st/emit! (modal/show + {:type :confirm + :title "Delete" + :message "Are you sure?" + :on-accept delete-fn})) do-duplicate #(js/console.log "Duplicating") do-edit #(js/console.log "Editing")] [:ul.context-list - [:> token-menu-entry {:title "Delete Token" :on-click do-delete}] - [:> token-menu-entry {:title "Duplicate Token" :on-click do-duplicate}] - [:> token-menu-entry {:title "Edit Token" :on-click do-edit}]])) + [:& token-menu-entry {:title "Delete Token" :on-click do-delete}] + [:& token-menu-entry {:title "Duplicate Token" :on-click do-duplicate}] + [:& token-menu-entry {:title "Edit Token" :on-click do-edit}]])) (mf/defc token-context-menu [] @@ -142,11 +148,11 @@ (.setAttribute ^js dropdown "style" new-style)))))) [:& dropdown {:show (boolean mdata) - :on-close #(st/emit! hide-token-context-menu)} + :on-close #(st/emit! tcm/hide-token-context-menu)} [:div {:class (stl/css :token-context-menu) :ref dropdown-ref :style {:top top :left left} :on-context-menu prevent-default} (when (= :token (:type mdata)) [:ul {:class (stl/css :context-list)} - [:& token-pill-context-menu {:token-id (:id mdata)}]])]])) \ No newline at end of file + [:& token-pill-context-menu {:token-id (:token-id mdata)}]])]])) \ No newline at end of file From fcd7a35b466b62077dcb69dc315ad75951ccbd1c Mon Sep 17 00:00:00 2001 From: Akshay Gupta Date: Wed, 15 May 2024 12:59:18 +0530 Subject: [PATCH 4/7] move context menu functions to data/tokens --- frontend/src/app/main/data/tokens.cljs | 29 +++++++++++++++ .../app/main/ui/workspace/tokens/common.cljs | 36 +------------------ .../ui/workspace/tokens/context_menu.cljs | 6 ++-- .../app/main/ui/workspace/tokens/sidebar.cljs | 10 +++--- 4 files changed, 38 insertions(+), 43 deletions(-) diff --git a/frontend/src/app/main/data/tokens.cljs b/frontend/src/app/main/data/tokens.cljs index e3e16b2d3..ac1be4897 100644 --- a/frontend/src/app/main/data/tokens.cljs +++ b/frontend/src/app/main/data/tokens.cljs @@ -8,6 +8,7 @@ (:require [app.common.data.macros :as dm] [app.common.files.changes-builder :as pcb] + [app.common.geom.point :as gpt] [app.common.types.shape :as cts] [app.common.uuid :as uuid] [app.main.data.workspace.changes :as dch] @@ -108,3 +109,31 @@ (= (toggle-or-apply-token shape-after-token-2-is-applied token-3) shape-after-token-3-is-applied) nil) + +;; Token Context Menu Functions ------------------------------------------------- + +(defn show-token-context-menu + [{:keys [position token-id] :as params}] + (dm/assert! (gpt/point? position)) + (ptk/reify ::show-token-context-menu + ptk/UpdateEvent + (update [_ state] + (assoc-in state [:workspace-local :token-context-menu] params)))) + +(def hide-token-context-menu + (ptk/reify ::hide-token-context-menu + ptk/UpdateEvent + (update [_ state] + (assoc-in state [:workspace-local :token-context-menu] nil)))) + +(defn delete-token + [id] + (dm/assert! (uuid? id)) + (ptk/reify ::delete-token + ptk/WatchEvent + (watch [it state _] + (let [data (get state :workspace-data) + changes (-> (pcb/empty-changes it) + (pcb/with-library-data data) + (pcb/delete-token id))] + (rx/of (dch/commit-changes changes)))))) \ No newline at end of file diff --git a/frontend/src/app/main/ui/workspace/tokens/common.cljs b/frontend/src/app/main/ui/workspace/tokens/common.cljs index d53805959..39fc4f58b 100644 --- a/frontend/src/app/main/ui/workspace/tokens/common.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/common.cljs @@ -7,12 +7,6 @@ (ns app.main.ui.workspace.tokens.common (:require-macros [app.main.style :as stl]) (:require - [app.common.data.macros :as dm] - [app.common.files.changes-builder :as pcb] - [app.common.geom.point :as gpt] - [app.main.data.workspace.changes :as dch] - [beicon.v2.core :as rx] - [potok.v2.core :as ptk] [rumext.v2 :as mf])) ;; Helpers --------------------------------------------------------------------- @@ -44,32 +38,4 @@ [:input {:ref input-ref :default-value default-value :autoFocus auto-focus? - :on-change on-change}]]) - -;; Token Context Menu Functions ------------------------------------------------- - -(defn show-token-context-menu - [{:keys [position token-id] :as params}] - (dm/assert! (gpt/point? position)) - (ptk/reify ::show-token-context-menu - ptk/UpdateEvent - (update [_ state] - (assoc-in state [:workspace-local :token-context-menu] params)))) - -(def hide-token-context-menu - (ptk/reify ::hide-token-context-menu - ptk/UpdateEvent - (update [_ state] - (assoc-in state [:workspace-local :token-context-menu] nil)))) - -(defn delete-token - [id] - (dm/assert! (uuid? id)) - (ptk/reify ::delete-token - ptk/WatchEvent - (watch [it state _] - (let [data (get state :workspace-data) - changes (-> (pcb/empty-changes it) - (pcb/with-library-data data) - (pcb/delete-token id))] - (rx/of (dch/commit-changes changes)))))) \ No newline at end of file + :on-change on-change}]]) \ No newline at end of file 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 8233316aa..f6a9f8d4e 100644 --- a/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs @@ -12,12 +12,12 @@ [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.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.tokens.common :as tcm] [app.util.dom :as dom] [app.util.timers :as timers] [okulary.core :as l] @@ -114,7 +114,7 @@ (mf/defc token-pill-context-menu [{:keys [token-id]}] - (let [delete-fn #(st/emit! (tcm/delete-token token-id)) + (let [delete-fn #(st/emit! (dt/delete-token token-id)) do-delete #(st/emit! (modal/show {:type :confirm :title "Delete" @@ -148,7 +148,7 @@ (.setAttribute ^js dropdown "style" new-style)))))) [:& dropdown {:show (boolean mdata) - :on-close #(st/emit! tcm/hide-token-context-menu)} + :on-close #(st/emit! dt/hide-token-context-menu)} [:div {:class (stl/css :token-context-menu) :ref dropdown-ref :style {:top top :left left} diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index c1eba6e12..f8bdfe226 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -15,7 +15,7 @@ [app.main.ui.components.search-bar :refer [search-bar]] [app.main.ui.icons :as i] [app.main.ui.workspace.sidebar.assets.common :as cmm] - [app.main.ui.workspace.tokens.common :as tcm] + [app.main.ui.workspace.tokens.common :refer [workspace-shapes]] [app.main.ui.workspace.tokens.core :refer [tokens-applied?] :as wtc] [app.util.dom :as dom] [rumext.v2 :as mf])) @@ -54,9 +54,9 @@ (fn [event token] (dom/prevent-default event) (dom/stop-propagation event) - (st/emit! (tcm/show-token-context-menu {:type :token - :position (dom/get-client-position event) - :token-id (:id token)})))) + (st/emit! (dt/show-token-context-menu {:type :token + :position (dom/get-client-position event) + :token-id (:id token)})))) on-toggle-open-click (mf/use-fn (mf/deps open? tokens) @@ -125,7 +125,7 @@ token-groups (mf/with-memo [tokens] (sorted-token-groups tokens)) selected-shape-ids (mf/deref refs/selected-shapes) - selected-shapes (tcm/workspace-shapes workspace-data current-page-id selected-shape-ids)] + selected-shapes (workspace-shapes workspace-data current-page-id selected-shape-ids)] [:article [:div.assets-bar (for [{:keys [token-key token-type-props tokens]} (concat (:filled token-groups) From 316db61c8a12378fc071847df0075c4d8d2a131a Mon Sep 17 00:00:00 2001 From: Akshay Gupta Date: Wed, 15 May 2024 13:23:47 +0530 Subject: [PATCH 5/7] remove warning modal when deletion of a token --- .../src/app/main/ui/workspace/tokens/context_menu.cljs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) 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 f6a9f8d4e..5721e15b5 100644 --- a/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs @@ -10,7 +10,6 @@ [app.common.data :as d] [app.common.data.macros :as dm] [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] @@ -114,12 +113,7 @@ (mf/defc token-pill-context-menu [{:keys [token-id]}] - (let [delete-fn #(st/emit! (dt/delete-token token-id)) - do-delete #(st/emit! (modal/show - {:type :confirm - :title "Delete" - :message "Are you sure?" - :on-accept delete-fn})) + (let [do-delete #(st/emit! (dt/delete-token token-id)) do-duplicate #(js/console.log "Duplicating") do-edit #(js/console.log "Editing")] [:ul.context-list From 5fa2048b234a0d0c119bfcc52563087d0c9d62b4 Mon Sep 17 00:00:00 2001 From: Akshay Gupta Date: Wed, 15 May 2024 14:40:46 +0530 Subject: [PATCH 6/7] re-use workspace context menu entry and fix double nested ul --- .../ui/workspace/tokens/context_menu.cljs | 95 +------------------ .../ui/workspace/tokens/context_menu.scss | 95 ------------------- 2 files changed, 5 insertions(+), 185 deletions(-) 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 5721e15b5..ec4fcb4c2 100644 --- a/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs @@ -17,6 +17,7 @@ [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.util.dom :as dom] [app.util.timers :as timers] [okulary.core :as l] @@ -25,101 +26,15 @@ (def tokens-menu-ref (l/derived :token-context-menu refs/workspace-local)) -(defn- prevent-default - [event] - (dom/prevent-default event) - (dom/stop-propagation event)) - -(mf/defc token-menu-entry - {::mf/props :obj} - [{:keys [title shortcut on-click on-pointer-enter on-pointer-leave - on-unmount children selected? icon disabled value]}] - (let [submenu-ref (mf/use-ref nil) - hovering? (mf/use-ref false) - on-pointer-enter - (mf/use-callback - (fn [] - (mf/set-ref-val! hovering? true) - (let [submenu-node (mf/ref-val submenu-ref)] - (when (some? submenu-node) - (dom/set-css-property! submenu-node "display" "block"))) - (when on-pointer-enter (on-pointer-enter)))) - - on-pointer-leave - (mf/use-callback - (fn [] - (mf/set-ref-val! hovering? false) - (let [submenu-node (mf/ref-val submenu-ref)] - (when (some? submenu-node) - (timers/schedule - 200 - #(when-not (mf/ref-val hovering?) - (dom/set-css-property! submenu-node "display" "none"))))) - (when on-pointer-leave (on-pointer-leave)))) - - set-dom-node - (mf/use-callback - (fn [dom] - (let [submenu-node (mf/ref-val submenu-ref)] - (when (and (some? dom) (some? submenu-node)) - (dom/set-css-property! submenu-node "top" (str (.-offsetTop dom) "px"))))))] - - (mf/use-effect - (mf/deps on-unmount) - (constantly on-unmount)) - - (if icon - [:li {:class (stl/css :icon-menu-item) - :disabled disabled - :data-value value - :ref set-dom-node - :on-click on-click - :on-pointer-enter on-pointer-enter - :on-pointer-leave on-pointer-leave} - [:span - {:class (stl/css :icon-wrapper)} - (if selected? [:span {:class (stl/css :selected-icon)} - i/tick] - [:span {:class (stl/css :selected-icon)}]) - [:span {:class (stl/css :shape-icon)} icon]] - [:span {:class (stl/css :title)} title]] - [:li {:class (stl/css :context-menu-item) - :disabled disabled - :ref set-dom-node - :data-value value - :on-click on-click - :on-pointer-enter on-pointer-enter - :on-pointer-leave on-pointer-leave} - [:span {:class (stl/css :title)} title] - (when shortcut - [:span {:class (stl/css :shortcut)} - (for [[idx sc] (d/enumerate (scd/split-sc shortcut))] - [:span {:key (dm/str shortcut "-" idx) - :class (stl/css :shortcut-key)} sc])]) - - (when (> (count children) 1) - [:span {:class (stl/css :submenu-icon)} i/arrow]) - - (when (> (count children) 1) - [:ul {:class (stl/css :token-context-submenu) - :ref submenu-ref - :style {:display "none" :left 250} - :on-context-menu prevent-default} - children])]))) - -(mf/defc menu-separator - [] - [:li {:class (stl/css :separator)}]) - (mf/defc token-pill-context-menu [{:keys [token-id]}] (let [do-delete #(st/emit! (dt/delete-token token-id)) do-duplicate #(js/console.log "Duplicating") do-edit #(js/console.log "Editing")] - [:ul.context-list - [:& token-menu-entry {:title "Delete Token" :on-click do-delete}] - [:& token-menu-entry {:title "Duplicate Token" :on-click do-duplicate}] - [:& token-menu-entry {:title "Edit Token" :on-click do-edit}]])) + [:* + [:& 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}]])) (mf/defc token-context-menu [] diff --git a/frontend/src/app/main/ui/workspace/tokens/context_menu.scss b/frontend/src/app/main/ui/workspace/tokens/context_menu.scss index 6a697ece0..49fe69662 100644 --- a/frontend/src/app/main/ui/workspace/tokens/context_menu.scss +++ b/frontend/src/app/main/ui/workspace/tokens/context_menu.scss @@ -29,98 +29,3 @@ .token-context-submenu { position: absolute; } - -.separator { - height: $s-12; -} - -.context-menu-item { - display: flex; - align-items: center; - justify-content: space-between; - height: $s-28; - width: 100%; - padding: $s-6; - border-radius: $br-8; - cursor: pointer; - - .title { - @include bodySmallTypography; - color: var(--menu-foreground-color); - } - .shortcut { - @include flexCenter; - gap: $s-2; - color: var(--menu-shortcut-foreground-color); - .shortcut-key { - @include bodySmallTypography; - @include flexCenter; - height: $s-20; - padding: $s-2 $s-6; - border-radius: $br-6; - background-color: var(--menu-shortcut-background-color); - } - } - - .submenu-icon svg { - @extend .button-icon-small; - stroke: var(--menu-foreground-color); - } - - &:hover { - background-color: var(--menu-background-color-hover); - .title { - color: var(--menu-foreground-color-hover); - } - .shortcut { - color: var(--menu-shortcut-foreground-color-hover); - } - } - &:focus { - border: 1px solid var(--menu-border-color-focus); - background-color: var(--menu-background-color-focus); - } -} - -.icon-menu-item { - display: flex; - justify-content: flex-start; - align-items: center; - height: $s-28; - padding: $s-6; - border-radius: $br-8; - &:hover { - background-color: var(--menu-background-color-hover); - } - - span.title { - margin-left: $s-6; - } - - .selected-icon { - svg { - @extend .button-icon-small; - stroke: var(--menu-foreground-color); - } - } - - .shape-icon { - margin-left: $s-2; - svg { - @extend .button-icon-small; - stroke: var(--menu-foreground-color); - } - } - - .icon-wrapper { - display: grid; - grid-template-columns: 1fr 1fr; - margin: 0; - } -} - -.icon-menu-item[disabled], -.context-menu-item[disabled] { - pointer-events: none; - opacity: 0.6; -} From d3d454a43c1f2428dfac73b866e49b07333e4239 Mon Sep 17 00:00:00 2001 From: Akshay Gupta Date: Wed, 15 May 2024 14:50:24 +0530 Subject: [PATCH 7/7] move delete token to tokens actions section --- frontend/src/app/main/data/tokens.cljs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/frontend/src/app/main/data/tokens.cljs b/frontend/src/app/main/data/tokens.cljs index ac1be4897..503941a8b 100644 --- a/frontend/src/app/main/data/tokens.cljs +++ b/frontend/src/app/main/data/tokens.cljs @@ -75,6 +75,18 @@ (pcb/add-token token))] (rx/of (dch/commit-changes changes))))))) +(defn delete-token + [id] + (dm/assert! (uuid? id)) + (ptk/reify ::delete-token + ptk/WatchEvent + (watch [it state _] + (let [data (get state :workspace-data) + changes (-> (pcb/empty-changes it) + (pcb/with-library-data data) + (pcb/delete-token id))] + (rx/of (dch/commit-changes changes)))))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; TEMP (Move to test) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -125,15 +137,3 @@ ptk/UpdateEvent (update [_ state] (assoc-in state [:workspace-local :token-context-menu] nil)))) - -(defn delete-token - [id] - (dm/assert! (uuid? id)) - (ptk/reify ::delete-token - ptk/WatchEvent - (watch [it state _] - (let [data (get state :workspace-data) - changes (-> (pcb/empty-changes it) - (pcb/with-library-data data) - (pcb/delete-token id))] - (rx/of (dch/commit-changes changes)))))) \ No newline at end of file