0
Fork 0
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:
alonso.torres 2021-06-22 09:58:18 +02:00
parent 234a698538
commit 9b9959da9a
5 changed files with 183 additions and 44 deletions

View file

@ -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]]))

View file

@ -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)))))))

View file

@ -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)

View file

@ -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)]]))])])))

View file

@ -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)