mirror of
https://github.com/penpot/penpot.git
synced 2025-01-25 07:58:49 -05:00
✨ Export library components
This commit is contained in:
parent
234a698538
commit
9b9959da9a
5 changed files with 183 additions and 44 deletions
|
@ -25,6 +25,7 @@
|
|||
[app.main.ui.shapes.shape :refer [shape-container]]
|
||||
[app.main.ui.shapes.svg-raw :as svg-raw]
|
||||
[app.main.ui.shapes.text :as text]
|
||||
[app.util.object :as obj]
|
||||
[app.util.timers :as ts]
|
||||
[cuerdas.core :as str]
|
||||
[rumext.alpha :as mf]))
|
||||
|
@ -73,10 +74,11 @@
|
|||
(mf/fnc group-wrapper
|
||||
[{:keys [shape frame] :as props}]
|
||||
(let [childs (mapv #(get objects %) (:shapes shape))]
|
||||
[:& group-shape {:frame frame
|
||||
:shape shape
|
||||
:is-child-selected? true
|
||||
:childs childs}]))))
|
||||
[:& shape-container {:shape shape}
|
||||
[:& group-shape {:frame frame
|
||||
:shape shape
|
||||
:is-child-selected? true
|
||||
:childs childs}]]))))
|
||||
|
||||
(defn svg-raw-wrapper-factory
|
||||
[objects]
|
||||
|
@ -207,7 +209,8 @@
|
|||
:height height
|
||||
:version "1.1"
|
||||
:xmlnsXlink "http://www.w3.org/1999/xlink"
|
||||
:xmlns "http://www.w3.org/2000/svg"}
|
||||
:xmlns "http://www.w3.org/2000/svg"
|
||||
:xmlns:penpot "https://penpot.app/xmlns"}
|
||||
[:& wrapper {:shape frame :view-box vbox}]]))
|
||||
|
||||
(mf/defc component-svg
|
||||
|
@ -238,5 +241,58 @@
|
|||
:height height
|
||||
:version "1.1"
|
||||
:xmlnsXlink "http://www.w3.org/1999/xlink"
|
||||
:xmlns "http://www.w3.org/2000/svg"}
|
||||
:xmlns "http://www.w3.org/2000/svg"
|
||||
:xmlns:penpot "https://penpot.app/xmlns"}
|
||||
[:& wrapper {:shape group :view-box vbox}]]))
|
||||
|
||||
(mf/defc component-symbol
|
||||
[{:keys [id data] :as props}]
|
||||
|
||||
(let [{:keys [name objects]} data
|
||||
root (get objects id)
|
||||
|
||||
{:keys [width height]} (:selrect root)
|
||||
vbox (str "0 0 " width " " height)
|
||||
|
||||
modifier (-> (gpt/point (:x root) (:y root))
|
||||
(gpt/negate)
|
||||
(gmt/translate-matrix))
|
||||
|
||||
modifier-ids (concat [id] (cp/get-children id objects))
|
||||
update-fn #(assoc-in %1 [%2 :modifiers :displacement] modifier)
|
||||
objects (reduce update-fn objects modifier-ids)
|
||||
root (assoc-in root [:modifiers :displacement] modifier)
|
||||
|
||||
group-wrapper
|
||||
(mf/use-memo
|
||||
(mf/deps objects)
|
||||
#(group-wrapper-factory objects))]
|
||||
|
||||
[:symbol {:id (str id)
|
||||
:viewBox vbox}
|
||||
[:title name]
|
||||
[:& group-wrapper {:shape root :view-box vbox}]]))
|
||||
|
||||
(mf/defc components-sprite-svg
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
|
||||
(let [data (obj/get props "data")
|
||||
children (obj/get props "children")
|
||||
embed? (obj/get props "embed?")]
|
||||
[:& (mf/provider embed/context) {:value embed?}
|
||||
[:svg {:version "1.1"
|
||||
:xmlns "http://www.w3.org/2000/svg"
|
||||
:xmlnsXlink "http://www.w3.org/1999/xlink"
|
||||
:xmlns:penpot "https://penpot.app/xmlns"
|
||||
:style {:width "100vw"
|
||||
:height "100vh"
|
||||
:display (when-not (some? children) "none")}}
|
||||
|
||||
[:defs
|
||||
(for [[component-id component-data] (:components data)]
|
||||
[:& component-symbol {:id component-id
|
||||
:key (str component-id)
|
||||
:data component-data}])]
|
||||
|
||||
children]]))
|
||||
|
|
|
@ -66,5 +66,16 @@
|
|||
(let [elem (mf/element exports/page-svg #js {:data data :embed? true})]
|
||||
(rds/renderToStaticMarkup elem)))))))
|
||||
|
||||
(defn render-components
|
||||
[data]
|
||||
(rx/concat
|
||||
(->> (rx/merge
|
||||
(populate-images-cache data)
|
||||
(populate-fonts-cache data))
|
||||
(rx/ignore))
|
||||
|
||||
|
||||
(->> (rx/of data)
|
||||
(rx/map
|
||||
(fn [data]
|
||||
(let [elem (mf/element exports/components-sprite-svg #js {:data data :embed? true})]
|
||||
(rds/renderToStaticMarkup elem)))))))
|
||||
|
|
|
@ -82,6 +82,7 @@
|
|||
|
||||
;; Used for export
|
||||
["/render-object/:file-id/:page-id/:object-id" :render-object]
|
||||
["/render-sprite/:file-id" :render-sprite]
|
||||
|
||||
["/dashboard/team/:team-id"
|
||||
["/members" :dashboard-team-members]
|
||||
|
@ -172,6 +173,14 @@
|
|||
:page-id page-id
|
||||
:object-id object-id}]))
|
||||
|
||||
:render-sprite
|
||||
(do
|
||||
(let [file-id (uuid (get-in route [:path-params :file-id]))
|
||||
component-id (get-in route [:query-params :component-id])
|
||||
component-id (when (some? component-id) (uuid component-id))]
|
||||
[:& render/render-sprite {:file-id file-id
|
||||
:component-id component-id}]))
|
||||
|
||||
:workspace
|
||||
(let [project-id (some-> params :path :project-id uuid)
|
||||
file-id (some-> params :path :file-id uuid)
|
||||
|
|
|
@ -123,3 +123,30 @@
|
|||
[:& object-svg {:objects @objects
|
||||
:object-id object-id
|
||||
:zoom 1}])))
|
||||
|
||||
(mf/defc render-sprite
|
||||
[{:keys [file-id component-id] :as props}]
|
||||
(let [file (mf/use-state nil)]
|
||||
(mf/use-effect
|
||||
(mf/deps file-id)
|
||||
(fn []
|
||||
(->> (repo/query! :file {:id file-id})
|
||||
(rx/subs
|
||||
(fn [result]
|
||||
(reset! file result))))
|
||||
(constantly nil)))
|
||||
|
||||
(when @file
|
||||
[:*
|
||||
[:& exports/components-sprite-svg {:data (:data @file) :embed true}
|
||||
|
||||
(when (some? component-id)
|
||||
[:use {:x 0 :y 0
|
||||
:xlinkHref (str "#" component-id)}])]
|
||||
|
||||
(when-not (some? component-id)
|
||||
[:ul
|
||||
(for [[id data] (get-in @file [:data :components])]
|
||||
(let [url (str "#/render-sprite/" (:id @file) "?component-id=" id)]
|
||||
[:li [:a {:href url} (:name data)]]))])])))
|
||||
|
||||
|
|
|
@ -70,26 +70,77 @@
|
|||
[{:keys [id file-id markup] :as page}]
|
||||
[(str file-id "/" id ".svg") markup])
|
||||
|
||||
(defn collect-color
|
||||
[result color]
|
||||
(defn collect-entries [result data keys]
|
||||
(-> result
|
||||
(assoc (str (:id color))
|
||||
(->> (select-keys color [:name :color :opacity :gradient])
|
||||
(assoc (str (:id data))
|
||||
(->> (select-keys data keys)
|
||||
(d/deep-mapm
|
||||
(fn [[k v]]
|
||||
[(-> k str/camel) v]))))))
|
||||
|
||||
(def ^:const typography-keys [:name :font-family :font-id :font-size
|
||||
:font-style :font-variant-id :font-weight
|
||||
:letter-spacing :line-height :text-transform])
|
||||
(def ^:const color-keys
|
||||
[:name :color :opacity :gradient])
|
||||
|
||||
(def ^:const typography-keys
|
||||
[:name :font-family :font-id :font-size :font-style :font-variant-id :font-weight
|
||||
:letter-spacing :line-height :text-transform])
|
||||
|
||||
(def ^:const media-keys
|
||||
[:name :mtype :width :height])
|
||||
|
||||
(defn collect-color
|
||||
[result color]
|
||||
(collect-entries result color color-keys))
|
||||
|
||||
(defn collect-typography
|
||||
[result typography]
|
||||
(-> result
|
||||
(assoc (str (:id typography))
|
||||
(->> (select-keys typography typography-keys)
|
||||
(d/deep-mapm
|
||||
(fn [[k v]]
|
||||
[(-> k str/camel) v]))))))
|
||||
(collect-entries result typography typography-keys))
|
||||
|
||||
(defn collect-media
|
||||
[result media]
|
||||
(collect-entries result media media-keys))
|
||||
|
||||
(defn parse-library-color
|
||||
[[file-id colors]]
|
||||
(let [markup
|
||||
(->> (vals colors)
|
||||
(reduce collect-color {})
|
||||
(json/encode))]
|
||||
[(str file-id "/colors.json") markup]))
|
||||
|
||||
(defn parse-library-typographies
|
||||
[[file-id typographies]]
|
||||
(let [markup
|
||||
(->> (vals typographies)
|
||||
(reduce collect-typography {})
|
||||
(json/encode))]
|
||||
[(str file-id "/typographies.json") markup]))
|
||||
|
||||
(defn parse-library-media
|
||||
[[file-id media]]
|
||||
(rx/merge
|
||||
(let [markup
|
||||
(->> (vals media)
|
||||
(reduce collect-media {})
|
||||
(json/encode))]
|
||||
(rx/of (vector (str file-id "/images.json") markup)))
|
||||
|
||||
(->> (rx/from (vals media))
|
||||
(rx/map #(assoc % :file-id file-id))
|
||||
(rx/flat-map
|
||||
(fn [media]
|
||||
(let [file-path (str file-id "/images/" (:id media) "." (dom/mtype->extension (:mtype media)))]
|
||||
(->> (http/send!
|
||||
{:uri (cfg/resolve-file-media media)
|
||||
:response-type :blob
|
||||
:method :get})
|
||||
(rx/map :body)
|
||||
(rx/map #(vector file-path %)))))))))
|
||||
|
||||
(defn parse-library-components
|
||||
[file]
|
||||
(->> (r/render-components (:data file))
|
||||
(rx/map #(vector (str (:id file) "/components.svg") %))))
|
||||
|
||||
(defn export-file
|
||||
[team-id file-id]
|
||||
|
@ -120,42 +171,27 @@
|
|||
(rx/flat-map vals)
|
||||
(rx/map #(vector (:id %) (get-in % [:data :colors])))
|
||||
(rx/filter #(d/not-empty? (second %)))
|
||||
(rx/map (fn [[file-id colors]]
|
||||
(let [markup
|
||||
(->> (vals colors)
|
||||
(reduce collect-color {})
|
||||
(json/encode))]
|
||||
[(str file-id "/colors.json") markup]))))
|
||||
(rx/map parse-library-color))
|
||||
|
||||
typographies-stream
|
||||
(->> files-stream
|
||||
(rx/flat-map vals)
|
||||
(rx/map #(vector (:id %) (get-in % [:data :typographies])))
|
||||
(rx/filter #(d/not-empty? (second %)))
|
||||
(rx/map (fn [[file-id typographies]]
|
||||
(let [markup
|
||||
(->> (vals typographies)
|
||||
(reduce collect-typography {})
|
||||
(json/encode))]
|
||||
[(str file-id "/typographies.json") markup]))))
|
||||
(rx/map parse-library-typographies))
|
||||
|
||||
media-stream
|
||||
(->> files-stream
|
||||
(rx/flat-map vals)
|
||||
(rx/map #(vector (:id %) (get-in % [:data :media])))
|
||||
(rx/filter #(d/not-empty? (second %)))
|
||||
(rx/flat-map
|
||||
(fn [[file-id media]]
|
||||
(->> media vals (mapv #(assoc % :file-id file-id)))))
|
||||
(rx/flat-map parse-library-media))
|
||||
|
||||
(rx/flat-map
|
||||
(fn [media]
|
||||
(->> (http/send!
|
||||
{:uri (cfg/resolve-file-media media)
|
||||
:response-type :blob
|
||||
:method :get})
|
||||
(rx/map :body)
|
||||
(rx/map #(vector (str file-id "/images/" (:id media)) %))))))
|
||||
components-stream
|
||||
(->> files-stream
|
||||
(rx/flat-map vals)
|
||||
(rx/filter #(d/not-empty? (get-in % [:data :components])))
|
||||
(rx/flat-map parse-library-components))
|
||||
|
||||
pages-stream
|
||||
(->> render-stream
|
||||
|
@ -171,7 +207,7 @@
|
|||
(->> (rx/merge
|
||||
manifest-stream
|
||||
pages-stream
|
||||
#_components-stream
|
||||
components-stream
|
||||
media-stream
|
||||
colors-stream
|
||||
typographies-stream)
|
||||
|
|
Loading…
Add table
Reference in a new issue