diff --git a/common/src/app/common/geom/shapes/bounds.cljc b/common/src/app/common/geom/shapes/bounds.cljc
index ba6f4c50c6..4b35744d30 100644
--- a/common/src/app/common/geom/shapes/bounds.cljc
+++ b/common/src/app/common/geom/shapes/bounds.cljc
@@ -154,7 +154,7 @@
(empty? (:shapes shape))
[(calculate-base-bounds shape)]
- (:masked-group shape)
+ (or (:masked-group shape) (= :bool (:type shape)))
[(calculate-base-bounds shape)]
(and (cph/frame-shape? shape) (not (:show-content shape)))
diff --git a/common/src/app/common/geom/shapes/grid_layout/positions.cljc b/common/src/app/common/geom/shapes/grid_layout/positions.cljc
index 6f73edb886..435d662187 100644
--- a/common/src/app/common/geom/shapes/grid_layout/positions.cljc
+++ b/common/src/app/common/geom/shapes/grid_layout/positions.cljc
@@ -142,7 +142,9 @@
:center
[(gpt/add origin-h (hv (/ child-width 2)))
- (gpo/project-point cell-bounds :h (gpo/center cell-bounds))]
+ (-> (gpo/project-point cell-bounds :h (gpo/center cell-bounds))
+ (gpt/add (hv (/ left-m 2)))
+ (gpt/subtract (hv (/ right-m 2))))]
[origin-h
(gpt/add (first cell-bounds) (hv left-m))])
@@ -155,7 +157,9 @@
:center
[(gpt/add origin-v (vv (/ child-height 2)))
- (gpo/project-point cell-bounds :v (gpo/center cell-bounds))]
+ (-> (gpo/project-point cell-bounds :v (gpo/center cell-bounds))
+ (gpt/add (vv top-m))
+ (gpt/subtract (vv bottom-m)))]
[origin-v
(gpt/add (first cell-bounds) (vv top-m))])]
diff --git a/common/src/app/common/pages/helpers.cljc b/common/src/app/common/pages/helpers.cljc
index 1dd97280d6..c0885d892f 100644
--- a/common/src/app/common/pages/helpers.cljc
+++ b/common/src/app/common/pages/helpers.cljc
@@ -635,8 +635,8 @@
(cond
(> (ctl/layout-z-index child-a) (ctl/layout-z-index child-b)) 1
(< (ctl/layout-z-index child-a) (ctl/layout-z-index child-b)) -1
- (> idx-a idx-b) 1
- (< idx-a idx-b) -1
+ (< idx-a idx-b) 1
+ (> idx-a idx-b) -1
:else 0))
(defn sort-layout-children-z-index
diff --git a/common/src/app/common/types/shape/attrs.cljc b/common/src/app/common/types/shape/attrs.cljc
index 100861cf25..1f787c44a4 100644
--- a/common/src/app/common/types/shape/attrs.cljc
+++ b/common/src/app/common/types/shape/attrs.cljc
@@ -73,7 +73,9 @@
:layout-item-min-h
:layout-item-max-w
:layout-item-min-w
- :layout-item-align-self}
+ :layout-item-align-self
+ :layout-item-absolute
+ :layout-item-z-index}
:group #{:proportion-lock
:width :height
@@ -164,7 +166,9 @@
:layout-item-min-h
:layout-item-max-w
:layout-item-min-w
- :layout-item-align-self}
+ :layout-item-align-self
+ :layout-item-absolute
+ :layout-item-z-index}
:circle #{:proportion-lock
:width :height
@@ -217,7 +221,9 @@
:layout-item-min-h
:layout-item-max-w
:layout-item-min-w
- :layout-item-align-self}
+ :layout-item-align-self
+ :layout-item-absolute
+ :layout-item-z-index}
:path #{:proportion-lock
:width :height
@@ -270,7 +276,9 @@
:layout-item-min-h
:layout-item-max-w
:layout-item-min-w
- :layout-item-align-self}
+ :layout-item-align-self
+ :layout-item-absolute
+ :layout-item-z-index}
:text #{:proportion-lock
:width :height
@@ -347,7 +355,9 @@
:layout-item-min-h
:layout-item-max-w
:layout-item-min-w
- :layout-item-align-self}
+ :layout-item-align-self
+ :layout-item-absolute
+ :layout-item-z-index}
:image #{:proportion-lock
:width :height
@@ -383,7 +393,9 @@
:layout-item-min-h
:layout-item-max-w
:layout-item-min-w
- :layout-item-align-self}
+ :layout-item-align-self
+ :layout-item-absolute
+ :layout-item-z-index}
:svg-raw #{:proportion-lock
:width :height
@@ -438,7 +450,9 @@
:layout-item-min-h
:layout-item-max-w
:layout-item-min-w
- :layout-item-align-self}
+ :layout-item-align-self
+ :layout-item-absolute
+ :layout-item-z-index}
:bool #{:proportion-lock
:width :height
@@ -492,6 +506,8 @@
:layout-item-min-h
:layout-item-max-w
:layout-item-min-w
- :layout-item-align-self}})
+ :layout-item-align-self
+ :layout-item-absolute
+ :layout-item-z-index}})
diff --git a/frontend/src/app/main/data/preview.cljs b/frontend/src/app/main/data/preview.cljs
new file mode 100644
index 0000000000..d00daefb9c
--- /dev/null
+++ b/frontend/src/app/main/data/preview.cljs
@@ -0,0 +1,110 @@
+;; This Source Code Form is subject to the terms of the Mozilla Public
+;; License, v. 2.0. If a copy of the MPL was not distributed with this
+;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
+;;
+;; Copyright (c) KALEIDOS INC
+
+(ns app.main.data.preview
+ (:require
+ ["js-beautify" :as beautify]
+ [app.common.data :as d]
+ [app.common.data.macros :as dm]
+ [app.common.pages.helpers :as cph]
+ [app.common.types.shape-tree :as ctst]
+ [app.main.data.workspace.state-helpers :as wsh]
+ [app.main.fonts :as fonts]
+ [app.main.refs :as refs]
+ [app.util.code-gen :as cg]
+ [app.util.timers :as ts]
+ [beicon.core :as rx]
+ [clojure.set :as set]
+ [cuerdas.core :as str]
+ [potok.core :as ptk]))
+
+(def style-type "css")
+(def markup-type "html")
+
+
+(def page-template
+ "
+
+
+
+
+
+ %s
+
+")
+
+(defn format-code [code type]
+ (cond-> code
+ (= type "svg")
+ (-> (str/replace "" "")
+ (str/replace "><" ">\n<"))
+
+ (or (= type "svg") (= type "html"))
+ (beautify/html #js {"indent_size" 2})))
+
+(defn update-preview-window
+ [preview code]
+ (when preview
+ (if (aget preview "load")
+ (.load preview code)
+ (ts/schedule #(update-preview-window preview code)))))
+
+(defn shapes->fonts
+ [shapes]
+ (->> shapes
+ (filter cph/text-shape?)
+ (map (comp fonts/get-content-fonts :content))
+ (reduce set/union #{})))
+
+(defn update-preview
+ [preview shape-id]
+ (ptk/reify ::update-preview
+ ptk/EffectEvent
+ (effect [_ state _]
+ (let [objects (wsh/lookup-page-objects state)
+ shape (get objects shape-id)
+
+ all-children
+ (->> (cph/selected-with-children objects [shape-id])
+ (ctst/sort-z-index objects)
+ (keep (d/getf objects)))
+
+ fonts (shapes->fonts all-children)]
+
+ (->> (rx/from fonts)
+ (rx/merge-map fonts/fetch-font-css)
+ (rx/reduce conj [])
+ (rx/map #(str/join "\n" %))
+ (rx/subs
+ (fn [fontfaces-css]
+ (let [style-code
+ (dm/str
+ fontfaces-css "\n"
+ (-> (cg/generate-style-code objects style-type all-children)
+ (format-code style-type)))
+
+ markup-code
+ (-> (cg/generate-markup-code objects markup-type [shape])
+ (format-code markup-type))]
+
+ (update-preview-window preview (str/format page-template style-code markup-code))))))))))
+
+(defn open-preview-selected
+ []
+ (ptk/reify ::open-preview-selected
+ ptk/WatchEvent
+ (watch [_ state _]
+ (let [shape-id (first (wsh/lookup-selected state))
+ closed-preview (rx/subject)
+ preview (.open js/window "/#/frame-preview")
+ listener-fn #(rx/push! closed-preview true)]
+ (.addEventListener preview "beforeunload" listener-fn)
+ (->> (rx/from-atom (refs/all-children-objects shape-id) {:emit-current-value? true})
+ (rx/take-until closed-preview)
+ (rx/debounce 1000)
+ (rx/map #(update-preview preview shape-id)))))))
diff --git a/frontend/src/app/main/ui.cljs b/frontend/src/app/main/ui.cljs
index 9dca64ce64..49879769c9 100644
--- a/frontend/src/app/main/ui.cljs
+++ b/frontend/src/app/main/ui.cljs
@@ -16,6 +16,7 @@
[app.main.ui.cursors :as c]
[app.main.ui.dashboard :refer [dashboard]]
[app.main.ui.debug.components-preview :as cm]
+ [app.main.ui.frame-preview :as frame-preview]
[app.main.ui.icons :as i]
[app.main.ui.messages :as msgs]
[app.main.ui.onboarding]
@@ -135,6 +136,9 @@
:page-id page-id
:layout-name layout
:key file-id}])
+
+ :frame-preview
+ [:& frame-preview/frame-preview]
nil)]]))
(mf/defc app
diff --git a/frontend/src/app/main/ui/components/numeric_input.cljs b/frontend/src/app/main/ui/components/numeric_input.cljs
index e501a85f75..a5b23b45d5 100644
--- a/frontend/src/app/main/ui/components/numeric_input.cljs
+++ b/frontend/src/app/main/ui/components/numeric_input.cljs
@@ -41,7 +41,7 @@
min-value (d/parse-double min-value)
max-value (d/parse-double max-value)
step-value (d/parse-double step-value 1)
- default (d/parse-double default 0)
+ default (d/parse-double default (when-not nillable? 0))
select-on-focus? (d/nilv (unchecked-get props "selectOnFocus") true)
diff --git a/frontend/src/app/main/ui/frame_preview.cljs b/frontend/src/app/main/ui/frame_preview.cljs
new file mode 100644
index 0000000000..9188edb51f
--- /dev/null
+++ b/frontend/src/app/main/ui/frame_preview.cljs
@@ -0,0 +1,75 @@
+;; This Source Code Form is subject to the terms of the Mozilla Public
+;; License, v. 2.0. If a copy of the MPL was not distributed with this
+;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
+;;
+;; Copyright (c) KALEIDOS INC
+
+(ns app.main.ui.frame-preview
+ (:require
+ [app.common.data :as d]
+ [rumext.v2 :as mf]))
+
+(mf/defc frame-preview
+ {::mf/wrap-props false
+ ::mf/wrap [mf/memo]}
+ []
+
+ (let [iframe-ref (mf/use-ref nil)
+ last-data* (mf/use-state nil)
+
+ zoom-ref (mf/use-ref nil)
+ zoom* (mf/use-state 1)
+ zoom @zoom*
+
+
+ handle-load
+ (mf/use-callback
+ (fn [data]
+ (prn "handle-load" data)
+ (reset! last-data* data)
+ (let [iframe-dom (mf/ref-val iframe-ref)]
+ (when iframe-dom
+ (-> iframe-dom .-contentWindow .-document .open)
+ (-> iframe-dom .-contentWindow .-document (.write data))
+ (-> iframe-dom .-contentWindow .-document .close)))))
+
+ load-ref
+ (mf/use-callback
+ (fn [iframe-dom]
+ (.log js/console "load-ref" iframe-dom)
+ (mf/set-ref-val! iframe-ref iframe-dom)
+ (when (and iframe-dom @last-data*)
+ (-> iframe-dom .-contentWindow .-document .open)
+ (-> iframe-dom .-contentWindow .-document (.write @last-data*))
+ (-> iframe-dom .-contentWindow .-document .close))))
+
+ change-zoom
+ (mf/use-callback
+ (fn []
+ (let [zoom-level (d/parse-integer (.-value (mf/ref-val zoom-ref)))]
+ (reset! zoom* (/ zoom-level 100)))))]
+
+ (mf/use-effect
+ (fn []
+ (aset js/window "load" handle-load)
+ #(js-delete js/window "load")))
+
+ [:div {:style {:display "flex" :width "100%" :height "100%" :flex-direction "column" :overflow "auto" :align-items "center"}}
+ [:input {:id "zoom-input"
+ :ref zoom-ref
+ :type "range" :min 1 :max 200 :default-value 100
+ :on-change change-zoom
+ :style {:max-width "500px"}}]
+
+ [:div {:style {:width "100%" :height "100%" :overflow "auto"}}
+ [:iframe {:ref load-ref
+ :frameborder "0"
+ :scrolling "no"
+ :style {:width (str (* 100 (if (> zoom 1)
+ (* 1 zoom)
+ (/ 1 zoom))) "%")
+ :height (str (* 100 (if (> zoom 1)
+ (* 1 zoom)
+ (/ 1 zoom))) "%")
+ :transform-origin "left top"
+ :transform (str "scale(" zoom ")")}}]]]))
diff --git a/frontend/src/app/main/ui/routes.cljs b/frontend/src/app/main/ui/routes.cljs
index 4944fcc85a..20a103ccb8 100644
--- a/frontend/src/app/main/ui/routes.cljs
+++ b/frontend/src/app/main/ui/routes.cljs
@@ -50,6 +50,7 @@
["/options" :settings-options]
["/access-tokens" :settings-access-tokens]]
+ ["/frame-preview" :frame-preview]
["/view/:file-id"
{:name :viewer
:conform
diff --git a/frontend/src/app/main/ui/shapes/frame.cljs b/frontend/src/app/main/ui/shapes/frame.cljs
index ae7fddc771..893fc33b9d 100644
--- a/frontend/src/app/main/ui/shapes/frame.cljs
+++ b/frontend/src/app/main/ui/shapes/frame.cljs
@@ -168,8 +168,7 @@
is-component? (mf/use-ctx muc/is-component?)
childs (cond-> childs
(ctl/any-layout? shape)
- (cph/sort-layout-children-z-index))
- ]
+ (cph/sort-layout-children-z-index))]
[:> frame-container props
[:g.frame-children {:opacity (:opacity shape)}
diff --git a/frontend/src/app/main/ui/viewer/inspect/code.cljs b/frontend/src/app/main/ui/viewer/inspect/code.cljs
index 91fdd23db8..c26c698e81 100644
--- a/frontend/src/app/main/ui/viewer/inspect/code.cljs
+++ b/frontend/src/app/main/ui/viewer/inspect/code.cljs
@@ -14,6 +14,7 @@
[app.common.types.shape-tree :as ctst]
[app.config :as cfg]
[app.main.data.events :as ev]
+ ;; [app.main.data.preview :as dp]
[app.main.fonts :as fonts]
[app.main.refs :as refs]
[app.main.store :as st]
@@ -95,6 +96,16 @@
(str/replace value old new))
value map))
+(defn gen-all-code
+ [style-code markup-code images-data]
+ (let [markup-code (cond-> markup-code
+ embed-images? (replace-map images-data))
+
+ style-code (cond-> style-code
+ remove-localhost?
+ (str/replace "http://localhost:3449" ""))]
+ (str/format page-template style-code markup-code)))
+
(mf/defc code
[{:keys [shapes frame on-expand from]}]
(let [style-type* (mf/use-state "css")
@@ -110,16 +121,8 @@
shapes (->> shapes
(map #(gsh/translate-to-frame % frame)))
- route (mf/deref refs/route)
- page-id (:page-id (:query-params route))
- flex-items (get-flex-elements page-id shapes from)
objects (get-objects from)
- ;; TODO REMOVE THIS
- shapes (->> shapes
- (map #(assoc % :parent (get objects (:parent-id %))))
- (map #(assoc % :flex-items flex-items)))
-
all-children (->> shapes
(map :id)
(cph/selected-with-children objects)
@@ -194,15 +197,13 @@
(mf/use-callback
(mf/deps style-code markup-code images-data)
(fn []
- (let [markup-code (cond-> markup-code
- embed-images? (replace-map images-data))
+ (wapi/write-to-clipboard (gen-all-code style-code markup-code images-data))))
- style-code (cond-> style-code
- remove-localhost?
- (str/replace "http://localhost:3449" ""))
-
- data (str/format page-template style-code markup-code)]
- (wapi/write-to-clipboard data))))]
+ ;;handle-open-review
+ ;;(mf/use-callback
+ ;; (fn []
+ ;; (st/emit! (dp/open-preview-selected))))
+ ]
(mf/use-effect
(mf/deps fonts)
@@ -231,6 +232,10 @@
[:button.download-button {:on-click handle-copy-all-code}
"Copy all code"]]
+ #_[:div.attributes-block
+ [:button.download-button {:on-click handle-open-review}
+ "Preview"]]
+
[:div.code-block
[:div.code-row-lang
[:& select {:default-value style-type
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs
index 0207f372be..dd62d15a55 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs
@@ -525,6 +525,7 @@
:on-focus #(do
(dom/select-target %)
(select-paddings true false true false))
+ :min 0
:value p1}]]
[:div {:class (stl/css :padding-simple)
:title "Horizontal padding"}
@@ -538,6 +539,7 @@
:on-focus #(do (dom/select-target %)
(select-paddings false true false true))
:on-blur #(select-paddings false false false false)
+ :min 0
:value p2}]]]
(= padding-type :multiple)
[:div {:class (stl/css :paddings-multiple)}
@@ -553,6 +555,7 @@
:on-focus #(do (dom/select-target %)
(select-padding :p1))
:on-blur #(select-paddings false false false false)
+ :min 0
:value (:p1 (:layout-padding values))}]]
[:div {:class (stl/css :padding-multiple)
@@ -566,6 +569,7 @@
:on-focus #(do (dom/select-target %)
(select-padding :p2))
:on-blur #(select-paddings false false false false)
+ :min 0
:value (:p2 (:layout-padding values))}]]
[:div {:class (stl/css :padding-multiple)
@@ -579,6 +583,7 @@
:on-focus #(do (dom/select-target %)
(select-padding :p3))
:on-blur #(select-paddings false false false false)
+ :min 0
:value (:p3 (:layout-padding values))}]]
[:div {:class (stl/css :padding-multiple)
@@ -592,6 +597,7 @@
:on-focus #(do (dom/select-target %)
(select-padding :p4))
:on-blur #(select-paddings false false false false)
+ :min 0
:value (:p4 (:layout-padding values))}]]])]
[:button {:class (stl/css-case :padding-toggle true
:selected (= padding-type :multiple))
@@ -612,6 +618,7 @@
:on-focus #(do
(dom/select-target %)
(select-paddings true false true false))
+ :min 0
:value p1}]]
[:div.padding-item.tooltip.tooltip-bottom-left
@@ -623,6 +630,7 @@
:on-focus #(do (dom/select-target %)
(select-paddings false true false true))
:on-blur #(select-paddings false false false false)
+ :min 0
:value p2}]]]
(= padding-type :multiple)
@@ -642,6 +650,7 @@
:on-focus #(do (dom/select-target %)
(select-padding num))
:on-blur #(select-paddings false false false false)
+ :min 0
:value (num (:layout-padding values))}]]])])
[:div.padding-icons
@@ -682,6 +691,7 @@
:on-blur (fn [_]
(select-gap nil)
(reset! gap-selected? :none))
+ :min 0
:value (:row-gap gap-value)
:disabled (and (= :nowrap wrap-type) (not is-col?))}]]
[:div {:class (stl/css-case :column-gap true
@@ -700,6 +710,7 @@
:on-blur (fn [_]
(select-gap nil)
(reset! gap-selected? :none))
+ :min 0
:value (:column-gap gap-value)
:disabled (and (= :nowrap wrap-type) is-col?)}]]]
@@ -720,6 +731,7 @@
:on-blur (fn [_]
(select-gap nil)
(reset! gap-selected? :none))
+ :min 0
:value (:column-gap gap-value)
:disabled (and (= :nowrap wrap-type) is-col?)}]]
@@ -737,6 +749,7 @@
:on-blur (fn [_]
(select-gap nil)
(reset! gap-selected? :none))
+ :min 0
:value (:row-gap gap-value)
:disabled (and (= :nowrap wrap-type) (not is-col?))}]]]])))
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs
index 7f88b351f7..7a54130e98 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs
@@ -42,23 +42,24 @@
(let [new-css-system (mf/use-ctx ctx/new-css-system)
margin-type (or (:layout-item-margin-type values) :simple)
- m1 (if (and (not (= :multiple (:layout-item-margin values)))
+ m1 (when (and (not (= :multiple (:layout-item-margin values)))
(= (dm/get-in values [:layout-item-margin :m1])
(dm/get-in values [:layout-item-margin :m3])))
(dm/get-in values [:layout-item-margin :m1])
- "--")
+ )
- m2 (if (and (not (= :multiple (:layout-item-margin values)))
+ m2 (when (and (not (= :multiple (:layout-item-margin values)))
(= (dm/get-in values [:layout-item-margin :m2])
(dm/get-in values [:layout-item-margin :m4])))
(dm/get-in values [:layout-item-margin :m2])
- "--")
+ )
select-margins
(fn [m1? m2? m3? m4?]
(st/emit! (udw/set-margins-selected {:m1 m1? :m2 m2? :m3 m3? :m4 m4?})))
select-margin #(select-margins (= % :m1) (= % :m2) (= % :m3) (= % :m4))]
+
(mf/use-effect
(fn []
(fn []
@@ -77,12 +78,12 @@
i/margin-top-bottom-refactor]
[:> numeric-input* {:className (stl/css :numeric-input)
:placeholder "--"
+ :nillable true
:value m1
:on-focus (fn [event]
(select-margins true false true false)
(dom/select-target event))
:on-change (partial on-margin-change :simple :m1)
-
:on-blur #(select-margins false false false false)}]]
[:div {:class (stl/css :horizontal-margin)
@@ -96,6 +97,7 @@
(dom/select-target event))
:on-change (partial on-margin-change :simple :m2)
:on-blur #(select-margins false false false false)
+ :nillable true
:value m2}]]]
(= margin-type :multiple)
@@ -111,6 +113,7 @@
(dom/select-target event))
:on-change (partial on-margin-change :multiple :m1)
:on-blur #(select-margins false false false false)
+ :nillable true
:value (:m1 (:layout-item-margin values))}]]
[:div {:class (stl/css :right-margin)
:title "Right margin"}
@@ -123,6 +126,7 @@
(dom/select-target event))
:on-change (partial on-margin-change :multiple :m2)
:on-blur #(select-margins false false false false)
+ :nillable true
:value (:m2 (:layout-item-margin values))}]]
[:div {:class (stl/css :bottom-margin)
@@ -136,6 +140,7 @@
(dom/select-target event))
:on-change (partial on-margin-change :multiple :m3)
:on-blur #(select-margins false false false false)
+ :nillable true
:value (:m3 (:layout-item-margin values))}]]
[:div {:class (stl/css :left-margin)
:title "Left margin"}
@@ -148,6 +153,7 @@
(dom/select-target event))
:on-change (partial on-margin-change :multiple :m4)
:on-blur #(select-margins false false false false)
+ :nillable true
:value (:m4 (:layout-item-margin values))}]]])]
[:button {:class (stl/css-case :margin-mode true
:selected (= margin-type :multiple))
@@ -169,6 +175,7 @@
(dom/select-target event))
:on-change (partial on-margin-change :simple :m1)
:on-blur #(select-margins false false false false)
+ :nillable true
:value m1}]]
[:div.margin-item.tooltip.tooltip-bottom-left
@@ -181,6 +188,7 @@
(dom/select-target event))
:on-change (partial on-margin-change :simple :m2)
:on-blur #(select-margins false false false false)
+ :nillable true
:value m2}]]]
(= margin-type :multiple)
@@ -201,6 +209,7 @@
(dom/select-target event))
:on-change (partial on-margin-change :multiple num)
:on-blur #(select-margins false false false false)
+ :nillable true
:value (num (:layout-item-margin values))}]]])])
[:div.margin-item-icons
@@ -519,8 +528,7 @@
:on-change-behaviour-v-refactor on-change-behaviour-v
:on-change on-change-behaviour}]
(when is-absolute?
- [:div {:class (stl/css-case :z-index-wrapper true
- :disabled (not is-absolute?))
+ [:div {:class (stl/css-case :z-index-wrapper true)
:title "z-index"}
[:span {:class (stl/css :icon-text)}
@@ -653,7 +661,6 @@
:on-focus #(dom/select-target %)
:on-change #(on-change-z-index %)
:nillable true
- :disabled (not is-absolute?)
:value (:layout-item-z-index values)}]]]])
[:*
diff --git a/frontend/src/app/util/code_gen/common.cljs b/frontend/src/app/util/code_gen/common.cljs
index 1cddbf506c..aa4719c626 100644
--- a/frontend/src/app/util/code_gen/common.cljs
+++ b/frontend/src/app/util/code_gen/common.cljs
@@ -11,13 +11,15 @@
(defn shape->selector
[shape]
- (let [name (-> (:name shape)
- (subs 0 (min 10 (count (:name shape))))
- (str/replace #"[^a-zA-Z0-9\s\:]+" ""))
- ;; selectors cannot start with numbers
- name (if (re-matches #"^\d.*" name) (dm/str "c-" name) name)
- id (-> (dm/str (:id shape))
- (subs 24 36))
- selector (str/css-selector (dm/str name " " id))
- selector (if (str/starts-with? selector "-") (subs selector 1) selector)]
- selector))
+ (if shape
+ (let [name (-> (:name shape)
+ (subs 0 (min 10 (count (:name shape))))
+ (str/replace #"[^a-zA-Z0-9\s\:]+" ""))
+ ;; selectors cannot start with numbers
+ name (if (re-matches #"^\d.*" name) (dm/str "c-" name) name)
+ id (-> (dm/str (:id shape))
+ (subs 24 36))
+ selector (str/css-selector (dm/str name " " id))
+ selector (if (str/starts-with? selector "-") (subs selector 1) selector)]
+ selector)
+ ""))
diff --git a/frontend/src/app/util/code_gen/markup_html.cljs b/frontend/src/app/util/code_gen/markup_html.cljs
index db7f27d4b6..4c5fdf0c5c 100644
--- a/frontend/src/app/util/code_gen/markup_html.cljs
+++ b/frontend/src/app/util/code_gen/markup_html.cljs
@@ -42,7 +42,7 @@
;; When a shape has several strokes or the stroke is not a "border"
(or (> (count (:strokes shape)) 1)
(and (= (count (:strokes shape)) 1)
- (not= (-> shape :strokes first :stroke-alignment) :center)))))
+ (not= (-> shape :strokes first :stroke-alignment) :inner)))))
(defn generate-html
([objects shape]
@@ -58,7 +58,8 @@
(let [svg-markup (generate-svg objects shape)]
(dm/fmt "%\n%\n%
"
indent
- (cgc/shape->selector shape)
+ (dm/str "shape " (d/name (:type shape)) " "
+ (cgc/shape->selector shape))
svg-markup
indent))
@@ -66,7 +67,8 @@
(let [text-shape-html (rds/renderToStaticMarkup (mf/element text/text-shape #js {:shape shape :code? true}))]
(dm/fmt "%\n%\n%
"
indent
- (cgc/shape->selector shape)
+ (dm/str "shape " (d/name (:type shape)) " "
+ (cgc/shape->selector shape))
text-shape-html
indent))
@@ -76,19 +78,22 @@
(dm/fmt "%
\n%"
indent
image-url
- (cgc/shape->selector shape)
+ (dm/str "shape " (d/name (:type shape)) " "
+ (cgc/shape->selector shape))
indent))
(empty? (:shapes shape))
(dm/fmt "%\n%
"
indent
- (cgc/shape->selector shape)
+ (dm/str "shape " (d/name (:type shape)) " "
+ (cgc/shape->selector shape))
indent)
:else
(dm/fmt "%\n%\n%
"
indent
- (cgc/shape->selector shape)
+ (dm/str (d/name (:type shape)) " "
+ (cgc/shape->selector shape))
(->> (:shapes shape)
(maybe-reverse)
(map #(generate-html objects (get objects %) (inc level)))
diff --git a/frontend/src/app/util/code_gen/style_css.cljs b/frontend/src/app/util/code_gen/style_css.cljs
index 18dab1a592..cabbda8051 100644
--- a/frontend/src/app/util/code_gen/style_css.cljs
+++ b/frontend/src/app/util/code_gen/style_css.cljs
@@ -21,7 +21,6 @@
;;
(def prelude "
html, body {
- background-color: #E8E9EA;
margin: 0;
min-height: 100%;
min-width: 100%;
@@ -78,6 +77,7 @@ svg {
:column-gap
:row-gap
:padding
+ :z-index
;; Flex related properties
:flex-direction
diff --git a/frontend/src/app/util/code_gen/style_css_formats.cljs b/frontend/src/app/util/code_gen/style_css_formats.cljs
index 440868be75..83ce8580c3 100644
--- a/frontend/src/app/util/code_gen/style_css_formats.cljs
+++ b/frontend/src/app/util/code_gen/style_css_formats.cljs
@@ -17,6 +17,8 @@
:top :position
:width :size
:height :size
+ :min-width :size
+ :min-height :size
:background :color
:background-color :color
:background-image :color-array
@@ -28,6 +30,7 @@
:row-gap :size-array
:column-gap :size-array
:padding :size-array
+ :margin :size-array
:grid-template-rows :tracks
:grid-template-columns :tracks
:transform :matrix
diff --git a/frontend/src/app/util/code_gen/style_css_values.cljs b/frontend/src/app/util/code_gen/style_css_values.cljs
index 53805f28f2..148adcb502 100644
--- a/frontend/src/app/util/code_gen/style_css_values.cljs
+++ b/frontend/src/app/util/code_gen/style_css_values.cljs
@@ -28,8 +28,9 @@
(cond
(or (and (ctl/any-layout-immediate-child? objects shape)
(not (ctl/layout-absolute? shape))
- (or (cph/group-shape? shape)
- (cph/frame-shape? shape)))
+ (or (cph/group-like-shape? shape)
+ (cph/frame-shape? shape)
+ (svg-markup? shape)))
(cph/root-frame? shape))
:relative
@@ -42,32 +43,20 @@
(defn get-shape-position
[shape objects coord]
- (let [
- parent (get objects (:parent-id shape))
- parent-value (dm/get-in parent [:selrect coord])
- [selrect _ _]
- (-> (:points shape)
- (gsh/transform-points (gsh/shape->center parent) (:transform-inverse parent))
- (gsh/calculate-geometry))
-
- ;;shape (gsh/transform-shape)
- shape-value (get selrect coord)
- ]
- (when (and (not (cph/root-frame? shape))
- (or (not (ctl/any-layout-immediate-child? objects shape))
- (ctl/layout-absolute? shape)))
- (- shape-value parent-value))))
-
-#_(defn get-shape-position
- [shape objects coord]
- (when-not (or (cph/root-frame? shape)
- (and (ctl/any-layout-immediate-child? objects shape)
- (not (ctl/layout-absolute? shape))))
+ (when (and (not (cph/root-frame? shape))
+ (or (not (ctl/any-layout-immediate-child? objects shape))
+ (ctl/layout-absolute? shape)))
(let [parent (get objects (:parent-id shape))
- bounds (gpo/parent-coords-bounds (:points shape) (:points parent))
- vv (gpt/to-vec (first (:points parent)) (first bounds))]
- (get vv coord))))
+ parent-value (dm/get-in parent [:selrect coord])
+
+ [selrect _ _]
+ (-> (:points shape)
+ (gsh/transform-points (gsh/shape->center parent) (:transform-inverse parent))
+ (gsh/calculate-geometry))
+
+ shape-value (get selrect coord)]
+ (- shape-value parent-value))))
(defmethod get-value :left
[_ shape objects]
@@ -83,7 +72,7 @@
(:layout-item-h-sizing shape)
(:layout-item-v-sizing shape))]
(cond
- (or (and (ctl/any-layout? shape) (= sizing :auto))
+ (or (and (ctl/any-layout? shape) (= sizing :auto) (not (svg-markup? shape)))
(and (ctl/any-layout-immediate-child? objects shape) (= sizing :fill)))
sizing
@@ -250,7 +239,8 @@
(defn get-grid-coord
[shape objects prop span-prop]
- (when (ctl/grid-layout-immediate-child? objects shape)
+ (when (and (ctl/grid-layout-immediate-child? objects shape)
+ (not (ctl/layout-absolute? shape)))
(let [parent (get objects (:parent-id shape))
cell (ctl/get-cell-by-shape-id parent (:id shape))]
(if (> (get cell span-prop) 1)
@@ -275,10 +265,22 @@
0))
(defmethod get-value :margin
- [_ shape objects]
+ [_ {:keys [layout-item-margin] :as shape} objects]
+
+ (when (ctl/any-layout-immediate-child? objects shape)
+ (let [default-margin {:m1 0 :m2 0 :m3 0 :m4 0}
+ {:keys [m1 m2 m3 m4]} (merge default-margin layout-item-margin)]
+ (when (or (not= m1 0) (not= m2 0) (not= m3 0) (not= m4 0))
+ [m1 m2 m3 m4]))))
+
+(defmethod get-value :z-index
+ [_ {:keys [layout-item-z-index] :as shape} objects]
(cond
- (ctl/flex-layout-immediate-child? objects shape)
- (:layout-item-margin shape)))
+ (cph/root-frame? shape)
+ 0
+
+ (ctl/any-layout-immediate-child? objects shape)
+ layout-item-z-index))
(defmethod get-value :max-height
[_ shape objects]
@@ -289,8 +291,11 @@
(defmethod get-value :min-height
[_ shape objects]
(cond
- (ctl/flex-layout-immediate-child? objects shape)
- (:layout-item-min-h shape)))
+ (and (ctl/flex-layout-immediate-child? objects shape) (some? (:layout-item-min-h shape)))
+ (:layout-item-min-h shape)
+
+ (and (ctl/auto-height? shape) (cph/frame-shape? shape) (not (:show-content shape)))
+ (-> shape :selrect :height)))
(defmethod get-value :max-width
[_ shape objects]
@@ -301,8 +306,11 @@
(defmethod get-value :min-width
[_ shape objects]
(cond
- (ctl/flex-layout-immediate-child? objects shape)
- (:layout-item-min-w shape)))
+ (and (ctl/flex-layout-immediate-child? objects shape) (some? (:layout-item-min-w shape)))
+ (:layout-item-min-w shape)
+
+ (and (ctl/auto-width? shape) (cph/frame-shape? shape) (not (:show-content shape)))
+ (-> shape :selrect :width)))
(defmethod get-value :align-self
[_ shape objects]
diff --git a/frontend/src/debug.cljs b/frontend/src/debug.cljs
index aa80159765..ea8e8a7e15 100644
--- a/frontend/src/debug.cljs
+++ b/frontend/src/debug.cljs
@@ -18,6 +18,7 @@
[app.common.uuid :as uuid]
[app.config :as cf]
[app.main.data.dashboard.shortcuts]
+ [app.main.data.preview :as dp]
[app.main.data.viewer.shortcuts]
[app.main.data.workspace :as dw]
[app.main.data.workspace.changes :as dwc]
@@ -212,6 +213,10 @@
[]
(dump-selected' @st/state))
+(defn ^:export preview-selected
+ []
+ (st/emit! (dp/open-preview-selected)))
+
(defn ^:export parent
[]
(let [state @st/state