0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-04-16 17:01:33 -05:00

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"}
funcool/rumext
{:git/tag "v2.9.4"
:git/sha "af08e55"
{:git/tag "v2.10"
:git/sha "d96ea18"
:git/url "https://github.com/funcool/rumext.git"}
instaparse/instaparse {:mvn/version "1.4.12"}

View file

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