Merge pull request #4158 from penpot/niwinz-staging-perfix-1

 Add performance enhancements for margin-section react component
This commit is contained in:
Eva Marco 2024-02-20 13:58:35 +01:00 committed by GitHub
commit 47bf121d25
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 360 additions and 264 deletions

View file

@ -19,8 +19,8 @@
:git/url "https://github.com/funcool/beicon.git"} :git/url "https://github.com/funcool/beicon.git"}
funcool/rumext funcool/rumext
{:git/tag "v2.9.4" {:git/tag "v2.10"
:git/sha "af08e55" :git/sha "d96ea18"
:git/url "https://github.com/funcool/rumext.git"} :git/url "https://github.com/funcool/rumext.git"}
instaparse/instaparse {:mvn/version "1.4.12"} instaparse/instaparse {:mvn/version "1.4.12"}

View file

@ -8,7 +8,6 @@
(:require-macros [app.main.style :as stl]) (:require-macros [app.main.style :as stl])
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.types.shape.layout :as ctl] [app.common.types.shape.layout :as ctl]
[app.main.data.workspace :as udw] [app.main.data.workspace :as udw]
[app.main.data.workspace.shape-layout :as dwsl] [app.main.data.workspace.shape-layout :as dwsl]
@ -21,7 +20,8 @@
[app.main.ui.workspace.sidebar.options.menus.layout-container :refer [get-layout-flex-icon]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [get-layout-flex-icon]]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf])) [rumext.v2 :as mf]
[rumext.v2.props :as-alias mf.props]))
(def layout-item-attrs (def layout-item-attrs
[:layout-item-margin ;; {:m1 0 :m2 0 :m3 0 :m4 0} [:layout-item-margin ;; {:m1 0 :m2 0 :m3 0 :m4 0}
@ -36,246 +36,351 @@
:layout-item-absolute :layout-item-absolute
:layout-item-z-index]) :layout-item-z-index])
(mf/defc margin-section (defn- select-margins
[{:keys [values change-margin-style on-margin-change] :as props}] [m1? m2? m3? m4?]
(let [margin-type (or (:layout-item-margin-type values) :simple)
m1 (when (and (not (= :multiple (:layout-item-margin values)))
(= (dm/get-in values [:layout-item-margin :m1])
(dm/get-in values [:layout-item-margin :m3])))
(dm/get-in values [:layout-item-margin :m1]))
m2 (when (and (not (= :multiple (:layout-item-margin values)))
(= (dm/get-in values [:layout-item-margin :m2])
(dm/get-in values [:layout-item-margin :m4])))
(dm/get-in values [:layout-item-margin :m2]))
select-margins
(fn [m1? m2? m3? m4?]
(st/emit! (udw/set-margins-selected {:m1 m1? :m2 m2? :m3 m3? :m4 m4?}))) (st/emit! (udw/set-margins-selected {:m1 m1? :m2 m2? :m3 m3? :m4 m4?})))
select-margin #(select-margins (= % :m1) (= % :m2) (= % :m3) (= % :m4))] (defn- select-margin
[prop]
(select-margins (= prop :m1) (= prop :m2) (= prop :m3) (= prop :m4)))
(mf/defc margin-simple
{::mf/props :obj}
[{:keys [margin on-change on-blur]}]
(let [m1 (:m1 margin)
m2 (:m2 margin)
m3 (:m3 margin)
m4 (:m4 margin)
m1 (when (and (not= margin :multiple) (= m1 m3)) m1)
m2 (when (and (not= margin :multiple) (= m2 m4)) m2)
on-focus
(mf/use-fn
(fn [event]
(let [attr (-> (dom/get-current-target event)
(dom/get-data "name")
(keyword))]
(case attr
:m1 (select-margins true false true false)
:m2 (select-margins false true false true))
(dom/select-target event))))
on-change'
(mf/use-fn
(mf/deps on-change)
(fn [value event]
(let [attr (-> (dom/get-current-target event)
(dom/get-data "name")
(keyword))]
(on-change :simple attr value))))]
(mf/use-effect
(fn []
(fn []
;;on destroy component
(select-margins false false false false))))
[:div {:class (stl/css :margin-row)}
[:div {:class (stl/css :inputs-wrapper)}
(cond
(= margin-type :simple)
[:div {:class (stl/css :margin-simple)} [:div {:class (stl/css :margin-simple)}
[:div {:class (stl/css :vertical-margin) [:div {:class (stl/css :vertical-margin)
:title "Vertical margin"} :title "Vertical margin"}
[:span {:class (stl/css :icon)} [:span {:class (stl/css :icon)}
i/margin-top-bottom-refactor] i/margin-top-bottom-refactor]
[:> numeric-input* {:className (stl/css :numeric-input) [:> numeric-input* {:class (stl/css :numeric-input)
:placeholder "--" :placeholder "--"
:data-name "m1"
:on-focus on-focus
:on-change on-change'
:on-blur on-blur
:nillable true :nillable true
:value m1 :value m1}]]
:on-focus (fn [event]
(select-margins true false true false)
(dom/select-target event))
:on-change (partial on-margin-change :simple :m1)
:on-blur #(select-margins false false false false)}]]
[:div {:class (stl/css :horizontal-margin) [:div {:class (stl/css :horizontal-margin)
:title "Horizontal margin"} :title "Horizontal margin"}
[:span {:class (stl/css :icon)} [:span {:class (stl/css :icon)}
i/margin-left-right-refactor] i/margin-left-right-refactor]
[:> numeric-input* {:className (stl/css :numeric-input) [:> numeric-input* {:class (stl/css :numeric-input)
:placeholder "--" :placeholder "--"
:on-focus (fn [event] :data-name "m2"
(select-margins false true false true) :on-focus on-focus
(dom/select-target event)) :on-change on-change'
:on-change (partial on-margin-change :simple :m2) :on-blur on-blur
:on-blur #(select-margins false false false false)
:nillable true :nillable true
:value m2}]]] :value m2}]]]))
(mf/defc margin-multiple
{::mf/props :obj}
[{:keys [margin on-change on-blur]}]
(let [m1 (:m1 margin)
m2 (:m2 margin)
m3 (:m3 margin)
m4 (:m4 margin)
on-focus
(mf/use-fn
(fn [event]
(let [attr (-> (dom/get-current-target event)
(dom/get-data "name")
(keyword))]
(select-margin attr)
(dom/select-target event))))
on-change'
(mf/use-fn
(mf/deps on-change)
(fn [value event]
(let [attr (-> (dom/get-current-target event)
(dom/get-data "name")
(keyword))]
(on-change :multiple attr value))))]
(= margin-type :multiple)
[:div {:class (stl/css :margin-multiple)} [:div {:class (stl/css :margin-multiple)}
[:div {:class (stl/css :top-margin) [:div {:class (stl/css :top-margin)
:title "Top margin"} :title "Top margin"}
[:span {:class (stl/css :icon)} [:span {:class (stl/css :icon)}
i/margin-top-refactor] i/margin-top-refactor]
[:> numeric-input* {:className (stl/css :numeric-input) [:> numeric-input* {:class (stl/css :numeric-input)
:placeholder "--" :placeholder "--"
:on-focus (fn [event] :data-name "m1"
(select-margin :m1) :on-focus on-focus
(dom/select-target event)) :on-change on-change'
:on-change (partial on-margin-change :multiple :m1) :on-blur on-blur
:on-blur #(select-margins false false false false)
:nillable true :nillable true
:value (:m1 (:layout-item-margin values))}]] :value m1}]]
[:div {:class (stl/css :right-margin) [:div {:class (stl/css :right-margin)
:title "Right margin"} :title "Right margin"}
[:span {:class (stl/css :icon)} [:span {:class (stl/css :icon)}
i/margin-right-refactor] i/margin-right-refactor]
[:> numeric-input* {:className (stl/css :numeric-input) [:> numeric-input* {:class (stl/css :numeric-input)
:placeholder "--" :placeholder "--"
:on-focus (fn [event] :data-name "m2"
(select-margin :m2) :on-focus on-focus
(dom/select-target event)) :on-change on-change'
:on-change (partial on-margin-change :multiple :m2) :on-blur on-blur
:on-blur #(select-margins false false false false)
:nillable true :nillable true
:value (:m2 (:layout-item-margin values))}]] :value m2}]]
[:div {:class (stl/css :bottom-margin) [:div {:class (stl/css :bottom-margin)
:title "Bottom margin"} :title "Bottom margin"}
[:span {:class (stl/css :icon)} [:span {:class (stl/css :icon)}
i/margin-bottom-refactor] i/margin-bottom-refactor]
[:> numeric-input* {:className (stl/css :numeric-input) [:> numeric-input* {:class (stl/css :numeric-input)
:placeholder "--" :placeholder "--"
:on-focus (fn [event] :data-name "m3"
(select-margin :m3) :on-focus on-focus
(dom/select-target event)) :on-change on-change'
:on-change (partial on-margin-change :multiple :m3) :on-blur on-blur
:on-blur #(select-margins false false false false)
:nillable true :nillable true
:value (:m3 (:layout-item-margin values))}]] :value m3}]]
[:div {:class (stl/css :left-margin) [:div {:class (stl/css :left-margin)
:title "Left margin"} :title "Left margin"}
[:span {:class (stl/css :icon)} [:span {:class (stl/css :icon)}
i/margin-left-refactor] i/margin-left-refactor]
[:> numeric-input* {:className (stl/css :numeric-input) [:> numeric-input* {:class (stl/css :numeric-input)
:placeholder "--" :placeholder "--"
:on-focus (fn [event] :data-name "m4"
(select-margin :m4) :on-focus on-focus
(dom/select-target event)) :on-change on-change'
:on-change (partial on-margin-change :multiple :m4) :on-blur on-blur
:on-blur #(select-margins false false false false)
:nillable true :nillable true
:value (:m4 (:layout-item-margin values))}]]])] :value m4}]]]))
[:button {:class (stl/css-case :margin-mode true
:selected (= margin-type :multiple))
(mf/defc margin-section
{::mf/props :obj
::mf/private true
::mf.props/expect #{:margin :type :on-type-change :on-change}}
[{:keys [type on-type-change] :as props}]
(let [type (d/nilv type :simple)
on-blur (mf/use-fn #(select-margins false false false false))
props (mf/spread-obj props {:on-blur on-blur})
on-type-change'
(mf/use-fn
(mf/deps type on-type-change)
(fn [_]
(if (= type :multiple)
(on-type-change :simple)
(on-type-change :multiple))))]
(mf/with-effect []
(fn [] (on-blur)))
[:div {:class (stl/css :margin-row)}
[:div {:class (stl/css :inputs-wrapper)}
(cond
(= type :simple)
[:> margin-simple props]
(= type :multiple)
[:> margin-multiple props])]
[:button {:class (stl/css-case
:margin-mode true
:selected (= type :multiple))
:title "Margin - multiple" :title "Margin - multiple"
:on-click #(change-margin-style (if (= margin-type :multiple) :simple :multiple))} :on-click on-type-change'}
i/margin-refactor]])) i/margin-refactor]]))
(mf/defc element-behaviour-horizontal (mf/defc element-behaviour-horizontal
[{:keys [auto? fill? layout-item-sizing on-change] :as props}] {::mf/props :obj}
[{:keys [^boolean is-auto ^boolean has-fill sizing on-change]}]
[:div {:class (stl/css-case :horizontal-behaviour true [:div {:class (stl/css-case :horizontal-behaviour true
:one-element (and (not fill?) (not auto?)) :one-element (and (not has-fill) (not is-auto))
:two-element (or fill? auto?) :two-element (or has-fill is-auto)
:three-element (and fill? auto?))} :three-element (and has-fill is-auto))}
[:& radio-buttons {:selected (d/name layout-item-sizing) [:& radio-buttons
{:selected (d/name sizing)
:on-change on-change :on-change on-change
:wide true :wide true
:name "flex-behaviour-h"} :name "flex-behaviour-h"}
[:& radio-button {:value "fix"
[:& radio-button
{:value "fix"
:icon i/fixed-width-refactor :icon i/fixed-width-refactor
:title "Fix width" :title "Fix width"
:id "behaviour-h-fix"}] :id "behaviour-h-fix"}]
(when fill?
[:& radio-button {:value "fill" (when has-fill
[:& radio-button
{:value "fill"
:icon i/fill-content-refactor :icon i/fill-content-refactor
:title "Width 100%" :title "Width 100%"
:id "behaviour-h-fill"}]) :id "behaviour-h-fill"}])
(when auto? (when is-auto
[:& radio-button {:value "auto" [:& radio-button
{:value "auto"
:icon i/hug-content-refactor :icon i/hug-content-refactor
:title "Fit content" :title "Fit content"
:id "behaviour-h-auto"}])]]) :id "behaviour-h-auto"}])]])
(mf/defc element-behaviour-vertical (mf/defc element-behaviour-vertical
[{:keys [auto? fill? layout-item-sizing on-change] :as props}] {::mf/props :obj}
[{:keys [^boolean is-auto ^boolean has-fill sizing on-change]}]
[:div {:class (stl/css-case :vertical-behaviour true [:div {:class (stl/css-case :vertical-behaviour true
:one-element (and (not fill?) (not auto?)) :one-element (and (not has-fill) (not is-auto))
:two-element (or fill? auto?) :two-element (or has-fill is-auto)
:three-element (and fill? auto?))} :three-element (and has-fill is-auto))}
[:& radio-buttons {:selected (d/name layout-item-sizing) [:& radio-buttons
{:selected (d/name sizing)
:on-change on-change :on-change on-change
:wide true :wide true
:name "flex-behaviour-v"} :name "flex-behaviour-v"}
[:& radio-button {:value "fix"
[:& radio-button
{:value "fix"
:icon i/fixed-width-refactor :icon i/fixed-width-refactor
:icon-class (stl/css :rotated) :icon-class (stl/css :rotated)
:title "Fix height" :title "Fix height"
:id "behaviour-v-fix"}] :id "behaviour-v-fix"}]
(when fill?
[:& radio-button {:value "fill" (when has-fill
[:& radio-button
{:value "fill"
:icon i/fill-content-refactor :icon i/fill-content-refactor
:icon-class (stl/css :rotated) :icon-class (stl/css :rotated)
:title "Height 100%" :title "Height 100%"
:id "behaviour-v-fill"}]) :id "behaviour-v-fill"}])
(when auto? (when is-auto
[:& radio-button {:value "auto" [:& radio-button
{:value "auto"
:icon i/hug-content-refactor :icon i/hug-content-refactor
:icon-class (stl/css :rotated) :icon-class (stl/css :rotated)
:title "Fit content" :title "Fit content"
:id "behaviour-v-auto"}])]]) :id "behaviour-v-auto"}])]])
(mf/defc element-behaviour (mf/defc element-behaviour
[{:keys [auto? {::mf/props :obj
fill? ::mf/private true}
layout-item-h-sizing [{:keys [^boolean is-auto
layout-item-v-sizing ^boolean has-fill
on-change-behaviour-h-refactor h-sizing
on-change-behaviour-v-refactor] :as props}] v-sizing
[:div {:class (stl/css-case :behaviour-menu true on-h-change
:wrap (and fill? auto?))} on-v-change]}]
[:& element-behaviour-horizontal {:auto? auto? [:div {:class (stl/css-case
:fill? fill? :behaviour-menu true
:layout-item-sizing layout-item-h-sizing :wrap (and has-fill is-auto))}
:on-change on-change-behaviour-h-refactor}]
[:& element-behaviour-vertical {:auto? auto? [:& element-behaviour-horizontal
:fill? fill? {:is-auto is-auto
:layout-item-sizing layout-item-v-sizing :has-fill has-fill
:on-change on-change-behaviour-v-refactor}]]) :sizing h-sizing
:on-change on-h-change}]
[:& element-behaviour-vertical
{:is-auto is-auto
:has-fill has-fill
:sizing v-sizing
:on-change on-v-change}]])
(mf/defc align-self-row (mf/defc align-self-row
[{:keys [is-col? align-self on-change] :as props}] {::mf/props :obj}
[{:keys [^boolean is-col align-self on-change]}]
[:& radio-buttons {:selected (d/name align-self) [:& radio-buttons {:selected (d/name align-self)
:on-change on-change :on-change on-change
:name "flex-align-self" :name "flex-align-self"
:allow-empty true} :allow-empty true}
[:& radio-button {:value "start" [:& radio-button {:value "start"
:icon (get-layout-flex-icon :align-self :start is-col?) :icon (get-layout-flex-icon :align-self :start is-col)
:title "Align self start" :title "Align self start"
:id "align-self-start"}] :id "align-self-start"}]
[:& radio-button {:value "center" [:& radio-button {:value "center"
:icon (get-layout-flex-icon :align-self :center is-col?) :icon (get-layout-flex-icon :align-self :center is-col)
:title "Align self center" :title "Align self center"
:id "align-self-center"}] :id "align-self-center"}]
[:& radio-button {:value "end" [:& radio-button {:value "end"
:icon (get-layout-flex-icon :align-self :end is-col?) :icon (get-layout-flex-icon :align-self :end is-col)
:title "Align self end" :title "Align self end"
:id "align-self-end"}]]) :id "align-self-end"}]])
(mf/defc layout-item-menu (mf/defc layout-item-menu
{::mf/wrap [#(mf/memo' % (mf/check-props ["ids" "values" "type" "is-layout-child?" "is-grid-parent?" "is-flex-parent?"]))]} {::mf/memo #{:ids :values :type :is-layout-child? :is-grid-parent :is-flex-parent?}
[{:keys [ids values is-layout-child? is-layout-container? is-grid-parent? is-flex-parent? is-flex-layout? is-grid-layout?] :as props}] ::mf/props :obj}
[{:keys [ids values
^boolean is-layout-child?
^boolean is-layout-container?
^boolean is-grid-parent?
^boolean is-flex-parent?
^boolean is-flex-layout?
^boolean is-grid-layout?]}]
(let [selection-parents-ref (mf/use-memo (mf/deps ids) #(refs/parents-by-ids ids)) (let [selection-parents* (mf/use-memo (mf/deps ids) #(refs/parents-by-ids ids))
selection-parents (mf/deref selection-parents-ref) selection-parents (mf/deref selection-parents*)
^boolean
is-absolute? (:layout-item-absolute values) is-absolute? (:layout-item-absolute values)
^boolean
is-col? (every? ctl/col? selection-parents) is-col? (every? ctl/col? selection-parents)
^boolean
is-layout-child? (and is-layout-child? (not is-absolute?)) is-layout-child? (and is-layout-child? (not is-absolute?))
state* (mf/use-state true) state* (mf/use-state true)
open? (deref state*) open? (deref state*)
toggle-content (mf/use-fn #(swap! state* not)) toggle-content (mf/use-fn #(swap! state* not))
has-content? (or is-layout-child? is-flex-parent? is-grid-parent? is-layout-container?) has-content? (or is-layout-child?
is-flex-parent?
is-grid-parent?
is-layout-container?)
;; Align self ;; Align self
align-self (:layout-item-align-self values) align-self (:layout-item-align-self values)
h-sizing (:layout-item-h-sizing values)
v-sizing (:layout-item-v-sizing values)
title title
(cond (cond
(and is-layout-container? (not is-layout-child?) is-flex-layout?) (and is-layout-container?
is-flex-layout?
(not is-layout-child?))
"Flex board" "Flex board"
(and is-layout-container? (not is-layout-child?) is-grid-layout?) (and is-layout-container?
is-grid-layout?
(not is-layout-child?))
"Grid board" "Grid board"
(and is-layout-container? (not is-layout-child?)) (and is-layout-container?
(not is-layout-child?))
"Layout board" "Layout board"
is-flex-parent? is-flex-parent?
@ -296,12 +401,15 @@
(st/emit! (dwsl/update-layout-child ids {:layout-item-align-self (keyword value)}))))) (st/emit! (dwsl/update-layout-child ids {:layout-item-align-self (keyword value)})))))
;; Margin ;; Margin
on-change-margin-type
change-margin-style (mf/use-fn
(mf/deps ids)
(fn [type] (fn [type]
(st/emit! (dwsl/update-layout-child ids {:layout-item-margin-type type}))) (st/emit! (dwsl/update-layout-child ids {:layout-item-margin-type type}))))
on-margin-change on-margin-change
(mf/use-fn
(mf/deps ids)
(fn [type prop val] (fn [type prop val]
(cond (cond
(and (= type :simple) (= prop :m1)) (and (= type :simple) (= prop :m1))
@ -311,24 +419,9 @@
(st/emit! (dwsl/update-layout-child ids {:layout-item-margin {:m2 val :m4 val}})) (st/emit! (dwsl/update-layout-child ids {:layout-item-margin {:m2 val :m4 val}}))
:else :else
(st/emit! (dwsl/update-layout-child ids {:layout-item-margin {prop val}})))) (st/emit! (dwsl/update-layout-child ids {:layout-item-margin {prop val}})))))
;; Behaviour ;; Behaviour
on-change-behaviour
(mf/use-fn
(mf/deps ids)
(fn [event]
(let [value (-> (dom/get-current-target event)
(dom/get-data "value")
(keyword))
dir (-> (dom/get-current-target event)
(dom/get-data "direction")
(keyword))]
(if (= dir :h)
(st/emit! (dwsl/update-layout-child ids {:layout-item-h-sizing value}))
(st/emit! (dwsl/update-layout-child ids {:layout-item-v-sizing value}))))))
on-change-behaviour-h on-change-behaviour-h
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
@ -336,7 +429,6 @@
(let [value (keyword value)] (let [value (keyword value)]
(st/emit! (dwsl/update-layout-child ids {:layout-item-h-sizing value}))))) (st/emit! (dwsl/update-layout-child ids {:layout-item-h-sizing value})))))
on-change-behaviour-v on-change-behaviour-v
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
@ -345,10 +437,14 @@
(st/emit! (dwsl/update-layout-child ids {:layout-item-v-sizing value}))))) (st/emit! (dwsl/update-layout-child ids {:layout-item-v-sizing value})))))
;; Size and position ;; Size and position
on-size-change on-size-change
(fn [measure value] (mf/use-fn
(st/emit! (dwsl/update-layout-child ids {measure value}))) (mf/deps ids)
(fn [value event]
(let [attr (-> (dom/get-current-target event)
(dom/get-data "attr")
(keyword))]
(st/emit! (dwsl/update-layout-child ids {attr value})))))
on-change-position on-change-position
(mf/use-fn (mf/use-fn
@ -391,10 +487,9 @@
[:div {:class (stl/css :z-index-wrapper) [:div {:class (stl/css :z-index-wrapper)
:title "z-index"} :title "z-index"}
[:span {:class (stl/css :icon-text)} [:span {:class (stl/css :icon-text)} "Z"]
"Z"]
[:> numeric-input* [:> numeric-input*
{:className (stl/css :numeric-input) {:class (stl/css :numeric-input)
:placeholder "--" :placeholder "--"
:on-focus #(dom/select-target %) :on-focus #(dom/select-target %)
:on-change #(on-change-z-index %) :on-change #(on-change-z-index %)
@ -402,28 +497,28 @@
:value (:layout-item-z-index values)}]]]) :value (:layout-item-z-index values)}]]])
[:div {:class (stl/css :row)} [:div {:class (stl/css :row)}
[:& element-behaviour {:fill? is-layout-child? [:& element-behaviour {:has-fill is-layout-child?
:auto? is-layout-container? :is-auto is-layout-container?
:layout-item-v-sizing (or (:layout-item-v-sizing values) :fix) :v-sizing (:layout-item-v-sizing values)
:layout-item-h-sizing (or (:layout-item-h-sizing values) :fix) :h-sizing (:layout-item-h-sizing values)
:on-change-behaviour-h-refactor on-change-behaviour-h :on-h-change on-change-behaviour-h
:on-change-behaviour-v-refactor on-change-behaviour-v :on-v-change on-change-behaviour-v}]]
:on-change on-change-behaviour}]]
(when (and is-layout-child? is-flex-parent?) (when (and is-layout-child? is-flex-parent?)
[:div {:class (stl/css :row)} [:div {:class (stl/css :row)}
[:& align-self-row {:is-col? is-col? [:& align-self-row {:is-col is-col?
:align-self align-self :align-self align-self
:on-change set-align-self}]]) :on-change set-align-self}]])
(when is-layout-child? (when is-layout-child?
[:div {:class (stl/css :row)} [:div {:class (stl/css :row)}
[:& margin-section {:values values [:& margin-section {:margin (:layout-item-margin values)
:change-margin-style change-margin-style :type (:layout-item-margin-type values)
:on-margin-change on-margin-change}]]) :on-type-change on-change-margin-type
:on-change on-margin-change}]])
(when (or (= (:layout-item-h-sizing values) :fill) (when (or (= h-sizing :fill)
(= (:layout-item-v-sizing values) :fill)) (= v-sizing :fill))
[:div {:class (stl/css :row)} [:div {:class (stl/css :row)}
[:div {:class (stl/css :advanced-options)} [:div {:class (stl/css :advanced-options)}
(when (= (:layout-item-h-sizing values) :fill) (when (= (:layout-item-h-sizing values) :fill)
@ -431,63 +526,64 @@
[:div {:class (stl/css :layout-item-min-w) [:div {:class (stl/css :layout-item-min-w)
:title (tr "workspace.options.layout-item.layout-item-min-w")} :title (tr "workspace.options.layout-item.layout-item-min-w")}
[:span {:class (stl/css :icon-text)} [:span {:class (stl/css :icon-text)} "MIN W"]
"MIN W"]
[:> numeric-input* [:> numeric-input*
{:className (stl/css :numeric-input) {:class (stl/css :numeric-input)
:no-validate true :no-validate true
:min 0 :min 0
:data-wrap true :data-wrap true
:placeholder "--" :placeholder "--"
:on-focus #(dom/select-target %) :data-attr "layout-item-min-w"
:on-change (partial on-size-change :layout-item-min-w) :on-focus dom/select-target
:on-change on-size-change
:value (get values :layout-item-min-w) :value (get values :layout-item-min-w)
:nillable true}]] :nillable true}]]
[:div {:class (stl/css :layout-item-max-w) [:div {:class (stl/css :layout-item-max-w)
:title (tr "workspace.options.layout-item.layout-item-max-w")} :title (tr "workspace.options.layout-item.layout-item-max-w")}
[:span {:class (stl/css :icon-text)} [:span {:class (stl/css :icon-text)} "MAX W"]
"MAX W"]
[:> numeric-input* [:> numeric-input*
{:className (stl/css :numeric-input) {:class (stl/css :numeric-input)
:no-validate true :no-validate true
:min 0 :min 0
:data-wrap true :data-wrap true
:placeholder "--" :placeholder "--"
:on-focus #(dom/select-target %) :data-attr "layout-item-max-w"
:on-change (partial on-size-change :layout-item-max-w) :on-focus dom/select-target
:on-change on-size-change
:value (get values :layout-item-max-w) :value (get values :layout-item-max-w)
:nillable true}]]]) :nillable true}]]])
(when (= (:layout-item-v-sizing values) :fill)
(when (= v-sizing :fill)
[:div {:class (stl/css :vertical-fill)} [:div {:class (stl/css :vertical-fill)}
[:div {:class (stl/css :layout-item-min-h) [:div {:class (stl/css :layout-item-min-h)
:title (tr "workspace.options.layout-item.layout-item-min-h")} :title (tr "workspace.options.layout-item.layout-item-min-h")}
[:span {:class (stl/css :icon-text)} [:span {:class (stl/css :icon-text)} "MIN H"]
"MIN H"]
[:> numeric-input* [:> numeric-input*
{:className (stl/css :numeric-input) {:class (stl/css :numeric-input)
:no-validate true :no-validate true
:min 0 :min 0
:data-wrap true :data-wrap true
:placeholder "--" :placeholder "--"
:on-focus #(dom/select-target %) :data-attr "layout-item-min-h"
:on-change (partial on-size-change :layout-item-min-h) :on-focus dom/select-target
:on-change on-size-change
:value (get values :layout-item-min-h) :value (get values :layout-item-min-h)
:nillable true}]] :nillable true}]]
[:div {:class (stl/css :layout-item-max-h) [:div {:class (stl/css :layout-item-max-h)
:title (tr "workspace.options.layout-item.layout-item-max-h")} :title (tr "workspace.options.layout-item.layout-item-max-h")}
[:span {:class (stl/css :icon-text)} [:span {:class (stl/css :icon-text)} "MAX H"]
"MAX H"]
[:> numeric-input* [:> numeric-input*
{:className (stl/css :numeric-input) {:class (stl/css :numeric-input)
:no-validate true :no-validate true
:min 0 :min 0
:data-wrap true :data-wrap true
:placeholder "--" :placeholder "--"
:on-focus #(dom/select-target %) :data-attr "layout-item-max-h"
:on-change (partial on-size-change :layout-item-max-h) :on-focus dom/select-target
:on-change on-size-change
:value (get values :layout-item-max-h) :value (get values :layout-item-max-h)
:nillable true}]]])]])])])) :nillable true}]]])]])])]))