mirror of
https://github.com/penpot/penpot.git
synced 2025-01-06 14:50:20 -05:00
Merge pull request #97 from tokens-studio/simple-context-menu
Simple context menu
This commit is contained in:
commit
d4dd49bdb7
7 changed files with 149 additions and 6 deletions
|
@ -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]
|
||||
|
@ -74,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)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -108,3 +121,19 @@
|
|||
(= (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))))
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -38,4 +38,4 @@
|
|||
[:input {:ref input-ref
|
||||
:default-value default-value
|
||||
:autoFocus auto-focus?
|
||||
:on-change on-change}]])
|
||||
:on-change on-change}]])
|
67
frontend/src/app/main/ui/workspace/tokens/context_menu.cljs
Normal file
67
frontend/src/app/main/ui/workspace/tokens/context_menu.cljs
Normal file
|
@ -0,0 +1,67 @@
|
|||
;; 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.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.context-menu :refer [menu-entry prevent-default]]
|
||||
[app.util.dom :as dom]
|
||||
[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))
|
||||
|
||||
(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")]
|
||||
[:*
|
||||
[:& 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
|
||||
[]
|
||||
(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! dt/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 (:token-id mdata)}]])]]))
|
31
frontend/src/app/main/ui/workspace/tokens/context_menu.scss
Normal file
31
frontend/src/app/main/ui/workspace/tokens/context_menu.scss
Normal file
|
@ -0,0 +1,31 @@
|
|||
// 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;
|
||||
}
|
|
@ -19,16 +19,17 @@
|
|||
|
||||
(mf/defc token-pill
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [on-click token highlighted?]}]
|
||||
(let [{:keys [name value]} token
|
||||
[{:keys [on-click token highlighted? on-context-menu]}]
|
||||
(let [{:keys [name value]} token]
|
||||
resolved-value (try
|
||||
(wtc/resolve-token-value token)
|
||||
(catch js/Error _ nil))]
|
||||
[:div {:class (stl/css-case :token-pill true
|
||||
:token-pill-highlighted highlighted?
|
||||
:token-pill-highlighted highlighted?)
|
||||
:token-pill-invalid (not resolved-value))
|
||||
:title (str (if resolved-value "Token value: " "Invalid token value: ") value)
|
||||
:on-click on-click}
|
||||
:on-click on-click
|
||||
:on-context-menu on-context-menu}
|
||||
name]))
|
||||
|
||||
(mf/defc token-section-icon
|
||||
|
@ -53,6 +54,15 @@
|
|||
[{: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! (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)
|
||||
#(when (seq tokens)
|
||||
|
@ -96,7 +106,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.
|
||||
|
|
Loading…
Reference in a new issue