diff --git a/frontend/resources/images/icons/align-bottom.svg b/frontend/resources/images/icons/align-bottom.svg
new file mode 100644
index 000000000..79e156fd8
--- /dev/null
+++ b/frontend/resources/images/icons/align-bottom.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/images/icons/align-middle.svg b/frontend/resources/images/icons/align-middle.svg
new file mode 100644
index 000000000..60a538eb3
--- /dev/null
+++ b/frontend/resources/images/icons/align-middle.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/images/icons/align-top.svg b/frontend/resources/images/icons/align-top.svg
new file mode 100644
index 000000000..4e95be8d3
--- /dev/null
+++ b/frontend/resources/images/icons/align-top.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/images/icons/auto-fix.svg b/frontend/resources/images/icons/auto-fix.svg
new file mode 100644
index 000000000..38c4d54e8
--- /dev/null
+++ b/frontend/resources/images/icons/auto-fix.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/images/icons/auto-height.svg b/frontend/resources/images/icons/auto-height.svg
new file mode 100644
index 000000000..963dda6d3
--- /dev/null
+++ b/frontend/resources/images/icons/auto-height.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/images/icons/auto-width.svg b/frontend/resources/images/icons/auto-width.svg
new file mode 100644
index 000000000..c88a331e3
--- /dev/null
+++ b/frontend/resources/images/icons/auto-width.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/images/icons/letter-spacing.svg b/frontend/resources/images/icons/letter-spacing.svg
new file mode 100644
index 000000000..6098501c7
--- /dev/null
+++ b/frontend/resources/images/icons/letter-spacing.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/images/icons/line-height.svg b/frontend/resources/images/icons/line-height.svg
new file mode 100644
index 000000000..ee08402cc
--- /dev/null
+++ b/frontend/resources/images/icons/line-height.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/images/icons/lowercase.svg b/frontend/resources/images/icons/lowercase.svg
new file mode 100644
index 000000000..9741dae12
--- /dev/null
+++ b/frontend/resources/images/icons/lowercase.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/images/icons/strikethrough.svg b/frontend/resources/images/icons/strikethrough.svg
new file mode 100644
index 000000000..bbec524b4
--- /dev/null
+++ b/frontend/resources/images/icons/strikethrough.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/images/icons/titlecase.svg b/frontend/resources/images/icons/titlecase.svg
new file mode 100644
index 000000000..473b6c8cb
--- /dev/null
+++ b/frontend/resources/images/icons/titlecase.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/images/icons/underline.svg b/frontend/resources/images/icons/underline.svg
new file mode 100644
index 000000000..3e35ddc93
--- /dev/null
+++ b/frontend/resources/images/icons/underline.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/images/icons/uppercase.svg b/frontend/resources/images/icons/uppercase.svg
new file mode 100644
index 000000000..3c681ac75
--- /dev/null
+++ b/frontend/resources/images/icons/uppercase.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/locales.json b/frontend/resources/locales.json
index 776f36fe8..c92565f06 100644
--- a/frontend/resources/locales.json
+++ b/frontend/resources/locales.json
@@ -912,7 +912,7 @@
"workspace.options.font-options" : {
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:200" ],
"translations" : {
- "en" : "Fonts & Font Size",
+ "en" : "Text",
"fr" : "TODO"
}
},
diff --git a/frontend/resources/styles/main/partials/colorpicker.scss b/frontend/resources/styles/main/partials/colorpicker.scss
index 9ced54c58..5abc8c6e6 100644
--- a/frontend/resources/styles/main/partials/colorpicker.scss
+++ b/frontend/resources/styles/main/partials/colorpicker.scss
@@ -165,6 +165,7 @@
font-size: $fs13;
&:focus {
+ border-color: $color-primary;
color: $color-white;
}
}
diff --git a/frontend/resources/styles/main/partials/sidebar-element-options.scss b/frontend/resources/styles/main/partials/sidebar-element-options.scss
index 37fb6071e..27c72ce40 100644
--- a/frontend/resources/styles/main/partials/sidebar-element-options.scss
+++ b/frontend/resources/styles/main/partials/sidebar-element-options.scss
@@ -186,7 +186,8 @@
.input-text {
background-color: $color-gray-50;
- border-color: $color-gray-40;
+ border: 1px solid transparent;
+ border-bottom-color: $color-gray-40;
color: $color-gray-10;
font-size: $fs13;
margin: $x-small;
@@ -195,7 +196,7 @@
&:focus {
color: lighten($color-gray-10, 8%);
- border-color: $color-gray-20;
+ border-color: $color-primary;
}
}
@@ -318,29 +319,31 @@
}
.editable-select {
- position: relative;
- width: 100%;
height: 38px;
+ margin-right: $small;
+ position: relative;
+ width: 60%;
.input-text {
- position: absolute;
- top: 0;
left: 0;
- width: 80%;
+ position: absolute;
+ top: -1px;
+ width: 60%;
}
-
+
.input-select {
+ background-color: transparent;
+ border: none;
+ border-bottom: 1px solid $color-gray-40;
+ color: transparent;
+ left: 0;
position: absolute;
top: 0;
- left: 0;
- border: none;
- color: transparent;
- background-color: transparent;
width: 100%;
option {
color: $color-gray-60;
- background: $color-gray-60;
+ background: $color-white;
font-size: $fs12;
}
}
@@ -381,16 +384,37 @@
}
+.row-flex.align-icons {
+ margin-left: 0;
+}
+
.align-icons {
+ border: 1px solid $color-gray-60;
+ border-radius: $br-small;
cursor: pointer;
+ display: flex;
+ flex: 1;
+ justify-content: space-between;
+ margin-left: $small;
+ padding: $small;
+
+ &:first-child {
+ margin-left: 0;
+ }
span {
+ align-items: center;
+ display: flex;
+ height: 18px;
+ justify-content: center;
+ margin-right: $small;
+ position: relative;
+ width: 18px;
svg {
fill: $color-gray-30;
- height: 20px;
- margin: $x-small $small;
- width: 20px;
+ height: 15px;
+ width: 15px;
}
&:hover,
@@ -402,6 +426,10 @@
}
+ &:last-child {
+ margin-right: 0;
+ }
+
}
@@ -455,3 +483,27 @@
}
}
}
+
+.input-icon {
+ align-items: center;
+ display: flex;
+ width: 100%;
+
+ &:first-child {
+ margin-right: $small;
+ }
+
+ .icon-before {
+ align-items: center;
+ display: flex;
+ height: 18px;
+ position: relative;
+ width: 18px;
+
+ svg {
+ fill: $color-gray-30;
+ height: 16px;
+ width: 16px;
+ }
+ }
+}
diff --git a/frontend/resources/styles/main/partials/workspace.scss b/frontend/resources/styles/main/partials/workspace.scss
index b7ab8f403..b49aa5e04 100644
--- a/frontend/resources/styles/main/partials/workspace.scss
+++ b/frontend/resources/styles/main/partials/workspace.scss
@@ -50,11 +50,11 @@
background-color: $color-canvas;
display: flex;
height: 100%;
- width: calc(100% - 500px);
+ width: calc(100% - 520px);
padding: 0;
margin: 0;
position: fixed;
- right: 230px;
+ right: 240px;
&.scrolling {
cursor: grab;
diff --git a/frontend/src/uxbox/builtins/icons.cljs b/frontend/src/uxbox/builtins/icons.cljs
index 9e12c7a00..d234e1980 100644
--- a/frontend/src/uxbox/builtins/icons.cljs
+++ b/frontend/src/uxbox/builtins/icons.cljs
@@ -15,6 +15,12 @@
(def text-align-justify (icon-xref :text-align-justify))
(def text-align-left (icon-xref :text-align-left))
(def text-align-right (icon-xref :text-align-right))
+(def align-top (icon-xref :align-top))
+(def align-bottom (icon-xref :align-bottom))
+(def align-middle (icon-xref :align-middle))
+(def auto-fix (icon-xref :auto-fix))
+(def auto-width (icon-xref :auto-width))
+(def auto-height (icon-xref :auto-height))
(def alignment (icon-xref :alignment))
(def arrow (icon-xref :arrow))
(def arrow-down (icon-xref :arrow-down))
@@ -46,12 +52,15 @@
(def image (icon-xref :image))
(def infocard (icon-xref :infocard))
(def layers (icon-xref :layers))
+(def letter-spacing (icon-xref :letter-spacing))
(def line (icon-xref :line))
+(def line-height (icon-xref :line-height))
(def loader (icon-xref :loader))
(def lock (icon-xref :lock))
(def lock-open (icon-xref :lock-open))
(def logo (icon-xref :uxbox-logo))
(def logo-icon (icon-xref :uxbox-logo-icon))
+(def lowercase (icon-xref :lowercase))
(def mail (icon-xref :mail))
(def minus (icon-xref :minus))
(def move (icon-xref :move))
@@ -79,9 +88,11 @@
(def shape-vdistribute (icon-xref :shape-vdistribute))
(def size-horiz (icon-xref :size-horiz))
(def size-vert (icon-xref :size-vert))
+(def strikethrough (icon-xref :strikethrough))
(def stroke (icon-xref :stroke))
(def sublevel (icon-xref :sublevel))
(def text (icon-xref :text))
+(def titlecase (icon-xref :titlecase))
(def toggle (icon-xref :toggle))
(def trash (icon-xref :trash))
(def tree (icon-xref :tree))
@@ -89,6 +100,8 @@
(def undo-history (icon-xref :undo-history))
(def ungroup (icon-xref :ungroup))
(def unlock (icon-xref :unlock))
+(def underline (icon-xref :underline))
+(def uppercase (icon-xref :uppercase))
(def user (icon-xref :user))
(def recent (icon-xref :recent))
diff --git a/frontend/src/uxbox/main/ui/settings/profile.cljs b/frontend/src/uxbox/main/ui/settings/profile.cljs
index e0f3b1a71..82c901397 100644
--- a/frontend/src/uxbox/main/ui/settings/profile.cljs
+++ b/frontend/src/uxbox/main/ui/settings/profile.cljs
@@ -103,7 +103,6 @@
:on-change (fm/on-input-change form :theme)}
[:option {:value "light"} "Default"]]
-
[:input.btn-primary
{:type "submit"
:class (when-not (:valid form) "btn-disabled")
diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/circle.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/circle.cljs
index 41eac204a..fe5df7677 100644
--- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/circle.cljs
+++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/circle.cljs
@@ -10,138 +10,14 @@
(ns uxbox.main.ui.workspace.sidebar.options.circle
(:require
[rumext.alpha :as mf]
- [uxbox.common.data :as d]
- [uxbox.builtins.icons :as i]
- [uxbox.main.data.workspace :as udw]
- [uxbox.main.geom :as geom]
- [uxbox.main.store :as st]
[uxbox.main.ui.workspace.sidebar.options.fill :refer [fill-menu]]
- [uxbox.main.ui.workspace.sidebar.options.stroke :refer [stroke-menu]]
- [uxbox.util.dom :as dom]
- [uxbox.util.geom.point :as gpt]
- [uxbox.util.i18n :as i18n :refer [tr t]]
- [uxbox.util.math :as math]))
-
-(mf/defc measures-menu
- [{:keys [shape] :as props}]
- (let [locale (i18n/use-locale)
-
- on-size-change
- (fn [event attr]
- (let [value (-> (dom/get-target event)
- (dom/get-value)
- (d/parse-integer 0))]
- (st/emit! (udw/update-circle-dimensions (:id shape) attr value))))
-
- on-proportion-lock-change
- (fn [event]
- (st/emit! (udw/toggle-shape-proportion-lock (:id shape))))
-
- on-size-rx-change #(on-size-change % :rx)
- on-size-ry-change #(on-size-change % :ry)
-
- on-position-change
- (fn [event attr]
- (let [value (-> (dom/get-target event)
- (dom/get-value)
- (d/parse-integer 0))]
- (st/emit! (udw/update-position (:id shape) {attr value}))))
-
- on-pos-cx-change #(on-position-change % :x)
- on-pos-cy-change #(on-position-change % :y)
-
- on-rotation-change
- (fn [event]
- (let [value (-> (dom/get-target event)
- (dom/get-value)
- (d/parse-integer 0))]
- (st/emit! (udw/update-shape (:id shape) {:rotation value}))))
-
- on-radius-change
- (fn [event]
- (let [value (-> (dom/get-target event)
- (dom/get-value)
- (d/parse-integer 0))]
- (st/emit! (udw/update-shape (:id shape) {:rx value :ry value}))))]
-
- [:div.element-set
- [:div.element-set-content
-
- ;; SIZE
- [:div.row-flex
- [:span.element-set-subtitle (t locale "workspace.options.size")]
- [:div.lock-size {:class (when (:proportion-lock shape) "selected")
- :on-click on-proportion-lock-change}
- (if (:proportion-lock shape)
- i/lock
- i/unlock)]
- [:div.input-element.pixels
- [:input.input-text {:type "number"
- :min "0"
- :on-change on-size-rx-change
- :value (str (-> (:rx shape)
- (d/coalesce 0)
- (math/round)))}]]
- [:div.input-element.pixels
- [:input.input-text {:type "number"
- :min "0"
- :on-change on-size-ry-change
- :value (str (-> (:ry shape)
- (d/coalesce 0)
- (math/round)))}]]]
-
- ;; POSITION
- [:div.row-flex
- [:span.element-set-subtitle (t locale "workspace.options.position")]
- [:div.input-element.pixels
- [:input.input-text {:type "number"
- :on-change on-pos-cx-change
- :value (str (-> (:cx shape)
- (d/coalesce 0)
- (math/round)))}]]
- [:div.input-element.pixels
- [:input.input-text {:type "number"
- :on-change on-pos-cy-change
- :value (str (-> (:cy shape)
- (d/coalesce 0)
- (math/round)))}]]]
-
- [:div.row-flex
- [:span.element-set-subtitle (t locale "workspace.options.rotation")]
- [:div.input-element.degrees
- [:input.input-text
- {:type "number"
- :min "0"
- :max "360"
- :on-change on-rotation-change
- :value (str (-> (:rotation shape)
- (d/coalesce 0)
- (math/round)))}]]
-
- [:input.slidebar
- {:type "range"
- :min "0"
- :max "360"
- :on-change on-rotation-change
- :value (str (-> (:rotation shape)
- (d/coalesce 0)
- (math/round)))
- :step "1"}]]
-
- [:div.row-flex
- [:span.element-set-subtitle (t locale "workspace.options.radius")]
- [:div.input-element.pixels
- [:input.input-text
- {:type "number"
- :on-change on-radius-change
- :value (str (-> (:rx shape)
- (d/coalesce 0)
- (math/round)))}]]
- [:div.input-element]]]]))
+ [uxbox.main.ui.workspace.sidebar.options.measures :refer [measures-menu]]
+ [uxbox.main.ui.workspace.sidebar.options.stroke :refer [stroke-menu]]))
(mf/defc options
[{:keys [shape] :as props}]
[:div
- [:& measures-menu {:shape shape}]
+ [:& measures-menu {:shape shape
+ :options #{:circle-size :position :rotation}}]
[:& fill-menu {:shape shape}]
[:& stroke-menu {:shape shape}]])
diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/group.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/group.cljs
index df0c4f0a4..7fb0802e3 100644
--- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/group.cljs
+++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/group.cljs
@@ -16,5 +16,6 @@
(mf/defc options
[{:keys [shape] :as props}]
[:div
- [:& measures-menu {:shape shape}]])
+ [:& measures-menu {:options #{:position :rotation}
+ :shape shape}]])
diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/icon.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/icon.cljs
index eb913474f..406242c67 100644
--- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/icon.cljs
+++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/icon.cljs
@@ -5,150 +5,14 @@
;; This Source Code Form is "Incompatible With Secondary Licenses", as
;; defined by the Mozilla Public License, v. 2.0.
;;
-;; Copyright (c) 2015-2020 Andrey Antukh
-;; Copyright (c) 2015-2020 Juan de la Cruz
+;; Copyright (c) 2020 UXBOX Labs SL
(ns uxbox.main.ui.workspace.sidebar.options.icon
(:require
[rumext.alpha :as mf]
- [uxbox.common.data :as d]
- [uxbox.builtins.icons :as i]
- [uxbox.main.data.workspace :as udw]
- [uxbox.main.geom :as geom]
- [uxbox.main.store :as st]
+ [uxbox.main.ui.workspace.sidebar.options.measures :refer [measures-menu]]
[uxbox.main.ui.workspace.sidebar.options.fill :refer [fill-menu]]
- [uxbox.main.ui.workspace.sidebar.options.stroke :refer [stroke-menu]]
- [uxbox.util.dom :as dom]
- [uxbox.util.geom.point :as gpt]
- [uxbox.util.i18n :as i18n :refer [tr t]]
- [uxbox.util.math :as math]))
-
-(mf/defc measures-menu
- [{:keys [shape] :as props}]
- (let [locale (i18n/use-locale)
-
- on-size-change
- (fn [event attr]
- (let [value (-> (dom/get-target event)
- (dom/get-value)
- (d/parse-integer 0))]
- (st/emit! (udw/update-rect-dimensions (:id shape) attr value))))
-
- on-proportion-lock-change
- (fn [event]
- (st/emit! (udw/toggle-shape-proportion-lock (:id shape))))
-
- on-position-change
- (fn [event attr]
- (let [value (-> (dom/get-target event)
- (dom/get-value)
- (d/parse-integer 0))]
- (st/emit! (udw/update-position (:id shape) {attr value}))))
-
- on-rotation-change
- (fn [event]
- (let [value (-> (dom/get-target event)
- (dom/get-value)
- (d/parse-integer 0))]
- (st/emit! (udw/update-shape (:id shape) {:rotation value}))))
-
- on-radius-change
- (fn [event]
- (let [value (-> (dom/get-target event)
- (dom/get-value)
- (d/parse-integer 0))]
- (st/emit! (udw/update-shape (:id shape) {:rx value :ry value}))))
-
- on-width-change #(on-size-change % :width)
- on-height-change #(on-size-change % :height)
- on-pos-x-change #(on-position-change % :x)
- on-pos-y-change #(on-position-change % :y)]
-
- [:div.element-set
- [:div.element-set-content
-
- ;; WIDTH & HEIGHT
- [:div.row-flex
- [:span.element-set-subtitle (t locale "workspace.options.size")]
- [:div.lock-size {:class (when (:proportion-lock shape) "selected")
- :on-click on-proportion-lock-change}
- (if (:proportion-lock shape)
- i/lock
- i/unlock)]
- [:div.input-element.pixels
- [:input.input-text {:type "number"
- :min "0"
- :no-validate true
- :on-change on-width-change
- :value (str (-> (:width shape)
- (d/coalesce 0)
- (math/round)))}]]
-
-
- [:div.input-element.pixels
- [:input.input-text {:type "number"
- :min "0"
- :no-validate true
- :on-change on-height-change
- :value (str (-> (:height shape)
- (d/coalesce 0)
- (math/round)))}]]]
-
- ;; POSITION
- [:div.row-flex
- [:span.element-set-subtitle (t locale "workspace.options.position")]
- [:div.input-element.pixels
- [:input.input-text {:placeholder "x"
- :type "number"
- :no-validate true
- :on-change on-pos-x-change
- :value (str (-> (:x shape)
- (d/coalesce 0)
- (math/round)))}]]
- [:div.input-element.pixels
- [:input.input-text {:placeholder "y"
- :type "number"
- :no-validate true
- :on-change on-pos-y-change
- :value (str (-> (:y shape)
- (d/coalesce 0)
- (math/round)))}]]]
-
- [:div.row-flex
- [:span.element-set-subtitle (t locale "workspace.options.rotation")]
- [:div.input-element.degrees
- [:input.input-text
- {:placeholder ""
- :type "number"
- :no-validate true
- :min "0"
- :max "360"
- :on-change on-rotation-change
- :value (str (-> (:rotation shape)
- (d/coalesce 0)
- (math/round)))}]]
- [:input.slidebar
- {:type "range"
- :min "0"
- :max "360"
- :step "1"
- :no-validate true
- :on-change on-rotation-change
- :value (str (-> (:rotation shape)
- (d/coalesce 0)))}]]
-
- [:div.row-flex
- [:span.element-set-subtitle (t locale "workspace.options.radius")]
- [:div.input-element.pixels
- [:input.input-text
- {:placeholder "rx"
- :type "number"
- :on-change on-radius-change
- :value (str (-> (:rx shape)
- (d/coalesce 0)
- (math/round)))}]]
- [:div.input-element]]]]))
-
+ [uxbox.main.ui.workspace.sidebar.options.stroke :refer [stroke-menu]]))
(mf/defc options
[{:keys [shape] :as props}]
diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/image.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/image.cljs
index f130fc535..30df2914c 100644
--- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/image.cljs
+++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/image.cljs
@@ -2,153 +2,17 @@
;; 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) 2015-2017 Andrey Antukh
-;; Copyright (c) 2015-2017 Juan de la Cruz
+;; 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 uxbox.main.ui.workspace.sidebar.options.image
(:require
[rumext.alpha :as mf]
- [uxbox.common.data :as d]
- [uxbox.builtins.icons :as i]
- [uxbox.main.data.workspace :as udw]
- [uxbox.main.geom :as geom]
- [uxbox.main.store :as st]
- [uxbox.util.dom :as dom]
- [uxbox.util.geom.point :as gpt]
- [uxbox.util.i18n :as i18n :refer [t]]
- [uxbox.util.math :as math]))
-
-
-(mf/defc measures-menu
- [{:keys [shape] :as props}]
- (let [locale (i18n/use-locale)
-
- on-size-change
- (fn [event attr]
- (let [value (-> (dom/get-target event)
- (dom/get-value)
- (d/parse-integer 0))]
- (st/emit! (udw/update-rect-dimensions (:id shape) attr value))))
-
- on-proportion-lock-change
- (fn [event]
- (st/emit! (udw/toggle-shape-proportion-lock (:id shape))))
-
- on-position-change
- (fn [event attr]
- (let [value (-> (dom/get-target event)
- (dom/get-value)
- (d/parse-integer 0))]
- (st/emit! (udw/update-position (:id shape) {attr value}))))
-
- on-rotation-change
- (fn [event]
- (let [value (-> (dom/get-target event)
- (dom/get-value)
- (d/parse-integer 0))]
- (st/emit! (udw/update-shape (:id shape) {:rotation value}))))
-
- on-radius-change
- (fn [event]
- (let [value (-> (dom/get-target event)
- (dom/get-value)
- (d/parse-integer 0))]
- (st/emit! (udw/update-shape (:id shape) {:rx value :ry value}))))
-
- on-width-change #(on-size-change % :width)
- on-height-change #(on-size-change % :height)
- on-pos-x-change #(on-position-change % :x)
- on-pos-y-change #(on-position-change % :y)]
-
- [:div.element-set
- [:div.element-set-content
-
- ;; WIDTH & HEIGHT
- [:div.row-flex
- [:span.element-set-subtitle (t locale "workspace.options.size")]
- [:div.lock-size {:class (when (:proportion-lock shape) "selected")
- :on-click on-proportion-lock-change}
- (if (:proportion-lock shape)
- i/lock
- i/unlock)]
- [:div.input-element.pixels
- [:input.input-text {:type "number"
- :min "0"
- :no-validate true
- :on-change on-width-change
- :value (str (-> (:width shape)
- (d/coalesce 0)
- (math/round)))}]]
-
-
- [:div.input-element.pixels
- [:input.input-text {:type "number"
- :min "0"
- :no-validate true
- :on-change on-height-change
- :value (str (-> (:height shape)
- (d/coalesce 0)
- (math/round)))}]]]
-
- ;; POSITION
- [:div.row-flex
- [:span.element-set-subtitle (t locale "workspace.options.position")]
- [:div.input-element.pixels
- [:input.input-text {:placeholder "x"
- :type "number"
- :no-validate true
- :on-change on-pos-x-change
- :value (str (-> (:x shape)
- (d/coalesce 0)
- (math/round)))}]]
- [:div.input-element.pixels
- [:input.input-text {:placeholder "y"
- :type "number"
- :no-validate true
- :on-change on-pos-y-change
- :value (str (-> (:y shape)
- (d/coalesce 0)
- (math/round)))}]]]
-
- [:div.row-flex
- [:span.element-set-subtitle (t locale "workspace.options.rotation")]
- [:div.input-element.degrees
- [:input.input-text
- {:placeholder ""
- :type "number"
- :no-validate true
- :min "0"
- :max "360"
- :on-change on-rotation-change
- :value (str (-> (:rotation shape)
- (d/coalesce 0)
- (math/round)))}]]
- [:input.slidebar
- {:type "range"
- :min "0"
- :max "360"
- :step "1"
- :no-validate true
- :on-change on-rotation-change
- :value (str (-> (:rotation shape)
- (d/coalesce 0)))}]]
-
- [:div.row-flex
- [:span.element-set-subtitle (t locale "workspace.options.radius")]
- [:div.input-element.pixels
- [:input.input-text
- {:placeholder "rx"
- :type "number"
- :on-change on-radius-change
- :value (str (-> (:rx shape)
- (d/coalesce 0)
- (math/round)))}]]
- [:div.input-element]]]]))
-
+ [uxbox.main.ui.workspace.sidebar.options.measures :refer [measures-menu]]))
(mf/defc options
[{:keys [shape] :as props}]
[:div
- [:& measures-menu {:shape shape}]
- #_[:& fill-menu {:shape shape}]
- #_[:& stroke-menu {:shape shape}]])
+ [:& measures-menu {:shape shape}]])
diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/measures.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/measures.cljs
index 1df1d64d7..51f1c67d0 100644
--- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/measures.cljs
+++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/measures.cljs
@@ -19,8 +19,9 @@
[uxbox.util.i18n :refer [t] :as i18n]))
(mf/defc measures-menu
- [{:keys [shape] :as props}]
- (let [locale (i18n/use-locale)
+ [{:keys [shape options] :as props}]
+ (let [options (or options #{:size :position :rotation :radius})
+ locale (i18n/use-locale)
on-size-change
(fn [event attr]
@@ -29,6 +30,13 @@
(d/parse-integer 0))]
(st/emit! (udw/update-rect-dimensions (:id shape) attr value))))
+ on-circle-size-change
+ (fn [event attr]
+ (let [value (-> (dom/get-target event)
+ (dom/get-value)
+ (d/parse-integer 0))]
+ (st/emit! (udw/update-circle-dimensions (:id shape) attr value))))
+
on-proportion-lock-change
(fn [event]
(st/emit! (udw/toggle-shape-proportion-lock (:id shape))))
@@ -57,89 +65,119 @@
on-width-change #(on-size-change % :width)
on-height-change #(on-size-change % :height)
on-pos-x-change #(on-position-change % :x)
- on-pos-y-change #(on-position-change % :y)]
+ on-pos-y-change #(on-position-change % :y)
+ on-size-rx-change #(on-circle-size-change % :rx)
+ on-size-ry-change #(on-circle-size-change % :ry)]
[:div.element-set
[:div.element-set-content
;; WIDTH & HEIGHT
- [:div.row-flex
- [:span.element-set-subtitle (t locale "workspace.options.size")]
- [:div.lock-size {:class (when (:proportion-lock shape) "selected")
- :on-click on-proportion-lock-change}
- (if (:proportion-lock shape)
- i/lock
- i/unlock)]
- [:div.input-element.pixels
- [:input.input-text {:type "number"
- :min "0"
- :no-validate true
- :on-change on-width-change
- :value (str (-> (:width shape)
- (d/coalesce 0)
- (math/round)))}]]
+ (when (options :size)
+ [:div.row-flex
+ [:span.element-set-subtitle (t locale "workspace.options.size")]
+ [:div.lock-size {:class (when (:proportion-lock shape) "selected")
+ :on-click on-proportion-lock-change}
+ (if (:proportion-lock shape)
+ i/lock
+ i/unlock)]
+ [:div.input-element.pixels
+ [:input.input-text {:type "number"
+ :min "0"
+ :no-validate true
+ :on-change on-width-change
+ :value (str (-> (:width shape)
+ (d/coalesce 0)
+ (math/round)))}]]
- [:div.input-element.pixels
- [:input.input-text {:type "number"
- :min "0"
- :no-validate true
- :on-change on-height-change
- :value (str (-> (:height shape)
- (d/coalesce 0)
- (math/round)))}]]]
+ [:div.input-element.pixels
+ [:input.input-text {:type "number"
+ :min "0"
+ :no-validate true
+ :on-change on-height-change
+ :value (str (-> (:height shape)
+ (d/coalesce 0)
+ (math/round)))}]]])
+
+ ;; Circle RX RY
+ (when (options :circle-size)
+ [:div.row-flex
+ [:span.element-set-subtitle (t locale "workspace.options.size")]
+ [:div.lock-size {:class (when (:proportion-lock shape) "selected")
+ :on-click on-proportion-lock-change}
+ (if (:proportion-lock shape)
+ i/lock
+ i/unlock)]
+ [:div.input-element.pixels
+ [:input.input-text {:type "number"
+ :min "0"
+ :on-change on-size-rx-change
+ :value (str (-> (:rx shape)
+ (d/coalesce 0)
+ (math/round)))}]]
+ [:div.input-element.pixels
+ [:input.input-text {:type "number"
+ :min "0"
+ :on-change on-size-ry-change
+ :value (str (-> (:ry shape)
+ (d/coalesce 0)
+ (math/round)))}]]])
;; POSITION
- [:div.row-flex
- [:span.element-set-subtitle (t locale "workspace.options.position")]
- [:div.input-element.pixels
- [:input.input-text {:placeholder "x"
- :type "number"
- :no-validate true
- :on-change on-pos-x-change
- :value (str (-> (:x shape)
- (d/coalesce 0)
- (math/round)))}]]
- [:div.input-element.pixels
- [:input.input-text {:placeholder "y"
- :type "number"
- :no-validate true
- :on-change on-pos-y-change
- :value (str (-> (:y shape)
- (d/coalesce 0)
- (math/round)))}]]]
+ (when (options :position)
+ [:div.row-flex
+ [:span.element-set-subtitle (t locale "workspace.options.position")]
+ [:div.input-element.pixels
+ [:input.input-text {:placeholder "x"
+ :type "number"
+ :no-validate true
+ :on-change on-pos-x-change
+ :value (str (-> (:x shape)
+ (d/coalesce 0)
+ (math/round)))}]]
+ [:div.input-element.pixels
+ [:input.input-text {:placeholder "y"
+ :type "number"
+ :no-validate true
+ :on-change on-pos-y-change
+ :value (str (-> (:y shape)
+ (d/coalesce 0)
+ (math/round)))}]]])
- [:div.row-flex
- [:span.element-set-subtitle (t locale "workspace.options.rotation")]
- [:div.input-element.degrees
- [:input.input-text
- {:placeholder ""
- :type "number"
- :no-validate true
+ (when (options :rotation)
+ [:div.row-flex
+ [:span.element-set-subtitle (t locale "workspace.options.rotation")]
+ [:div.input-element.degrees
+ [:input.input-text
+ {:placeholder ""
+ :type "number"
+ :no-validate true
+ :min "0"
+ :max "360"
+ :on-change on-rotation-change
+ :value (str (-> (:rotation shape)
+ (d/coalesce 0)
+ (math/round)))}]]
+ [:input.slidebar
+ {:type "range"
:min "0"
:max "360"
+ :step "1"
+ :no-validate true
:on-change on-rotation-change
:value (str (-> (:rotation shape)
- (d/coalesce 0)
- (math/round)))}]]
- [:input.slidebar
- {:type "range"
- :min "0"
- :max "360"
- :step "1"
- :no-validate true
- :on-change on-rotation-change
- :value (str (-> (:rotation shape)
- (d/coalesce 0)))}]]
+ (d/coalesce 0)))}]])
- [:div.row-flex
- [:span.element-set-subtitle (t locale "workspace.options.radius")]
- [:div.input-element.pixels
- [:input.input-text
- {:placeholder "rx"
- :type "number"
- :on-change on-radius-change
- :value (str (-> (:rx shape)
- (d/coalesce 0)
- (math/round)))}]]
- [:div.input-element]]]]))
+ (when (options :radius)
+ [:div.row-flex
+ [:span.element-set-subtitle (t locale "workspace.options.radius")]
+ [:div.input-element.pixels
+ [:input.input-text
+ {:placeholder "rx"
+ :type "number"
+ :on-change on-radius-change
+ :value (str (-> (:rx shape)
+ (d/coalesce 0)
+ (math/round)))}]]
+ [:div.input-element]])]]))
diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/page.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/page.cljs
index ba3bd3bd4..22776af74 100644
--- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/page.cljs
+++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/page.cljs
@@ -2,8 +2,10 @@
;; 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) 2015-2016 Andrey Antukh
-;; Copyright (c) 2015-2016 Juan de la Cruz
+;; 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 uxbox.main.ui.workspace.sidebar.options.page
"Page options menu entries."
@@ -13,52 +15,14 @@
[okulary.core :as l]
[uxbox.common.data :as d]
[uxbox.builtins.icons :as i]
- [uxbox.main.constants :as c]
- [uxbox.main.data.workspace :as udw]
+ [uxbox.main.data.workspace :as dw]
[uxbox.main.refs :as refs]
[uxbox.main.store :as st]
[uxbox.main.ui.modal :as modal]
[uxbox.main.ui.workspace.colorpicker :refer [colorpicker-modal]]
- [uxbox.util.data :refer [parse-int]]
[uxbox.util.dom :as dom]
[uxbox.util.i18n :refer [tr]]))
-;; (mf/defc metadata-options
-;; [{:keys [page] :as props}]
-;; (let [metadata (:metadata page)
-;; change-color
-;; (fn [color]
-;; #_(st/emit! (->> (assoc metadata :background color)
-;; (udp/update-metadata (:id page)))))
-;; on-color-change
-;; (fn [event]
-;; (let [value (dom/event->value event)]
-;; (change-color value)))
-
-;; show-color-picker
-;; (fn [event]
-;; (let [x (.-clientX event)
-;; y (.-clientY event)
-;; props {:x x :y y
-;; :default "#ffffff"
-;; :value (:background metadata)
-;; :transparent? true
-;; :on-change change-color}]
-;; (modal/show! colorpicker-modal props)))]
-
-;; [:div.element-set
-;; [:div.element-set-title (tr "workspace.options.page-measures")]
-;; [:div.element-set-content
-;; [:span (tr "workspace.options.background-color")]
-;; [:div.row-flex.color-data
-;; [:span.color-th
-;; {:style {:background-color (:background metadata "#ffffff")}
-;; :on-click show-color-picker}]
-;; [:div.color-info
-;; [:input
-;; {:on-change on-color-change
-;; :value (:background metadata "#ffffff")}]]]]]))
-
(def default-options
"Default data for page metadata."
{:grid-x 10
@@ -78,18 +42,18 @@
(let [value (-> (dom/get-target event)
(dom/get-value)
(d/parse-integer 0))]
- (st/emit! (udw/update-options {:grid-x value}))))
+ (st/emit! (dw/update-options {:grid-x value}))))
on-y-change
(fn [event]
(let [value (-> (dom/get-target event)
(dom/get-value)
(d/parse-integer 0))]
- (st/emit! (udw/update-options {:grid-y value}))))
+ (st/emit! (dw/update-options {:grid-y value}))))
change-color
(fn [color]
- (st/emit! (udw/update-options {:grid-color color})))
+ (st/emit! (dw/update-options {:grid-color color})))
on-color-change
(fn [event]
diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/path.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/path.cljs
index cccb9de03..1e2824411 100644
--- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/path.cljs
+++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/path.cljs
@@ -2,8 +2,10 @@
;; 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) 2015-2016 Juan de la Cruz
-;; Copyright (c) 2015-2019 Andrey Antukh
+;; 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 uxbox.main.ui.workspace.sidebar.options.path
(:require
diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/rect.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/rect.cljs
index f75b68014..5f5fcf7b1 100644
--- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/rect.cljs
+++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/rect.cljs
@@ -11,8 +11,8 @@
(:require
[rumext.alpha :as mf]
[uxbox.main.ui.workspace.sidebar.options.fill :refer [fill-menu]]
- [uxbox.main.ui.workspace.sidebar.options.stroke :refer [stroke-menu]]
- [uxbox.main.ui.workspace.sidebar.options.measures :refer [measures-menu]]))
+ [uxbox.main.ui.workspace.sidebar.options.measures :refer [measures-menu]]
+ [uxbox.main.ui.workspace.sidebar.options.stroke :refer [stroke-menu]]))
(mf/defc options
[{:keys [shape] :as props}]
diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/text.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/text.cljs
index 9bddea6ed..8ca243ec1 100644
--- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/text.cljs
+++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/text.cljs
@@ -2,137 +2,21 @@
;; 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) 2015-2017 Andrey Antukh
-;; Copyright (c) 2015-2017 Juan de la Cruz
+;; 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 uxbox.main.ui.workspace.sidebar.options.text
(:require
[rumext.alpha :as mf]
- [potok.core :as ptk]
- [uxbox.common.data :as d]
- [uxbox.main.store :as st]
- [uxbox.main.geom :as geom]
- [uxbox.main.data.workspace :as udw]
[uxbox.builtins.icons :as i]
- [uxbox.util.i18n :refer (tr)]
- [uxbox.util.router :as r]
+ [uxbox.common.data :as d]
+ [uxbox.main.data.workspace :as dw]
+ [uxbox.main.store :as st]
+ [uxbox.main.ui.workspace.sidebar.options.measures :refer [measures-menu]]
[uxbox.util.dom :as dom]
- [uxbox.util.geom.point :as gpt]
- [uxbox.util.math :as math :refer [precision-or-0]]
- [uxbox.util.data :refer [parse-int
- parse-float
- read-string
- index-by-id]]))
-
-
-(mf/defc measures-menu
- [{:keys [shape] :as props}]
- (let [on-size-change
- (fn [event attr]
- (let [value (-> (dom/get-target event)
- (dom/get-value)
- (d/parse-integer 0))]
- (st/emit! (udw/update-rect-dimensions (:id shape) attr value))))
-
- on-proportion-lock-change
- (fn [event]
- (st/emit! (udw/toggle-shape-proportion-lock (:id shape))))
-
- on-position-change
- (fn [event attr]
- (let [value (-> (dom/get-target event)
- (dom/get-value)
- (d/parse-integer))]
- (st/emit! (udw/update-position (:id shape) {attr value}))))
-
- on-rotation-change
- (fn [event]
- (let [value (-> (dom/get-target event)
- (dom/get-value)
- (d/parse-integer 0))]
- (st/emit! (udw/update-shape (:id shape) {:rotation value}))))
-
- on-radius-change
- (fn [event]
- (let [value (-> (dom/get-target event)
- (dom/get-value)
- (d/parse-double 0))]
- (st/emit! (udw/update-shape (:id shape) {:rx value :ry value}))))
-
- on-width-change #(on-size-change % :width)
- on-height-change #(on-size-change % :height)
- on-pos-x-change #(on-position-change % :x)
- on-pos-y-change #(on-position-change % :y)]
-
- [:div.element-set
- [:div.element-set-title (tr "workspace.options.measures")]
- [:div.element-set-content
- [:span (tr "workspace.options.size")]
-
- ;; WIDTH & HEIGHT
- [:div.row-flex
- [:div.input-element.pixels
- [:input.input-text {:type "number"
- :min "0"
- :on-change on-width-change
- :value (-> (:width shape)
- (math/precision 2)
- (d/coalesce-str "0"))}]]
-
- [:div.lock-size {:class (when (:proportion-lock shape) "selected")
- :on-click on-proportion-lock-change}
- (if (:proportion-lock shape)
- i/lock
- i/unlock)]
-
- [:div.input-element.pixels
- [:input.input-text {:type "number"
- :min "0"
- :on-change on-height-change
- :value (-> (:height shape)
- (math/precision 2)
- (d/coalesce-str "0"))}]]]
-
- ;; POSITION
- [:span (tr "workspace.options.position")]
- [:div.row-flex
- [:div.input-element.pixels
- [:input.input-text {:placeholder "x"
- :type "number"
- :on-change on-pos-x-change
- :value (-> (:x shape)
- (math/precision 2)
- (d/coalesce-str "0"))}]]
- [:div.input-element.pixels
- [:input.input-text {:placeholder "y"
- :type "number"
- :on-change on-pos-y-change
- :value (-> (:y shape)
- (math/precision 2)
- (d/coalesce-str "0"))}]]]
-
- [:span (tr "workspace.options.rotation-radius")]
- [:div.row-flex
- [:div.input-element.degrees
- [:input.input-text {:placeholder ""
- :type "number"
- :min 0
- :max 360
- :on-change on-rotation-change
- :value (-> (:rotation shape 0)
- (math/precision 2)
- (d/coalesce-str "0"))}]]
-
- [:div.input-element.pixels
- [:input.input-text
- {:placeholder "rx"
- :type "number"
- :on-change on-radius-change
- :value (-> (:rx shape)
- (math/precision 2)
- (d/coalesce-str "0"))}]]]]]))
-
-
+ [uxbox.util.i18n :refer [tr]]))
(declare +fonts+)
@@ -156,7 +40,7 @@
attrs {:font-family value
:font-weight "normal"
:font-style "normal"}]
- (st/emit! (udw/update-shape id attrs))))
+ (st/emit! (dw/update-shape id attrs))))
on-font-size-change
(fn [event]
@@ -164,7 +48,7 @@
(dom/get-value)
(d/parse-integer 0))
attrs {:font-size value}]
- (st/emit! (udw/update-shape id attrs))))
+ (st/emit! (dw/update-shape id attrs))))
on-font-letter-spacing-change
(fn [event]
@@ -172,7 +56,7 @@
(dom/get-value)
(d/parse-double 0))
attrs {:letter-spacing value}]
- (st/emit! (udw/update-shape id attrs))))
+ (st/emit! (dw/update-shape id attrs))))
on-font-line-height-change
(fn [event]
@@ -180,12 +64,12 @@
(dom/get-value)
(d/parse-double 0))
attrs {:line-height value}]
- (st/emit! (udw/update-shape id attrs))))
+ (st/emit! (dw/update-shape id attrs))))
on-font-align-change
(fn [event value]
(let [attrs {:text-align value}]
- (st/emit! (udw/update-shape id attrs))))
+ (st/emit! (dw/update-shape id attrs))))
on-font-style-change
(fn [event]
@@ -194,12 +78,11 @@
(d/read-string))
attrs {:font-style style
:font-weight weight}]
- (st/emit! (udw/update-shape id attrs))))
+ (st/emit! (dw/update-shape id attrs))))
]
[:div.element-set
[:div.element-set-title (tr "workspace.options.font-options")]
[:div.element-set-content
- [:span (tr "workspace.options.font-family")]
[:div.row-flex
[:select.input-select {:value font-family
:on-change on-font-family-change}
@@ -208,7 +91,6 @@
:key (:id font)}
(:name font)])]]
- [:span (tr "workspace.options.font-weight")]
[:div.row-flex
[:div.editable-select
[:select.input-select {:value font-size
@@ -240,39 +122,106 @@
:key (:name style)}
(:name style)])]]
- [:span (tr "workspace.options.line-height-letter-spacing")]
- [:div.row-flex
- [:input.input-text {:type "number"
- :step "0.1"
- :min "0"
- :max "200"
- :value (-> line-height
- (math/precision 2)
- (d/coalesce-str "0"))
- :on-change on-font-line-height-change}]
- [:input.input-text {:type "number"
- :step "0.1"
- :min "0"
- :max "200"
- :value (-> letter-spacing
- (math/precision 2)
- (d/coalesce-str "0"))
- :on-change on-font-letter-spacing-change}]]
-
- [:span (tr "workspace.options.text-align")]
[:div.row-flex.align-icons
- [:span {:class (when (= text-align "left") "current")
+ [:span.tooltip.tooltip-bottom
+ {:alt "Align left"
+ :class (when (= text-align "left") "current")
:on-click #(on-font-align-change % "left")}
i/text-align-left]
- [:span {:class (when (= text-align "center") "current")
+ [:span.tooltip.tooltip-bottom
+ {:alt "Align center"
+ :class (when (= text-align "center") "current")
:on-click #(on-font-align-change % "center")}
i/text-align-center]
- [:span {:class (when (= text-align "right") "current")
+ [:span.tooltip.tooltip-bottom
+ {:alt "Align right"
+ :class (when (= text-align "right") "current")
:on-click #(on-font-align-change % "right")}
i/text-align-right]
- [:span {:class (when (= text-align "justify") "current")
+ [:span.tooltip.tooltip-bottom
+ {:alt "Justify"
+ :class (when (= text-align "justify") "current")
:on-click #(on-font-align-change % "justify")}
- i/text-align-justify]]]]))
+ i/text-align-justify]]
+
+ [:div.row-flex
+ [:div.input-icon
+ [:span.icon-before.tooltip.tooltip-bottom
+ {:alt "Line height"}
+ i/line-height]
+ [:input.input-text {:type "number"
+ :step "0.1"
+ :min "0"
+ :max "200"
+ :value (-> line-height
+ (math/precision 2)
+ (d/coalesce-str "0"))
+ :on-change on-font-line-height-change}]]
+ [:div.input-icon
+ [:span.icon-before.tooltip.tooltip-bottom
+ {:alt "Letter spacing"}
+ i/letter-spacing]
+ [:input.input-text {:type "number"
+ :step "0.1"
+ :min "0"
+ :max "200"
+ :value (-> letter-spacing
+ (math/precision 2)
+ (d/coalesce-str "0"))
+ :on-change on-font-letter-spacing-change}]]]
+
+ [:div.row-flex
+ [:div.align-icons
+ [:span.tooltip.tooltip-bottom
+ {:alt "Align top"}
+ i/align-top]
+ [:span.tooltip.tooltip-bottom
+ {:alt "Align middle"}
+ i/align-middle]
+ [:span.tooltip.tooltip-bottom
+ {:alt "Align bottom"}
+ i/align-bottom]]
+
+ [:div.align-icons
+ [:span.tooltip.tooltip-bottom
+ {:alt "Auto height"}
+ i/auto-height]
+ [:span.tooltip.tooltip-bottom
+ {:alt "Auto width"}
+ i/auto-width]
+ [:span.tooltip.tooltip-bottom
+ {:alt "Fixed size"}
+ i/auto-fix]]]
+
+ [:div.row-flex
+ [:span.element-set-subtitle "Decoration"]
+ [:div.align-icons
+ [:span.tooltip.tooltip-bottom
+ {:alt "None"}
+ i/minus]
+ [:span.tooltip.tooltip-bottom
+ {:alt "Underline"}
+ i/underline]
+ [:span.tooltip.tooltip-bottom
+ {:alt "Strikethrough"}
+ i/strikethrough]]]
+
+ [:div.row-flex
+ [:span.element-set-subtitle "Case"]
+ [:div.align-icons
+ [:span.tooltip.tooltip-bottom
+ {:alt "None"}
+ i/minus]
+ [:span.tooltip.tooltip-bottom
+ {:alt "Uppercase"}
+ i/uppercase]
+ [:span.tooltip.tooltip-bottom
+ {:alt "Lowercase"}
+ i/lowercase]
+ [:span.tooltip.tooltip-bottom
+ {:alt "Titlecase"}
+ i/titlecase]]]
+ ]]))
(def +fonts+
[{:id "sourcesanspro"