0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-23 23:35:58 -05:00

🐛 Make the layout boards export as responsive markup

This commit is contained in:
alonso.torres 2024-03-14 15:52:26 +01:00
parent 6bf3363429
commit 5c33bc6892
5 changed files with 82 additions and 69 deletions

View file

@ -76,7 +76,7 @@
(let [style-code (let [style-code
(dm/str (dm/str
fontfaces-css "\n" fontfaces-css "\n"
(-> (cg/generate-style-code objects style-type all-children) (-> (cg/generate-style-code objects style-type [shape] all-children)
(cb/format-code style-type))) (cb/format-code style-type)))
markup-code markup-code

View file

@ -124,11 +124,11 @@
style-code style-code
(mf/use-memo (mf/use-memo
(mf/deps fontfaces-css style-type all-children cg/generate-style-code) (mf/deps fontfaces-css style-type shapes all-children cg/generate-style-code)
(fn [] (fn []
(dm/str (dm/str
fontfaces-css "\n" fontfaces-css "\n"
(-> (cg/generate-style-code objects style-type all-children) (-> (cg/generate-style-code objects style-type shapes all-children)
(cb/format-code style-type))))) (cb/format-code style-type)))))
markup-code markup-code

View file

@ -19,8 +19,8 @@
(generate-markup objects shapes))) (generate-markup objects shapes)))
(defn generate-style-code (defn generate-style-code
[objects type shapes] [objects type root-shapes all-shapes]
(let [generate-style (let [generate-style
(case type (case type
"css" css/generate-style)] "css" css/generate-style)]
(generate-style objects shapes))) (generate-style objects root-shapes all-shapes)))

View file

@ -35,8 +35,8 @@ body {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
padding: 2rem; width: 100vw;
gap: 2rem; min-height: 100vh;
} }
* { * {
@ -94,6 +94,7 @@ body {
:flex-direction :flex-direction
:flex-wrap :flex-wrap
:flex :flex
:flex-grow
;; Grid related properties ;; Grid related properties
:grid-template-rows :grid-template-rows
@ -117,8 +118,8 @@ body {
:grid-area]) :grid-area])
(defn shape->css-property (defn shape->css-property
[shape objects property] [shape objects property options]
(when-let [value (get-value property shape objects)] (when-let [value (get-value property shape objects options)]
[property value])) [property value]))
(defn shape->wrapper-css-properties (defn shape->wrapper-css-properties
@ -155,10 +156,10 @@ body {
(defn shape->css-properties (defn shape->css-properties
"Given a shape extract the CSS properties in the format of list [property value]" "Given a shape extract the CSS properties in the format of list [property value]"
[shape objects properties] [shape objects properties options]
(->> properties (->> properties
(keep (fn [property] (keep (fn [property]
(when-let [value (get-value property shape objects)] (when-let [value (get-value property shape objects options)]
[property value]))))) [property value])))))
(defn format-css-value (defn format-css-value
@ -189,7 +190,7 @@ body {
([objects shape properties options] ([objects shape properties options]
(-> shape (-> shape
(shape->css-properties objects properties) (shape->css-properties objects properties options)
(format-css-properties options)))) (format-css-properties options))))
(defn format-js-styles (defn format-js-styles
@ -248,13 +249,13 @@ body {
properties properties
(-> shape (-> shape
(shape->css-properties objects css-properties) (shape->css-properties objects css-properties options)
(format-css-properties options)) (format-css-properties options))
wrapper-properties wrapper-properties
(when wrapper? (when wrapper?
(-> (d/concat-vec (-> (d/concat-vec
(shape->css-properties shape objects shape-wrapper-css-properties) (shape->css-properties shape objects shape-wrapper-css-properties options)
(shape->wrapper-css-properties shape objects)) (shape->wrapper-css-properties shape objects))
(format-css-properties options))) (format-css-properties options)))
@ -285,7 +286,7 @@ body {
([objects shape property options] ([objects shape property options]
(-> shape (-> shape
(shape->css-property objects property) (shape->css-property objects property options)
(format-css-property options)))) (format-css-property options))))
(defn get-css-value (defn get-css-value
@ -293,18 +294,19 @@ body {
(get-css-value objects shape property nil)) (get-css-value objects shape property nil))
([objects shape property options] ([objects shape property options]
(when-let [prop (shape->css-property shape objects property)] (when-let [prop (shape->css-property shape objects property options)]
(format-css-value prop options)))) (format-css-value prop options))))
(defn generate-style (defn generate-style
([objects shapes] ([objects root-shapes all-shapes]
(generate-style objects shapes nil)) (generate-style objects root-shapes all-shapes nil))
([objects shapes options] ([objects root-shapes all-shapes options]
(dm/str (let [options (assoc options :root-shapes (into #{} (map :id) root-shapes))]
prelude (dm/str
(->> shapes prelude
(keep #(get-shape-css-selector % objects options)) (->> all-shapes
(str/join "\n\n"))))) (keep #(get-shape-css-selector % objects options))
(str/join "\n\n"))))))
(defn shadow->css (defn shadow->css
[shadow] [shadow]

View file

@ -25,10 +25,10 @@
:image fill-image}) :image fill-image})
(defmulti get-value (defmulti get-value
(fn [property _shape _objects] property)) (fn [property _shape _objects _options] property))
(defmethod get-value :position (defmethod get-value :position
[_ shape objects] [_ shape objects _]
(cond (cond
(or (and (ctl/any-layout-immediate-child? objects shape) (or (and (ctl/any-layout-immediate-child? objects shape)
(not (ctl/position-absolute? shape)) (not (ctl/position-absolute? shape))
@ -65,15 +65,15 @@
(- shape-value parent-value)))) (- shape-value parent-value))))
(defmethod get-value :left (defmethod get-value :left
[_ shape objects] [_ shape objects _]
(get-shape-position shape objects :x)) (get-shape-position shape objects :x))
(defmethod get-value :top (defmethod get-value :top
[_ shape objects] [_ shape objects _]
(get-shape-position shape objects :y)) (get-shape-position shape objects :y))
(defmethod get-value :flex (defmethod get-value :flex
[_ shape objects] [_ shape objects _]
(let [parent (cfh/get-parent objects (:id shape))] (let [parent (cfh/get-parent objects (:id shape))]
(when (and (ctl/flex-layout-immediate-child? objects shape) (when (and (ctl/flex-layout-immediate-child? objects shape)
(or (and (contains? #{:row :row-reverse} (:layout-flex-dir parent)) (or (and (contains? #{:row :row-reverse} (:layout-flex-dir parent))
@ -112,15 +112,26 @@
(get shape type)))) (get shape type))))
(defmethod get-value :width (defmethod get-value :width
[_ shape objects] [_ shape objects options]
(get-shape-size shape objects :width)) (let [root? (contains? (:root-shapes options) (:id shape))]
(if (and root? (ctl/any-layout? shape))
:fill
(get-shape-size shape objects :width))))
(defmethod get-value :height (defmethod get-value :height
[_ shape objects] [_ shape objects options]
(get-shape-size shape objects :height)) (let [root? (contains? (:root-shapes options) (:id shape))]
(when-not (and root? (ctl/any-layout? shape))
(get-shape-size shape objects :height))))
(defmethod get-value :flex-grow
[_ shape _ options]
(let [root? (contains? (:root-shapes options) (:id shape))]
(when (and root? (ctl/any-layout? shape))
1)))
(defmethod get-value :transform (defmethod get-value :transform
[_ shape objects] [_ shape objects _]
(if (cgc/svg-markup? shape) (if (cgc/svg-markup? shape)
(let [parent (get objects (:parent-id shape)) (let [parent (get objects (:parent-id shape))
transform transform
@ -145,7 +156,7 @@
transform-str)))) transform-str))))
(defmethod get-value :background (defmethod get-value :background
[_ {:keys [fills] :as shape} _] [_ {:keys [fills] :as shape} _ _]
(let [single-fill? (= (count fills) 1)] (let [single-fill? (= (count fills) 1)]
(when (and (not (cgc/svg-markup? shape)) (not (cfh/group-shape? shape)) single-fill?) (when (and (not (cgc/svg-markup? shape)) (not (cfh/group-shape? shape)) single-fill?)
(fill->color (first fills))))) (fill->color (first fills)))))
@ -164,12 +175,12 @@
:width width}))) :width width})))
(defmethod get-value :border (defmethod get-value :border
[_ shape _] [_ shape _ _]
(when-not (cgc/svg-markup? shape) (when-not (cgc/svg-markup? shape)
(get-stroke-data (first (:strokes shape))))) (get-stroke-data (first (:strokes shape)))))
(defmethod get-value :border-radius (defmethod get-value :border-radius
[_ {:keys [rx r1 r2 r3 r4] :as shape} _] [_ {:keys [rx r1 r2 r3 r4] :as shape} _ _]
(cond (cond
(cfh/circle-shape? shape) (cfh/circle-shape? shape)
"50%" "50%"
@ -181,76 +192,76 @@
[r1 r2 r3 r4])) [r1 r2 r3 r4]))
(defmethod get-value :box-shadow (defmethod get-value :box-shadow
[_ shape _] [_ shape _ _]
(when-not (cgc/svg-markup? shape) (when-not (cgc/svg-markup? shape)
(:shadow shape))) (:shadow shape)))
(defmethod get-value :filter (defmethod get-value :filter
[_ shape _] [_ shape _ _]
(when-not (cgc/svg-markup? shape) (when-not (cgc/svg-markup? shape)
(get-in shape [:blur :value]))) (get-in shape [:blur :value])))
(defmethod get-value :display (defmethod get-value :display
[_ shape _] [_ shape _ _]
(cond (cond
(:hidden shape) "none" (:hidden shape) "none"
(ctl/flex-layout? shape) "flex" (ctl/flex-layout? shape) "flex"
(ctl/grid-layout? shape) "grid")) (ctl/grid-layout? shape) "grid"))
(defmethod get-value :opacity (defmethod get-value :opacity
[_ shape _] [_ shape _ _]
(when (< (:opacity shape) 1) (when (< (:opacity shape) 1)
(:opacity shape))) (:opacity shape)))
(defmethod get-value :overflow (defmethod get-value :overflow
[_ shape _] [_ shape _ _]
(when (and (cfh/frame-shape? shape) (when (and (cfh/frame-shape? shape)
(not (cgc/svg-markup? shape)) (not (cgc/svg-markup? shape))
(not (:show-content shape))) (not (:show-content shape)))
"hidden")) "hidden"))
(defmethod get-value :flex-direction (defmethod get-value :flex-direction
[_ shape _] [_ shape _ _]
(:layout-flex-dir shape)) (:layout-flex-dir shape))
(defmethod get-value :align-items (defmethod get-value :align-items
[_ shape _] [_ shape _ _]
(:layout-align-items shape)) (:layout-align-items shape))
(defmethod get-value :align-content (defmethod get-value :align-content
[_ shape _] [_ shape _ _]
(:layout-align-content shape)) (:layout-align-content shape))
(defmethod get-value :justify-items (defmethod get-value :justify-items
[_ shape _] [_ shape _ _]
(:layout-justify-items shape)) (:layout-justify-items shape))
(defmethod get-value :justify-content (defmethod get-value :justify-content
[_ shape _] [_ shape _ _]
(:layout-justify-content shape)) (:layout-justify-content shape))
(defmethod get-value :flex-wrap (defmethod get-value :flex-wrap
[_ shape _] [_ shape _ _]
(:layout-wrap-type shape)) (:layout-wrap-type shape))
(defmethod get-value :gap (defmethod get-value :gap
[_ shape _] [_ shape _ _]
(let [[g1 g2] (ctl/gaps shape)] (let [[g1 g2] (ctl/gaps shape)]
(when (and (= g1 g2) (or (not= g1 0) (not= g2 0))) (when (and (= g1 g2) (or (not= g1 0) (not= g2 0)))
[g1]))) [g1])))
(defmethod get-value :row-gap (defmethod get-value :row-gap
[_ shape _] [_ shape _ _]
(let [[g1 g2] (ctl/gaps shape)] (let [[g1 g2] (ctl/gaps shape)]
(when (and (not= g1 g2) (not= g1 0)) [g1]))) (when (and (not= g1 g2) (not= g1 0)) [g1])))
(defmethod get-value :column-gap (defmethod get-value :column-gap
[_ shape _] [_ shape _ _]
(let [[g1 g2] (ctl/gaps shape)] (let [[g1 g2] (ctl/gaps shape)]
(when (and (not= g1 g2) (not= g2 0)) [g2]))) (when (and (not= g1 g2) (not= g2 0)) [g2])))
(defmethod get-value :padding (defmethod get-value :padding
[_ {:keys [layout-padding]} _] [_ {:keys [layout-padding]} _ _]
(when (some? layout-padding) (when (some? layout-padding)
(let [default-padding {:p1 0 :p2 0 :p3 0 :p4 0} (let [default-padding {:p1 0 :p2 0 :p3 0 :p4 0}
{:keys [p1 p2 p3 p4]} (merge default-padding layout-padding)] {:keys [p1 p2 p3 p4]} (merge default-padding layout-padding)]
@ -258,11 +269,11 @@
[p1 p2 p3 p4])))) [p1 p2 p3 p4]))))
(defmethod get-value :grid-template-rows (defmethod get-value :grid-template-rows
[_ shape _] [_ shape _ _]
(:layout-grid-rows shape)) (:layout-grid-rows shape))
(defmethod get-value :grid-template-columns (defmethod get-value :grid-template-columns
[_ shape _] [_ shape _ _]
(:layout-grid-columns shape)) (:layout-grid-columns shape))
(defn area-cell? (defn area-cell?
@ -270,7 +281,7 @@
(and (= position :area) (d/not-empty? area-name))) (and (= position :area) (d/not-empty? area-name)))
(defmethod get-value :grid-template-areas (defmethod get-value :grid-template-areas
[_ shape _] [_ shape _ _]
(when (and (ctl/grid-layout? shape) (when (and (ctl/grid-layout? shape)
(some area-cell? (vals (:layout-grid-cells shape)))) (some area-cell? (vals (:layout-grid-cells shape))))
(let [result (let [result
@ -304,15 +315,15 @@
(get cell prop)))))) (get cell prop))))))
(defmethod get-value :grid-column (defmethod get-value :grid-column
[_ shape objects] [_ shape objects _]
(get-grid-coord shape objects :column :column-span)) (get-grid-coord shape objects :column :column-span))
(defmethod get-value :grid-row (defmethod get-value :grid-row
[_ shape objects] [_ shape objects _]
(get-grid-coord shape objects :row :row-span)) (get-grid-coord shape objects :row :row-span))
(defmethod get-value :grid-area (defmethod get-value :grid-area
[_ shape objects] [_ shape objects _]
(when (and (ctl/grid-layout-immediate-child? objects shape) (when (and (ctl/grid-layout-immediate-child? objects shape)
(not (ctl/position-absolute? shape))) (not (ctl/position-absolute? shape)))
(let [parent (get objects (:parent-id shape)) (let [parent (get objects (:parent-id shape))
@ -321,7 +332,7 @@
(str/replace (:area-name cell) " " "-"))))) (str/replace (:area-name cell) " " "-")))))
(defmethod get-value :flex-shrink (defmethod get-value :flex-shrink
[_ shape objects] [_ shape objects _]
(when (and (ctl/flex-layout-immediate-child? objects shape) (when (and (ctl/flex-layout-immediate-child? objects shape)
(not (and (contains? #{:row :reverse-row} (:layout-flex-dir shape)) (not (and (contains? #{:row :reverse-row} (:layout-flex-dir shape))
@ -337,7 +348,7 @@
0)) 0))
(defmethod get-value :margin (defmethod get-value :margin
[_ {:keys [layout-item-margin] :as shape} objects] [_ {:keys [layout-item-margin] :as shape} objects _]
(when (ctl/any-layout-immediate-child? objects shape) (when (ctl/any-layout-immediate-child? objects shape)
(let [default-margin {:m1 0 :m2 0 :m3 0 :m4 0} (let [default-margin {:m1 0 :m2 0 :m3 0 :m4 0}
@ -346,7 +357,7 @@
[m1 m2 m3 m4])))) [m1 m2 m3 m4]))))
(defmethod get-value :z-index (defmethod get-value :z-index
[_ {:keys [layout-item-z-index] :as shape} objects] [_ {:keys [layout-item-z-index] :as shape} objects _]
(cond (cond
(cfh/root-frame? shape) (cfh/root-frame? shape)
0 0
@ -355,13 +366,13 @@
layout-item-z-index)) layout-item-z-index))
(defmethod get-value :max-height (defmethod get-value :max-height
[_ shape objects] [_ shape objects _]
(cond (cond
(ctl/any-layout-immediate-child? objects shape) (ctl/any-layout-immediate-child? objects shape)
(:layout-item-max-h shape))) (:layout-item-max-h shape)))
(defmethod get-value :min-height (defmethod get-value :min-height
[_ shape objects] [_ shape objects _]
(cond (cond
(and (ctl/any-layout-immediate-child? objects shape) (some? (:layout-item-min-h shape))) (and (ctl/any-layout-immediate-child? objects shape) (some? (:layout-item-min-h shape)))
(:layout-item-min-h shape) (:layout-item-min-h shape)
@ -370,13 +381,13 @@
(-> shape :selrect :height))) (-> shape :selrect :height)))
(defmethod get-value :max-width (defmethod get-value :max-width
[_ shape objects] [_ shape objects _]
(cond (cond
(ctl/any-layout-immediate-child? objects shape) (ctl/any-layout-immediate-child? objects shape)
(:layout-item-max-w shape))) (:layout-item-max-w shape)))
(defmethod get-value :min-width (defmethod get-value :min-width
[_ shape objects] [_ shape objects _]
(cond (cond
(and (ctl/any-layout-immediate-child? objects shape) (some? (:layout-item-min-w shape))) (and (ctl/any-layout-immediate-child? objects shape) (some? (:layout-item-min-w shape)))
(:layout-item-min-w shape) (:layout-item-min-w shape)
@ -385,7 +396,7 @@
(-> shape :selrect :width))) (-> shape :selrect :width)))
(defmethod get-value :align-self (defmethod get-value :align-self
[_ shape objects] [_ shape objects _]
(cond (cond
(ctl/flex-layout-immediate-child? objects shape) (ctl/flex-layout-immediate-child? objects shape)
(:layout-item-align-self shape) (:layout-item-align-self shape)
@ -397,7 +408,7 @@
(when (not= align-self :auto) align-self)))) (when (not= align-self :auto) align-self))))
(defmethod get-value :justify-self (defmethod get-value :justify-self
[_ shape objects] [_ shape objects _]
(cond (cond
(ctl/grid-layout-immediate-child? objects shape) (ctl/grid-layout-immediate-child? objects shape)
(let [parent (get objects (:parent-id shape)) (let [parent (get objects (:parent-id shape))
@ -406,10 +417,10 @@
(when (not= justify-self :auto) justify-self)))) (when (not= justify-self :auto) justify-self))))
(defmethod get-value :grid-auto-flow (defmethod get-value :grid-auto-flow
[_ shape _] [_ shape _ _]
(when (and (ctl/grid-layout? shape) (= (:layout-grid-dir shape) :column)) (when (and (ctl/grid-layout? shape) (= (:layout-grid-dir shape) :column))
"column")) "column"))
(defmethod get-value :default (defmethod get-value :default
[property shape _] [property shape _ _]
(get shape property)) (get shape property))