0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-04-03 10:31:38 -05:00

Merge pull request #3460 from penpot/niwinz-develop-enhancements-2

 Several enhancements (performance and code style)
This commit is contained in:
Alejandro 2023-08-09 08:30:00 +02:00 committed by GitHub
commit 6ceb816362
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 328 additions and 294 deletions

View file

@ -87,7 +87,7 @@
[:*
#_[:div.modal-wrapper
#_[:& app.main.ui.releases/release-notes-modal {:version "1.16"}]
#_[:& app.main.ui.releases/release-notes-modal {:version "1.19"}]
#_[:& app.main.ui.onboarding/onboarding-templates-modal]
#_[:& app.main.ui.onboarding/onboarding-modal]
#_[:& app.main.ui.onboarding/onboarding-team-modal]]

View file

@ -7,6 +7,7 @@
(ns app.main.ui.dashboard.export
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.main.data.modal :as modal]
[app.main.features :as features]
[app.main.store :as st]
@ -20,8 +21,8 @@
(def ^:const options [:all :merge :detach])
(mf/defc export-entry
{::mf/wrap-props false}
[{:keys [file]}]
[:div.file-entry
{:class (dom/classnames
:loading (:loading? file)
@ -35,72 +36,89 @@
[:div.file-name-label (:name file)]]])
(defn mark-file-error [files file-id]
(->> files
(mapv #(cond-> %
(= file-id (:id %))
(assoc :export-error? true
:loading? false)))))
(defn- mark-file-error
[files file-id]
(mapv #(cond-> %
(= file-id (:id %))
(assoc :export-error? true
:loading? false))
files))
(defn mark-file-success [files file-id]
(->> files
(mapv #(cond-> %
(= file-id (:id %))
(assoc :export-success? true
:loading? false)))))
(defn- mark-file-success
[files file-id]
(mapv #(cond-> %
(= file-id (:id %))
(assoc :export-success? true
:loading? false))
files))
(def export-types
[:all :merge :detach])
(mf/defc export-dialog
{::mf/register modal/components
::mf/register-as :export}
::mf/register-as :export
::mf/wrap-props false}
[{:keys [team-id files has-libraries? binary?]}]
(let [state (mf/use-state {:status :prepare
:files (->> files (mapv #(assoc % :loading? true)))})
selected-option (mf/use-state :all)
(let [components-v2 (features/use-feature :components-v2)
state* (mf/use-state
#(let [files (mapv (fn [file] (assoc file :loading? true)) files)]
{:status :prepare
:selected :all
:files files}))
components-v2 (features/use-feature :components-v2)
state (deref state*)
selected (:selected state)
status (:status state)
start-export
(fn []
(swap! state assoc :status :exporting)
(->> (uw/ask-many!
{:cmd (if binary? :export-binary-file :export-standard-file)
:team-id team-id
:export-type @selected-option
:files files
:components-v2 components-v2})
(rx/delay-emit 1000)
(rx/subs
(fn [msg]
(when (= :error (:type msg))
(swap! state update :files mark-file-error (:file-id msg)))
(mf/use-fn
(mf/deps team-id selected files components-v2)
(fn []
(swap! state* assoc :status :exporting)
(->> (uw/ask-many!
{:cmd (if binary? :export-binary-file :export-standard-file)
:team-id team-id
:export-type selected
:files files
:components-v2 components-v2})
(rx/delay-emit 1000)
(rx/subs
(fn [msg]
(cond
(= :error (:type msg))
(swap! state* update :files mark-file-error (:file-id msg))
(when (= :finish (:type msg))
(swap! state update :files mark-file-success (:file-id msg))
(dom/trigger-download-uri (:filename msg) (:mtype msg) (:uri msg)))))))
(= :finish (:type msg))
(do
(swap! state* update :files mark-file-success (:file-id msg))
(dom/trigger-download-uri (:filename msg) (:mtype msg) (:uri msg)))))))))
cancel-fn
(mf/use-callback
on-cancel
(mf/use-fn
(fn [event]
(dom/prevent-default event)
(st/emit! (modal/hide))))
accept-fn
(mf/use-callback
(mf/deps @selected-option)
on-accept
(mf/use-fn
(mf/deps start-export)
(fn [event]
(dom/prevent-default event)
(start-export)))
on-change-handler
(mf/use-callback
(fn [_ type]
(reset! selected-option type)))]
on-change
(mf/use-fn
(fn [event]
(let [type (-> (dom/get-target event)
(dom/get-data "type")
(keyword))]
(swap! state* assoc :selected type))))]
(mf/use-effect
(fn []
(when-not has-libraries?
;; Start download automatically
(start-export))))
(mf/with-effect [has-libraries?]
;; Start download automatically when no libraries
(when-not has-libraries?
(start-export)))
[:div.modal-overlay
[:div.modal-container.export-dialog
@ -109,52 +127,53 @@
[:h2 (tr "dashboard.export.title")]]
[:div.modal-close-button
{:on-click cancel-fn} i/close]]
{:on-click on-cancel} i/close]]
(cond
(= (:status @state) :prepare)
(= status :prepare)
[:*
[:div.modal-content
[:p.explain (tr "dashboard.export.explain")]
[:p.detail (tr "dashboard.export.detail")]
(for [type [:all :merge :detach]]
(let [selected? (= @selected-option type)]
[:div.export-option {:class (when selected? "selected")}
[:label.option-container
;; Execution time translation strings:
;; dashboard.export.options.all.message
;; dashboard.export.options.all.title
;; dashboard.export.options.detach.message
;; dashboard.export.options.detach.title
;; dashboard.export.options.merge.message
;; dashboard.export.options.merge.title
[:h3 (tr (str "dashboard.export.options." (d/name type) ".title"))]
[:p (tr (str "dashboard.export.options." (d/name type) ".message"))]
[:input {:type "radio"
:checked selected?
:on-change #(on-change-handler % type)
:name "export-option"}]
[:span {:class "option-radio-check"}]]]))]
(for [type export-types]
[:div.export-option {:class (when (= selected type) "selected")
:key (name type)}
[:label.option-container
;; Execution time translation strings:
;; dashboard.export.options.all.message
;; dashboard.export.options.all.title
;; dashboard.export.options.detach.message
;; dashboard.export.options.detach.title
;; dashboard.export.options.merge.message
;; dashboard.export.options.merge.title
[:h3 (tr (dm/str "dashboard.export.options." (d/name type) ".title"))]
[:p (tr (dm/str "dashboard.export.options." (d/name type) ".message"))]
[:input {:type "radio"
:checked (= selected type)
:data-type (name type)
:on-change on-change
:name "export-option"}]
[:span {:class "option-radio-check"}]]])]
[:div.modal-footer
[:div.action-buttons
[:input.cancel-button
{:type "button"
:value (tr "labels.cancel")
:on-click cancel-fn}]
:on-click on-cancel}]
[:input.accept-button
{:class "primary"
:type "button"
:value (tr "labels.continue")
:on-click accept-fn}]]]]
:on-click on-accept}]]]]
(= (:status @state) :exporting)
(= status :exporting)
[:*
[:div.modal-content
(for [file (:files @state)]
[:& export-entry {:file file}])]
(for [file (:files state)]
[:& export-entry {:file file :key (dm/str (:id file))}])]
[:div.modal-footer
[:div.action-buttons
@ -162,5 +181,5 @@
{:class "primary"
:type "button"
:value (tr "labels.close")
:disabled (->> @state :files (some :loading?))
:on-click cancel-fn}]]]])]]))
:disabled (->> state :files (some :loading?))
:on-click on-cancel}]]]])]]))

View file

@ -33,40 +33,41 @@
;;; --- RELEASE NOTES MODAL
(mf/defc release-notes
[{:keys [version] :as props}]
(let [slide (mf/use-state :start)
klass (mf/use-state "fadeInDown")
{::mf/wrap-props false}
[{:keys [version]}]
(let [slide* (mf/use-state :start)
slide (deref slide*)
klass* (mf/use-state "fadeInDown")
klass (deref klass*)
navigate
(mf/use-callback #(reset! slide %))
(mf/use-fn #(reset! slide* %))
next
(mf/use-callback
(mf/use-fn
(mf/deps slide)
(fn []
(if (= @slide :start)
(if (= slide :start)
(navigate 0)
(navigate (inc @slide)))))
(navigate (inc slide)))))
finish
(mf/use-callback
(mf/use-fn
(mf/deps version)
#(st/emit! (modal/hide)
(du/mark-onboarding-as-viewed {:version version})))]
(mf/use-effect
(mf/deps)
(fn []
#(st/emit! (du/mark-onboarding-as-viewed {:version version}))))
(mf/with-effect []
#(st/emit! (du/mark-onboarding-as-viewed {:version version})))
(mf/use-layout-effect
(mf/deps @slide)
(fn []
(when (not= :start @slide)
(reset! klass "fadeIn"))
(let [sem (tm/schedule 300 #(reset! klass nil))]
(fn []
(reset! klass nil)
(tm/dispose! sem)))))
(mf/with-effect [slide]
(when (not= :start slide)
(reset! klass* "fadeIn"))
(let [sem (tm/schedule 300 #(reset! klass* nil))]
(fn []
(reset! klass* nil)
(tm/dispose! sem))))
(rc/render-release-notes
{:next next

View file

@ -13,7 +13,7 @@
[{:keys [klass finish version]}]
(mf/html
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/beta-on.jpg" :border "0" :alt "Penpot is now BETA"}]]

View file

@ -12,10 +12,10 @@
(defmethod c/render-release-notes "1.11"
[{:keys [slide klass next finish navigate version]}]
(mf/html
(case @slide
(case slide
:start
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/login-on.jpg" :border "0" :alt "What's new Beta release 1.11"}]]
@ -33,7 +33,7 @@
0
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.11-animations.gif" :border "0" :alt "Animations"}]]
@ -46,13 +46,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 3}]]]]]]
1
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.11-bg-export.gif" :border "0" :alt "Ignore background on export"}]]
@ -65,13 +65,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 3}]]]]]]
2
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.11-zoom-widget.gif" :border "0" :alt "New zoom widget"}]]
@ -84,6 +84,6 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click finish} "Start!"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 3}]]]]]])))

View file

@ -12,10 +12,10 @@
(defmethod c/render-release-notes "1.12"
[{:keys [slide klass next finish navigate version]}]
(mf/html
(case @slide
(case slide
:start
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/login-on.jpg" :border "0" :alt "What's new Beta release 1.12"}]]
@ -33,7 +33,7 @@
0
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.12-ui.gif" :border "0" :alt "Adjustable UI"}]]
@ -46,13 +46,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
1
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.12-guides.gif" :border "0" :alt "Guides"}]]
@ -65,13 +65,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
2
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.12-scrollbars.gif" :border "0" :alt "Scrollbars"}]]
@ -83,13 +83,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
3
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.12-nudge.gif" :border "0" :alt "Nudge amount"}]]
@ -102,6 +102,6 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click finish} "Start!"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]])))

View file

@ -12,10 +12,10 @@
(defmethod c/render-release-notes "1.13"
[{:keys [slide klass next finish navigate version]}]
(mf/html
(case @slide
(case slide
:start
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/login-on.jpg" :border "0" :alt "What's new Beta release 1.13"}]]
@ -33,7 +33,7 @@
0
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.13-multi-export.gif" :border "0" :alt "Multiple exports"}]]
@ -46,13 +46,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
1
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.13-multiple-fills.gif" :border "0" :alt "Multiple fills and strokes"}]]
@ -65,13 +65,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
2
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.13-members.gif" :border "0" :alt "Members area redesign"}]]
@ -84,13 +84,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
3
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.13-focus.gif" :border "0" :alt "Focus mode"}]]
@ -103,6 +103,6 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click finish} "Start!"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]])))

View file

@ -12,10 +12,10 @@
(defmethod c/render-release-notes "1.14"
[{:keys [slide klass next finish navigate version]}]
(mf/html
(case @slide
(case slide
:start
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/login-on.jpg" :border "0" :alt "What's new Beta release 1.14"}]]
@ -33,7 +33,7 @@
0
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.14-shortcuts.gif" :border "0" :alt "Shortcuts panel"}]]
@ -46,13 +46,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
1
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.14-color-group.gif" :border "0" :alt "Colors selection"}]]
@ -65,13 +65,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
2
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.14-fix-on-scroll.gif" :border "0" :alt "Fix elements at scroll"}]]
@ -84,13 +84,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
3
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.14-group-assets.gif" :border "0" :alt "Group library assets with drag & drop"}]]
@ -103,6 +103,6 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click finish} "Start!"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]])))

View file

@ -12,10 +12,10 @@
(defmethod c/render-release-notes "1.15"
[{:keys [slide klass next finish navigate version]}]
(mf/html
(case @slide
(case slide
:start
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/login-on.jpg" :border "0" :alt "What's new Beta release 1.15"}]]
@ -33,7 +33,7 @@
0
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.15-nested-boards.gif" :border "0" :alt "Nested boards"}]]
@ -46,13 +46,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
1
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.15-share.gif" :border "0" :alt "Share prototype options"}]]
@ -65,13 +65,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
2
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.15-comments.gif" :border "0" :alt "Comments positioning"}]]
@ -84,13 +84,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
3
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.15-view-mode.gif" :border "0" :alt "View Mode improvements"}]]
@ -103,6 +103,6 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click finish} "Start!"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]])))

View file

@ -12,10 +12,10 @@
(defmethod c/render-release-notes "1.16"
[{:keys [slide klass next finish navigate version]}]
(mf/html
(case @slide
(case slide
:start
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/login-on.jpg" :border "0" :alt "What's new Beta release 1.16"}]]
@ -33,7 +33,7 @@
0
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.16-dashboard.gif" :border "0" :alt "Dashboard refreshed look & feel"}]]
@ -46,13 +46,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
1
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.16-slider.gif" :border "0" :alt "Libraries & templates module"}]]
@ -60,18 +60,18 @@
[:div.modal-title
[:h2 "Libraries & templates module"]]
[:div.modal-content
[:p "This new module will allow you to import a curated selection of the files that are available at the Libraries & Templates page directly from your projects dashboard."]
[:p "This new module will allow you to import a curated selection of the files that are available at the Libraries & Templates page directly from your projects dashboard."]
[:p "You no longer need to to download most of them to the computer before importing."]]
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
2
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.16-onboarding.gif" :border "0" :alt "Improved onboarding"}]]
@ -84,13 +84,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
3
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.16-click-zoom.gif" :border "0" :alt "Zoom to shape with double click"}]]
@ -103,6 +103,6 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click finish} "Start!"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]])))

View file

@ -12,10 +12,10 @@
(defmethod c/render-release-notes "1.17"
[{:keys [slide klass next finish navigate version]}]
(mf/html
(case @slide
(case slide
:start
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/onboarding-version.jpg" :border "0" :alt "What's new release 1.17"}]]
@ -33,7 +33,7 @@
0
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.17-flex-layout.gif" :border "0" :alt "Flex-Layout"}]]
@ -46,13 +46,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
1
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.17-inspect.gif" :border "0" :alt "Inspect at the workspace"}]]
@ -60,18 +60,18 @@
[:div.modal-title
[:h2 "Inspect at the workspace"]]
[:div.modal-content
[:p "Now you can inspect designs to get measures, properties and production-ready code right at the workspace, so designers and developers can share the same space while working."]
[:p "Now you can inspect designs to get measures, properties and production-ready code right at the workspace, so designers and developers can share the same space while working."]
[:p "Also, inspect mode provides a safer view-only mode and other improvements."]]
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
2
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.17-webhook.gif" :border "0" :alt "Webhooks"}]]
@ -84,13 +84,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
3
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.17-ally.gif" :border "0" :alt "Accessibility improvements"}]]
@ -103,6 +103,6 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click finish} "Start!"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]])))

View file

@ -12,10 +12,10 @@
(defmethod c/render-release-notes "1.18"
[{:keys [slide klass next finish navigate version]}]
(mf/html
(case @slide
(case slide
:start
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/onboarding-version.jpg" :border "0" :alt "What's new release 1.18"}]]
@ -33,7 +33,7 @@
0
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.18-spacing.gif" :border "0" :alt "Spacing management"}]]
@ -46,13 +46,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
1
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.18-absolute.gif" :border "0" :alt "Position absolute feature"}]]
@ -60,18 +60,18 @@
[:div.modal-title
[:h2 "Absolute position elements in Flex layout"]]
[:div.modal-content
[:p "Sometimes you need to freely position an element in a specific place regardless of the size of the layout where it belongs."]
[:p "Sometimes you need to freely position an element in a specific place regardless of the size of the layout where it belongs."]
[:p "Now you can exclude elements from the Flex layout flow using absolute position."]]
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
2
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.18-z-index.gif" :border "0" :alt "Z-index feature"}]]
@ -84,13 +84,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
3
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.18-scale.gif" :border "0" :alt "Scale content proportionally"}]]
@ -103,6 +103,6 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click finish} "Start!"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]])))

View file

@ -12,10 +12,10 @@
(defmethod c/render-release-notes "1.19"
[{:keys [slide klass next finish navigate version]}]
(mf/html
(case @slide
(case slide
:start
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/onboarding-version.jpg"
@ -42,7 +42,7 @@
0
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.19-contributions.png"
@ -73,13 +73,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 2}]]]]]]
1
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/1.19-tokens.gif"
@ -100,7 +100,7 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click finish} "Start!"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 2}]]]]]])))

View file

@ -12,10 +12,10 @@
(defmethod c/render-release-notes "1.4"
[{:keys [slide klass next finish navigate version]}]
(mf/html
(case @slide
(case slide
:start
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/login-on.jpg" :border "0" :alt "What's new Alpha release 1.4.0"}]]
@ -33,7 +33,7 @@
0
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/select-files.gif" :border "0" :alt "New file selection"}]]
@ -46,13 +46,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
1
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/manage-files.gif" :border "0" :alt "Manage files"}]]
@ -65,13 +65,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
2
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/rtl.gif" :border "0" :alt "RTL support"}]]
@ -84,13 +84,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
3
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/blend-modes.gif" :border "0" :alt "Blend modes"}]]
@ -103,7 +103,7 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click finish} "Start!"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]])))

View file

@ -12,10 +12,10 @@
(defmethod c/render-release-notes "1.5"
[{:keys [slide klass next finish navigate version]}]
(mf/html
(case @slide
(case slide
:start
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/login-on.jpg" :border "0" :alt "What's new Alpha release 1.5.0"}]]
@ -33,7 +33,7 @@
0
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/path-tool.gif" :border "0" :alt "New path tool"}]]
@ -46,13 +46,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 3}]]]]]]
1
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/assets-organiz.gif" :border "0" :alt "Manage libraries"}]]
@ -65,13 +65,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 3}]]]]]]
2
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/smart-inputs.gif" :border "0" :alt "Smart inputs"}]]
@ -84,7 +84,7 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click finish} "Start!"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 3}]]]]]])))

View file

@ -12,10 +12,10 @@
(defmethod c/render-release-notes "1.6"
[{:keys [slide klass next finish navigate version]}]
(mf/html
(case @slide
(case slide
:start
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/login-on.jpg" :border "0" :alt "What's new Alpha release 1.6.0"}]]
@ -33,7 +33,7 @@
0
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/custom-fonts.gif" :border "0" :alt "Upload/use custom fonts"}]]
@ -46,13 +46,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
1
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/scale-text.gif" :border "0" :alt "Interactively scale text"}]]
@ -65,13 +65,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
2
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/performance.gif" :border "0" :alt "Performance improvements"}]]
@ -84,13 +84,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
3
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/shapes-to-path.gif" :border "0" :alt "Shapes to path"}]]
@ -103,6 +103,6 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click finish} "Start!"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]])))

View file

@ -12,10 +12,10 @@
(defmethod c/render-release-notes "1.7"
[{:keys [slide klass next finish navigate version]}]
(mf/html
(case @slide
(case slide
:start
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/login-on.jpg" :border "0" :alt "What's new Alpha release 1.7"}]]
@ -33,7 +33,7 @@
0
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/export.gif" :border "0" :alt "Export & Import"}]]
@ -49,13 +49,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
1
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/constraints.gif" :border "0" :alt "Resizing constraints"}]]
@ -71,13 +71,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
2
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/group-components.gif" :border "0" :alt "Library assets management improvements"}]]
@ -91,13 +91,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
3
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/copy-paste.gif" :border "0" :alt "Paste components from file to file"}]]
@ -109,6 +109,6 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click finish} "Start!"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]])))

View file

@ -12,10 +12,10 @@
(defmethod c/render-release-notes "1.8"
[{:keys [slide klass next finish navigate version]}]
(mf/html
(case @slide
(case slide
:start
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/login-on.jpg" :border "0" :alt "What's new Alpha release 1.8"}]]
@ -33,7 +33,7 @@
0
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/share-viewer.gif" :border "0" :alt "Share options and pages at view mode"}]]
@ -46,13 +46,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
1
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/stroke-caps.gif" :border "0" :alt "Path stroke caps"}]]
@ -65,13 +65,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
2
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/navigate-history.gif" :border "0" :alt "Navigable history"}]]
@ -84,13 +84,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
3
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/export-artboards.gif" :border "0" :alt "Export artboards PDF"}]]
@ -103,6 +103,6 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click finish} "Start!"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]])))

View file

@ -12,10 +12,10 @@
(defmethod c/render-release-notes "1.9"
[{:keys [slide klass next finish navigate version]}]
(mf/html
(case @slide
(case slide
:start
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/login-on.jpg" :border "0" :alt "What's new Alpha release 1.9"}]]
@ -33,7 +33,7 @@
0
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/advanced-proto.gif" :border "0" :alt "Advanced interactions"}]]
@ -46,13 +46,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
1
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/flows-proto.gif" :border "0" :alt "Multiple flows"}]]
@ -65,13 +65,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
2
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/booleans.gif" :border "0" :alt "Boolean shapes"}]]
@ -84,13 +84,13 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click next} "Continue"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]]
3
[:div.modal-overlay
[:div.animated {:class @klass}
[:div.animated {:class klass}
[:div.modal-container.onboarding.feature
[:div.modal-left
[:img {:src "images/features/libraries-feature.gif" :border "0" :alt "Libraries & templates"}]]
@ -103,6 +103,6 @@
[:div.modal-navigation
[:button.btn-secondary {:on-click finish} "Start!"]
[:& c/navigation-bullets
{:slide @slide
{:slide slide
:navigate navigate
:total 4}]]]]]])))

View file

@ -7,8 +7,10 @@
(ns app.main.ui.workspace.viewport.outline
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.exceptions :as ex]
[app.common.geom.shapes :as gsh]
[app.common.pages.helpers :as cph]
[app.common.types.container :as ctn]
[app.main.refs :as refs]
[app.main.ui.hooks :as hooks]
@ -16,83 +18,95 @@
[app.util.object :as obj]
[app.util.path.format :as upf]
[clojure.set :as set]
[rumext.v2 :as mf]
[rumext.v2.util :refer [map->obj]]))
[rumext.v2 :as mf]))
(mf/defc outline
{::mf/wrap-props false}
[props]
(let [shape (obj/get props "shape")
zoom (obj/get props "zoom" 1)
modifier (obj/get props "modifier")
(let [shape (unchecked-get props "shape")
modifier (unchecked-get props "modifier")
shape (gsh/transform-shape shape (:modifiers modifier))
zoom (d/nilv (unchecked-get props "zoom") 1)
shape (gsh/transform-shape shape (:modifiers modifier))
transform (gsh/transform-str shape)
path? (= :path (:type shape))
path-data
(mf/use-memo
(mf/deps shape)
#(when path?
(or (ex/ignoring (upf/format-path (:content shape)))
"")))
;; Note that we don't use mf/deref to avoid a repaint dependency here
objects (deref refs/workspace-page-objects)
;; NOTE: that we don't use mf/deref to avoid a repaint dependency here
objects (deref refs/workspace-page-objects)
color (if (ctn/in-any-component? objects shape)
"var(--color-component-highlight)"
"var(--color-primary)")
{:keys [x y width height selrect]} shape
x (dm/get-prop shape :x)
y (dm/get-prop shape :y)
width (dm/get-prop shape :width)
height (dm/get-prop shape :height)
selrect (dm/get-prop shape :selrect)
type (dm/get-prop shape :type)
content (get shape :content)
path? (cph/path-shape? shape)
border-radius-attrs (attrs/extract-border-radius shape)
path-data
(mf/with-memo [path? content]
(when (and ^boolean path? (some? content))
(d/nilv (ex/ignoring (upf/format-path content)) "")))
path? (some? (.-d border-radius-attrs))
border-attrs
(attrs/extract-border-radius shape)
outline-type (case (:type shape)
:circle "ellipse"
:path "path"
(if path? "path" "rect"))
outline-type
(case type
:circle "ellipse"
:path "path"
(if (some? (obj/get border-attrs "d"))
"path"
"rect"))
common {:fill "none"
:stroke color
:strokeWidth (/ 2 zoom)
:pointerEvents "none"
:transform transform}
props
(obj/merge!
#js {:fill "none"
:stroke color
:strokeWidth (/ 2 zoom)
:pointerEvents "none"
:transform transform}
props (case (:type shape)
:circle
{:cx (+ x (/ width 2))
:cy (+ y (/ height 2))
:rx (/ width 2)
:ry (/ height 2)}
(case type
:circle
#js {:cx (+ x (/ width 2))
:cy (+ y (/ height 2))
:rx (/ width 2)
:ry (/ height 2)}
:path
{:d path-data
:transform nil}
:path
#js {:d path-data
:transform nil}
{:x (:x selrect)
:y (:y selrect)
:width (:width selrect)
:height (:height selrect)
:rx (.-rx border-radius-attrs)
:ry (.-ry border-radius-attrs)
:d (.-d border-radius-attrs)})]
(let [x (dm/get-prop selrect :x)
y (dm/get-prop selrect :y)
w (dm/get-prop selrect :width)
h (dm/get-prop selrect :height)]
#js {:x x
:y y
:width w
:height h
:rx (obj/get border-attrs "rx")
:ry (obj/get border-attrs "ry")
:d (obj/get border-attrs "d")})))
]
[:> outline-type (map->obj (merge common props))]))
[:> outline-type props]))
(mf/defc shape-outlines-render
{::mf/wrap-props false
::mf/wrap [#(mf/memo' % (mf/check-props ["shapes" "zoom" "modifiers"]))]}
[props]
(let [shapes (obj/get props "shapes")
zoom (obj/get props "zoom")
modifiers (obj/get props "modifiers")]
(let [shapes (unchecked-get props "shapes")
zoom (unchecked-get props "zoom")
modifiers (unchecked-get props "modifiers")]
(for [shape shapes]
(let [modifier (get modifiers (:id shape))]
[:& outline {:key (str "outline-" (:id shape))
(let [shape-id (dm/get-prop shape :id)
modifier (get modifiers shape-id)]
[:& outline {:key (dm/str "outline-" shape-id)
:shape shape
:modifier modifier
:zoom zoom}]))))