mirror of
https://github.com/penpot/penpot.git
synced 2025-05-18 10:56:13 +02:00
Merge pull request #4158 from penpot/niwinz-staging-perfix-1
⚡ Add performance enhancements for margin-section react component
This commit is contained in:
commit
47bf121d25
2 changed files with 360 additions and 264 deletions
|
@ -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"}
|
||||||
|
|
|
@ -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}]]])]])])]))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue