Merge pull request #5605 from penpot/niwinz-enhancements-2

 Add performance enhacements
This commit is contained in:
Aitor Moreno 2025-01-20 13:22:07 +01:00 committed by GitHub
commit 013a8c95df
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
37 changed files with 547 additions and 485 deletions

View file

@ -79,7 +79,6 @@
[component new-component-id library-data] [component new-component-id library-data]
(let [components-v2 (dm/get-in library-data [:options :components-v2])] (let [components-v2 (dm/get-in library-data [:options :components-v2])]
(if components-v2 (if components-v2
(let [main-instance-page (ctf/get-component-page library-data component) (let [main-instance-page (ctf/get-component-page library-data component)
main-instance-shape (ctf/get-component-root library-data component) main-instance-shape (ctf/get-component-root library-data component)
delta (gpt/point (+ (:width main-instance-shape) 50) 0) delta (gpt/point (+ (:width main-instance-shape) 50) 0)
@ -205,21 +204,23 @@
(cond-> {} (cond-> {}
force-frame? (assoc :force-frame-id frame-id))) force-frame? (assoc :force-frame-id frame-id)))
first-shape (cond-> (first new-shapes) first-shape
(not (nil? parent-id)) (cond-> (first new-shapes)
(assoc :parent-id parent-id) (not (nil? parent-id))
(and (not (nil? parent)) (= :frame (:type parent))) (assoc :parent-id parent-id)
(assoc :frame-id (:id parent)) (and (not (nil? parent)) (= :frame (:type parent)))
(and (not (nil? parent)) (not= :frame (:type parent))) (assoc :frame-id (:id parent))
(assoc :frame-id (:frame-id parent)) (and (not (nil? parent)) (not= :frame (:type parent)))
(and (not (nil? parent)) (ctn/in-any-component? objects parent)) (assoc :frame-id (:frame-id parent))
(dissoc :component-root) (and (not (nil? parent)) (ctn/in-any-component? objects parent))
(and (nil? parent) (not (nil? frame-id))) (dissoc :component-root)
(assoc :frame-id frame-id)) (and (nil? parent) (not (nil? frame-id)))
(assoc :frame-id frame-id))
;; on copy/paste old id is used later to reorder the paster layers ;; on copy/paste old id is used later to reorder the paster layers
changes (cond-> (pcb/add-object changes first-shape {:ignore-touched true}) changes
(some? old-id) (pcb/amend-last-change #(assoc % :old-id old-id))) (cond-> (pcb/add-object changes first-shape {:ignore-touched true})
(some? old-id) (pcb/amend-last-change #(assoc % :old-id old-id)))
changes changes
(if (ctl/grid-layout? objects (:parent-id first-shape)) (if (ctl/grid-layout? objects (:parent-id first-shape))
@ -240,9 +241,10 @@
(pcb/reorder-grid-children [(:parent-id first-shape)]))) (pcb/reorder-grid-children [(:parent-id first-shape)])))
changes) changes)
changes (reduce #(pcb/add-object %1 %2 {:ignore-touched true}) changes
changes (reduce #(pcb/add-object %1 %2 {:ignore-touched true})
(rest new-shapes))] changes
(rest new-shapes))]
[new-shape changes]))) [new-shape changes])))
@ -1488,7 +1490,7 @@
(defn- update-tokens (defn- update-tokens
"Token synchronization algorithm. Copy the applied tokens that have changed "Token synchronization algorithm. Copy the applied tokens that have changed
in the origin shape to the dest shape (applying or removing as necessary). in the origin shape to the dest shape (applying or removing as necessary).
Only the given token attributes are synced." Only the given token attributes are synced."
[changes container dest-shape orig-shape token-attrs] [changes container dest-shape orig-shape token-attrs]
(let [orig-tokens (get orig-shape :applied-tokens {}) (let [orig-tokens (get orig-shape :applied-tokens {})

View file

@ -115,6 +115,9 @@
(sm/register! ::recent-color schema:recent-color) (sm/register! ::recent-color schema:recent-color)
(sm/register! ::color-attrs schema:color-attrs) (sm/register! ::color-attrs schema:color-attrs)
(def valid-color?
(sm/lazy-validator schema:color))
(def check-color! (def check-color!
(sm/check-fn schema:color :hint "expected valid color struct")) (sm/check-fn schema:color :hint "expected valid color struct"))
@ -143,7 +146,6 @@
;; --- fill ;; --- fill
;; FIXME: revisit, this generates invalid colors
(defn fill->shape-color (defn fill->shape-color
[fill] [fill]
(d/without-nils (d/without-nils
@ -154,16 +156,6 @@
:ref-id (:fill-color-ref-id fill) :ref-id (:fill-color-ref-id fill)
:ref-file (:fill-color-ref-file fill)})) :ref-file (:fill-color-ref-file fill)}))
(defn fill->color
[fill]
(d/without-nils
{:color (:fill-color fill)
:opacity (:fill-opacity fill)
:gradient (:fill-color-gradient fill)
:image (:fill-image fill)
:id (:fill-color-ref-id fill)
:file-id (:fill-color-ref-file fill)}))
(defn set-fill-color (defn set-fill-color
[shape position color opacity gradient image] [shape position color opacity gradient image]
(update-in shape [:fills position] (update-in shape [:fills position]

View file

@ -464,8 +464,8 @@
Returns a list ((asset ((container shapes) (container shapes)...))...)" Returns a list ((asset ((container shapes) (container shapes)...))...)"
[file-data library-data asset-type] [file-data library-data asset-type]
(let [assets-seq (case asset-type (let [assets-seq (case asset-type
:component (ctkl/components-seq library-data) :component (ctkl/components-seq library-data)
:color (ctcl/colors-seq library-data) :color (ctcl/colors-seq library-data)
:typography (ctyl/typographies-seq library-data)) :typography (ctyl/typographies-seq library-data))
find-usages-in-container find-usages-in-container

View file

@ -0,0 +1,65 @@
;; 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 common-tests.helpers-test
(:require
[app.common.data :as d]
[app.common.test-helpers.components :as thc]
[app.common.test-helpers.compositions :as tho]
[app.common.test-helpers.files :as thf]
[app.common.test-helpers.ids-map :as thi]
[app.common.test-helpers.shapes :as ths]
[clojure.test :as t]))
(t/use-fixtures :each thi/test-fixture)
(t/deftest create-file
(let [f1 (thf/sample-file :file1)
f2 (thf/sample-file :file2 :page-label :page1)
f3 (thf/sample-file :file3 :name "testing file")
f4 (-> (thf/sample-file :file4 :page-label :page2)
(thf/add-sample-page :page3 :name "testing page")
(ths/add-sample-shape :shape1))
f5 (-> f4
(ths/add-sample-shape :shape2)
(thf/switch-to-page :page2)
(ths/add-sample-shape :shape3 :name "testing shape" :width 100))
s1 (ths/get-shape f4 :shape1)
s2 (ths/get-shape f5 :shape2 :page-label :page3)
s3 (ths/get-shape f5 :shape3)]
;; (thf/pprint-file f4)
(t/is (= (:name f1) "Test file"))
(t/is (= (:name f3) "testing file"))
(t/is (= (:id f2) (thi/id :file2)))
(t/is (= (:id f4) (thi/id :file4)))
(t/is (= (-> f4 :data :pages-index vals first :id) (thi/id :page2)))
(t/is (= (-> f4 :data :pages-index vals first :name) "Page 1"))
(t/is (= (-> f4 :data :pages-index vals second :id) (thi/id :page3)))
(t/is (= (-> f4 :data :pages-index vals second :name) "testing page"))
(t/is (= (:id (thf/current-page f2)) (thi/id :page1)))
(t/is (= (:id (thf/current-page f4)) (thi/id :page3)))
(t/is (= (:id (thf/current-page f5)) (thi/id :page2)))
(t/is (= (:id s1) (thi/id :shape1)))
(t/is (= (:name s1) "Rectangle"))
(t/is (= (:id s2) (thi/id :shape2)))
(t/is (= (:name s2) "Rectangle"))
(t/is (= (:id s3) (thi/id :shape3)))
(t/is (= (:name s3) "testing shape"))
(t/is (= (:width s3) 100))
(t/is (= (:width (:selrect s3)) 100))))
(t/deftest create-components
(let [f1 (-> (thf/sample-file :file1)
(tho/add-simple-component-with-copy :component1 :main-root :main-child :copy-root))]
#_(thf/dump-file f1)
#_(thf/pprint-file f4)
(t/is (= (:name f1) "Test file"))))

View file

@ -35,12 +35,12 @@
[common-tests.svg-test] [common-tests.svg-test]
[common-tests.text-test] [common-tests.text-test]
[common-tests.time-test] [common-tests.time-test]
[common-tests.types-modifiers-test] [common-tests.types.absorb-assets-test]
[common-tests.types-shape-interactions-test] [common-tests.types.components-test]
[common-tests.types.modifiers-test]
[common-tests.types.shape-decode-encode-test] [common-tests.types.shape-decode-encode-test]
[common-tests.types.shape-interactions-test]
[common-tests.types.tokens-lib-test] [common-tests.types.tokens-lib-test]
[common-tests.types.types-component-test]
[common-tests.types.types-libraries-test]
[common-tests.uuid-test])) [common-tests.uuid-test]))
#?(:cljs (enable-console-print!)) #?(:cljs (enable-console-print!))
@ -82,10 +82,10 @@
'common-tests.svg-test 'common-tests.svg-test
'common-tests.text-test 'common-tests.text-test
'common-tests.time-test 'common-tests.time-test
'common-tests.types-modifiers-test 'common-tests.types.modifiers-test
'common-tests.types-shape-interactions-test 'common-tests.types.shape-interactions-test
'common-tests.types.shape-decode-encode-test 'common-tests.types.shape-decode-encode-test
'common-tests.types.tokens-lib-test 'common-tests.types.tokens-lib-test
'common-tests.types.types-component-test 'common-tests.types.components-test
'common-tests.types.types-libraries-test 'common-tests.types.absorb-assets-test
'common-tests.uuid-test)) 'common-tests.uuid-test))

View file

@ -4,7 +4,7 @@
;; ;;
;; Copyright (c) KALEIDOS INC ;; Copyright (c) KALEIDOS INC
(ns common-tests.types.types-libraries-test (ns common-tests.types.absorb-assets-test
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.test-helpers.components :as thc] [app.common.test-helpers.components :as thc]
@ -23,55 +23,7 @@
(t/use-fixtures :each thi/test-fixture) (t/use-fixtures :each thi/test-fixture)
(t/deftest test-create-file (t/deftest absorb-components
(let [f1 (thf/sample-file :file1)
f2 (thf/sample-file :file2 :page-label :page1)
f3 (thf/sample-file :file3 :name "testing file")
f4 (-> (thf/sample-file :file4 :page-label :page2)
(thf/add-sample-page :page3 :name "testing page")
(ths/add-sample-shape :shape1))
f5 (-> f4
(ths/add-sample-shape :shape2)
(thf/switch-to-page :page2)
(ths/add-sample-shape :shape3 :name "testing shape" :width 100))
s1 (ths/get-shape f4 :shape1)
s2 (ths/get-shape f5 :shape2 :page-label :page3)
s3 (ths/get-shape f5 :shape3)]
;; (thf/pprint-file f4)
(t/is (= (:name f1) "Test file"))
(t/is (= (:name f3) "testing file"))
(t/is (= (:id f2) (thi/id :file2)))
(t/is (= (:id f4) (thi/id :file4)))
(t/is (= (-> f4 :data :pages-index vals first :id) (thi/id :page2)))
(t/is (= (-> f4 :data :pages-index vals first :name) "Page 1"))
(t/is (= (-> f4 :data :pages-index vals second :id) (thi/id :page3)))
(t/is (= (-> f4 :data :pages-index vals second :name) "testing page"))
(t/is (= (:id (thf/current-page f2)) (thi/id :page1)))
(t/is (= (:id (thf/current-page f4)) (thi/id :page3)))
(t/is (= (:id (thf/current-page f5)) (thi/id :page2)))
(t/is (= (:id s1) (thi/id :shape1)))
(t/is (= (:name s1) "Rectangle"))
(t/is (= (:id s2) (thi/id :shape2)))
(t/is (= (:name s2) "Rectangle"))
(t/is (= (:id s3) (thi/id :shape3)))
(t/is (= (:name s3) "testing shape"))
(t/is (= (:width s3) 100))
(t/is (= (:width (:selrect s3)) 100))))
(t/deftest test-create-components
(let [f1 (-> (thf/sample-file :file1)
(tho/add-simple-component-with-copy :component1 :main-root :main-child :copy-root))]
#_(thf/dump-file f1)
#_(thf/pprint-file f4)
(t/is (= (:name f1) "Test file"))))
(t/deftest test-absorb-components
(let [;; Setup (let [;; Setup
library (-> (thf/sample-file :library :is-shared true) library (-> (thf/sample-file :library :is-shared true)
(tho/add-simple-component :component1 :main-root :rect1)) (tho/add-simple-component :component1 :main-root :rect1))
@ -105,7 +57,7 @@
(t/is (ctk/is-main-of? main-root' copy-root' true)) (t/is (ctk/is-main-of? main-root' copy-root' true))
(t/is (ctk/main-instance-of? (:id main-root') (:id (second pages')) component')))) (t/is (ctk/main-instance-of? (:id main-root') (:id (second pages')) component'))))
(t/deftest test-absorb-colors (t/deftest absorb-colors
(let [;; Setup (let [;; Setup
library (-> (thf/sample-file :library :is-shared true) library (-> (thf/sample-file :library :is-shared true)
(ths/add-sample-library-color :color1 {:name "Test color" (ths/add-sample-library-color :color1 {:name "Test color"
@ -142,7 +94,7 @@
(t/is (= (:fill-color-ref-id fill') (thi/id :color1))) (t/is (= (:fill-color-ref-id fill') (thi/id :color1)))
(t/is (= (:fill-color-ref-file fill') (:id file'))))) (t/is (= (:fill-color-ref-file fill') (:id file')))))
(t/deftest test-absorb-typographies (t/deftest absorb-typographies
(let [;; Setup (let [;; Setup
library (-> (thf/sample-file :library :is-shared true) library (-> (thf/sample-file :library :is-shared true)
(ths/add-sample-typography :typography1 {:name "Test typography"})) (ths/add-sample-typography :typography1 {:name "Test typography"}))

View file

@ -4,7 +4,7 @@
;; ;;
;; Copyright (c) KALEIDOS INC ;; Copyright (c) KALEIDOS INC
(ns common-tests.types.types-component-test (ns common-tests.types.components-test
(:require (:require
[app.common.test-helpers.ids-map :as thi] [app.common.test-helpers.ids-map :as thi]
[app.common.test-helpers.shapes :as ths] [app.common.test-helpers.shapes :as ths]

View file

@ -4,14 +4,14 @@
;; ;;
;; Copyright (c) KALEIDOS INC ;; Copyright (c) KALEIDOS INC
(ns common-tests.types-modifiers-test (ns common-tests.types.modifiers-test
(:require (:require
[app.common.geom.matrix :as gmt] [app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
[app.common.types.modifiers :as ctm] [app.common.types.modifiers :as ctm]
[clojure.test :as t])) [clojure.test :as t]))
(t/deftest test-modifiers->transform (t/deftest modifiers->transform
(let [modifiers (let [modifiers
(-> (ctm/empty) (-> (ctm/empty)
(ctm/move (gpt/point 100 200)) (ctm/move (gpt/point 100 200))

View file

@ -4,7 +4,7 @@
;; ;;
;; Copyright (c) KALEIDOS INC ;; Copyright (c) KALEIDOS INC
(ns common-tests.types-shape-interactions-test (ns common-tests.types.shape-interactions-test
(:require (:require
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
@ -50,7 +50,6 @@
(t/is (= :after-delay (:event-type new-interaction))) (t/is (= :after-delay (:event-type new-interaction)))
(t/is (= 300 (:delay new-interaction))))))) (t/is (= 300 (:delay new-interaction)))))))
(t/deftest set-action-type (t/deftest set-action-type
(let [interaction ctsi/default-interaction] (let [interaction ctsi/default-interaction]

View file

@ -89,7 +89,7 @@
text-ids (filter is-text? ids) text-ids (filter is-text? ids)
shape-ids (remove is-text? ids) shape-ids (remove is-text? ids)
undo-id (js/Symbol) undo-id (js/Symbol)
attrs attrs
(cond-> {} (cond-> {}
@ -146,7 +146,8 @@
(rx/of (dwsh/update-shapes shape-ids transform-attrs))))))) (rx/of (dwsh/update-shapes shape-ids transform-attrs)))))))
(defn change-fill (defn change-fill
([ids color position] (change-fill ids color position nil)) ([ids color position]
(change-fill ids color position nil))
([ids color position options] ([ids color position options]
(ptk/reify ::change-fill (ptk/reify ::change-fill
ptk/WatchEvent ptk/WatchEvent

View file

@ -29,7 +29,7 @@
[app.main.ui.workspace.nudge] [app.main.ui.workspace.nudge]
[app.main.ui.workspace.palette :refer [palette]] [app.main.ui.workspace.palette :refer [palette]]
[app.main.ui.workspace.plugins] [app.main.ui.workspace.plugins]
[app.main.ui.workspace.sidebar :refer [left-sidebar right-sidebar]] [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.collapsable-button :refer [collapsed-button]]
[app.main.ui.workspace.sidebar.history :refer [history-toolbox*]] [app.main.ui.workspace.sidebar.history :refer [history-toolbox*]]
[app.main.ui.workspace.tokens.modals] [app.main.ui.workspace.tokens.modals]
@ -111,14 +111,14 @@
[:* [:*
(if (:collapse-left-sidebar layout) (if (:collapse-left-sidebar layout)
[:& collapsed-button] [:& collapsed-button]
[:& left-sidebar {:layout layout [:> left-sidebar* {:layout layout
:file file
:page-id page-id}])
[:> right-sidebar* {:section options-mode
:selected selected
:layout layout
:file file :file file
:page-id page-id}]) :page-id page-id}]])]))
[:& right-sidebar {:section options-mode
:selected selected
:layout layout
:file file
:page-id page-id}]])]))
(mf/defc workspace-loader* (mf/defc workspace-loader*
{::mf/private true} {::mf/private true}

View file

@ -8,19 +8,21 @@
(:require-macros [app.main.style :as stl]) (:require-macros [app.main.style :as stl])
(:require (:require
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
[app.common.types.color :as ctc]
[app.main.data.event :as ev] [app.main.data.event :as ev]
[app.main.data.workspace.colors :as mdc] [app.main.data.workspace.colors :as mdc]
[app.main.data.workspace.libraries :as dwl] [app.main.data.workspace.libraries :as dwl]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.color-bullet :as cb] [app.main.ui.components.color-bullet :as cb]
[app.main.ui.hooks :as h] [app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.util.color :as uc] [app.util.color :as uc]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :refer [tr]] [app.util.i18n :refer [tr]]
[app.util.keyboard :as kbd] [app.util.keyboard :as kbd]
[app.util.object :as obj] [app.util.object :as obj]
[okulary.core :as l]
[potok.v2.core :as ptk] [potok.v2.core :as ptk]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
@ -48,25 +50,23 @@
[:& cb/color-name {:color color :size size :origin :palette}]])) [:& cb/color-name {:color color :size size :origin :palette}]]))
(mf/defc palette* (mf/defc palette*
[{:keys [current-colors size width selected]}] [{:keys [colors size width selected]}]
(let [;; We had to do this due to a bug that leave some bugged colors (let [state (mf/use-state #(do {:show-menu false}))
current-colors (h/use-equal-memo (filter #(or (:gradient %) (:color %) (:image %)) current-colors)) offset-step (cond
state (mf/use-state {:show-menu false}) (<= size 64) 40
offset-step (cond (<= size 80) 72
(<= size 64) 40 :else 72)
(<= size 80) 72
:else 72)
buttons-size (cond buttons-size (cond
(<= size 64) 164 (<= size 64) 164
:else 132) :else 132)
width (- width buttons-size) width (- width buttons-size)
visible (int (/ width offset-step)) visible (int (/ width offset-step))
show-arrows? (> (count current-colors) visible) show-arrows? (> (count colors) visible)
visible (if show-arrows? visible (if show-arrows?
(int (/ (- width 48) offset-step)) (int (/ (- width 48) offset-step))
visible) visible)
offset (:offset @state 0) offset (:offset @state 0)
max-offset (- (count current-colors) max-offset (- (count colors)
visible) visible)
container (mf/use-ref nil) container (mf/use-ref nil)
bullet-size (cond bullet-size (cond
@ -79,7 +79,7 @@
:else 64) :else 64)
on-left-arrow-click on-left-arrow-click
(mf/use-callback (mf/use-fn
(mf/deps max-offset visible) (mf/deps max-offset visible)
(fn [_] (fn [_]
(swap! state update :offset (swap! state update :offset
@ -89,7 +89,7 @@
offset))))) offset)))))
on-right-arrow-click on-right-arrow-click
(mf/use-callback (mf/use-fn
(mf/deps max-offset visible) (mf/deps max-offset visible)
(fn [_] (fn [_]
(swap! state update :offset (swap! state update :offset
@ -99,7 +99,7 @@
offset))))) offset)))))
on-scroll on-scroll
(mf/use-callback (mf/use-fn
(mf/deps max-offset) (mf/deps max-offset)
(fn [event] (fn [event]
(let [event (dom/event->native-event event) (let [event (dom/event->native-event event)
@ -109,12 +109,12 @@
(on-right-arrow-click event) (on-right-arrow-click event)
(on-left-arrow-click event)))))] (on-left-arrow-click event)))))]
(mf/use-layout-effect (mf/with-layout-effect []
#(let [dom (mf/ref-val container) (let [dom (mf/ref-val container)
width (obj/get dom "clientWidth")] width (obj/get dom "clientWidth")]
(swap! state assoc :width width))) (swap! state assoc :width width)))
(mf/with-effect [width current-colors] (mf/with-effect [width colors]
(when (not= 0 (:offset @state)) (when (not= 0 (:offset @state))
(swap! state assoc :offset 0))) (swap! state assoc :offset 0)))
@ -126,10 +126,10 @@
[:button {:class (stl/css :left-arrow) [:button {:class (stl/css :left-arrow)
:disabled (= offset 0) :disabled (= offset 0)
:on-click on-left-arrow-click} i/arrow]) :on-click on-left-arrow-click} i/arrow])
[:div {:class (stl/css :color-palette-content) [:div {:class (stl/css :color-palette-content)
:ref container :ref container
:on-wheel on-scroll} :on-wheel on-scroll}
(if (empty? current-colors) (if (empty? colors)
[:div {:class (stl/css :color-palette-empty) [:div {:class (stl/css :color-palette-empty)
:style {:position "absolute" :style {:position "absolute"
:left "50%" :left "50%"
@ -140,44 +140,61 @@
:style {:position "relative" :style {:position "relative"
:max-width (str width "px") :max-width (str width "px")
:right (str (* offset-step offset) "px")}} :right (str (* offset-step offset) "px")}}
(for [[idx item] (map-indexed vector current-colors)] (for [[idx item] (map-indexed vector colors)]
[:> palette-item* {:color item :key idx :size size :selected selected}])])] [:> palette-item* {:color item :key idx :size size :selected selected}])])]
(when show-arrows? (when show-arrows?
[:button {:class (stl/css :right-arrow) [:button {:class (stl/css :right-arrow)
:disabled (= offset max-offset) :disabled (= offset max-offset)
:on-click on-right-arrow-click} i/arrow])])) :on-click on-right-arrow-click} i/arrow])]))
(defn library->colors [shared-libs selected] (mf/defc recent-colors-palette*
(map #(merge % {:file-id selected}) {::mf/private true}
(-> shared-libs [props]
(get-in [selected :data :colors]) (let [colors (mf/deref refs/recent-colors)
(vals))))
(mf/defc color-palette colors (mf/with-memo [colors]
(->> (reverse colors)
(filter ctc/valid-color?)
(vec)))
props (mf/spread-props props {:colors colors})]
[:> palette* props]))
(defn- make-library-colors-ref
[file-id]
(l/derived (fn [libraries]
(dm/get-in libraries [file-id :data :colors]))
refs/libraries))
(mf/defc file-color-palette*
{::mf/private true}
[{:keys [file-id] :as props}]
(let [colors-ref (mf/with-memo [file-id]
(make-library-colors-ref file-id))
colors (mf/deref colors-ref)
colors (mf/with-memo [colors file-id]
(->> (vals colors)
(filter ctc/valid-color?)
(map #(assoc % :file-id file-id))
(sort-by :name)
(vec)))
props (mf/spread-props props {:colors colors})]
[:> palette* props]))
(mf/defc color-palette*
{::mf/wrap [mf/memo]} {::mf/wrap [mf/memo]}
[{:keys [size width selected] :as props}] [{:keys [selected] :as props}]
(let [recent-colors (mf/deref refs/recent-colors) (let [file-id (mf/use-ctx ctx/current-file-id)]
file-colors (mf/deref refs/workspace-file-colors) (cond
shared-libs (mf/deref refs/libraries) (= selected :recent)
colors (mf/use-state [])] [:> recent-colors-palette* props]
(mf/with-effect [selected shared-libs] (= selected :file)
(let [colors' (cond (let [props (mf/spread-props props {:file-id file-id})]
(= selected :recent) (reverse recent-colors) [:> file-color-palette* props])
(= selected :file) (->> (vals file-colors) (sort-by :name))
:else (->> (library->colors shared-libs selected) (sort-by :name)))]
(reset! colors (into [] colors'))))
(mf/with-effect [recent-colors selected] :else
(when (= selected :recent) (let [props (mf/spread-props props {:file-id selected})]
(reset! colors (reverse recent-colors)))) [:> file-color-palette* props]))))
(mf/with-effect [file-colors selected]
(when (= selected :file)
(reset! colors (into [] (->> (vals file-colors)
(sort-by :name))))))
[:> palette* {:current-colors @colors
:size size
:width width
:selected selected}]))

View file

@ -74,6 +74,8 @@
.color-palette-content { .color-palette-content {
overflow: hidden; overflow: hidden;
display: flex;
align-items: center;
} }
.color-palette-inside { .color-palette-inside {

View file

@ -11,45 +11,73 @@
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.ui.components.color-bullet :as cb] [app.main.ui.components.color-bullet :as cb]
[app.main.ui.components.dropdown :refer [dropdown]] [app.main.ui.components.dropdown :refer [dropdown]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.util.i18n :refer [tr]] [app.util.i18n :refer [tr]]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(mf/defc color-palette-ctx-menu (def ^:private xf:sample-colors
[{:keys [show-menu? close-menu on-select-palette selected]}] (comp (map val)
(let [recent-colors (mf/deref refs/recent-colors) (take 7)))
file-colors (mf/deref refs/workspace-file-colors)
shared-libs (mf/deref refs/libraries)]
[:& dropdown {:show show-menu?
:on-close close-menu}
[:ul {:class (stl/css :palette-menu)}
(for [{:keys [data id] :as library} (vals shared-libs)]
(let [colors (-> data :colors vals)]
[:li {:class (stl/css-case :palette-library true
:selected (= selected id))
:key (dm/str "library-" id)
:on-click on-select-palette
:data-palette (dm/str id)}
[:div {:class (stl/css :option-wrapper)}
[:div {:class (stl/css :library-name)}
[:div {:class (stl/css :lib-name-wrapper)}
[:span {:class (stl/css :lib-name)}
(dm/str (:name library))]
[:span {:class (stl/css :lib-num)}
(dm/str "(" (count colors) ")")]]
(when (= selected id)
[:span {:class (stl/css :icon-wrapper)}
i/tick])]
[:div {:class (stl/css :color-sample)
:style #js {"--bullet-size" "20px"}}
(for [[i {:keys [color id gradient]}] (map-indexed vector (take 7 colors))]
[:& cb/color-bullet {:key (dm/str "color-" i)
:mini true
:color {:color color :id id :gradient gradient}}])]]]))
[:li {:class (stl/css-case :file-library true (defn- extract-colors
:selected (= selected :file)) [{:keys [data] :as file}]
:on-click on-select-palette (let [colors (into [] xf:sample-colors (:colors data))]
(-> file
(assoc :colors colors)
(dissoc :data))))
(mf/defc color-palette-ctx-menu*
[{:keys [show on-close on-select selected]}]
(let [recent-colors (mf/deref refs/recent-colors)
libraries (mf/deref refs/libraries)
file-id (mf/use-ctx ctx/current-file-id)
local-colors (mf/with-memo [libraries file-id]
(let [colors (dm/get-in libraries [file-id :data :colors])]
(into [] xf:sample-colors colors)))
libraries (mf/with-memo [libraries file-id]
(->> (dissoc libraries file-id)
(vals)
(mapv extract-colors)))
recent-colors (mf/with-memo [recent-colors]
(->> (reverse recent-colors)
(take 7)
(map-indexed (fn [index color]
(assoc color ::id (dm/str index))))
(vec)))]
[:& dropdown {:show show :on-close on-close}
[:ul {:class (stl/css :palette-menu)}
(for [{:keys [id colors] :as library} libraries]
[:li {:class (stl/css-case :palette-library true
:selected (= selected id))
:key (dm/str "library-" id)
:on-click on-select
:data-palette (dm/str id)}
[:div {:class (stl/css :option-wrapper)}
[:div {:class (stl/css :library-name)}
[:div {:class (stl/css :lib-name-wrapper)}
[:span {:class (stl/css :lib-name)}
(dm/str (:name library))]
[:span {:class (stl/css :lib-num)}
(dm/str "(" (count colors) ")")]]
(when (= selected id)
[:span {:class (stl/css :icon-wrapper)}
i/tick])]
[:div {:class (stl/css :color-sample)
:style {:--bullet-size "20px"}}
(for [color colors]
[:& cb/color-bullet {:key (dm/str (:id color))
:mini true
:color color}])]]])
[:li {:class (stl/css-case
:file-library true
:selected (= selected :file))
:on-click on-select
:data-palette "file"} :data-palette "file"}
[:div {:class (stl/css :option-wrapper)} [:div {:class (stl/css :option-wrapper)}
@ -59,21 +87,22 @@
[:span {:class (stl/css :lib-name)} [:span {:class (stl/css :lib-name)}
(dm/str (tr "workspace.libraries.colors.file-library"))] (dm/str (tr "workspace.libraries.colors.file-library"))]
[:span {:class (stl/css :lib-num)} [:span {:class (stl/css :lib-num)}
(dm/str "(" (count file-colors) ")")]] (dm/str "(" (count local-colors) ")")]]
(when (= selected :file) (when (= selected :file)
[:span {:class (stl/css :icon-wrapper)} [:span {:class (stl/css :icon-wrapper)}
i/tick])] i/tick])]
[:div {:class (stl/css :color-sample) [:div {:class (stl/css :color-sample)
:style #js {"--bullet-size" "20px"}} :style {:--bullet-size "20px"}}
(for [[i color] (map-indexed vector (take 7 (vals file-colors)))] (for [color local-colors]
[:& cb/color-bullet {:key (dm/str "color-" i) [:& cb/color-bullet {:key (dm/str (:id color))
:mini true :mini true
:color color}])]]] :color color}])]]]
[:li {:class (stl/css :recent-colors true [:li {:class (stl/css
:selected (= selected :recent)) :recent-colors true
:on-click on-select-palette :selected (= selected :recent))
:on-click on-select
:data-palette "recent"} :data-palette "recent"}
[:div {:class (stl/css :option-wrapper)} [:div {:class (stl/css :option-wrapper)}
[:div {:class (stl/css :library-name)} [:div {:class (stl/css :library-name)}
@ -87,8 +116,9 @@
[:span {:class (stl/css :icon-wrapper)} [:span {:class (stl/css :icon-wrapper)}
i/tick])] i/tick])]
[:div {:class (stl/css :color-sample) [:div {:class (stl/css :color-sample)
:style #js {"--bullet-size" "20px"}} :style {:--bullet-size "20px"}}
(for [[idx color] (map-indexed vector (take 7 (reverse recent-colors)))]
[:& cb/color-bullet {:key (str "color-" idx) (for [color recent-colors]
[:& cb/color-bullet {:key (dm/str (::id color))
:mini true :mini true
:color color}])]]]]])) :color color}])]]]]]))

View file

@ -10,6 +10,7 @@
[app.common.colors :as c] [app.common.colors :as c]
[app.common.data :as d] [app.common.data :as d]
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
[app.common.types.color :as ctc]
[app.main.data.event :as ev] [app.main.data.event :as ev]
[app.main.data.workspace :as dw] [app.main.data.workspace :as dw]
[app.main.data.workspace.colors :as mdc] [app.main.data.workspace.colors :as mdc]
@ -17,6 +18,7 @@
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.color-bullet :as cb] [app.main.ui.components.color-bullet :as cb]
[app.main.ui.components.select :refer [select]] [app.main.ui.components.select :refer [select]]
[app.main.ui.context :as ctx]
[app.main.ui.hooks :as h] [app.main.ui.hooks :as h]
[app.main.ui.hooks.resize :as r] [app.main.ui.hooks.resize :as r]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
@ -27,103 +29,107 @@
(mf/defc libraries (mf/defc libraries
[{:keys [state on-select-color on-add-library-color disable-gradient disable-opacity disable-image]}] [{:keys [state on-select-color on-add-library-color disable-gradient disable-opacity disable-image]}]
(let [selected (h/use-shared-state mdc/colorpicker-selected-broadcast-key :recent) (let [selected* (h/use-shared-state mdc/colorpicker-selected-broadcast-key :recent)
current-colors (mf/use-state []) selected (deref selected*)
shared-libs (mf/deref refs/libraries) file-id (mf/use-ctx ctx/current-file-id)
file-colors (mf/deref refs/workspace-file-colors)
current-colors* (mf/use-state [])
current-colors (deref current-colors*)
libraries (mf/deref refs/libraries)
recent-colors (mf/deref refs/recent-colors) recent-colors (mf/deref refs/recent-colors)
recent-colors (h/use-equal-memo (filter #(or (:gradient %) (:color %) (:image %)) recent-colors)) recent-colors (mf/with-memo [recent-colors]
(filterv ctc/valid-color? recent-colors))
library-options
(mf/with-memo []
[{:value "recent" :label (tr "workspace.libraries.colors.recent-colors")}
{:value "file" :label (tr "workspace.libraries.colors.file-library")}])
options
(mf/with-memo [library-options file-id]
(into library-options
(comp
(map val)
(map (fn [lib] {:value (d/name (:id lib)) :label (:name lib)})))
(dissoc libraries file-id)))
on-library-change on-library-change
(mf/use-fn (mf/use-fn
(fn [event] (fn [event]
(reset! selected (reset! selected*
(if (or (= event "recent") (if (or (= event "recent")
(= event "file")) (= event "file"))
(keyword event) (keyword event)
(parse-uuid event))))) (parse-uuid event)))))
check-valid-color? valid-color?
(mf/use-fn (mf/use-fn
(mf/deps disable-gradient disable-opacity disable-image)
(fn [color] (fn [color]
(and (or (not disable-gradient) (not (:gradient color))) (and (or (not disable-gradient) (not (:gradient color)))
(or (not disable-opacity) (= 1 (:opacity color))) (or (not disable-opacity) (= 1 (:opacity color)))
(or (not disable-image) (not (:image color)))))) (or (not disable-image) (not (:image color))))))
;; Sort colors by hue and lightness
get-sorted-colors
(mf/use-fn
(fn [colors]
(sort c/sort-colors (into [] (filter check-valid-color?) colors))))
toggle-palette toggle-palette
(mf/use-fn (mf/use-fn
(mf/deps @selected) (mf/deps selected)
(fn [] (fn []
(r/set-resize-type! :bottom) (r/set-resize-type! :bottom)
(dom/add-class! (dom/get-element-by-class "color-palette") "fade-out-down") (dom/add-class! (dom/get-element-by-class "color-palette") "fade-out-down")
(st/emit! (dw/remove-layout-flag :textpalette) (st/emit! (dw/remove-layout-flag :textpalette)
(-> (mdc/show-palette @selected) (-> (mdc/show-palette selected)
(vary-meta assoc ::ev/origin "workspace-colorpicker"))))) (vary-meta assoc ::ev/origin "workspace-colorpicker")))))
shared-libs-options (mapv (fn [lib] {:value (d/name (:id lib)) :label (:name lib)}) (vals shared-libs))
library-options [{:value "recent" :label (tr "workspace.libraries.colors.recent-colors")}
{:value "file" :label (tr "workspace.libraries.colors.file-library")}]
options (concat library-options shared-libs-options)
on-color-click on-color-click
(mf/use-fn (mf/use-fn
(mf/deps state @selected) (mf/deps state selected on-select-color)
(fn [event] (fn [event]
(when-not (= :recent @selected) (when-not (= :recent selected)
(st/emit! (ptk/event (st/emit! (ptk/event
::ev/event ::ev/event
{::ev/name "use-library-color" {::ev/name "use-library-color"
::ev/origin "colorpicker" ::ev/origin "colorpicker"
:external-library (not= :file @selected)}))) :external-library (not= :file selected)})))
(on-select-color state event)))] (on-select-color state event)))]
;; Load library colors when the select is changed ;; Load library colors when the select is changed
(mf/with-effect [@selected recent-colors file-colors] (mf/with-effect [selected recent-colors libraries file-id valid-color?]
(let [colors (cond (let [file-id (if (= selected :file)
(= @selected :recent) file-id
;; The `map?` check is to keep backwards compatibility. We transform from string to map selected)
(map #(if (map? %) % {:color %}) (reverse (or recent-colors [])))
(= @selected :file) colors (if (= selected :recent)
(->> (vals file-colors) (sort-by :name)) ;; NOTE: The `map?` check is to keep backwards
;; compatibility We transform from string to map
(->> (reverse recent-colors)
(filter valid-color?)
(map-indexed (fn [index color]
(let [color (if (map? color) color {:color color})]
(assoc color ::id (dm/str index)))))
(sort c/sort-colors))
(->> (dm/get-in libraries [file-id :data :colors])
(vals)
(filter valid-color?)
(map-indexed (fn [index color]
(-> color
(assoc :file-id file-id)
(assoc ::id (dm/str index)))))
(sort-by :name)))]
:else ;; Library UUID (reset! current-colors* colors)))
(as-> @selected file-id
(->> (get-in shared-libs [file-id :data :colors])
(vals)
(sort-by :name)
(map #(assoc % :file-id file-id)))))]
(if (not= @selected :recent)
(reset! current-colors (get-sorted-colors colors))
(reset! current-colors (into [] (filter check-valid-color? colors))))))
;; If the file colors change and the file option is selected updates the state
(mf/with-effect [file-colors]
(when (= @selected :file)
(let [colors (vals file-colors)]
(reset! current-colors (get-sorted-colors colors)))))
[:div {:class (stl/css :libraries)} [:div {:class (stl/css :libraries)}
[:div {:class (stl/css :select-wrapper)} [:div {:class (stl/css :select-wrapper)}
[:& select [:& select
{:class (stl/css :shadow-type-select) {:class (stl/css :shadow-type-select)
:default-value (or (name @selected) "recent") :default-value (or (d/name selected) "recent")
:options options :options options
:on-change on-library-change}]] :on-change on-library-change}]]
[:div {:class (stl/css :selected-colors)} [:div {:class (stl/css :selected-colors)}
(when (= @selected :file) (when (= selected :file)
[:button {:class (stl/css :add-color-btn) [:button {:class (stl/css :add-color-btn)
:on-click on-add-library-color} :on-click on-add-library-color}
i/add]) i/add])
@ -132,8 +138,8 @@
:on-click toggle-palette} :on-click toggle-palette}
i/swatches] i/swatches]
(for [[idx color] (map-indexed vector @current-colors)] (for [color current-colors]
[:& cb/color-bullet [:& cb/color-bullet
{:key (dm/str "color-" idx) {:key (dm/str "color-" (::id color))
:color color :color color
:on-click on-color-click}])]])) :on-click on-color-click}])]]))

View file

@ -19,8 +19,8 @@
[app.main.ui.hooks :as h] [app.main.ui.hooks :as h]
[app.main.ui.hooks.resize :as r] [app.main.ui.hooks.resize :as r]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.workspace.color-palette :refer [color-palette]] [app.main.ui.workspace.color-palette :refer [color-palette*]]
[app.main.ui.workspace.color-palette-ctx-menu :refer [color-palette-ctx-menu]] [app.main.ui.workspace.color-palette-ctx-menu :refer [color-palette-ctx-menu*]]
[app.main.ui.workspace.text-palette :refer [text-palette]] [app.main.ui.workspace.text-palette :refer [text-palette]]
[app.main.ui.workspace.text-palette-ctx-menu :refer [text-palette-ctx-menu]] [app.main.ui.workspace.text-palette-ctx-menu :refer [text-palette-ctx-menu]]
[app.util.dom :as dom] [app.util.dom :as dom]
@ -195,13 +195,14 @@
:selected selected-text :selected selected-text
:width vport-width}]]) :width vport-width}]])
(when color-palette? (when color-palette?
[:* [:& color-palette-ctx-menu {:show-menu? show-menu? [:*
:close-menu on-close-menu [:> color-palette-ctx-menu* {:show show-menu?
:on-select-palette on-select-palette :on-close on-close-menu
:selected @selected}] :on-select on-select-palette
[:& color-palette {:size size :selected @selected}]
:selected @selected [:> color-palette* {:size size
:width vport-width}]])]] :selected @selected
:width vport-width}]])]]
[:div {:class (stl/css :handler) [:div {:class (stl/css :handler)
:on-click toggle-palettes :on-click toggle-palettes
:data-testid "toggle-palettes-visibility"} :data-testid "toggle-palettes-visibility"}

View file

@ -48,7 +48,7 @@
:size "s" :size "s"
:aria-label (tr "workspace.sidebar.collapse")}]]) :aria-label (tr "workspace.sidebar.collapse")}]])
(mf/defc left-sidebar (mf/defc left-sidebar*
{::mf/wrap [mf/memo] {::mf/wrap [mf/memo]
::mf/props :obj} ::mf/props :obj}
[{:keys [layout file page-id] :as props}] [{:keys [layout file page-id] :as props}]
@ -179,9 +179,8 @@
;; --- Right Sidebar (Component) ;; --- Right Sidebar (Component)
(mf/defc right-sidebar (mf/defc right-sidebar*
{::mf/wrap-props false {::mf/wrap [mf/memo]}
::mf/wrap [mf/memo]}
[{:keys [layout section file page-id] :as props}] [{:keys [layout section file page-id] :as props}]
(let [drawing-tool (:tool (mf/deref refs/workspace-drawing)) (let [drawing-tool (:tool (mf/deref refs/workspace-drawing))

View file

@ -64,19 +64,6 @@
(:color color) (:color color) (:color color) (:color color)
:else (:value color)) :else (:value color))
apply-color
(mf/use-fn
(mf/deps color)
(fn [event]
(st/emit!
(dwl/add-recent-color color)
(dc/apply-color-from-palette color (kbd/alt? event))
(ptk/event
::ev/event
{::ev/name "use-library-color"
::ev/origin "sidebar"
:external-library (not local?)}))))
rename-color rename-color
(mf/use-fn (mf/use-fn
(mf/deps file-id color-id) (mf/deps file-id color-id)
@ -189,10 +176,17 @@
on-click on-click
(mf/use-fn (mf/use-fn
(mf/deps color-id apply-color on-asset-click read-only?) (mf/deps color on-asset-click read-only?)
(when-not read-only? (fn [event]
(dwl/add-recent-color color) (when-not read-only?
(partial on-asset-click color-id apply-color)))] (st/emit! (ptk/data-event ::ev/event
{::ev/name "use-library-color"
::ev/origin "sidebar"
:external-library (not local?)}))
(when-not (on-asset-click event (:id color))
(st/emit! (dwl/add-recent-color color)
(dc/apply-color-from-palette color (kbd/alt? event)))))))]
(mf/with-effect [editing?] (mf/with-effect [editing?]
(when editing? (when editing?

View file

@ -71,17 +71,13 @@
[root-shape container] [root-shape container]
(get-component-root-and-container file-id component) (get-component-root-and-container file-id component)
unselect-all
(mf/use-fn
(fn []
(st/emit! (dw/unselect-all-assets))))
on-component-click on-component-click
(mf/use-fn (mf/use-fn
(mf/deps component-id on-asset-click) (mf/deps component-id on-asset-click)
(fn [event] (fn [event]
(dom/stop-propagation event) (dom/stop-propagation event)
(on-asset-click component-id unselect-all event))) (when-not (on-asset-click event component-id)
(st/emit! (dw/unselect-all-assets)))))
on-component-double-click on-component-double-click
(mf/use-fn (mf/use-fn

View file

@ -196,21 +196,19 @@
on-asset-click on-asset-click
(mf/use-fn (mf/use-fn
(mf/deps file-id selected) (mf/deps file-id selected)
(fn [asset-type asset-groups asset-id default-click event] (fn [asset-type asset-groups event asset-id]
(cond (cond
(kbd/mod? event) (kbd/mod? event)
(do (do
(dom/stop-propagation event) (dom/stop-propagation event)
(st/emit! (dw/toggle-selected-assets file-id asset-id asset-type))) (st/emit! (dw/toggle-selected-assets file-id asset-id asset-type))
true)
(kbd/shift? event) (kbd/shift? event)
(do (do
(dom/stop-propagation event) (dom/stop-propagation event)
(extend-selected selected asset-type asset-groups asset-id file-id)) (extend-selected selected asset-type asset-groups asset-id file-id)
true))))
:else
(when default-click
(default-click event)))))
on-component-click on-component-click
(mf/use-fn (mf/deps on-asset-click) (partial on-asset-click :components)) (mf/use-fn (mf/deps on-asset-click) (partial on-asset-click :components))

View file

@ -82,7 +82,9 @@
on-asset-click on-asset-click
(mf/use-fn (mf/use-fn
(mf/deps object-id on-asset-click) (mf/deps object-id on-asset-click)
(partial on-asset-click object-id nil))] (fn [event]
(on-asset-click event object-id)))]
[:div {:ref item-ref [:div {:ref item-ref
:class-name (stl/css-case :class-name (stl/css-case
:selected (contains? selected-objects object-id) :selected (contains? selected-objects object-id)

View file

@ -39,7 +39,7 @@
(mf/defc typography-item (mf/defc typography-item
{::mf/wrap-props false} {::mf/wrap-props false}
[{:keys [typography file-id local? handle-change selected apply-typography editing-id renaming-id on-asset-click [{:keys [typography file-id local? handle-change selected editing-id renaming-id on-asset-click
on-context-menu selected-full selected-paths move-typography rename?]}] on-context-menu selected-full selected-paths move-typography rename?]}]
(let [item-ref (mf/use-ref) (let [item-ref (mf/use-ref)
typography-id (:id typography) typography-id (:id typography)
@ -91,26 +91,17 @@
(mf/deps typography) (mf/deps typography)
(partial handle-change typography)) (partial handle-change typography))
apply-typography
(mf/use-fn
(mf/deps typography)
(partial apply-typography typography))
on-asset-click on-asset-click
(mf/use-fn (mf/use-fn
(mf/deps typography apply-typography on-asset-click) (mf/deps typography on-asset-click read-only? local?)
(partial on-asset-click typography-id apply-typography)) (fn [event]
(when-not read-only?
on-click (st/emit! (ptk/data-event ::ev/event
(mf/use-fn {::ev/name "use-library-typography"
(mf/deps typography apply-typography on-asset-click) ::ev/origin "sidebar"
(fn [ev] :external-library (not local?)}))
(st/emit! (ptk/event (when-not (on-asset-click event (:id typography))
::ev/event (st/emit! (dwt/apply-typography typography file-id))))))]
{::ev/name "use-library-typography"
::ev/origin "sidebar"
:external-library (not local?)}))
(on-asset-click ev)))]
[:div {:class (stl/css :typography-item) [:div {:class (stl/css :typography-item)
:ref item-ref :ref item-ref
@ -126,7 +117,7 @@
:typography typography :typography typography
:local? local? :local? local?
:selected? (contains? selected typography-id) :selected? (contains? selected typography-id)
:on-click on-click :on-click on-asset-click
:on-change handle-change :on-change handle-change
:on-context-menu on-context-menu :on-context-menu on-context-menu
:editing? editing? :editing? editing?
@ -139,7 +130,7 @@
(mf/defc typographies-group (mf/defc typographies-group
{::mf/wrap-props false} {::mf/wrap-props false}
[{:keys [file-id prefix groups open-groups force-open? file local? selected local-data [{:keys [file-id prefix groups open-groups force-open? file local? selected local-data
editing-id renaming-id on-asset-click handle-change apply-typography on-rename-group editing-id renaming-id on-asset-click handle-change on-rename-group
on-ungroup on-context-menu selected-full]}] on-ungroup on-context-menu selected-full]}]
(let [group-open? (if (false? (get open-groups prefix)) ;; if the user has closed it specifically, respect that (let [group-open? (if (false? (get open-groups prefix)) ;; if the user has closed it specifically, respect that
false false
@ -208,7 +199,6 @@
:local? local? :local? local?
:handle-change handle-change :handle-change handle-change
:selected selected :selected selected
:apply-typography apply-typography
:editing-id editing-id :editing-id editing-id
:renaming-id renaming-id :renaming-id renaming-id
:rename? (= (:rename-typography local-data) id) :rename? (= (:rename-typography local-data) id)
@ -234,7 +224,6 @@
:local-data local-data :local-data local-data
:on-asset-click on-asset-click :on-asset-click on-asset-click
:handle-change handle-change :handle-change handle-change
:apply-typography apply-typography
:on-rename-group on-rename-group :on-rename-group on-rename-group
:on-ungroup on-ungroup :on-ungroup on-ungroup
:on-context-menu on-context-menu :on-context-menu on-context-menu
@ -284,13 +273,6 @@
(fn [typography changes] (fn [typography changes]
(st/emit! (dwl/update-typography (merge typography changes) file-id)))) (st/emit! (dwl/update-typography (merge typography changes) file-id))))
apply-typography
(mf/use-fn
(mf/deps file-id read-only?)
(fn [typography _event]
(when-not read-only?
(st/emit! (dwt/apply-typography typography file-id)))))
create-group create-group
(mf/use-fn (mf/use-fn
(mf/deps typographies selected on-clear-selection file-id (:id @state)) (mf/deps typographies selected on-clear-selection file-id (:id @state))
@ -438,7 +420,6 @@
:local-data local-data :local-data local-data
:on-asset-click on-asset-click :on-asset-click on-asset-click
:handle-change handle-change :handle-change handle-change
:apply-typography apply-typography
:on-rename-group on-rename-group :on-rename-group on-rename-group
:on-ungroup on-ungroup :on-ungroup on-ungroup
:on-context-menu on-context-menu :on-context-menu on-context-menu

View file

@ -42,15 +42,20 @@
;; --- Options ;; --- Options
(mf/defc shape-options (mf/defc shape-options*
{::mf/wrap [#(mf/throttle % 60)]} {::mf/wrap [#(mf/throttle % 60)]}
[{:keys [shape shapes-with-children page-id file-id shared-libs]}] [{:keys [shape shapes-with-children page-id file-id shared-libs] :as props}]
(let [workspace-modifiers (mf/deref refs/workspace-modifiers) (let [shape-type (dm/get-prop shape :type)
modifiers (get-in workspace-modifiers [(:id shape) :modifiers]) shape-id (dm/get-prop shape :id)
shape (gsh/transform-shape shape modifiers)]
modifiers (mf/deref refs/workspace-modifiers)
modifiers (dm/get-in modifiers [shape-id :modifiers])
shape (gsh/transform-shape shape modifiers)]
[:* [:*
(case (:type shape) (case shape-type
:frame [:& frame/options {:shape shape :shape-with-children shapes-with-children :file-id file-id :shared-libs shared-libs}] :frame [:> frame/options* props]
:group [:& group/options {:shape shape :shape-with-children shapes-with-children :file-id file-id :shared-libs shared-libs}] :group [:& group/options {:shape shape :shape-with-children shapes-with-children :file-id file-id :shared-libs shared-libs}]
:text [:& text/options {:shape shape :file-id file-id :shared-libs shared-libs}] :text [:& text/options {:shape shape :file-id file-id :shared-libs shared-libs}]
:rect [:& rect/options {:shape shape}] :rect [:& rect/options {:shape shape}]
@ -73,7 +78,7 @@
(when (= (:type panel) :component-swap) (when (= (:type panel) :component-swap)
[:& component-menu {:shapes (:shapes panel) :swap-opened? true}])) [:& component-menu {:shapes (:shapes panel) :swap-opened? true}]))
(mf/defc design-menu (mf/defc design-menu*
{::mf/wrap [mf/memo]} {::mf/wrap [mf/memo]}
[{:keys [selected objects page-id file-id selected-shapes shapes-with-children]}] [{:keys [selected objects page-id file-id selected-shapes shapes-with-children]}]
(let [sp-panel (mf/deref refs/specialized-panel) (let [sp-panel (mf/deref refs/specialized-panel)
@ -104,7 +109,7 @@
[:& specialized-panel {:panel sp-panel}] [:& specialized-panel {:panel sp-panel}]
(d/not-empty? drawing) (d/not-empty? drawing)
[:& shape-options [:> shape-options*
{:shape (:object drawing) {:shape (:object drawing)
:page-id page-id :page-id page-id
:file-id file-id :file-id file-id
@ -114,7 +119,7 @@
[:& page/options] [:& page/options]
(= 1 (count selected)) (= 1 (count selected))
[:& shape-options [:> shape-options*
{:shape (first selected-shapes) {:shape (first selected-shapes)
:page-id page-id :page-id page-id
:file-id file-id :file-id file-id
@ -151,12 +156,13 @@
(st/emit! :interrupt (dwc/set-workspace-read-only false))))) (st/emit! :interrupt (dwc/set-workspace-read-only false)))))
design-content design-content
(mf/html [:& design-menu {:selected selected (mf/html [:> design-menu*
:objects objects {:selected selected
:page-id page-id :objects objects
:file-id file-id :page-id page-id
:selected-shapes selected-shapes :file-id file-id
:shapes-with-children shapes-with-children}]) :selected-shapes selected-shapes
:shapes-with-children shapes-with-children}])
inspect-content inspect-content
(mf/html [:div {:class (stl/css :element-options :inspect-options)} (mf/html [:div {:class (stl/css :element-options :inspect-options)}

View file

@ -168,7 +168,7 @@
(seq fills) (seq fills)
[:& h/sortable-container {} [:& h/sortable-container {}
(for [[index value] (d/enumerate (:fills values []))] (for [[index value] (d/enumerate (:fills values []))]
[:& color-row {:color (ctc/fill->color value) [:& color-row {:color (ctc/fill->shape-color value)
:key index :key index
:index index :index index
:title (tr "workspace.options.fill") :title (tr "workspace.options.fill")

View file

@ -33,7 +33,7 @@
[app.main.ui.workspace.tokens.token-types :as wtty] [app.main.ui.workspace.tokens.token-types :as wtty]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[clojure.set :refer [rename-keys union]] [clojure.set :as set]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(def measure-attrs (def measure-attrs
@ -48,16 +48,27 @@
:show-content :show-content
:hide-in-viewer]) :hide-in-viewer])
(def ^:private type->options (def ^:private generic-options
{:bool #{:size :position :rotation} #{:size :position :rotation})
:circle #{:size :position :rotation}
:frame #{:presets :size :position :rotation :radius :clip-content :show-in-viewer} (def ^:private rect-options
:group #{:size :position :rotation} #{:size :position :rotation :radius})
:image #{:size :position :rotation :radius}
:path #{:size :position :rotation} (def ^:private frame-options
:rect #{:size :position :rotation :radius} #{:presets :size :position :rotation :radius :clip-content :show-in-viewer})
:svg-raw #{:size :position :rotation}
:text #{:size :position :rotation}}) (defn- type->options
[type]
(case type
:bool generic-options
:circle generic-options
:frame frame-options
:group generic-options
:image rect-options
:path generic-options
:rect rect-options
:svg-raw generic-options
:text generic-options))
(def ^:private clip-content-icon (i/icon-xref :clip-content (stl/css :checkbox-button))) (def ^:private clip-content-icon (i/icon-xref :clip-content (stl/css :checkbox-button)))
(def ^:private play-icon (i/icon-xref :play (stl/css :checkbox-button))) (def ^:private play-icon (i/icon-xref :play (stl/css :checkbox-button)))
@ -67,37 +78,45 @@
(defn select-measure-keys (defn select-measure-keys
"Consider some shapes can be drawn from bottom to top or from left to right" "Consider some shapes can be drawn from bottom to top or from left to right"
[shape] [shape]
(let [shape (cond (let [flip-x (get shape :flip-x)
(and (:flip-x shape) (:flip-y shape)) flip-y (get shape :flip-y)
(rename-keys shape {:r1 :r3 :r2 :r4 :r3 :r1 :r4 :r2})
(:flip-x shape) shape (cond
(rename-keys shape {:r1 :r2 :r2 :r1 :r3 :r4 :r4 :r3}) (and flip-x flip-y)
(set/rename-keys shape {:r1 :r3 :r2 :r4 :r3 :r1 :r4 :r2})
(:flip-y shape) flip-x
(rename-keys shape {:r1 :r4 :r2 :r3 :r3 :r2 :r4 :r1}) (set/rename-keys shape {:r1 :r2 :r2 :r1 :r3 :r4 :r4 :r3})
:else flip-y
shape)] (set/rename-keys shape {:r1 :r4 :r2 :r3 :r3 :r2 :r4 :r1})
:else
shape)]
(select-keys shape measure-attrs))) (select-keys shape measure-attrs)))
;; -- User/drawing coords (mf/defc measures-menu*
(mf/defc measures-menu {::mf/props :obj
{::mf/wrap-props false
::mf/wrap [mf/memo]} ::mf/wrap [mf/memo]}
[{:keys [ids ids-with-children values type all-types shape]}] [{:keys [ids ids-with-children values type all-types shape]}]
(let [options (if (= type :multiple) (let [design-tokens? (mf/use-ctx muc/design-tokens)
(reduce #(union %1 %2) (map #(get type->options %) all-types))
(get type->options type))
design-tokens? (mf/use-ctx muc/design-tokens) options
(mf/with-memo [type all-types]
(if (= type :multiple)
(into #{} (mapcat type->options) all-types)
(type->options type)))
ids-with-children (or ids-with-children ids) ids-with-children
(or ids-with-children ids)
old-shapes (if (= type :multiple) old-shapes
(deref (refs/objects-by-id ids)) (if (= type :multiple)
[shape]) (deref (refs/objects-by-id ids))
frames (map #(deref (refs/object-by-id (:frame-id %))) old-shapes) [shape])
frames
(map #(deref (refs/object-by-id (:frame-id %))) old-shapes)
ids (hooks/use-equal-memo ids) ids (hooks/use-equal-memo ids)

View file

@ -19,7 +19,6 @@
[app.main.ui.components.color-input :refer [color-input*]] [app.main.ui.components.color-input :refer [color-input*]]
[app.main.ui.components.numeric-input :refer [numeric-input*]] [app.main.ui.components.numeric-input :refer [numeric-input*]]
[app.main.ui.components.reorder-handler :refer [reorder-handler]] [app.main.ui.components.reorder-handler :refer [reorder-handler]]
[app.main.ui.context :as ctx]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.formats :as fmt] [app.main.ui.formats :as fmt]
[app.main.ui.hooks :as h] [app.main.ui.hooks :as h]
@ -49,27 +48,23 @@
[{:keys [index color disable-gradient disable-opacity disable-image disable-picker on-change [{:keys [index color disable-gradient disable-opacity disable-image disable-picker on-change
on-reorder on-detach on-open on-close on-remove on-reorder on-detach on-open on-close on-remove
disable-drag on-focus on-blur select-only select-on-focus]}] disable-drag on-focus on-blur select-only select-on-focus]}]
(let [current-file-id (mf/use-ctx ctx/current-file-id) (let [shared-libs (mf/deref refs/libraries)
file-colors (mf/deref refs/workspace-file-colors) hover-detach (mf/use-state false)
shared-libs (mf/deref refs/libraries) on-change (h/use-ref-callback on-change)
hover-detach (mf/use-state false)
on-change (h/use-ref-callback on-change)
src-colors (if (= (:file-id color) current-file-id)
file-colors
(dm/get-in shared-libs [(:file-id color) :data :colors]))
color-name (dm/get-in src-colors [(:id color) :name]) src-colors (dm/get-in shared-libs [(:ref-file color) :data :colors])
color-name (dm/get-in src-colors [(:ref-id color) :name])
multiple-colors? (uc/multiple? color) multiple-colors? (uc/multiple? color)
library-color? (and (:id color) color-name (not multiple-colors?)) library-color? (and (:ref-id color) color-name (not multiple-colors?))
gradient-color? (and (not multiple-colors?) gradient-color? (and (not multiple-colors?)
(:gradient color) (:gradient color)
(get-in color [:gradient :type])) (dm/get-in color [:gradient :type]))
image-color? (and (not multiple-colors?) image-color? (and (not multiple-colors?)
(:image color)) (:image color))
editing-text* (mf/use-state false) editing-text* (mf/use-state false)
editing-text? (deref editing-text*) editing-text? (deref editing-text*)
opacity? opacity?
(and (not multiple-colors?) (and (not multiple-colors?)
@ -124,10 +119,9 @@
(mf/use-fn (mf/use-fn
(mf/deps color on-change) (mf/deps color on-change)
(fn [value] (fn [value]
(let [color (assoc color (let [color (-> color
:opacity (/ value 100) (assoc :opacity (/ value 100))
:id nil (dissoc :ref-id :ref-file))]
:file-id nil)]
(st/emit! (dwl/add-recent-color color) (st/emit! (dwl/add-recent-color color)
(on-change color))))) (on-change color)))))
@ -209,13 +203,11 @@
:gradient-name-wrapper gradient-color?)} :gradient-name-wrapper gradient-color?)}
[:div {:class (stl/css :color-bullet-wrapper)} [:div {:class (stl/css :color-bullet-wrapper)}
[:& cb/color-bullet {:color (cond-> color [:& cb/color-bullet {:color (cond-> color
(nil? color-name) (assoc (nil? color-name) (dissoc :ref-id :ref-file))
:id nil
:file-id nil))
:mini true :mini true
:on-click handle-click-color}]] :on-click handle-click-color}]]
(cond (cond
;; Rendering a color with ID ;; Rendering a color with ID
library-color? library-color?
[:* [:*
[:div {:class (stl/css :color-name) [:div {:class (stl/css :color-name)
@ -235,7 +227,7 @@
gradient-color? gradient-color?
[:* [:*
[:div {:class (stl/css :color-name)} [:div {:class (stl/css :color-name)}
(uc/gradient-type->string (get-in color [:gradient :type]))]] (uc/gradient-type->string (dm/get-in color [:gradient :type]))]]
;; Rendering an image ;; Rendering an image
image-color? image-color?
@ -250,7 +242,7 @@
"" ""
(-> color :color cc/remove-hash)) (-> color :color cc/remove-hash))
:placeholder (tr "settings.multiple") :placeholder (tr "settings.multiple")
:className (stl/css :color-input) :class (stl/css :color-input)
:on-focus on-focus :on-focus on-focus
:on-blur on-blur :on-blur on-blur
:on-change handle-value-change}]])] :on-change handle-value-change}]])]

View file

@ -8,6 +8,7 @@
(:require-macros [app.main.style :as stl]) (:require-macros [app.main.style :as stl])
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.types.color :as ctc]
[app.main.ui.components.numeric-input :refer [numeric-input*]] [app.main.ui.components.numeric-input :refer [numeric-input*]]
[app.main.ui.components.reorder-handler :refer [reorder-handler]] [app.main.ui.components.reorder-handler :refer [reorder-handler]]
[app.main.ui.components.select :refer [select]] [app.main.ui.components.select :refer [select]]
@ -147,12 +148,7 @@
[:& reorder-handler {:ref dref}]) [:& reorder-handler {:ref dref}])
;; Stroke Color ;; Stroke Color
[:& color-row {:color {:color (:stroke-color stroke) [:& color-row {:color (ctc/stroke->shape-color stroke)
:opacity (:stroke-opacity stroke)
:id (:stroke-color-ref-id stroke)
:file-id (:stroke-color-ref-file stroke)
:gradient (:stroke-color-gradient stroke)
:image (:stroke-image stroke)}
:index index :index index
:title title :title title
:on-change on-color-change-refactor :on-change on-color-change-refactor

View file

@ -16,7 +16,7 @@
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]] [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]] [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu*]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
@ -51,10 +51,10 @@
:type type :type type
:values layer-values}] :values layer-values}]
[:& measures-menu {:ids ids [:> measures-menu* {:ids ids
:type type :type type
:values measure-values :values measure-values
:shape shape}] :shape shape}]
[:& layout-container-menu [:& layout-container-menu
{:type type {:type type

View file

@ -16,7 +16,7 @@
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]] [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]] [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu*]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]] [app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
@ -53,10 +53,10 @@
:type type :type type
:values layer-values}] :values layer-values}]
[:& measures-menu {:ids ids [:> measures-menu* {:ids ids
:type type :type type
:values measure-values :values measure-values
:shape shape}] :shape shape}]
[:& layout-container-menu [:& layout-container-menu
{:type type {:type type

View file

@ -6,10 +6,9 @@
(ns app.main.ui.workspace.sidebar.options.shapes.frame (ns app.main.ui.workspace.sidebar.options.shapes.frame
(:require (:require
[app.common.data :as d] [app.common.data.macros :as dm]
[app.common.types.shape.layout :as ctl] [app.common.types.shape.layout :as ctl]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.ui.hooks :as hooks]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.color-selection :refer [color-selection-menu]] [app.main.ui.workspace.sidebar.options.menus.color-selection :refer [color-selection-menu]]
[app.main.ui.workspace.sidebar.options.menus.component :refer [component-menu]] [app.main.ui.workspace.sidebar.options.menus.component :refer [component-menu]]
@ -20,55 +19,68 @@
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]] [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [select-measure-keys measures-menu]] [app.main.ui.workspace.sidebar.options.menus.measures :refer [select-measure-keys measures-menu*]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(mf/defc options (mf/defc options*
[{:keys [shape file-id shape-with-children shared-libs] :as props}] [{:keys [shape file-id shapes-with-children shared-libs] :as props}]
(let [ids [(:id shape)] (let [shape-id (dm/get-prop shape :id)
type (:type shape) shape-type (dm/get-prop shape :type)
objects (->> shape-with-children (group-by :id) (d/mapm (fn [_ v] (first v))))
stroke-values (select-keys shape stroke-attrs) ids (mf/with-memo [shape-id]
layer-values (select-keys shape layer-attrs) [shape-id])
measure-values (select-measure-keys shape)
constraint-values (select-keys shape constraint-attrs) stroke-values (select-keys shape stroke-attrs)
layer-values (select-keys shape layer-attrs)
measure-values (select-measure-keys shape)
constraint-values (select-keys shape constraint-attrs)
layout-container-values (select-keys shape layout-container-flex-attrs) layout-container-values (select-keys shape layout-container-flex-attrs)
layout-item-values (select-keys shape layout-item-attrs) layout-item-values (select-keys shape layout-item-attrs)
ids (hooks/use-equal-memo ids) is-layout-child-ref
(mf/with-memo [ids]
(refs/is-layout-child? ids))
is-layout-child?
(mf/deref is-layout-child-ref)
is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids)) is-flex-parent-ref
is-layout-child? (mf/deref is-layout-child-ref) (mf/with-memo [ids]
(refs/flex-layout-child? ids))
is-flex-parent?
(mf/deref is-flex-parent-ref)
is-flex-parent-ref (mf/use-memo (mf/deps ids) #(refs/flex-layout-child? ids)) is-grid-parent-ref
is-flex-parent? (mf/deref is-flex-parent-ref) (mf/with-memo [ids]
(refs/grid-layout-child? ids))
is-grid-parent?
(mf/deref is-grid-parent-ref)
is-grid-parent-ref (mf/use-memo (mf/deps ids) #(refs/grid-layout-child? ids)) parents-by-ids-ref
is-grid-parent? (mf/deref is-grid-parent-ref) (mf/with-memo [ids]
(refs/parents-by-ids ids))
parents
(mf/deref parents-by-ids-ref)
is-layout-container? (ctl/any-layout? shape) is-layout-container? (ctl/any-layout? shape)
is-flex-layout? (ctl/flex-layout? shape) is-flex-layout? (ctl/flex-layout? shape)
is-grid-layout? (ctl/grid-layout? shape) is-grid-layout? (ctl/grid-layout? shape)
is-layout-child-absolute? (ctl/item-absolute? shape) is-layout-child-absolute? (ctl/item-absolute? shape)]
ids (hooks/use-equal-memo ids)
parents-by-ids-ref (mf/use-memo (mf/deps ids) #(refs/parents-by-ids ids))
parents (mf/deref parents-by-ids-ref)]
[:* [:*
[:& layer-menu {:ids ids [:& layer-menu {:ids ids
:type type :type shape-type
:values layer-values}] :values layer-values}]
[:& measures-menu {:ids [(:id shape)] [:> measures-menu* {:ids ids
:values measure-values :values measure-values
:type type :type shape-type
:shape shape}] :shape shape}]
[:& component-menu {:shapes [shape]}] [:& component-menu {:shapes [shape]}]
[:& layout-container-menu [:& layout-container-menu
{:type type {:type shape-type
:ids [(:id shape)] :ids [(:id shape)]
:values layout-container-values :values layout-container-values
:multiple false}] :multiple false}]
@ -81,7 +93,7 @@
(when (or is-layout-child? is-layout-container?) (when (or is-layout-child? is-layout-container?)
[:& layout-item-menu [:& layout-item-menu
{:ids ids {:ids ids
:type type :type shape-type
:values layout-item-values :values layout-item-values
:is-flex-parent? is-flex-parent? :is-flex-parent? is-flex-parent?
:is-grid-parent? is-grid-parent? :is-grid-parent? is-grid-parent?
@ -96,13 +108,13 @@
:values constraint-values}]) :values constraint-values}])
[:& fill-menu {:ids ids [:& fill-menu {:ids ids
:type type :type shape-type
:values (select-keys shape fill-attrs-shape)}] :values (select-keys shape fill-attrs-shape)}]
[:& stroke-menu {:ids ids [:& stroke-menu {:ids ids
:type type :type shape-type
:values stroke-values}] :values stroke-values}]
[:& color-selection-menu {:type type [:& color-selection-menu {:type shape-type
:shapes (vals objects) :shapes shapes-with-children
:file-id file-id :file-id file-id
:shared-libs shared-libs}] :shared-libs shared-libs}]
[:& shadow-menu {:ids ids [:& shadow-menu {:ids ids

View file

@ -20,7 +20,7 @@
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-menu]] [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measures-menu]] [app.main.ui.workspace.sidebar.options.menus.measures :refer [measures-menu*]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-menu]] [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]] [app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
@ -69,7 +69,7 @@
[:div {:class (stl/css :options)} [:div {:class (stl/css :options)}
[:& layer-menu {:type type :ids layer-ids :values layer-values}] [:& layer-menu {:type type :ids layer-ids :values layer-values}]
[:& measures-menu {:type type :ids measure-ids :values measure-values :shape shape}] [:> measures-menu* {:type type :ids measure-ids :values measure-values :shape shape}]
[:& component-menu {:shapes [shape]}] ;;remove this in components-v2 [:& component-menu {:shapes [shape]}] ;;remove this in components-v2
[:& layout-container-menu [:& layout-container-menu

View file

@ -16,7 +16,7 @@
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]] [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]] [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu*]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
@ -53,10 +53,10 @@
:type type :type type
:values layer-values}] :values layer-values}]
[:& measures-menu {:ids ids [:> measures-menu* {:ids ids
:type type :type type
:values measure-values :values measure-values
:shape shape}] :shape shape}]
[:& layout-container-menu [:& layout-container-menu
{:type type {:type type

View file

@ -25,7 +25,7 @@
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]] [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [select-measure-keys measure-attrs measures-menu]] [app.main.ui.workspace.sidebar.options.menus.measures :refer [select-measure-keys measure-attrs measures-menu*]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-attrs shadow-menu]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-attrs shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.text :as ot] [app.main.ui.workspace.sidebar.options.menus.text :as ot]
@ -359,7 +359,7 @@
[:& layer-menu {:type type :ids layer-ids :values layer-values}]) [:& layer-menu {:type type :ids layer-ids :values layer-values}])
(when-not (empty? measure-ids) (when-not (empty? measure-ids)
[:& measures-menu {:type type :all-types all-types :ids measure-ids :values measure-values :shape shapes}]) [:> measures-menu* {:type type :all-types all-types :ids measure-ids :values measure-values :shape shapes}])
(when-not (empty? components) (when-not (empty? components)
[:& component-menu {:shapes components}]) [:& component-menu {:shapes components}])

View file

@ -16,7 +16,7 @@
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]] [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]] [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu*]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]] [app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
@ -52,10 +52,10 @@
[:& layer-menu {:ids ids [:& layer-menu {:ids ids
:type type :type type
:values layer-values}] :values layer-values}]
[:& measures-menu {:ids ids [:> measures-menu* {:ids ids
:type type :type type
:values measure-values :values measure-values
:shape shape}] :shape shape}]
[:& layout-container-menu [:& layout-container-menu
{:type type {:type type

View file

@ -16,7 +16,7 @@
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]] [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [select-measure-keys measures-menu]] [app.main.ui.workspace.sidebar.options.menus.measures :refer [select-measure-keys measures-menu*]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]] [app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
@ -55,10 +55,10 @@
[:& layer-menu {:ids ids [:& layer-menu {:ids ids
:type type :type type
:values layer-values}] :values layer-values}]
[:& measures-menu {:ids ids [:> measures-menu* {:ids ids
:type type :type type
:values measure-values :values measure-values
:shape shape}] :shape shape}]
[:& layout-container-menu [:& layout-container-menu
{:type type {:type type

View file

@ -17,7 +17,7 @@
[app.main.ui.workspace.sidebar.options.menus.grid-cell :as grid-cell] [app.main.ui.workspace.sidebar.options.menus.grid-cell :as grid-cell]
[app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]] [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu*]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]] [app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
@ -124,10 +124,10 @@
(when (contains? svg-elements tag) (when (contains? svg-elements tag)
[:* [:*
[:& measures-menu {:ids ids [:> measures-menu* {:ids ids
:type type :type type
:values measure-values :values measure-values
:shape shape}] :shape shape}]
[:& layout-container-menu [:& layout-container-menu
{:type type {:type type

View file

@ -22,7 +22,7 @@
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]] [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]] [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu*]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.text :refer [text-menu]] [app.main.ui.workspace.sidebar.options.menus.text :refer [text-menu]]
@ -98,7 +98,7 @@
[:& layer-menu {:ids ids [:& layer-menu {:ids ids
:type type :type type
:values layer-values}] :values layer-values}]
[:& measures-menu [:> measures-menu*
{:ids ids {:ids ids
:type type :type type
:values (select-keys shape measure-attrs) :values (select-keys shape measure-attrs)