0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-04-15 08:21:40 -05:00

Merge remote-tracking branch 'origin/staging'

This commit is contained in:
Alejandro Alonso 2023-06-21 12:44:56 +02:00
commit 50bdad3450
36 changed files with 341 additions and 126 deletions

View file

@ -1,5 +1,34 @@
# CHANGELOG
## 1.18.6 (Unreleased)
### :bug: Bugs fixed
- Fix comments navigation from workspace [Taiga #5504](https://tree.taiga.io/project/penpot/issue/5504)
### :sparkles: Enhancements
- Add the ability to overwrite internal resolver with `PENPOT_INTERNAL_RESOLVER` environment
variable [GH #3310](https://github.com/penpot/penpot/issues/3310)
## 1.18.5
### :bug: Bugs fixed
- Fix add flow option in contextual menu for frames
- Fix issues related with invitations
- Fix problem with undefined gaps
- Add deleted fonts auto match mechanism
## 1.18.4
### :bug: Bugs fixed
- Fix zooming while color picker breaks UI [GH #3214](https://github.com/penpot/penpot/issues/3214)
- Fix problem with layout not reflowing on shape deletion [Taiga #5289](https://tree.taiga.io/project/penpot/issue/5289)
- Fix extra long typography names on assets and palette [Taiga #5199](https://tree.taiga.io/project/penpot/issue/5199)
- Fix background-color property on inspect code [Taiga #5300](https://tree.taiga.io/project/penpot/issue/5300)
## 1.18.3
### :bug: Bugs fixed
@ -29,6 +58,7 @@
## 1.18.0
### :sparkles: New features
- Adds more accessibility improvements in dashboard [Taiga #4577](https://tree.taiga.io/project/penpot/us/4577)
- Adds paddings and gaps prediction on layout creation [Taiga #4838](https://tree.taiga.io/project/penpot/task/4838)
- Add visual feedback when proportionally scaling text elements with **K** [Taiga #3415](https://tree.taiga.io/project/penpot/us/3415)

View file

@ -169,14 +169,16 @@
[{:keys [::db/pool] :as cfg} params]
(when-not (contains? cf/flags :registration)
(if-not (contains? params :invitation-token)
(when-not (contains? params :invitation-token)
(ex/raise :type :restriction
:code :registration-disabled)
(let [invitation (tokens/verify (::main/props cfg) {:token (:invitation-token params) :iss :team-invitation})]
(when-not (= (:email params) (:member-email invitation))
(ex/raise :type :restriction
:code :email-does-not-match-invitation
:hint "email should match the invitation")))))
:code :registration-disabled)))
(when (contains? params :invitation-token)
(let [invitation (tokens/verify (::main/props cfg) {:token (:invitation-token params) :iss :team-invitation})]
(when-not (= (:email params) (:member-email invitation))
(ex/raise :type :restriction
:code :email-does-not-match-invitation
:hint "email should match the invitation"))))
(when-let [domains (cf/get :registration-domain-whitelist)]
(when-not (email-domain-in-whitelist? domains (:email params))

View file

@ -241,7 +241,7 @@
(update :parent-stack conjv (:id obj)))))
(defn close-artboard [file]
(let [parent-id (-> file :parent-id peek)
(let [parent-id (-> file :parent-stack peek)
parent (lookup-shape file parent-id)
current-frame-id (or (:frame-id parent)
(when (nil? (:current-component-id file))

View file

@ -162,7 +162,6 @@
(defn add-lines-positions
[parent layout-bounds layout-lines]
(let [row? (ctl/row? parent)
col? (ctl/col? parent)
auto-width? (ctl/auto-width? parent)
@ -410,6 +409,9 @@
reverse? (ctl/reverse? shape)
children (cond->> children (not reverse?) reverse)
;; Don't take into account absolute children
children (->> children (remove (comp ctl/layout-absolute? second)))
;; Creates the layout lines information
layout-lines
(->> (init-layout-lines shape children layout-bounds)

View file

@ -179,7 +179,7 @@
[layout-line modif-tree]))]
(let [children (->> children
(map (d/getf objects))
(keep (d/getf objects))
(remove :hidden)
(remove gco/invalid-geometry?)
(map apply-modifiers))

View file

@ -28,7 +28,7 @@
(s/def ::color-gradient/width ::us/safe-number)
(s/def ::color-gradient-stop/color ::us/rgb-color-str)
(s/def ::color-gradient-stop/opacity ::us/safe-number)
(s/def ::color-gradient-stop/opacity (s/nilable ::us/safe-number))
(s/def ::color-gradient-stop/offset ::us/safe-number)
(s/def ::color-gradient/stop

View file

@ -8,6 +8,7 @@
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.math :as mth]
[app.common.spec :as us]
[app.common.uuid :as uuid]
[clojure.spec.alpha :as s]))
@ -262,8 +263,8 @@
(defn gaps
[{:keys [layout-gap]}]
(let [layout-gap-row (or (-> layout-gap :row-gap) 0)
layout-gap-col (or (-> layout-gap :column-gap) 0)]
(let [layout-gap-row (or (-> layout-gap :row-gap (mth/finite 0)) 0)
layout-gap-col (or (-> layout-gap :column-gap (mth/finite 0)) 0)]
[layout-gap-row layout-gap-col]))
(defn child-min-width

View file

@ -21,7 +21,8 @@ update_flags /var/www/app/js/config.js
export PENPOT_BACKEND_URI=${PENPOT_BACKEND_URI:-http://penpot-backend:6060};
export PENPOT_EXPORTER_URI=${PENPOT_EXPORTER_URI:-http://penpot-exporter:6061};
export PENPOT_INTERNAL_RESOLVER=${PENPOT_INTERNAL_RESOLVER:-127.0.0.11};
envsubst "\$PENPOT_BACKEND_URI,\$PENPOT_EXPORTER_URI" < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf
envsubst "\$PENPOT_BACKEND_URI,\$PENPOT_EXPORTER_URI,\$PENPOT_INTERNAL_RESOLVER" < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf
exec "$@";

View file

@ -38,7 +38,7 @@ http {
gzip_types text/plain text/css text/javascript application/javascript application/json application/transit+json;
resolver 127.0.0.11;
resolver $PENPOT_INTERNAL_RESOLVER;
map $http_upgrade $connection_upgrade {
default upgrade;

View file

@ -434,6 +434,14 @@
cursor: pointer;
position: relative;
.name-block {
color: $color-gray-20;
width: calc(100% - 24px - #{$size-2});
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
& span {
margin-left: $size-1;
color: $color-gray-30;

View file

@ -1095,7 +1095,10 @@
flex-grow: 1;
font-size: $fs11;
margin-top: 4px;
max-width: calc(var(--width, 256px) - 100px);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.element-set-actions-button svg {

View file

@ -9,6 +9,10 @@
& .typography-name {
color: $color-white;
max-width: 160px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
& .typography-font,

View file

@ -44,6 +44,7 @@
[app.main.data.workspace.drawing.common :as dwdc]
[app.main.data.workspace.edition :as dwe]
[app.main.data.workspace.fix-bool-contents :as fbc]
[app.main.data.workspace.fix-deleted-fonts :as fdf]
[app.main.data.workspace.groups :as dwg]
[app.main.data.workspace.guides :as dwgu]
[app.main.data.workspace.highlight :as dwh]
@ -131,6 +132,7 @@
components-v2 (features/active-feature? state :components-v2)]
(rx/merge
(rx/of (fbc/fix-bool-contents))
(rx/of (fdf/fix-deleted-fonts))
(if (and has-graphics? components-v2)
(rx/of (remove-graphics (:id file) (:name file)))
(rx/empty)))))))
@ -1256,17 +1258,18 @@
not-group-like? (and (= (count selected) 1)
(not (contains? #{:group :bool} (:type head))))
no-bool-shapes? (->> all-selected (some (comp #{:frame :text} :type)))]
(rx/concat
(when (and (some? shape) (not (contains? selected (:id shape))))
(rx/of (dws/select-shape (:id shape))))
(rx/of (show-context-menu
(-> params
(assoc
:kind :shape
:disable-booleans? (or no-bool-shapes? not-group-like?)
:disable-flatten? no-bool-shapes?
:selected (conj selected (:id shape)))))))))))
(if (and (some? shape) (not (contains? selected (:id shape))))
(rx/concat
(rx/of (dws/select-shape (:id shape)))
(rx/of (show-shape-context-menu params)))
(rx/of (show-context-menu
(-> params
(assoc
:kind :shape
:disable-booleans? (or no-bool-shapes? not-group-like?)
:disable-flatten? no-bool-shapes?
:selected (conj selected (:id shape)))))))))))
(defn show-page-item-context-menu
[{:keys [position page] :as params}]

View file

@ -0,0 +1,129 @@
;; 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.workspace.fix-deleted-fonts
(:require
[app.common.data :as d]
[app.common.pages.helpers :as cph]
[app.common.text :as txt]
[app.main.data.workspace.changes :as dch]
[app.main.data.workspace.state-helpers :as wsh]
[app.main.fonts :as fonts]
[beicon.core :as rx]
[potok.core :as ptk]))
;; This event will update the file so the texts with non existing custom fonts try to be fixed.
;; This can happen when:
;; - Exporting/importing files to different teams or penpot instances
;; - Moving files from one team to another in the same instance
;; - Custom fonts are explicitly deleted in the team area
(defn has-invalid-font-family
[node]
(let [fonts (deref fonts/fontsdb)]
(and
(some? (:font-family node))
(nil? (get fonts (:font-id node))))))
(defn calculate-alternative-font-id
[value]
(let [fonts (deref fonts/fontsdb)]
(->> (vals fonts)
(filter #(= (:family %) value))
(first)
:id)))
(defn should-fix-deleted-font-shape?
[shape]
(let [text-nodes (txt/node-seq txt/is-text-node? (:content shape))]
(and (cph/text-shape? shape) (some has-invalid-font-family text-nodes))))
(defn should-fix-deleted-font-component?
[component]
(->> (:objects component)
(vals)
(d/seek should-fix-deleted-font-shape?)))
(defn should-fix-deleted-font-typography?
[typography]
(let [fonts (deref fonts/fontsdb)]
(nil? (get fonts (:font-id typography)))))
(defn fix-deleted-font
[node]
(let [alternative-font-id (calculate-alternative-font-id (:font-family node))]
(cond-> node
(some? alternative-font-id) (assoc :font-id alternative-font-id))))
(defn fix-deleted-font-shape
[shape]
(let [transform (partial txt/transform-nodes has-invalid-font-family fix-deleted-font)]
(update shape :content transform)))
(defn fix-deleted-font-component
[component]
(update component
:objects
(fn [objects]
(d/mapm #(fix-deleted-font-shape %2) objects))))
(defn fix-deleted-font-typography
[typography]
(let [alternative-font-id (calculate-alternative-font-id (:font-family typography))]
(cond-> typography
(some? alternative-font-id) (assoc :font-id alternative-font-id))))
(defn fix-deleted-fonts
[]
(ptk/reify ::fix-deleted-fonts
ptk/WatchEvent
(watch [it state _]
(let [objects (wsh/lookup-page-objects state)
ids (into #{}
(comp (filter should-fix-deleted-font-shape?) (map :id))
(vals objects))
components (->> (wsh/lookup-local-components state)
(vals)
(filter should-fix-deleted-font-component?))
component-changes
(into []
(map (fn [component]
{:type :mod-component
:id (:id component)
:objects (-> (fix-deleted-font-component component) :objects)}))
components)
typographies (->> (get-in state [:workspace-data :typographies])
(vals)
(filter should-fix-deleted-font-typography?))
typography-changes
(into []
(map (fn [typography]
{:type :mod-typography
:typography (fix-deleted-font-typography typography)}))
typographies)]
(rx/concat
(rx/of (dch/update-shapes ids #(fix-deleted-font-shape %) {:reg-objects? false
:save-undo? false
:ignore-tree true}))
(if (empty? component-changes)
(rx/empty)
(rx/of (dch/commit-changes {:origin it
:redo-changes component-changes
:undo-changes []
:save-undo? false})))
(if (empty? typography-changes)
(rx/empty)
(rx/of (dch/commit-changes {:origin it
:redo-changes typography-changes
:undo-changes []
:save-undo? false}))))))))

View file

@ -126,8 +126,10 @@
all-width (->> selrects
(map :width)
(reduce +))
column-gap (if (or (= direction :row) (= direction :row-reverse))
(/ (- (- max-x min-x) all-width) (dec (count shapes)))
column-gap (if (and (> (count shapes) 1)
(or (= direction :row) (= direction :row-reverse)))
(/ (- (- max-x min-x) all-width)
(dec (count shapes)))
0)
min-y (->> selrects
@ -139,8 +141,10 @@
all-height (->> selrects
(map :height)
(reduce +))
row-gap (if (or (= direction :column) (= direction :column-reverse))
(/ (- (- max-y min-y) all-height) (dec (count shapes)))
row-gap (if (and (> (count shapes) 1)
(or (= direction :column) (= direction :column-reverse)))
(/ (- (- max-y min-y) all-height)
(dec (count shapes)))
0)
layout-gap {:row-gap (max row-gap 0) :column-gap (max column-gap 0)}

View file

@ -323,8 +323,8 @@
(rx/of (dwu/start-undo-transaction undo-id)
(dc/detach-comment-thread ids)
(ptk/data-event :layout/update all-parents)
(dch/commit-changes changes)
(ptk/data-event :layout/update all-parents)
(dwu/commit-undo-transaction undo-id))))
(defn create-and-add-shape

View file

@ -8,6 +8,7 @@
(:require
[app.common.colors :as clr]
[app.common.data :as d]
[app.common.exceptions :as ex]
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
@ -30,6 +31,7 @@
[app.util.svg :as usvg]
[app.util.webapi :as wapi]
[beicon.core :as rx]
[clojure.spec.alpha :as s]
[cuerdas.core :as str]
[potok.core :as ptk]))
@ -38,11 +40,12 @@
(defonce default-image {:x 0 :y 0 :width 1 :height 1 :rx 0 :ry 0})
(defn- assert-valid-num [attr num]
(us/verify!
:expr (and (d/num? num)
(when-not (and (d/num? num)
(<= num max-safe-int)
(>= num min-safe-int))
:hint (str/ffmt "%1 attribute has invalid value: %2" (d/name attr) num))
(ex/raise :type :assertion
:code :expr-validation
:hint (str/ffmt "%1 attribute has invalid value: %2" (d/name attr) num)))
;; If the number is between 0-1 we round to 1 (same in negative form
(cond
@ -52,11 +55,24 @@
(defn- assert-valid-pos-num
[attr num]
(us/verify!
:expr (pos? num)
:hint (str/ffmt "%1 attribute should be positive" (d/name attr)))
(when-not (pos? num)
(ex/raise :type :assertion
:code :expr-validation
:hint (str/ffmt "%1 attribute should be positive" (d/name attr))))
num)
(defn- assert-valid-blend-mode
[mode]
(let [clean-value (-> mode
str/trim
str/lower
keyword)]
(when-not (s/valid? ::cts/blend-mode clean-value)
(ex/raise :type :assertion
:code :expr-validation
:hint (str/ffmt "%1 is not a valid blend mode" clean-value)))
clean-value))
(defn- svg-dimensions [data]
(let [width (get-in data [:attrs :width] 100)
height (get-in data [:attrs :height] 100)
@ -100,13 +116,13 @@
(-> (update :svg-attrs dissoc :fill-opacity)
(update-in [:svg-attrs :style] dissoc :fill-opacity)
(assoc-in [:fills 0 :fill-opacity] (-> (get-in shape [:svg-attrs :fill-opacity])
(d/parse-double))))
(d/parse-double 1))))
(get-in shape [:svg-attrs :style :fill-opacity])
(-> (update-in [:svg-attrs :style] dissoc :fill-opacity)
(update :svg-attrs dissoc :fill-opacity)
(assoc-in [:fills 0 :fill-opacity] (-> (get-in shape [:svg-attrs :style :fill-opacity])
(d/parse-double)))))))
(d/parse-double 1)))))))
(defn setup-stroke [shape]
(let [stroke-linecap (-> (or (get-in shape [:svg-attrs :stroke-linecap])
@ -133,12 +149,12 @@
(get-in shape [:svg-attrs :stroke-opacity])
(-> (update :svg-attrs dissoc :stroke-opacity)
(assoc-in [:strokes 0 :stroke-opacity] (-> (get-in shape [:svg-attrs :stroke-opacity])
(d/parse-double))))
(d/parse-double 1))))
(get-in shape [:svg-attrs :style :stroke-opacity])
(-> (update-in [:svg-attrs :style] dissoc :stroke-opacity)
(assoc-in [:strokes 0 :stroke-opacity] (-> (get-in shape [:svg-attrs :style :stroke-opacity])
(d/parse-double))))
(d/parse-double 1))))
(get-in shape [:svg-attrs :stroke-width])
(-> (update :svg-attrs dissoc :stroke-width)
@ -165,21 +181,21 @@
(get-in shape [:svg-attrs :opacity])
(-> (update :svg-attrs dissoc :opacity)
(assoc :opacity (-> (get-in shape [:svg-attrs :opacity])
(d/parse-double))))
(d/parse-double 1))))
(get-in shape [:svg-attrs :style :opacity])
(-> (update-in [:svg-attrs :style] dissoc :opacity)
(assoc :opacity (-> (get-in shape [:svg-attrs :style :opacity])
(d/parse-double))))
(d/parse-double 1))))
(get-in shape [:svg-attrs :mix-blend-mode])
(-> (update :svg-attrs dissoc :mix-blend-mode)
(assoc :blend-mode (-> (get-in shape [:svg-attrs :mix-blend-mode]) keyword)))
(assoc :blend-mode (-> (get-in shape [:svg-attrs :mix-blend-mode]) assert-valid-blend-mode)))
(get-in shape [:svg-attrs :style :mix-blend-mode])
(-> (update-in [:svg-attrs :style] dissoc :mix-blend-mode)
(assoc :blend-mode (-> (get-in shape [:svg-attrs :style :mix-blend-mode]) keyword)))))
(assoc :blend-mode (-> (get-in shape [:svg-attrs :style :mix-blend-mode]) assert-valid-blend-mode)))))
(defn create-raw-svg [name frame-id svg-data {:keys [tag attrs] :as data}]
(let [{:keys [x y width height offset-x offset-y]} svg-data]

View file

@ -46,12 +46,16 @@
(defn format-padding-margin-shorthand
[values]
;; Values come in [p1 p2 p3 p4]
(let [[p1 p2 p3 p4] values]
(let [[p1 p2 p3 p4] values
p1 (format-number p1)
p2 (format-number p2)
p3 (format-number p3)
p4 (format-number p4)]
(cond
(apply = values)
(= p1 p2 p3 p4)
{:p1 p1}
(= 4 (count (set values)))
(= 4 (count (set [p1 p2 p3 p4])))
{:p1 p1 :p2 p2 :p3 p3 :p4 p4}
(and (= p1 p3) (= p2 p4))
@ -59,7 +63,6 @@
(and (not= p1 p3) (= p2 p4))
{:p1 p1 :p2 p2 :p3 p3}
:else
{:p1 p1 :p2 p2 :p3 p3 :p4 p4})))
@ -71,7 +74,7 @@
(= sizing :fill) "100%"
(= sizing :auto) "auto"
(number? value) (format-pixels value)
:else value)))
:else value)))
(defn format-padding
[padding-values type]
@ -92,5 +95,5 @@
(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))))
(str/fmt "%spx" (format-number row-gap))
(str/fmt "%spx %spx" (format-number row-gap) (format-number column-gap)))))

View file

@ -290,7 +290,6 @@
[:text {:x (+ x (/ width 2))
:y (+ y (/ height 2))
:text-anchor "middle"
:text-align "center"
:dominant-baseline "central"
:style {:fill distance-text-color
:font-size font-size}}
@ -352,8 +351,8 @@
[:rect.padding-rect {:x (:x rect-data)
:y (:y rect-data)
:width (:width rect-data)
:height (:height rect-data)
:width (max 0 (:width rect-data))
:height (max 0 (:height rect-data))
:on-pointer-enter on-pointer-enter
:on-pointer-leave on-pointer-leave
:on-pointer-down on-pointer-down

View file

@ -107,13 +107,13 @@
[:& copy-button {:data (copy-data shape :layout-align-content)}]])
[:div.attributes-unit-row
[:div.attributes-label "Gap"]
(if (= (:row-gap (:layout-gap shape)) (:column-gap (:layout-gap shape)))
[:div.attributes-label "Gaps"]
(if (= (:row-gap (:layout-gap shape)) (:column-gap (:layout-gap shape)))
[:div.attributes-value
[:span (str/capital (d/name (:row-gap (:layout-gap shape)))) "px"]]
[:span (-> shape :layout-gap :row-gap fm/format-pixels)]]
[:div.attributes-value
[:span.items (:row-gap (:layout-gap shape)) "px"]
[:span (:column-gap (:layout-gap shape)) "px"]])
[:span.items (-> shape :layout-gap :row-gap fm/format-pixels)]
[:span (-> shape :layout-gap :column-gap fm/format-pixels)]])
[:& copy-button {:data (copy-data shape :layout-gap)}]]
[:div.attributes-unit-row

View file

@ -72,7 +72,9 @@
page-id (:page-id (:query-params route))
flex-items (get-flex-elements page-id shapes from)
objects (get-objects from)
shapes (map #(assoc % :flex-items flex-items) shapes)
shapes (->> shapes
(map #(assoc % :parent (get objects (:parent-id %))))
(map #(assoc % :flex-items flex-items)))
style-code (-> (cg/generate-style-code @style-type shapes)
(format-code "css"))

View file

@ -77,6 +77,7 @@
on-thread-click
(mf/use-callback
(mf/deps page-id)
(fn [thread]
(when (not= page-id (:page-id thread))
(st/emit! (dw/go-to-page (:page-id thread))))

View file

@ -349,7 +349,7 @@
(mf/defc context-menu-prototype
[{:keys [shapes]}]
(let [options (mf/deref refs/workspace-page-options)
options-mode (mf/deref refs/options-mode)
options-mode (mf/deref refs/options-mode-global)
do-add-flow #(st/emit! (dwi/add-flow-selected-frame))
do-remove-flow #(st/emit! (dwi/remove-flow (:id %)))
flows (:flows options)

View file

@ -1280,7 +1280,8 @@
:auto-focus true
:default-value (cph/merge-path-item (:path color) (:name color))}]
[:div.name-block {:on-double-click rename-color-clicked}
[:div.name-block {:title (:name color)
:on-double-click rename-color-clicked}
(:name color)
(when-not (= (:name color) default-name)
[:span default-name])])

View file

@ -8,6 +8,7 @@
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.math :as mth]
[app.main.data.workspace :as udw]
[app.main.data.workspace.shape-layout :as dwsl]
[app.main.refs :as refs]
@ -337,7 +338,7 @@
i/auto-gap]
[:> numeric-input {:no-validate true
:placeholder "--"
:on-focus (fn [event]
:on-focus (fn [event]
(select-gap :column-gap)
(reset! gap-selected? :column-gap)
(dom/select-target event))
@ -535,9 +536,10 @@
set-gap
(fn [gap-multiple? type val]
(if gap-multiple?
(st/emit! (dwsl/update-layout ids {:layout-gap {:row-gap val :column-gap val}}))
(st/emit! (dwsl/update-layout ids {:layout-gap {type val}}))))
(let [val (mth/finite val 0)]
(if gap-multiple?
(st/emit! (dwsl/update-layout ids {:layout-gap {:row-gap val :column-gap val}}))
(st/emit! (dwsl/update-layout ids {:layout-gap {type val}})))))
;; Padding
@ -547,15 +549,16 @@
on-padding-change
(fn [type prop val]
(cond
(and (= type :simple) (= prop :p1))
(st/emit! (dwsl/update-layout ids {:layout-padding {:p1 val :p3 val}}))
(let [val (mth/finite val 0)]
(cond
(and (= type :simple) (= prop :p1))
(st/emit! (dwsl/update-layout ids {:layout-padding {:p1 val :p3 val}}))
(and (= type :simple) (= prop :p2))
(st/emit! (dwsl/update-layout ids {:layout-padding {:p2 val :p4 val}}))
(and (= type :simple) (= prop :p2))
(st/emit! (dwsl/update-layout ids {:layout-padding {:p2 val :p4 val}}))
:else
(st/emit! (dwsl/update-layout ids {:layout-padding {prop val}}))))
:else
(st/emit! (dwsl/update-layout ids {:layout-padding {prop val}})))))
;; Grid-direction

View file

@ -499,7 +499,7 @@
:font-weight (:font-weight typography)
:font-style (:font-style typography)}}
(tr "workspace.assets.typography.sample")]
[:div.typography-name (:name typography)]]
[:div.typography-name {:title (:name typography)}(:name typography)]]
[:div.element-set-actions
(when on-detach
[:div.element-set-actions-button
@ -517,7 +517,7 @@
(if (not editable?)
[:div.element-set-content.typography-read-only-data
[:div.row-flex.typography-name
[:span (:name typography)]]
[:span {:title (:name typography)} (:name typography)]]
[:div.row-flex
[:span.label (tr "workspace.assets.typography.font-id")]

View file

@ -42,7 +42,8 @@
:attrs attrs}))
selected-ids))))]
[:div.typography-item {:on-click handle-click}
[:div.typography-item {:title (:name typography)
:on-click handle-click}
[:div.typography-name
{:style {:font-family (:font-family typography)
:font-weight (:font-weight typography)

View file

@ -543,8 +543,8 @@
[:clipPath {:id "clip-handlers"}
[:rect {:x (+ (:x vbox) rule-area-size)
:y (+ (:y vbox) rule-area-size)
:width (- (:width vbox) (* rule-area-size 2))
:height (- (:height vbox) (* rule-area-size 2))}]])]
:width (max 0 (- (:width vbox) (* rule-area-size 2)))
:height (max 0 (- (:height vbox) (* rule-area-size 2)))}]])]
[:& selection/selection-handlers
{:selected selected

View file

@ -361,9 +361,10 @@
(fn [event]
(let [event (.getBrowserEvent ^js event)
target (dom/get-target event)
mod? (kbd/mod? event)]
mod? (kbd/mod? event)
picking-color? (= "pixel-overlay" (.-id target))]
(when (uwvv/inside-viewport? target)
(when (or (uwvv/inside-viewport? target) picking-color?)
(dom/prevent-default event)
(dom/stop-propagation event)
(let [raw-pt (dom/get-client-position event)

View file

@ -183,7 +183,8 @@
[:*
[:div.pixel-overlay
{:tab-index 0
{:id "pixel-overlay"
:tab-index 0
:style {:cursor cur/picker}
:on-pointer-down handle-pointer-down-picker
:on-pointer-up handle-pointer-up-picker

View file

@ -10,6 +10,7 @@
[app.common.data.macros :as dm]
[app.common.pages.helpers :as cph]
[app.common.text :as txt]
[app.common.types.shape.layout :as ctl]
[app.main.ui.formats :as fmt]
[app.util.color :as uc]
[cuerdas.core :as str]))
@ -21,12 +22,6 @@
(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 fill-color->background
[fill]
(uc/color->background {:color (:fill-color fill)
@ -58,10 +53,15 @@
(str/format "%spx %s %s" width style (uc/color->background color)))))
(defn format-position [_ shape]
(cond
(cph/frame-shape? shape) "relative"
(empty? (:flex-items shape)) "absolute"
:else "static"))
(let [relative? (cph/frame-shape? shape)
absolute? (or (empty? (:flex-items shape))
(and (ctl/any-layout? (:parent shape)) (ctl/layout-absolute? shape)))]
(cond
absolute? "absolute"
relative? "relative"
;; static is default value in css
:else nil)))
(defn get-size
[type values]
@ -80,7 +80,8 @@
{:position {:props [:type]
:to-prop {:type "position"}
:format {:type format-position}}
:layout {:props (if (empty? (:flex-items shape))
:layout {:props (if (or (empty? (:flex-items shape))
(ctl/layout-absolute? shape))
[:width :height :x :y :radius :rx :r1]
[:width :height :radius :rx :r1])
:to-prop {:x "left"
@ -89,12 +90,12 @@
: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 #(get-size :width %)
:height #(get-size :height %)}
:multi {:r1 [:r1 :r2 :r3 :r4]}}
:fill {:props [:fills]
:to-prop {:fills (if (> (count (:fills shape)) 1) "background-image" "background")}
:to-prop {:fills (if (> (count (:fills shape)) 1) "background-image" "background-color")}
:format {:fills format-fill-color}}
:stroke {:props [:strokes]
:to-prop {:strokes "border"}
@ -124,7 +125,7 @@
:layout-align-items d/name
:layout-justify-content d/name
:layout-wrap-type d/name
:layout-gap format-gap
:layout-gap fmt/format-gap
:layout-padding fmt/format-padding}}})
(def style-text

View file

@ -90,27 +90,26 @@
[shape-id]
(when (some? shape-id)
(p/let [text-data (calc-text-node-positions shape-id)]
(when (d/not-empty? text-data)
(->> text-data
(mapv (fn [{:keys [node position text direction]}]
(let [{:keys [x y width height]} position
styles (js/getComputedStyle ^js node)
get (fn [prop]
(let [value (.getPropertyValue styles prop)]
(when (and value (not= value ""))
value)))]
(d/without-nils
{:x x
:y (+ y height)
:width width
:height height
:direction direction
:font-family (str (get "font-family"))
:font-size (str (get "font-size"))
:font-weight (str (get "font-weight"))
:text-transform (str (get "text-transform"))
:text-decoration (str (get "text-decoration"))
:letter-spacing (str (get "letter-spacing"))
:font-style (str (get "font-style"))
:fills (transit/decode-str (get "--fills"))
:text text})))))))))
(->> text-data
(mapv (fn [{:keys [node position text direction]}]
(let [{:keys [x y width height]} position
styles (js/getComputedStyle ^js node)
get (fn [prop]
(let [value (.getPropertyValue styles prop)]
(when (and value (not= value ""))
value)))]
(d/without-nils
{:x x
:y (+ y height)
:width width
:height height
:direction direction
:font-family (str (get "font-family"))
:font-size (str (get "font-size"))
:font-weight (str (get "font-weight"))
:text-transform (str (get "text-transform"))
:text-decoration (str (get "text-decoration"))
:letter-spacing (str (get "letter-spacing"))
:font-style (str (get "font-style"))
:fills (transit/decode-str (get "--fills"))
:text text}))))))))

View file

@ -387,7 +387,7 @@ msgid "dashboard.export.title"
msgstr "Export files"
msgid "dashboard.fonts.deleted-placeholder"
msgstr "Font deleted"
msgstr "Missing font"
#: src/app/main/ui/dashboard/fonts.cljs
msgid "dashboard.fonts.dismiss-all"

View file

@ -393,7 +393,7 @@ msgid "dashboard.export.title"
msgstr "Exportar ficheros"
msgid "dashboard.fonts.deleted-placeholder"
msgstr "Fuente eliminada"
msgstr "Fuente no encontrada"
#: src/app/main/ui/dashboard/fonts.cljs
msgid "dashboard.fonts.dismiss-all"

View file

@ -181,9 +181,9 @@ function build-docker-images {
pushd ./docker/images;
docker build -t penpotapp/frontend:$CURRENT_BRANCH -f Dockerfile.frontend .;
docker build -t penpotapp/backend:$CURRENT_BRANCH -f Dockerfile.backend .;
docker build -t penpotapp/exporter:$CURRENT_BRANCH -f Dockerfile.exporter .;
docker build -t penpotapp/frontend:$CURRENT_BRANCH -t penpotapp/frontend:latest -f Dockerfile.frontend .;
docker build -t penpotapp/backend:$CURRENT_BRANCH -t penpotapp/backend:latest -f Dockerfile.backend .;
docker build -t penpotapp/exporter:$CURRENT_BRANCH -t penpotapp/exporter:latest -f Dockerfile.exporter .;
popd;
}

View file

@ -1 +1 @@
1.18.3
1.18.6