mirror of
https://github.com/penpot/penpot.git
synced 2025-01-23 06:58:58 -05:00
Merge pull request #2565 from penpot/eva-autolayout-code
Eva autolayout code
This commit is contained in:
commit
527e4643da
14 changed files with 277 additions and 153 deletions
|
@ -23,12 +23,12 @@
|
|||
;; ITEMS
|
||||
;; :layout-item-margin ;; {:m1 0 :m2 0 :m3 0 :m4 0}
|
||||
;; :layout-item-margin-type ;; :simple :multiple
|
||||
;; :layout-item-h-sizing ;; :fill :fix :auto
|
||||
;; :layout-item-v-sizing ;; :fill :fix :auto
|
||||
;; :layout-item-h-sizing ;; :fill :fix :auto
|
||||
;; :layout-item-v-sizing ;; :fill :fix :auto
|
||||
;; :layout-item-max-h ;; num
|
||||
;; :layout-item-min-h ;; num
|
||||
;; :layout-item-max-w ;; num
|
||||
;; :layout-item-min-w
|
||||
;; :layout-item-min-w ;; num
|
||||
|
||||
(s/def ::layout #{:flex :grid})
|
||||
(s/def ::layout-flex-dir #{:row :reverse-row :column :reverse-column})
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
"@sentry/tracing": "^6.17.4",
|
||||
"date-fns": "^2.28.0",
|
||||
"draft-js": "^0.11.7",
|
||||
"highlight.js": "^11.5.1",
|
||||
"highlight.js": "^11.6.0",
|
||||
"js-beautify": "^1.14.4",
|
||||
"jszip": "^3.10.0",
|
||||
"luxon": "^3.0.1",
|
||||
|
|
|
@ -104,16 +104,19 @@
|
|||
(ptk/reify ::toogle-layout-flex
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (wsh/lookup-page-objects state page-id)
|
||||
selected (wsh/lookup-selected state)
|
||||
selected-shapes (map (d/getf objects) selected)
|
||||
single? (= (count selected-shapes) 1)
|
||||
has-flex-layout? (and single? (= :flex (:layout (first selected-shapes))))]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (wsh/lookup-page-objects state page-id)
|
||||
selected (wsh/lookup-selected state)
|
||||
selected-shapes (map (d/getf objects) selected)
|
||||
single? (= (count selected-shapes) 1)
|
||||
has-flex-layout? (and single? (= :flex (:layout (first selected-shapes))))
|
||||
is-frame? (and single? (= :frame (:type (first selected-shapes))))]
|
||||
|
||||
(if has-flex-layout?
|
||||
(rx/of (remove-layout selected))
|
||||
(rx/of (create-layout-from-selection :flex)))))))
|
||||
(if is-frame?
|
||||
(rx/of (create-layout [(first selected)] :flex))
|
||||
(rx/of (create-layout-from-selection :flex))))))))
|
||||
|
||||
(defn update-layout
|
||||
[ids changes]
|
||||
|
|
|
@ -447,14 +447,14 @@
|
|||
(some (partial ctl/layout-child? objects))))
|
||||
workspace-page-objects))
|
||||
|
||||
(defn get-flex-child-viewer?
|
||||
(defn get-flex-child-viewer
|
||||
[ids page-id]
|
||||
(l/derived
|
||||
(fn [state]
|
||||
(let [objects (wsh/lookup-viewer-objects state page-id)]
|
||||
(into []
|
||||
(comp (filter (partial ctl/layout-child? objects))
|
||||
(map (d/getf objects)))
|
||||
(comp (map (d/getf objects))
|
||||
(filter (partial ctl/layout-child? objects)))
|
||||
ids)))
|
||||
st/state =))
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
(mf/use-effect
|
||||
(mf/deps code type block-ref)
|
||||
(fn []
|
||||
(hljs/highlightBlock (mf/ref-val block-ref))))
|
||||
(hljs/highlightElement (mf/ref-val block-ref))))
|
||||
[:pre.code-display {:class type
|
||||
:ref block-ref} code]))
|
||||
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.math :as mth]))
|
||||
[app.common.math :as mth]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
(defn format-percent
|
||||
([value]
|
||||
|
@ -60,4 +61,34 @@
|
|||
{:p1 p1 :p2 p2 :p3 p3}
|
||||
|
||||
:else
|
||||
{:p1 p1 :p2 p2 :p3 p3})))
|
||||
{:p1 p1 :p2 p2 :p3 p3})))
|
||||
|
||||
(defn format-size [type value shape]
|
||||
(let [sizing (if (= type :width)
|
||||
(:layout-item-h-sizing shape)
|
||||
(:layout-item-v-sizing shape))]
|
||||
(if (= sizing :fill)
|
||||
"100%"
|
||||
(str (format-pixels value)))))
|
||||
|
||||
(defn format-padding
|
||||
[padding-values type]
|
||||
(let [new-padding (if (= :margin type)
|
||||
{:m1 0 :m2 0 :m3 0 :m4 0}
|
||||
{:p1 0 :p2 0 :p3 0 :p4 0})
|
||||
merged-padding (merge new-padding padding-values)
|
||||
short-hand (format-padding-margin-shorthand (vals merged-padding))
|
||||
parsed-values (map #(str/fmt "%spx" %) (vals short-hand))]
|
||||
(str/join " " parsed-values)))
|
||||
|
||||
(defn format-margin
|
||||
[margin-values]
|
||||
(format-padding margin-values :margin))
|
||||
|
||||
(defn format-gap
|
||||
[gap-values]
|
||||
(let [row-gap (:row-gap gap-values)
|
||||
column-gap (:column-gap gap-values)]
|
||||
(if (= row-gap column-gap)
|
||||
(str/fmt "%spx" row-gap)
|
||||
(str/fmt "%spx %spx" row-gap column-gap))))
|
|
@ -23,29 +23,31 @@
|
|||
:rx "border-radius"
|
||||
:r1 "border-radius"}
|
||||
:format {:rotation #(str/fmt "rotate(%sdeg)" %)
|
||||
:r1 #(apply str/fmt "%spx, %spx, %spx, %spx" %)}
|
||||
:r1 #(apply str/fmt "%spx, %spx, %spx, %spx" %)
|
||||
:width (partial fmt/format-size :width)
|
||||
:height (partial fmt/format-size :height)}
|
||||
:multi {:r1 [:r1 :r2 :r3 :r4]}})
|
||||
|
||||
(defn copy-data
|
||||
([shape]
|
||||
(apply copy-data shape properties))
|
||||
([shape & properties]
|
||||
([shape & properties]
|
||||
(cg/generate-css-props shape properties params)))
|
||||
|
||||
(mf/defc layout-block
|
||||
[{:keys [shape]}]
|
||||
(let [selrect (:selrect shape)
|
||||
{:keys [width height x y]} selrect]
|
||||
{:keys [x y]} selrect]
|
||||
[:*
|
||||
[:div.attributes-unit-row
|
||||
[:div.attributes-label (tr "handoff.attributes.layout.width")]
|
||||
[:div.attributes-value (fmt/format-pixels width)]
|
||||
[:& copy-button {:data (copy-data selrect :width)}]]
|
||||
[:div.attributes-value (fmt/format-size :width (:width shape) shape)]
|
||||
[:& copy-button {:data (copy-data shape :width)}]]
|
||||
|
||||
[:div.attributes-unit-row
|
||||
[:div.attributes-label (tr "handoff.attributes.layout.height")]
|
||||
[:div.attributes-value (fmt/format-pixels height)]
|
||||
[:& copy-button {:data (copy-data selrect :height)}]]
|
||||
[:div.attributes-value (fmt/format-size :height (:height shape) shape)]
|
||||
[:& copy-button {:data (copy-data shape :height)}]]
|
||||
|
||||
(when (not= (:x shape) 0)
|
||||
[:div.attributes-unit-row
|
||||
|
|
|
@ -13,20 +13,6 @@
|
|||
[cuerdas.core :as str]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(defn format-gap
|
||||
[gap-values]
|
||||
(let [row-gap (:row-gap gap-values)
|
||||
column-gap (:column-gap gap-values)]
|
||||
(if (= row-gap column-gap)
|
||||
(str/fmt "%spx" row-gap)
|
||||
(str/fmt "%spx %spx" row-gap column-gap))))
|
||||
|
||||
(defn format-padding
|
||||
[padding-values]
|
||||
(let [short-hand (fm/format-padding-margin-shorthand (vals padding-values))
|
||||
parsed-values (map #(str/fmt "%spx" %) (vals short-hand))]
|
||||
(str/join " " parsed-values)))
|
||||
|
||||
(def properties [:layout
|
||||
:layout-flex-dir
|
||||
:layout-align-items
|
||||
|
@ -49,7 +35,7 @@
|
|||
:layout-flex-dir "flex-direction"
|
||||
:layout-align-items "align-items"
|
||||
:layout-justify-content "justify-content"
|
||||
:layout-wrap-type "wrap"
|
||||
:layout-wrap-type "flex-wrap"
|
||||
:layout-gap "gap"
|
||||
:layout-padding "padding"}
|
||||
:format {:layout name
|
||||
|
@ -57,8 +43,8 @@
|
|||
:layout-align-items name
|
||||
:layout-justify-content name
|
||||
:layout-wrap-type name
|
||||
:layout-gap format-gap
|
||||
:layout-padding format-padding}})
|
||||
:layout-gap fm/format-gap
|
||||
:layout-padding fm/format-padding}})
|
||||
|
||||
(def layout-align-content-params
|
||||
{:props [:layout-align-content]
|
||||
|
@ -109,7 +95,7 @@
|
|||
[:& copy-button {:data (copy-data shape :layout-justify-content)}]]
|
||||
|
||||
[:div.attributes-unit-row
|
||||
[:div.attributes-label "Wrap"]
|
||||
[:div.attributes-label "Flex wrap"]
|
||||
[:div.attributes-value (str/capital (d/name (:layout-wrap-type shape)))]
|
||||
[:& copy-button {:data (copy-data shape :layout-wrap-type)}]]
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
[app.main.refs :as refs]
|
||||
[app.main.ui.components.copy-button :refer [copy-button]]
|
||||
[app.main.ui.formats :as fmt]
|
||||
[app.main.ui.hooks :as hooks]
|
||||
[app.main.ui.viewer.handoff.code :as cd]
|
||||
[app.util.code-gen :as cg]
|
||||
[cuerdas.core :as str]
|
||||
[rumext.v2 :as mf]))
|
||||
|
@ -18,41 +18,31 @@
|
|||
|
||||
(defn format-margin
|
||||
[margin-values]
|
||||
(let [short-hand (fmt/format-padding-margin-shorthand (vals margin-values))
|
||||
(let [short-hand (fmt/format-padding-margin-shorthand (vals margin-values))
|
||||
parsed-values (map #(str/fmt "%spx" %) (vals short-hand))]
|
||||
(str/join " " parsed-values)))
|
||||
|
||||
(def properties [:layout-item-margin ;; {:m1 0 :m2 0 :m3 0 :m4 0}
|
||||
:layout-item-h-sizing ;; :fill-width :fix-width :auto-width
|
||||
:layout-item-v-sizing ;; :fill-height :fix-height :auto-height
|
||||
:layout-item-max-h ;; num
|
||||
:layout-item-min-h ;; num
|
||||
:layout-item-max-w ;; num
|
||||
:layout-item-min-w ;; num
|
||||
:layout-item-align-self ;; :start :end :center :strech :baseline
|
||||
])
|
||||
|
||||
(def properties [:layout-item-margin ;; {:m1 0 :m2 0 :m3 0 :m4 0}
|
||||
:layout-item-max-h ;; num
|
||||
:layout-item-min-h ;; num
|
||||
:layout-item-max-w ;; num
|
||||
:layout-item-min-w ;; num
|
||||
:layout-item-align-self]) ;; :start :end :center
|
||||
|
||||
(def layout-flex-item-params
|
||||
{:props [:layout-item-margin
|
||||
:layout-item-h-sizing
|
||||
:layout-item-v-sizing
|
||||
:layout-item-max-h
|
||||
:layout-item-min-h
|
||||
:layout-item-max-w
|
||||
:layout-item-min-w
|
||||
:layout-item-align-self]
|
||||
:to-prop {:layout-item-margin "margin"
|
||||
:layout-item-h-sizing "width"
|
||||
:layout-item-v-sizing "height"
|
||||
:layout-item-align-self "align-self"
|
||||
:layout-item-max-h "max. height"
|
||||
:layout-item-min-h "min. height"
|
||||
:layout-item-max-w "max. width"
|
||||
:layout-item-min-w "min. width"}
|
||||
:layout-item-max-h "max-height"
|
||||
:layout-item-min-h "min-height"
|
||||
:layout-item-max-w "max-width"
|
||||
:layout-item-min-w "min-width"}
|
||||
:format {:layout-item-margin format-margin
|
||||
:layout-item-h-sizing name
|
||||
:layout-item-v-sizing name
|
||||
:layout-item-align-self name}})
|
||||
|
||||
(defn copy-data
|
||||
|
@ -69,65 +59,97 @@
|
|||
(for [[k v] values]
|
||||
[:span.items {:key (str type "-" k "-" v)} v "px"])]))
|
||||
|
||||
(defn manage-sizing
|
||||
[value type]
|
||||
(let [ref-value-h {:fill "Width 100%"
|
||||
:fix "Fixed width"
|
||||
:auto "Fit content"}
|
||||
ref-value-v {:fill "Height 100%"
|
||||
:fix "Fixed height"
|
||||
:auto "Fit content"}]
|
||||
(if (= :h type)
|
||||
(ref-value-h value)
|
||||
(ref-value-v value))))
|
||||
|
||||
(mf/defc layout-element-block
|
||||
[{:keys [shape]}]
|
||||
[:*
|
||||
[:div.attributes-unit-row
|
||||
[:div.attributes-label "Width"]
|
||||
[:div.attributes-value (str/capital (d/name (:layout-item-h-sizing shape)))]
|
||||
[:& copy-button {:data (copy-data shape :layout-item-h-sizing)}]]
|
||||
(let [old-margin (:layout-item-margin shape)
|
||||
new-margin {:m1 0 :m2 0 :m3 0 :m4 0}
|
||||
merged-margin (merge new-margin old-margin)
|
||||
shape (assoc shape :layout-item-margin merged-margin)]
|
||||
|
||||
[:div.attributes-unit-row
|
||||
[:div.attributes-label "Height"]
|
||||
[:div.attributes-value (str/capital (d/name (:layout-item-v-sizing shape)))]
|
||||
[:& copy-button {:data (copy-data shape :layout-item-v-sizing)}]]
|
||||
[:*
|
||||
(when (:layout-item-align-self shape)
|
||||
[:div.attributes-unit-row
|
||||
[:div.attributes-label "Align self"]
|
||||
[:div.attributes-value (str/capital (d/name (:layout-item-align-self shape)))]
|
||||
[:& copy-button {:data (copy-data shape :layout-item-align-self)}]])
|
||||
|
||||
[:div.attributes-unit-row
|
||||
[:div.attributes-label "Align self"]
|
||||
[:div.attributes-value (str/capital (d/name (:layout-item-align-self shape)))]
|
||||
[:& copy-button {:data (copy-data shape :layout-item-align-self)}]]
|
||||
(when (:layout-item-margin shape)
|
||||
[:div.attributes-unit-row
|
||||
[:div.attributes-label "Margin"]
|
||||
[:& manage-margin {:margin merged-margin :type "margin"}]
|
||||
[:& copy-button {:data (copy-data shape :layout-item-margin)}]])
|
||||
|
||||
(when (:layout-item-h-sizing shape)
|
||||
[:div.attributes-unit-row
|
||||
[:div.attributes-label "Horizontal sizing"]
|
||||
[:div.attributes-value (manage-sizing (:layout-item-h-sizing shape) :h)]
|
||||
[:& copy-button {:data (copy-data shape :layout-item-h-sizing)}]])
|
||||
|
||||
[:div.attributes-unit-row
|
||||
[:div.attributes-label "Margin"]
|
||||
[:& manage-margin {:margin (:layout-item-margin shape) :type "margin"}]
|
||||
[:& copy-button {:data (copy-data shape :layout-item-margin)}]]
|
||||
(when (:layout-item-v-sizing shape)
|
||||
[:div.attributes-unit-row
|
||||
[:div.attributes-label "Vertical sizing"]
|
||||
[:div.attributes-value (manage-sizing (:layout-item-v-sizing shape) :v)]
|
||||
[:& copy-button {:data (copy-data shape :layout-item-v-sizing)}]])
|
||||
|
||||
(when (= :fill (:layout-item-h-sizing shape))
|
||||
[:*
|
||||
(when (some? (:layout-item-max-w shape))
|
||||
[:div.attributes-unit-row
|
||||
[:div.attributes-label "Max. width"]
|
||||
[:div.attributes-value (fmt/format-pixels (:layout-item-max-w shape))]
|
||||
[:& copy-button {:data (copy-data shape :layout-item-max-w)}]])
|
||||
|
||||
[:div.attributes-unit-row
|
||||
[:div.attributes-label "Max. width"]
|
||||
[:div.attributes-value (fmt/format-pixels (:layout-item-max-w shape))]
|
||||
[:& copy-button {:data (copy-data shape :layout-item-max-w)}]]
|
||||
(when (some? (:layout-item-min-w shape))
|
||||
[:div.attributes-unit-row
|
||||
[:div.attributes-label "Min. width"]
|
||||
[:div.attributes-value (fmt/format-pixels (:layout-item-min-w shape))]
|
||||
[:& copy-button {:data (copy-data shape :layout-item-min-w)}]])])
|
||||
|
||||
[:div.attributes-unit-row
|
||||
[:div.attributes-label "Min. width"]
|
||||
[:div.attributes-value (fmt/format-pixels (:layout-item-min-w shape))]
|
||||
[:& copy-button {:data (copy-data shape :layout-item-min-w)}]]
|
||||
(when (= :fill (:layout-item-v-sizing shape))
|
||||
[:*
|
||||
(when (:layout-item-max-h shape)
|
||||
[:div.attributes-unit-row
|
||||
[:div.attributes-label "Max. height"]
|
||||
[:div.attributes-value (fmt/format-pixels (:layout-item-max-h shape))]
|
||||
[:& copy-button {:data (copy-data shape :layout-item-max-h)}]])
|
||||
|
||||
[:div.attributes-unit-row
|
||||
[:div.attributes-label "Max. height"]
|
||||
[:div.attributes-value (fmt/format-pixels (:layout-item-max-h shape))]
|
||||
[:& copy-button {:data (copy-data shape :layout-item-max-h)}]]
|
||||
|
||||
[:div.attributes-unit-row
|
||||
[:div.attributes-label "Min. height"]
|
||||
[:div.attributes-value (fmt/format-pixels (:layout-item-min-w shape))]
|
||||
[:& copy-button {:data (copy-data shape :layout-item-min-h)}]]])
|
||||
|
||||
(defn get-flex-elements [page-id shapes]
|
||||
(let [ids (mapv :id shapes)
|
||||
ids (hooks/use-equal-memo ids)
|
||||
get-layout-children-refs (mf/use-memo (mf/deps ids page-id) #(refs/get-flex-child-viewer? ids page-id))]
|
||||
|
||||
(mf/deref get-layout-children-refs)))
|
||||
(when (:layout-item-min-h shape)
|
||||
[:div.attributes-unit-row
|
||||
[:div.attributes-label "Min. height"]
|
||||
[:div.attributes-value (fmt/format-pixels (:layout-item-min-h shape))]
|
||||
[:& copy-button {:data (copy-data shape :layout-item-min-h)}]])])]))
|
||||
|
||||
(mf/defc layout-flex-element-panel
|
||||
[{:keys [shapes]}]
|
||||
(let [route (mf/deref refs/route)
|
||||
page-id (:page-id (:query-params route))
|
||||
shapes (get-flex-elements page-id shapes)]
|
||||
(when (and (= (count shapes) 1) (seq shapes))
|
||||
(let [route (mf/deref refs/route)
|
||||
page-id (:page-id (:query-params route))
|
||||
mod-shapes (cd/get-flex-elements page-id shapes)
|
||||
shape (first mod-shapes)
|
||||
has-margin? (some? (:layout-item-margin shape))
|
||||
has-values? (or (some? (:layout-item-max-w shape))
|
||||
(some? (:layout-item-max-h shape))
|
||||
(some? (:layout-item-min-w shape))
|
||||
(some? (:layout-item-min-h shape)))
|
||||
has-align? (some? (:layout-item-align-self shape))
|
||||
has-sizing? (or (some? (:layout-item-h-sizing shape))
|
||||
(some? (:layout-item-w-sizing shape)))
|
||||
must-show (or has-margin? has-values? has-align? has-sizing?)]
|
||||
(when (and (= (count mod-shapes) 1) must-show)
|
||||
[:div.attributes-block
|
||||
[:div.attributes-block-title
|
||||
[:div.attributes-block-title-text "Flex element"]
|
||||
[:& copy-button {:data (copy-data (first shapes))}]]
|
||||
[:& copy-button {:data (copy-data shape)}]]
|
||||
|
||||
[:& layout-element-block {:shape (first shapes)}]])))
|
||||
[:& layout-element-block {:shape shape}]])))
|
||||
|
|
|
@ -9,9 +9,11 @@
|
|||
["js-beautify" :as beautify]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.main.data.events :as ev]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.code-block :refer [code-block]]
|
||||
[app.main.ui.components.copy-button :refer [copy-button]]
|
||||
[app.main.ui.hooks :as hooks]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.code-gen :as cg]
|
||||
[app.util.dom :as dom]
|
||||
|
@ -40,13 +42,23 @@
|
|||
(cond-> code
|
||||
(= type "svg") (beautify/html #js {"indent_size" 2}))))
|
||||
|
||||
(defn get-flex-elements [page-id shapes]
|
||||
(let [ids (mapv :id shapes)
|
||||
ids (hooks/use-equal-memo ids)
|
||||
get-layout-children-refs (mf/use-memo (mf/deps ids page-id) #(refs/get-flex-child-viewer ids page-id))]
|
||||
|
||||
(mf/deref get-layout-children-refs)))
|
||||
|
||||
(mf/defc code
|
||||
[{:keys [shapes frame on-expand]}]
|
||||
(let [style-type (mf/use-state "css")
|
||||
(let [style-type (mf/use-state "css")
|
||||
markup-type (mf/use-state "svg")
|
||||
shapes (->> shapes
|
||||
(map #(gsh/translate-to-frame % frame)))
|
||||
|
||||
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)
|
||||
shapes (map #(assoc % :flex-items flex-items) shapes)
|
||||
style-code (-> (cg/generate-style-code @style-type shapes)
|
||||
(format-code "css"))
|
||||
|
||||
|
@ -67,15 +79,14 @@
|
|||
(fn []
|
||||
(st/emit! (ptk/event ::ev/event
|
||||
{::ev/name "copy-handoff-style"
|
||||
:type @style-type}))))
|
||||
]
|
||||
:type @style-type}))))]
|
||||
|
||||
[:div.element-options
|
||||
[:div.code-block
|
||||
[:div.code-row-lang "CSS"
|
||||
|
||||
[:button.expand-button
|
||||
{:on-click on-expand }
|
||||
{:on-click on-expand}
|
||||
i/full-screen]
|
||||
|
||||
[:& copy-button {:data style-code
|
||||
|
@ -96,6 +107,4 @@
|
|||
:on-copied on-markup-copied}]]
|
||||
[:div.code-row-display
|
||||
[:& code-block {:type @markup-type
|
||||
:code markup-code}]]]
|
||||
|
||||
]))
|
||||
:code markup-code}]]]]))
|
||||
|
|
|
@ -375,7 +375,9 @@
|
|||
has-group? (->> shapes (d/seek cph/group-shape?))
|
||||
is-group? (and single? has-group?)
|
||||
ids (->> shapes (map :id))
|
||||
add-flex #(st/emit! (dwsl/create-layout-from-selection :flex))
|
||||
add-flex #(st/emit! (if is-frame?
|
||||
(dwsl/create-layout ids :flex)
|
||||
(dwsl/create-layout-from-selection :flex)))
|
||||
remove-flex #(st/emit! (dwsl/remove-layout ids))]
|
||||
(cond
|
||||
(or (not single?) (and is-frame? (not is-flex-container?)) is-group?)
|
||||
|
|
|
@ -34,7 +34,14 @@
|
|||
(mf/defc margin-section
|
||||
[{:keys [values change-margin-style on-margin-change] :as props}]
|
||||
|
||||
(let [margin-type (or (:layout-item-margin-type values) :simple)]
|
||||
(let [margin-type (or (:layout-item-margin-type values) :simple)
|
||||
margins (if (nil? (:layout-item-margin values))
|
||||
{:m1 0 :m2 0 :m3 0 :m4 0}
|
||||
(:layout-item-margin values))
|
||||
rx (if (and (not (= :multiple (:layout-item-margin-type values)))
|
||||
(apply = (vals margins)))
|
||||
(:m1 margins)
|
||||
"--")]
|
||||
|
||||
[:div.margin-row
|
||||
[:div.margin-icons
|
||||
|
@ -59,7 +66,7 @@
|
|||
{:placeholder "--"
|
||||
:on-click #(dom/select-target %)
|
||||
:on-change (partial on-margin-change :simple)
|
||||
:value (or (-> values :layout-item-margin :m1) 0)}]]]
|
||||
:value rx}]]]
|
||||
|
||||
(= margin-type :multiple)
|
||||
(for [num [:m1 :m2 :m3 :m4]]
|
||||
|
|
|
@ -19,6 +19,11 @@
|
|||
(if (= style :inner-shadow) "inset " "")
|
||||
(str/fmt "%spx %spx %spx %spx %s" offset-x offset-y blur spread css-color))))
|
||||
|
||||
(defn format-gap
|
||||
[{row-gap :row-gap column-gap :column-gap}]
|
||||
(if (= row-gap column-gap)
|
||||
(str/fmt "%spx" row-gap)
|
||||
(str/fmt "%spx %spx" row-gap column-gap)))
|
||||
|
||||
(defn format-fill-color [_ shape]
|
||||
(let [color {:color (:fill-color shape)
|
||||
|
@ -37,27 +42,50 @@
|
|||
(str/format "%spx %s %s" width style (uc/color->background color)))))
|
||||
|
||||
(def styles-data
|
||||
{:layout {:props [:width :height :x :y :radius :rx :r1]
|
||||
:to-prop {:x "left"
|
||||
:y "top"
|
||||
:rotation "transform"
|
||||
:rx "border-radius"
|
||||
:r1 "border-radius"}
|
||||
:format {:rotation #(str/fmt "rotate(%sdeg)" %)
|
||||
:r1 #(apply str/fmt "%spx, %spx, %spx, %spx" %)}
|
||||
:multi {:r1 [:r1 :r2 :r3 :r4]}}
|
||||
:fill {:props [:fill-color :fill-color-gradient]
|
||||
:to-prop {:fill-color "background" :fill-color-gradient "background"}
|
||||
:format {:fill-color format-fill-color :fill-color-gradient format-fill-color}}
|
||||
:stroke {:props [:stroke-style]
|
||||
:to-prop {:stroke-style "border"}
|
||||
:format {:stroke-style format-stroke}}
|
||||
:shadow {:props [:shadow]
|
||||
:to-prop {:shadow :box-shadow}
|
||||
:format {:shadow #(str/join ", " (map shadow->css %1))}}
|
||||
:blur {:props [:blur]
|
||||
:to-prop {:blur "filter"}
|
||||
:format {:blur #(str/fmt "blur(%spx)" (:value %))}}})
|
||||
{:layout {:props [:width :height :x :y :radius :rx :r1]
|
||||
:to-prop {:x "left"
|
||||
:y "top"
|
||||
:rotation "transform"
|
||||
:rx "border-radius"
|
||||
:r1 "border-radius"}
|
||||
:format {:rotation #(str/fmt "rotate(%sdeg)" %)
|
||||
:r1 #(apply str/fmt "%spx, %spx, %spx, %spx" %)
|
||||
:width (partial fmt/format-size :width)
|
||||
:height (partial fmt/format-size :height)}
|
||||
:multi {:r1 [:r1 :r2 :r3 :r4]}}
|
||||
:fill {:props [:fill-color :fill-color-gradient]
|
||||
:to-prop {:fill-color "background" :fill-color-gradient "background"}
|
||||
:format {:fill-color format-fill-color :fill-color-gradient format-fill-color}}
|
||||
:stroke {:props [:stroke-style]
|
||||
:to-prop {:stroke-style "border"}
|
||||
:format {:stroke-style format-stroke}}
|
||||
:shadow {:props [:shadow]
|
||||
:to-prop {:shadow :box-shadow}
|
||||
:format {:shadow #(str/join ", " (map shadow->css %1))}}
|
||||
:blur {:props [:blur]
|
||||
:to-prop {:blur "filter"}
|
||||
:format {:blur #(str/fmt "blur(%spx)" (:value %))}}
|
||||
:layout-flex {:props [:layout
|
||||
:layout-align-items
|
||||
:layout-flex-dir
|
||||
:layout-justify-content
|
||||
:layout-gap
|
||||
:layout-padding
|
||||
:layout-wrap-type]
|
||||
:to-prop {:layout "display"
|
||||
:layout-flex-dir "flex-direction"
|
||||
:layout-align-items "align-items"
|
||||
:layout-justify-content "justify-content"
|
||||
:layout-wrap-type "flex-wrap"
|
||||
:layout-gap "gap"
|
||||
:layout-padding "padding"}
|
||||
:format {:layout name
|
||||
:layout-flex-dir name
|
||||
:layout-align-items name
|
||||
:layout-justify-content name
|
||||
:layout-wrap-type name
|
||||
:layout-gap format-gap
|
||||
:layout-padding fmt/format-padding}}})
|
||||
|
||||
(def style-text
|
||||
{:props [:fill-color
|
||||
|
@ -78,6 +106,26 @@
|
|||
:text-transform name
|
||||
:fill-color format-fill-color}})
|
||||
|
||||
(def layout-flex-item-params
|
||||
{:props [:layout-item-margin
|
||||
:layout-item-max-h
|
||||
:layout-item-min-h
|
||||
:layout-item-max-w
|
||||
:layout-item-min-w
|
||||
:layout-item-align-self]
|
||||
:to-prop {:layout-item-margin "margin"
|
||||
:layout-item-max-h "max-height"
|
||||
:layout-item-min-h "min-height"
|
||||
:layout-item-max-w "max-width"
|
||||
:layout-item-min-w "min-width"
|
||||
:layout-item-align-self "align-self"}
|
||||
:format {:layout-item-margin fmt/format-margin
|
||||
:layout-item-max-h #(str % "px")
|
||||
:layout-item-min-h #(str % "px")
|
||||
:layout-item-max-w #(str % "px")
|
||||
:layout-item-min-w #(str % "px")
|
||||
:layout-item-align-self name}})
|
||||
|
||||
(defn generate-css-props
|
||||
([values properties]
|
||||
(generate-css-props values properties nil))
|
||||
|
@ -126,10 +174,24 @@
|
|||
(str/join "\n")))))
|
||||
|
||||
(defn shape->properties [shape]
|
||||
(let [props (->> styles-data vals (mapcat :props))
|
||||
to-prop (->> styles-data vals (map :to-prop) (reduce merge))
|
||||
format (->> styles-data vals (map :format) (reduce merge))
|
||||
multi (->> styles-data vals (map :multi) (reduce merge))]
|
||||
(let [;; This property is added in an earlier step (code.cljs),
|
||||
;; it will come with a vector of flex-items if any.
|
||||
;; If there are none it will continue as usual.
|
||||
flex-items (:flex-items shape)
|
||||
|
||||
props (->> styles-data vals (mapcat :props))
|
||||
to-prop (->> styles-data vals (map :to-prop) (reduce merge))
|
||||
format (->> styles-data vals (map :format) (reduce merge))
|
||||
multi (->> styles-data vals (map :multi) (reduce merge))
|
||||
props (if (seq flex-items)
|
||||
(concat props (:props layout-flex-item-params))
|
||||
props)
|
||||
to-prop (if (seq flex-items)
|
||||
(merge to-prop (:to-prop layout-flex-item-params))
|
||||
to-prop)
|
||||
format (if (seq flex-items)
|
||||
(merge format (:format layout-flex-item-params))
|
||||
format)]
|
||||
(generate-css-props shape props {:to-prop to-prop
|
||||
:format format
|
||||
:multi multi
|
||||
|
|
|
@ -2493,10 +2493,10 @@ hasha@^2.2.0:
|
|||
is-stream "^1.0.1"
|
||||
pinkie-promise "^2.0.0"
|
||||
|
||||
highlight.js@^11.5.1:
|
||||
version "11.5.1"
|
||||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.5.1.tgz#027c24e4509e2f4dcd00b4a6dda542ce0a1f7aea"
|
||||
integrity sha512-LKzHqnxr4CrD2YsNoIf/o5nJ09j4yi/GcH5BnYz9UnVpZdS4ucMgvP61TDty5xJcFGRjnH4DpujkS9bHT3hq0Q==
|
||||
highlight.js@^11.6.0:
|
||||
version "11.6.0"
|
||||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.6.0.tgz#a50e9da05763f1bb0c1322c8f4f755242cff3f5a"
|
||||
integrity sha512-ig1eqDzJaB0pqEvlPVIpSSyMaO92bH1N2rJpLMN/nX396wTpDA4Eq0uK+7I/2XG17pFaaKE0kjV/XPeGt7Evjw==
|
||||
|
||||
hmac-drbg@^1.0.1:
|
||||
version "1.0.1"
|
||||
|
|
Loading…
Add table
Reference in a new issue