diff --git a/common/app/common/data.cljc b/common/app/common/data.cljc index 5e58a61bc..c661194e0 100644 --- a/common/app/common/data.cljc +++ b/common/app/common/data.cljc @@ -6,7 +6,7 @@ (ns app.common.data "Data manipulation and query helper functions." - (:refer-clojure :exclude [concat read-string hash-map merge]) + (:refer-clojure :exclude [concat read-string hash-map merge name]) #?(:cljs (:require-macros [app.common.data])) (:require @@ -359,7 +359,7 @@ ;; Code for ClojureScript (let [mdata (aapi/resolve &env v) arglists (second (get-in mdata [:meta :arglists])) - sym (symbol (name v)) + sym (symbol (core/name v)) andsym (symbol "&") procarg #(if (= % andsym) % (gensym "param"))] (if (pos? (count arglists)) @@ -391,3 +391,16 @@ (defn any-key? [element & rest] (some #(contains? element %) rest)) + +(defn name + "Improved version of name that won't fail if the input is not a keyword" + [maybe-keyword] + (cond + (keyword? maybe-keyword) + (core/name maybe-keyword) + + (nil? maybe-keyword) nil + + :else + (str maybe-keyword))) + diff --git a/frontend/resources/locales.json b/frontend/resources/locales.json index b6dc8e929..02498fc18 100644 --- a/frontend/resources/locales.json +++ b/frontend/resources/locales.json @@ -5512,5 +5512,38 @@ "en": "Imported SVG Attributes", "es": "Atributos del SVG Importado" } + }, + + "handoff.attributes.stroke.alignment.inner" : { + "translations" : { + "en" : "Inside", + "es" : "Interior", + "fr" : "Intérieur", + "ru" : "Внутрь", + "zh_cn" : "内部" + }, + "permanent": true + }, + + "handoff.attributes.stroke.alignment.outer" : { + "translations" : { + "en" : "Outside", + "es" : "Exterior", + "fr" : "Extérieur", + "ru" : "Наружу", + "zh_cn" : "外部" + }, + "permanent": true + }, + + "handoff.attributes.stroke.alignment.center" : { + "translations" : { + "en" : "Center", + "es" : "Centro", + "fr" : "Centre", + "ru" : "Центр", + "zh_cn" : "居中" + }, + "permanent": true } } diff --git a/frontend/resources/styles/main/partials/handoff.scss b/frontend/resources/styles/main/partials/handoff.scss index 18267d300..60739b8c4 100644 --- a/frontend/resources/styles/main/partials/handoff.scss +++ b/frontend/resources/styles/main/partials/handoff.scss @@ -94,6 +94,10 @@ .attributes-label, .attributes-value { + margin-right: 0.5rem; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; width: 50%; } .copy-button { diff --git a/frontend/src/app/main/data/workspace/svg_upload.cljs b/frontend/src/app/main/data/workspace/svg_upload.cljs index 5c875bf2f..baea021f4 100644 --- a/frontend/src/app/main/data/workspace/svg_upload.cljs +++ b/frontend/src/app/main/data/workspace/svg_upload.cljs @@ -44,7 +44,7 @@ "Given a tag returns its layer name" [tag] (str "svg-" (cond (string? tag) tag - (keyword? tag) (name tag) + (keyword? tag) (d/name tag) (nil? tag) "node" :else (str tag)))) diff --git a/frontend/src/app/main/ui/handoff/attributes.cljs b/frontend/src/app/main/ui/handoff/attributes.cljs index 4cf91cafb..b8fac8588 100644 --- a/frontend/src/app/main/ui/handoff/attributes.cljs +++ b/frontend/src/app/main/ui/handoff/attributes.cljs @@ -19,16 +19,17 @@ [app.main.ui.handoff.attributes.shadow :refer [shadow-panel]] [app.main.ui.handoff.attributes.blur :refer [blur-panel]] [app.main.ui.handoff.attributes.image :refer [image-panel]] - [app.main.ui.handoff.attributes.text :refer [text-panel]])) + [app.main.ui.handoff.attributes.text :refer [text-panel]] + [app.main.ui.handoff.attributes.svg :refer [svg-panel]])) (def type->options {:multiple [:fill :stroke :image :text :shadow :blur] :frame [:layout :fill] - :group [:layout] - :rect [:layout :fill :stroke :shadow :blur] - :circle [:layout :fill :stroke :shadow :blur] - :path [:layout :fill :stroke :shadow :blur] - :image [:image :layout :shadow :blur] + :group [:layout :svg] + :rect [:layout :fill :stroke :shadow :blur :svg] + :circle [:layout :fill :stroke :shadow :blur :svg] + :path [:layout :fill :stroke :shadow :blur :svg] + :image [:image :layout :shadow :blur :svg] :text [:layout :text :shadow :blur]}) (mf/defc attributes @@ -46,7 +47,8 @@ :shadow shadow-panel :blur blur-panel :image image-panel - :text text-panel) + :text text-panel + :svg svg-panel) {:shapes shapes :frame frame :locale locale}]) diff --git a/frontend/src/app/main/ui/handoff/attributes/layout.cljs b/frontend/src/app/main/ui/handoff/attributes/layout.cljs index c161fffa9..bd1304ded 100644 --- a/frontend/src/app/main/ui/handoff/attributes/layout.cljs +++ b/frontend/src/app/main/ui/handoff/attributes/layout.cljs @@ -37,53 +37,55 @@ (mf/defc layout-block [{:keys [shape locale]}] - [:* - [:div.attributes-unit-row - [:div.attributes-label (t locale "handoff.attributes.layout.width")] - [:div.attributes-value (mth/precision (:width shape) 2) "px"] - [:& copy-button {:data (copy-data shape :width)}]] - - [:div.attributes-unit-row - [:div.attributes-label (t locale "handoff.attributes.layout.height")] - [:div.attributes-value (mth/precision (:height shape) 2) "px"] - [:& copy-button {:data (copy-data shape :height)}]] - - (when (not= (:x shape) 0) + (let [selrect (:selrect shape) + {:keys [width height x y]} selrect] + [:* [:div.attributes-unit-row - [:div.attributes-label (t locale "handoff.attributes.layout.left")] - [:div.attributes-value (mth/precision (:x shape) 2) "px"] - [:& copy-button {:data (copy-data shape :x)}]]) + [:div.attributes-label (t locale "handoff.attributes.layout.width")] + [:div.attributes-value (mth/precision width 2) "px"] + [:& copy-button {:data (copy-data selrect :width)}]] - (when (not= (:y shape) 0) [:div.attributes-unit-row - [:div.attributes-label (t locale "handoff.attributes.layout.top")] - [:div.attributes-value (mth/precision (:y shape) 2) "px"] - [:& copy-button {:data (copy-data shape :y)}]]) + [:div.attributes-label (t locale "handoff.attributes.layout.height")] + [:div.attributes-value (mth/precision height 2) "px"] + [:& copy-button {:data (copy-data selrect :height)}]] - (when (and (:rx shape) (not= (:rx shape) 0)) - [:div.attributes-unit-row - [:div.attributes-label (t locale "handoff.attributes.layout.radius")] - [:div.attributes-value (mth/precision (:rx shape) 2) "px"] - [:& copy-button {:data (copy-data shape :rx)}]]) + (when (not= (:x shape) 0) + [:div.attributes-unit-row + [:div.attributes-label (t locale "handoff.attributes.layout.left")] + [:div.attributes-value (mth/precision x 2) "px"] + [:& copy-button {:data (copy-data selrect :x)}]]) - (when (and (:r1 shape) - (or (not= (:r1 shape) 0) - (not= (:r2 shape) 0) - (not= (:r3 shape) 0) - (not= (:r4 shape) 0))) - [:div.attributes-unit-row - [:div.attributes-label (t locale "handoff.attributes.layout.radius")] - [:div.attributes-value (mth/precision (:r1 shape) 2) ", " - (mth/precision (:r2 shape) 2) ", " - (mth/precision (:r3 shape) 2) ", " - (mth/precision (:r4 shape) 2) "px"] - [:& copy-button {:data (copy-data shape :r1)}]]) + (when (not= (:y shape) 0) + [:div.attributes-unit-row + [:div.attributes-label (t locale "handoff.attributes.layout.top")] + [:div.attributes-value (mth/precision y 2) "px"] + [:& copy-button {:data (copy-data selrect :y)}]]) - (when (not= (:rotation shape 0) 0) - [:div.attributes-unit-row - [:div.attributes-label (t locale "handoff.attributes.layout.rotation")] - [:div.attributes-value (mth/precision (:rotation shape) 2) "deg"] - [:& copy-button {:data (copy-data shape :rotation)}]])]) + (when (and (:rx shape) (not= (:rx shape) 0)) + [:div.attributes-unit-row + [:div.attributes-label (t locale "handoff.attributes.layout.radius")] + [:div.attributes-value (mth/precision (:rx shape) 2) "px"] + [:& copy-button {:data (copy-data shape :rx)}]]) + + (when (and (:r1 shape) + (or (not= (:r1 shape) 0) + (not= (:r2 shape) 0) + (not= (:r3 shape) 0) + (not= (:r4 shape) 0))) + [:div.attributes-unit-row + [:div.attributes-label (t locale "handoff.attributes.layout.radius")] + [:div.attributes-value (mth/precision (:r1 shape) 2) ", " + (mth/precision (:r2 shape) 2) ", " + (mth/precision (:r3 shape) 2) ", " + (mth/precision (:r4 shape) 2) "px"] + [:& copy-button {:data (copy-data shape :r1)}]]) + + (when (not= (:rotation shape 0) 0) + [:div.attributes-unit-row + [:div.attributes-label (t locale "handoff.attributes.layout.rotation")] + [:div.attributes-value (mth/precision (:rotation shape) 2) "deg"] + [:& copy-button {:data (copy-data shape :rotation)}]])])) (mf/defc layout-panel diff --git a/frontend/src/app/main/ui/handoff/attributes/shadow.cljs b/frontend/src/app/main/ui/handoff/attributes/shadow.cljs index 1ddb7b86f..75ee452c4 100644 --- a/frontend/src/app/main/ui/handoff/attributes/shadow.cljs +++ b/frontend/src/app/main/ui/handoff/attributes/shadow.cljs @@ -11,6 +11,7 @@ (:require [rumext.alpha :as mf] [cuerdas.core :as str] + [app.common.data :as d] [app.util.i18n :refer [t]] [app.util.code-gen :as cg] [app.main.ui.icons :as i] @@ -40,7 +41,7 @@ copy-data (shadow-copy-data shadow)] [:div.attributes-shadow-block [:div.attributes-shadow-row - [:div.attributes-label (->> shadow :style name (str "handoff.attributes.shadow.style.") (t locale))] + [:div.attributes-label (->> shadow :style d/name (str "handoff.attributes.shadow.style.") (t locale))] [:div.attributes-shadow [:div.attributes-label (t locale "handoff.attributes.shadow.shorthand.offset-x")] [:div.attributes-value (str (:offset-x shadow))]] diff --git a/frontend/src/app/main/ui/handoff/attributes/stroke.cljs b/frontend/src/app/main/ui/handoff/attributes/stroke.cljs index 14faeb5ec..99f5e3741 100644 --- a/frontend/src/app/main/ui/handoff/attributes/stroke.cljs +++ b/frontend/src/app/main/ui/handoff/attributes/stroke.cljs @@ -11,6 +11,8 @@ (:require [rumext.alpha :as mf] [cuerdas.core :as str] + [app.common.data :as d] + [app.common.math :as mth] [app.util.i18n :refer [t]] [app.util.color :as uc] [app.main.ui.icons :as i] @@ -27,13 +29,15 @@ (defn format-stroke [shape] (let [width (:stroke-width shape) - style (name (:stroke-style shape)) + style (d/name (:stroke-style shape)) + style (if (= style "svg") "solid" style) color (-> shape shape->color uc/color->background)] (str/format "%spx %s %s" width style color))) -(defn has-stroke? [shape] - (and (:stroke-style shape) - (not= (:stroke-style shape) :none))) +(defn has-stroke? [{:keys [stroke-style]}] + (and stroke-style + (and (not= stroke-style :none) + (not= stroke-style :svg)))) (defn copy-stroke-data [shape] (cg/generate-css-props @@ -59,12 +63,15 @@ :copy-data (copy-color-data shape) :on-change-format #(reset! color-format %)}] - [:div.attributes-stroke-row - [:div.attributes-label (t locale "handoff.attributes.stroke.width")] - [:div.attributes-value (:stroke-width shape) "px"] - [:div.attributes-value (->> shape :stroke-style name (str "handoff.attributes.stroke.style.") (t locale))] - [:div.attributes-label (->> shape :stroke-alignment name (str "handoff.attributes.stroke.alignment.") (t locale))] - [:& copy-button {:data (copy-stroke-data shape)}]]])) + (let [{:keys [stroke-style stroke-alignment]} shape + stroke-style (if (= stroke-style :svg) :solid stroke-style) + stroke-alignment (or stroke-alignment :center)] + [:div.attributes-stroke-row + [:div.attributes-label (t locale "handoff.attributes.stroke.width")] + [:div.attributes-value (mth/precision (:stroke-width shape) 2) "px"] + [:div.attributes-value (->> stroke-style d/name (str "handoff.attributes.stroke.style.") (t locale))] + [:div.attributes-label (->> stroke-alignment d/name (str "handoff.attributes.stroke.alignment.") (t locale))] + [:& copy-button {:data (copy-stroke-data shape)}]])])) (mf/defc stroke-panel [{:keys [shapes locale]}] diff --git a/frontend/src/app/main/ui/handoff/attributes/svg.cljs b/frontend/src/app/main/ui/handoff/attributes/svg.cljs new file mode 100644 index 000000000..b8e80d04f --- /dev/null +++ b/frontend/src/app/main/ui/handoff/attributes/svg.cljs @@ -0,0 +1,57 @@ +;; 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/. +;; +;; This Source Code Form is "Incompatible With Secondary Licenses", as +;; defined by the Mozilla Public License, v. 2.0. +;; +;; Copyright (c) 2020 UXBOX Labs SL + +(ns app.main.ui.handoff.attributes.svg + (:require + [rumext.alpha :as mf] + [app.common.data :as d] + [cuerdas.core :as str] + [app.util.i18n :refer [tr]] + #_[app.common.math :as mth] + #_[app.main.ui.icons :as i] + #_[app.util.code-gen :as cg] + [app.main.ui.components.copy-button :refer [copy-button]])) + + +(defn map->css [attr] + (->> attr + (map (fn [[attr-key attr-value]] (str (d/name attr-key) ":" attr-value))) + (str/join "; "))) + +(mf/defc svg-attr [{:keys [attr value]}] + (if (map? value) + [:* + [:div.attributes-block-title + [:div.attributes-block-title-text (d/name attr)] + [:& copy-button {:data (map->css value)}]] + + (for [[attr-key attr-value] value] + [:& svg-attr {:attr attr-key :value attr-value}])] + + [:div.attributes-unit-row + [:div.attributes-label (d/name attr)] + [:div.attributes-value (str value)] + [:& copy-button {:data (d/name value)}]])) + +(mf/defc svg-block + [{:keys [shape]}] + [:* + (for [[attr-key attr-value] (:svg-attrs shape)] + [:& svg-attr {:attr attr-key :value attr-value}])] ) + + +(mf/defc svg-panel + [{:keys [shapes]}] + + (let [shape (first shapes)] + (when (and (:svg-attrs shape) (not (empty? (:svg-attrs shape)))) + [:div.attributes-block + [:div.attributes-block-title + [:div.attributes-block-title-text (tr "workspace.sidebar.options.svg-attrs.title")]] + [:& svg-block {:shape shape}]]))) diff --git a/frontend/src/app/main/ui/handoff/exports.cljs b/frontend/src/app/main/ui/handoff/exports.cljs index a992b6980..43d3c649a 100644 --- a/frontend/src/app/main/ui/handoff/exports.cljs +++ b/frontend/src/app/main/ui/handoff/exports.cljs @@ -114,7 +114,7 @@ [:input.input-text {:on-change (partial on-suffix-change index) :value (:suffix export)}] [:select.input-select {:on-change (partial on-type-change index) - :value (name (:type export))} + :value (d/name (:type export))} [:option {:value "png"} "PNG"] [:option {:value "jpeg"} "JPEG"] [:option {:value "svg"} "SVG"]] diff --git a/frontend/src/app/main/ui/handoff/right_sidebar.cljs b/frontend/src/app/main/ui/handoff/right_sidebar.cljs index cce8f4f10..71fed541d 100644 --- a/frontend/src/app/main/ui/handoff/right_sidebar.cljs +++ b/frontend/src/app/main/ui/handoff/right_sidebar.cljs @@ -12,6 +12,7 @@ [rumext.alpha :as mf] [okulary.core :as l] [app.util.i18n :refer [t] :as i18n] + [app.common.data :as d] [app.main.store :as st] [app.main.ui.icons :as i] [app.main.ui.components.tab-container :refer [tab-container tab-element]] @@ -49,7 +50,7 @@ [:* [:span.tool-window-bar-icon [:& element-icon {:shape (-> shapes first)}]] - [:span.tool-window-bar-title (->> selected-type name (str "handoff.tabs.code.selected.") (t locale))]]) + [:span.tool-window-bar-title (->> selected-type d/name (str "handoff.tabs.code.selected.") (t locale))]]) ] [:div.tool-window-content [:& tab-container {:on-change-tab #(do diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/svg_attrs.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/svg_attrs.cljs index 8c008d53f..c7dbdec88 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/svg_attrs.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/svg_attrs.cljs @@ -32,7 +32,7 @@ (fn [] (on-delete attr))) - label (->> attr last name)] + label (->> attr last d/name)] [:div.element-set-content (if (string? value) [:div.row-flex.row-flex-removable @@ -48,7 +48,7 @@ [:* [:div.element-set-title {:style {:border-bottom "1px solid #444" :margin-bottom "0.5rem"}} - [:span (str (name (last attr)))]] + [:span (str (d/name (last attr)))]] (for [[key value] value] [:& attribute-value {:key key diff --git a/frontend/src/app/util/svg.cljs b/frontend/src/app/util/svg.cljs index 32edc14a7..bc3979a8c 100644 --- a/frontend/src/app/util/svg.cljs +++ b/frontend/src/app/util/svg.cljs @@ -63,7 +63,7 @@ "Transforms attributes to their react equivalent" [attrs] (letfn [(transform-key [key] - (-> (name key) + (-> (d/name key) (str/replace ":" "-") (str/camel) (keyword)))