mirror of
https://github.com/penpot/penpot.git
synced 2026-08-06 04:48:39 +00:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
f76710296c
@ -20,7 +20,9 @@
|
|||||||
[app.common.path-names :as cpn]
|
[app.common.path-names :as cpn]
|
||||||
[app.common.transit :as t]
|
[app.common.transit :as t]
|
||||||
[app.common.types.component :as ctc]
|
[app.common.types.component :as ctc]
|
||||||
|
[app.common.types.components-list :as ctkl]
|
||||||
[app.common.types.shape :as cts]
|
[app.common.types.shape :as cts]
|
||||||
|
[app.common.types.variant :as ctv]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
[app.main.data.comments :as dcmt]
|
[app.main.data.comments :as dcmt]
|
||||||
@ -551,7 +553,6 @@
|
|||||||
component-id (:component-id shape)
|
component-id (:component-id shape)
|
||||||
undo-id (js/Symbol)]
|
undo-id (js/Symbol)]
|
||||||
|
|
||||||
|
|
||||||
(when valid?
|
(when valid?
|
||||||
(if (ctc/is-variant-container? shape)
|
(if (ctc/is-variant-container? shape)
|
||||||
;; Rename the full variant when it is a variant container
|
;; Rename the full variant when it is a variant container
|
||||||
@ -566,6 +567,43 @@
|
|||||||
(dwl/rename-component component-id clean-name))
|
(dwl/rename-component component-id clean-name))
|
||||||
(dwu/commit-undo-transaction undo-id))))))))))
|
(dwu/commit-undo-transaction undo-id))))))))))
|
||||||
|
|
||||||
|
(defn rename-shape-or-variant
|
||||||
|
([id name]
|
||||||
|
(rename-shape-or-variant nil nil id name))
|
||||||
|
([file-id page-id id name]
|
||||||
|
(ptk/reify ::rename-shape-or-variant
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ state _]
|
||||||
|
(let [file-id (d/nilv file-id (:current-file-id state))
|
||||||
|
page-id (d/nilv page-id (:current-page-id state))
|
||||||
|
|
||||||
|
file-data (dsh/lookup-file-data state file-id)
|
||||||
|
shape
|
||||||
|
(-> (dsh/lookup-page-objects state file-id page-id)
|
||||||
|
(get id))
|
||||||
|
|
||||||
|
is-variant? (ctc/is-variant? shape)
|
||||||
|
variant-id (when is-variant? (:variant-id shape))
|
||||||
|
variant-name (when is-variant? (:variant-name shape))
|
||||||
|
component-id (:component-id shape)
|
||||||
|
component (ctkl/get-component file-data (:component-id shape))
|
||||||
|
variant-properties (:variant-properties component)]
|
||||||
|
(cond
|
||||||
|
(and variant-name (ctv/valid-properties-formula? name))
|
||||||
|
(rx/of (dwva/update-properties-names-and-values
|
||||||
|
component-id variant-id variant-properties (ctv/properties-formula->map name))
|
||||||
|
(dwva/remove-empty-properties variant-id)
|
||||||
|
(dwva/update-error component-id))
|
||||||
|
|
||||||
|
variant-name
|
||||||
|
(rx/of (dwva/update-properties-names-and-values
|
||||||
|
component-id variant-id variant-properties {})
|
||||||
|
(dwva/remove-empty-properties variant-id)
|
||||||
|
(dwva/update-error component-id name))
|
||||||
|
|
||||||
|
:else
|
||||||
|
(rx/of (end-rename-shape id name))))))))
|
||||||
|
|
||||||
;; --- Update Selected Shapes attrs
|
;; --- Update Selected Shapes attrs
|
||||||
|
|
||||||
(defn update-selected-shapes
|
(defn update-selected-shapes
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
[app.main.ui.components.dropdown :refer [dropdown-content*]]
|
[app.main.ui.components.dropdown :refer [dropdown-content*]]
|
||||||
[app.main.ui.icons :as deprecated-icon]
|
[app.main.ui.icons :as deprecated-icon]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
|
[app.util.globals :as ug]
|
||||||
[app.util.i18n :as i18n :refer [tr]]
|
[app.util.i18n :as i18n :refer [tr]]
|
||||||
[app.util.keyboard :as kbd]
|
[app.util.keyboard :as kbd]
|
||||||
[app.util.timers :as tm]
|
[app.util.timers :as tm]
|
||||||
@ -53,14 +54,13 @@
|
|||||||
(def ^:private valid-option?
|
(def ^:private valid-option?
|
||||||
(sm/lazy-validator schema:option))
|
(sm/lazy-validator schema:option))
|
||||||
|
|
||||||
(mf/defc context-menu*
|
(mf/defc context-menu-inner*
|
||||||
[{:keys [show on-close options selectable selected
|
[{:keys [on-close options selectable selected
|
||||||
top left fixed min-width origin width]
|
top left fixed min-width origin width]
|
||||||
:as props}]
|
:as props}]
|
||||||
|
|
||||||
(assert (every? valid-option? options) "expected valid options")
|
(assert (every? valid-option? options) "expected valid options")
|
||||||
(assert (fn? on-close) "missing `on-close` prop")
|
(assert (fn? on-close) "missing `on-close` prop")
|
||||||
(assert (boolean? show) "missing `show` prop")
|
|
||||||
(assert (vector? options) "missing `options` prop")
|
(assert (vector? options) "missing `options` prop")
|
||||||
|
|
||||||
(let [width (d/nilv width "initial")
|
(let [width (d/nilv width "initial")
|
||||||
@ -80,14 +80,15 @@
|
|||||||
offset-x (get state :offset-x)
|
offset-x (get state :offset-x)
|
||||||
offset-y (get state :offset-y)
|
offset-y (get state :offset-y)
|
||||||
levels (get state :levels)
|
levels (get state :levels)
|
||||||
|
internal-id (mf/use-id)
|
||||||
|
|
||||||
on-local-close
|
on-local-close
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps on-close)
|
(mf/deps on-close)
|
||||||
(fn []
|
(fn []
|
||||||
(swap! state* assoc :levels [{:parent nil
|
(swap! state* assoc :levels [{:parent nil :options options}])
|
||||||
:options options}])
|
(when (fn? on-close)
|
||||||
(on-close)))
|
(on-close))))
|
||||||
|
|
||||||
props
|
props
|
||||||
(mf/spread-props props {:on-close on-local-close})
|
(mf/spread-props props {:on-close on-local-close})
|
||||||
@ -216,11 +217,22 @@
|
|||||||
(swap! state* assoc :levels [{:parent nil
|
(swap! state* assoc :levels [{:parent nil
|
||||||
:options options}]))
|
:options options}]))
|
||||||
|
|
||||||
|
(mf/with-effect [internal-id]
|
||||||
|
(ug/dispatch! (ug/event "penpot:context-menu:open" #js {:id internal-id})))
|
||||||
|
|
||||||
|
(mf/with-effect [internal-id on-local-close]
|
||||||
|
(letfn [(on-event [event]
|
||||||
|
(when-let [detail (unchecked-get event "detail")]
|
||||||
|
(when (not= internal-id (unchecked-get detail "id"))
|
||||||
|
(on-local-close event))))]
|
||||||
|
(ug/listen "penpot:context-menu:open" on-event)
|
||||||
|
(partial ug/unlisten "penpot:context-menu:open" on-event)))
|
||||||
|
|
||||||
(mf/with-effect [ids]
|
(mf/with-effect [ids]
|
||||||
(tm/schedule-on-idle
|
(tm/schedule-on-idle
|
||||||
#(dom/focus! (dom/get-element (first ids)))))
|
#(dom/focus! (dom/get-element (first ids)))))
|
||||||
|
|
||||||
(when (and show (some? levels))
|
(when (some? levels)
|
||||||
[:> dropdown-content* props
|
[:> dropdown-content* props
|
||||||
(let [level (peek levels)
|
(let [level (peek levels)
|
||||||
options (:options level)
|
options (:options level)
|
||||||
@ -229,7 +241,7 @@
|
|||||||
[:div {:class (stl/css-case
|
[:div {:class (stl/css-case
|
||||||
:is-selectable selectable
|
:is-selectable selectable
|
||||||
:context-menu true
|
:context-menu true
|
||||||
:is-open show
|
:is-open true
|
||||||
:fixed fixed)
|
:fixed fixed)
|
||||||
:style {:top (+ top offset-y)
|
:style {:top (+ top offset-y)
|
||||||
:left (+ left offset-x)}
|
:left (+ left offset-x)}
|
||||||
@ -241,7 +253,7 @@
|
|||||||
:role "menu"
|
:role "menu"
|
||||||
:ref check-menu-offscreen}
|
:ref check-menu-offscreen}
|
||||||
|
|
||||||
(when-let [parent (:parent level)]
|
(when parent
|
||||||
[:*
|
[:*
|
||||||
[:li {:id "go-back-sub-option"
|
[:li {:id "go-back-sub-option"
|
||||||
:class (stl/css :context-menu-item)
|
:class (stl/css :context-menu-item)
|
||||||
@ -256,7 +268,7 @@
|
|||||||
|
|
||||||
[:li {:class (stl/css :separator)}]])
|
[:li {:class (stl/css :separator)}]])
|
||||||
|
|
||||||
(for [[index option] (d/enumerate (:options level))]
|
(for [[index option] (d/enumerate options)]
|
||||||
(let [name (:name option)
|
(let [name (:name option)
|
||||||
id (:id option)
|
id (:id option)
|
||||||
sub-options (:options option)
|
sub-options (:options option)
|
||||||
@ -297,3 +309,12 @@
|
|||||||
:data-testid id}
|
:data-testid id}
|
||||||
name
|
name
|
||||||
[:span {:class (stl/css :submenu-icon)} deprecated-icon/arrow]])]))))]])])))
|
[:span {:class (stl/css :submenu-icon)} deprecated-icon/arrow]])]))))]])])))
|
||||||
|
|
||||||
|
(mf/defc context-menu*
|
||||||
|
{::mf/private true}
|
||||||
|
[{:keys [show] :as props}]
|
||||||
|
|
||||||
|
(assert (boolean? show) "expected `show` prop to be a boolean")
|
||||||
|
|
||||||
|
(when ^boolean show
|
||||||
|
[:> context-menu-inner* props]))
|
||||||
|
|||||||
@ -11,7 +11,6 @@
|
|||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.types.variant :as ctv]
|
[app.common.types.variant :as ctv]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
[app.main.data.workspace.variants :as dwv]
|
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.util.debug :as dbg]
|
[app.util.debug :as dbg]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
@ -69,15 +68,7 @@
|
|||||||
name (str/trim (dom/get-value name-input))]
|
name (str/trim (dom/get-value name-input))]
|
||||||
(on-stop-edit)
|
(on-stop-edit)
|
||||||
(reset! edition* false)
|
(reset! edition* false)
|
||||||
(if variant-name
|
(st/emit! (dw/rename-shape-or-variant shape-id name)))))
|
||||||
(if (ctv/valid-properties-formula? name)
|
|
||||||
(st/emit! (dwv/update-properties-names-and-values component-id variant-id variant-properties (ctv/properties-formula->map name))
|
|
||||||
(dwv/remove-empty-properties variant-id)
|
|
||||||
(dwv/update-error component-id))
|
|
||||||
(st/emit! (dwv/update-properties-names-and-values component-id variant-id variant-properties {})
|
|
||||||
(dwv/remove-empty-properties variant-id)
|
|
||||||
(dwv/update-error component-id name)))
|
|
||||||
(st/emit! (dw/end-rename-shape shape-id name))))))
|
|
||||||
|
|
||||||
cancel-edit
|
cancel-edit
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
|||||||
@ -217,7 +217,7 @@
|
|||||||
(u/display-not-valid :name value)
|
(u/display-not-valid :name value)
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(st/emit! (dw/end-rename-shape id value)))))}
|
(st/emit! (dw/rename-shape-or-variant file-id page-id id value)))))}
|
||||||
|
|
||||||
:blocked
|
:blocked
|
||||||
{:this true
|
{:this true
|
||||||
|
|||||||
@ -35,14 +35,26 @@ goog.scope(function () {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
self.event = function(...args) {
|
self.event = function(name, detail) {
|
||||||
return new CustomEvent(...args);
|
const options = {};
|
||||||
|
if (detail !== undefined) {
|
||||||
|
options.detail = detail;
|
||||||
|
}
|
||||||
|
return new CustomEvent(name, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
self.dispatch_BANG_ = function(...args) {
|
self.dispatch_BANG_ = function(...args) {
|
||||||
self.document.dispatchEvent(...args);
|
self.document.dispatchEvent(...args);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.listen = function(...args) {
|
||||||
|
self.document.addEventListener(...args);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.unlisten = function(...args) {
|
||||||
|
self.document.removeEventListener(...args);
|
||||||
|
}
|
||||||
|
|
||||||
self.window = (function () {
|
self.window = (function () {
|
||||||
if (typeof goog.global.window !== "undefined") {
|
if (typeof goog.global.window !== "undefined") {
|
||||||
return goog.global.window;
|
return goog.global.window;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user