Improve performance and usability of new css styles

This commit is contained in:
Andrey Antukh 2023-05-31 11:07:07 +02:00
parent b65452cb73
commit f3b856b2af
5 changed files with 186 additions and 139 deletions

View file

@ -13,8 +13,8 @@
funcool/tubax {:mvn/version "2021.05.20-0"} funcool/tubax {:mvn/version "2021.05.20-0"}
funcool/rumext funcool/rumext
{:git/tag "v2.3" {:git/tag "v2.6"
:git/sha "09942e7" :git/sha "97203a5"
:git/url "https://github.com/funcool/rumext.git" :git/url "https://github.com/funcool/rumext.git"
} }

View file

@ -7,25 +7,95 @@
(ns app.main.style (ns app.main.style
"A fonts loading macros." "A fonts loading macros."
(:require (:require
[app.common.data :as d] [clojure.core :as c]
[clojure.data.json :as json])) [clojure.data.json :as json]
[clojure.java.io :as io]
[rumext.v2.util :as mfu]))
(def ^:dynamic *css-data* nil)
(def ^:private xform-css
(map (fn [k]
(let [cn (name k)]
(if (and (qualified-keyword? k)
(= "app.main.style" (namespace k)))
(or (get *css-data* (keyword cn)) cn)
cn)))))
(defmacro css*
"Just coerces all params to strings and concats them with
space. Used mainly to set a set of classes together."
[& selectors]
(->> selectors
(map name)
(interpose " ")
(apply str)))
(defmacro css (defmacro css
[selector] "Uses a css-modules defined data for real class lookup, then concat
(let [;; Get the associated styles will be module.cljs => module.css.json all classes with space in the same way as `css*`."
filename (:file (meta *ns*)) [& selectors]
styles-file (str "./src/" (subs filename 0 (- (count filename) 4)) "css.json") (let [fname (-> *ns* meta :file)
data (-> (slurp styles-file) path (str (subs fname 0 (- (count fname) 4)) "css.json")
(json/read-str)) data (-> (slurp (io/resource path))
result (get data (d/name selector))] (json/read-str :key-fn keyword))]
`~result)) (if (symbol? (first selectors))
`(if ~(with-meta (first selectors) {:tag 'boolean})
(css* ~@(binding [*css-data* data]
(into [] xform-css (rest selectors))))
(css* ~@(rest selectors)))
`(css* ~@(binding [*css-data* data]
(into [] xform-css selectors))))))
(defmacro styles (defmacro styles
[] []
(let [;; Get the associated styles will be module.cljs => module.css.json ;; Get the associated styles will be module.cljs => module.css.json
filename (:file (meta *ns*)) (let [fname (-> *ns* meta :file)
styles-file (str "./src/" (subs filename 0 (- (count filename) 4)) "css.json") path (str (subs fname 0 (- (count fname) 4)) "css.json")]
data (-> (slurp styles-file) (-> (slurp (io/resource path))
(json/read-str)) (json/read-str :key-fn keyword))))
data (into {} (map (fn [[k v]] [(keyword k) v])) data)]
`~data)) (def ^:private xform-css-case
(comp
(partition-all 2)
(keep (fn [[k v]]
(let [cls (cond
(and (qualified-keyword? k)
(= "app.main.style" (namespace k)))
(let [cn (name k)]
(or (get *css-data* (keyword cn)) cn))
(simple-keyword? k)
(name k)
(string? k)
k)]
(when cls
(cond
(true? v) cls
(false? v) nil
:else `(if ~v ~cls ""))))))
(interpose " ")))
(defmacro css-case
[& params]
(let [fname (-> *ns* meta :file)
path (str (subs fname 0 (- (count fname) 4)) "css.json")
data (-> (slurp (io/resource path))
(json/read-str :key-fn keyword))]
(if (symbol? (first params))
`(if ~(with-meta (first params) {:tag 'boolean})
~(binding [*css-data* data]
(-> (into [] xform-css-case (rest params))
(mfu/compile-concat :safe? false)))
~(-> (into [] xform-css-case (rest params))
(mfu/compile-concat :safe? false)))
`~(binding [*css-data* data]
(-> (into [] xform-css-case params)
(mfu/compile-concat :safe? false))))))
(defmacro css-case*
[& params]
(-> (into [] xform-css-case params)
(mfu/compile-concat :safe? false)))

View file

@ -314,6 +314,7 @@
[:& si/element-icon {:shape item [:& si/element-icon {:shape item
:main-instance? main-instance?}]] :main-instance? main-instance?}]]
[:& layer-name {:ref ref [:& layer-name {:ref ref
:parent-size parent-size
:shape-id (:id item) :shape-id (:id item)
:shape-name (:name item) :shape-name (:name item)
:shape-touched? (boolean (seq (:touched item))) :shape-touched? (boolean (seq (:touched item)))

View file

@ -5,8 +5,9 @@
;; Copyright (c) KALEIDOS INC ;; Copyright (c) KALEIDOS INC
(ns app.main.ui.workspace.sidebar.layer-name (ns app.main.ui.workspace.sidebar.layer-name
(:require-macros [app.main.style :refer [css]]) (:require-macros [app.main.style :as stl])
(:require (:require
[app.common.data :as d]
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
[app.main.data.workspace :as dw] [app.main.data.workspace :as dw]
[app.main.store :as st] [app.main.store :as st]
@ -33,7 +34,7 @@
edition? (deref edition*) edition? (deref edition*)
local-ref (mf/use-ref) local-ref (mf/use-ref)
ref (or external-ref local-ref) ref (d/nilv external-ref local-ref)
shape-for-rename (mf/deref lens:shape-for-rename) shape-for-rename (mf/deref lens:shape-for-rename)
new-css-system (mf/use-ctx ctx/new-css-system) new-css-system (mf/use-ctx ctx/new-css-system)
@ -86,26 +87,25 @@
(if ^boolean edition? (if ^boolean edition?
[:input [:input
{:class (if new-css-system {:class (stl/css new-css-system ::stl/element-name ::stl/element-name-input)
(dom/classnames (css :element-name-input) true) :style {"--depth" depth "--parent-size" parent-size}
(dom/classnames :element-name true))
:style #js {"--depth" depth "--parent-size" parent-size}
:type "text" :type "text"
:ref ref :ref ref
:on-blur accept-edit :on-blur accept-edit
:on-key-down on-key-down :on-key-down on-key-down
:auto-focus true :auto-focus true
:default-value (or shape-name "")}] :default-value (d/nilv shape-name "")}]
[:span [:span
{:class (if new-css-system {:class (if ^boolean new-css-system
(dom/classnames (css :element-name) true (stl/css-case
(css :selected) selected? ::stl/element-name true
(css :hidden) hidden? ::stl/selected selected?
(css :type-comp) type-comp ::stl/hidden hidden?
(css :type-frame) type-frame) ::stl/type-comp type-comp
(dom/classnames :element-name true)) ::stl/type-frame type-frame)
:style #js {"--depth" depth "--parent-size" parent-size} (stl/css* :element-name))
:style {"--depth" depth "--parent-size" parent-size}
:ref ref :ref ref
:on-double-click start-edit} :on-double-click start-edit}
(or shape-name "") (d/nilv shape-name "")
(when ^boolean shape-touched? " *")]))) (when ^boolean shape-touched? " *")])))

View file

@ -5,7 +5,7 @@
;; Copyright (c) KALEIDOS INC ;; Copyright (c) KALEIDOS INC
(ns app.main.ui.workspace.sidebar.layers (ns app.main.ui.workspace.sidebar.layers
(:require-macros [app.main.style :refer [css]]) (:require-macros [app.main.style :as stl :refer [css]])
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
@ -48,9 +48,7 @@
root (get objects uuid/zero) root (get objects uuid/zero)
new-css-system (mf/use-ctx ctx/new-css-system)] new-css-system (mf/use-ctx ctx/new-css-system)]
[:ul [:ul
{:class (if new-css-system {:class (stl/css new-css-system ::stl/element-list)}
(dom/classnames (css :element-list) true)
(dom/classnames :element-list true))}
[:& hooks/sortable-container {} [:& hooks/sortable-container {}
(for [[index id] (reverse (d/enumerate (:shapes root)))] (for [[index id] (reverse (d/enumerate (:shapes root)))]
(when-let [obj (get objects id)] (when-let [obj (get objects id)]
@ -84,9 +82,7 @@
selected (hooks/use-equal-memo selected) selected (hooks/use-equal-memo selected)
root (get objects uuid/zero) root (get objects uuid/zero)
new-css-system (mf/use-ctx ctx/new-css-system)] new-css-system (mf/use-ctx ctx/new-css-system)]
[:ul {:class (if new-css-system [:ul {:class (stl/css new-css-system ::stl/element-list)}
(dom/classnames (css :element-list) true)
(dom/classnames :element-list true))}
(for [[index id] (d/enumerate (:shapes root))] (for [[index id] (d/enumerate (:shapes root))]
(when-let [obj (get objects id)] (when-let [obj (get objects id)]
[:& layer-item [:& layer-item
@ -130,8 +126,8 @@
(or (empty? filters) (or (empty? filters)
(and (contains? filters :component) (and (contains? filters :component)
(contains? shape :component-id)) (contains? shape :component-id))
(let [direct-filters (filter #{:frame :rect :circle :path :bool :image :text} filters)] (let [direct-filters (into #{} (filter #{:frame :rect :circle :path :bool :image :text}) filters)]
(some #{(:type shape)} direct-filters)) (contains? direct-filters (:type shape)))
(and (contains? filters :group) (and (contains? filters :group)
(and (cph/group-shape? shape) (and (cph/group-shape? shape)
(not (contains? shape :component-id)) (not (contains? shape :component-id))
@ -254,12 +250,7 @@
#(mf/html #(mf/html
(if show-search? (if show-search?
[:* [:*
[:div {:class (if ^boolean new-css-system [:div {:class (stl/css new-css-system ::stl/tool-window-bar ::stl/search)}
(dom/classnames (css :tool-window-bar) true
(css :search) true)
(dom/classnames :tool-window-bar true
:search true))}
(if ^boolean new-css-system (if ^boolean new-css-system
[:& search-bar [:& search-bar
{:on-change update-search-text-v2 {:on-change update-search-text-v2
@ -268,14 +259,15 @@
:placeholder (tr "workspace.sidebar.layers.search")} :placeholder (tr "workspace.sidebar.layers.search")}
[:button [:button
{:on-click toggle-filters {:on-click toggle-filters
:class (dom/classnames :active active? :class (stl/css-case
(css :filter-button) true)} ::stl/filters-button true
:active active?)}
i/filter-refactor]] i/filter-refactor]]
[:span.search-box [:span.search-box
[:button.filter [:button.filter
{:on-click toggle-filters {:on-click toggle-filters
:class (dom/classnames :active active?)} :class (stl/css-case :active active?)}
i/icon-filter] i/icon-filter]
[:div [:div
[:input {:on-change update-search-text-v1 [:input {:on-change update-search-text-v1
@ -286,15 +278,13 @@
(when (not (= "" current-search)) (when (not (= "" current-search))
[:button.clear {:on-click clear-search-text} i/exclude])]]) [:button.clear {:on-click clear-search-text} i/exclude])]])
[:button {:class (dom/classnames (css :close-search) new-css-system) [:button {:class (stl/css-case ::stl/close-search new-css-system)
:on-click toggle-search} :on-click toggle-search}
(if ^boolean new-css-system (if ^boolean new-css-system
i/close-refactor i/close-refactor
i/cross)]] i/cross)]]
[:div {:class (if ^boolean new-css-system [:div {:class (stl/css new-css-system ::stl/active-filters)}
(dom/classnames (css :active-filters) true)
(dom/classnames :active-filters true))}
(for [fkey current-filters] (for [fkey current-filters]
(let [fname (d/name fkey) (let [fname (d/name fkey)
name (case fkey name (case fkey
@ -307,17 +297,17 @@
:shape (tr "workspace.sidebar.layers.shapes") :shape (tr "workspace.sidebar.layers.shapes")
(tr fkey))] (tr fkey))]
(if ^boolean new-css-system (if ^boolean new-css-system
[:button {:class (dom/classnames (css :layer-filter) true) [:button {:class (stl/css ::stl/layer-filter)
:key fname :key fname
:data-filter fname :data-filter fname
:on-click remove-filter} :on-click remove-filter}
[:span {:class (dom/classnames (css :layer-filter-icon) true)} [:span {:class (stl/css ::stl/layer-filter-icon)}
[:& sic/element-icon-refactor-by-type [:& sic/element-icon-refactor-by-type
{:type fkey {:type fkey
:main-instance? (= fkey :component)}]] :main-instance? (= fkey :component)}]]
[:span {:class (dom/classnames (css :layer-filter-name) true)} [:span {:class (stl/css ::stl/layer-filter-name)}
name] name]
[:span {:class (dom/classnames (css :layer-filter-close) true)} [:span {:class (stl/css ::stl/layer-filter-close)}
i/close-small-refactor]] i/close-small-refactor]]
[:span {:on-click remove-filter [:span {:on-click remove-filter
@ -327,89 +317,89 @@
(when ^boolean show-menu? (when ^boolean show-menu?
(if ^boolean new-css-system (if ^boolean new-css-system
[:ul {:class (css :filters-container)} [:ul {:class (stl/css ::stl/filters-container)}
[:li {:class (dom/classnames [:li {:class (stl/css-case
(css :filter-menu-item) true ::stl/filter-menu-item true
(css :selected) (contains? current-filters :frame)) ::stl/selected (contains? current-filters :frame))
:data-filter "frame" :data-filter "frame"
:on-click add-filter} :on-click add-filter}
[:div {:class (dom/classnames (css :filter-menu-item-name-wrapper) true)} [:div {:class (stl/css ::stl/filter-menu-item-name-wrapper)}
[:span {:class (dom/classnames (css :filter-menu-item-icon) true)} i/board-refactor] [:span {:class (stl/css ::stl/filter-menu-item-icon)} i/board-refactor]
[:span {:class (dom/classnames (css :filter-menu-item-name) true)} [:span {:class (stl/css ::stl/filter-menu-item-name)}
(tr "workspace.sidebar.layers.frames")]] (tr "workspace.sidebar.layers.frames")]]
(when (contains? current-filters :frame) (when (contains? current-filters :frame)
[:span {:class (dom/classnames (css :filter-menu-item-tick) true)} i/tick-refactor])] [:span {:class (stl/css ::stl/filter-menu-item-tick)} i/tick-refactor])]
[:li {:class (dom/classnames [:li {:class (stl/css-case
(css :filter-menu-item) true ::stl/filter-menu-item true
(css :selected) (contains? current-filters :group)) ::stl/selected (contains? current-filters :group))
:data-filter "group" :data-filter "group"
:on-click add-filter} :on-click add-filter}
[:div {:class (dom/classnames (css :filter-menu-item-name-wrapper) true)} [:div {:class (stl/css ::stl/filter-menu-item-name-wrapper)}
[:span {:class (dom/classnames (css :filter-menu-item-icon) true)} i/group-refactor] [:span {:class (stl/css ::stl/filter-menu-item-icon)} i/group-refactor]
[:span {:class (dom/classnames (css :filter-menu-item-name) true)} [:span {:class (stl/css ::stl/filter-menu-item-name)}
(tr "workspace.sidebar.layers.groups")]] (tr "workspace.sidebar.layers.groups")]]
(when (contains? current-filters :group) (when (contains? current-filters :group)
[:span {:class (dom/classnames (css :filter-menu-item-tick) true)} i/tick-refactor])] [:span {:class (stl/css ::stl/filter-menu-item-tick)} i/tick-refactor])]
[:li {:class (dom/classnames [:li {:class (stl/css-case
(css :filter-menu-item) true :filter-menu-item true
(css :selected) (contains? current-filters :mask)) :selected (contains? current-filters :mask))
:data-filter "mask" :data-filter "mask"
:on-click add-filter} :on-click add-filter}
[:div {:class (dom/classnames (css :filter-menu-item-name-wrapper) true)} [:div {:class (stl/css ::stl/filter-menu-item-name-wrapper)}
[:span {:class (dom/classnames (css :filter-menu-item-icon) true)} i/mask-refactor] [:span {:class (stl/css ::stl/filter-menu-item-icon)} i/mask-refactor]
[:span {:class (dom/classnames (css :filter-menu-item-name) true)} [:span {:class (stl/css ::stl/filter-menu-item-name)}
(tr "workspace.sidebar.layers.masks")]] (tr "workspace.sidebar.layers.masks")]]
(when (contains? current-filters :mask) (when (contains? current-filters :mask)
[:span {:class (dom/classnames (css :filter-menu-item-tick) true)} i/tick-refactor])] [:span {:class (stl/css ::stl/filter-menu-item-tick)} i/tick-refactor])]
[:li {:class (dom/classnames [:li {:class (stl/css-case
(css :filter-menu-item) true :filter-menu-item true
(css :selected) (contains? current-filters :component)) :selected (contains? current-filters :component))
:data-filter "component" :data-filter "component"
:on-click add-filter} :on-click add-filter}
[:div {:class (dom/classnames (css :filter-menu-item-name-wrapper) true)} [:div {:class (stl/css ::stl/filter-menu-item-name-wrapper)}
[:span {:class (dom/classnames (css :filter-menu-item-icon) true)} i/component-refactor] [:span {:class (stl/css ::stl/filter-menu-item-icon)} i/component-refactor]
[:span {:class (dom/classnames (css :filter-menu-item-name) true)} [:span {:class (stl/css ::stl/filter-menu-item-name)}
(tr "workspace.sidebar.layers.components")]] (tr "workspace.sidebar.layers.components")]]
(when (contains? current-filters :component) (when (contains? current-filters :component)
[:span {:class (dom/classnames (css :filter-menu-item-tick) true)} i/tick-refactor])] [:span {:class (stl/css ::stl/filter-menu-item-tick)} i/tick-refactor])]
[:li {:class (dom/classnames [:li {:class (stl/css-case
(css :filter-menu-item) true :filter-menu-item true
(css :selected) (contains? current-filters :text)) :selected (contains? current-filters :text))
:data-filter "text" :data-filter "text"
:on-click add-filter} :on-click add-filter}
[:div {:class (dom/classnames (css :filter-menu-item-name-wrapper) true)} [:div {:class (stl/css ::stl/filter-menu-item-name-wrapper)}
[:span {:class (dom/classnames (css :filter-menu-item-icon) true)} i/text-refactor] [:span {:class (stl/css ::stl/filter-menu-item-icon)} i/text-refactor]
[:span {:class (dom/classnames (css :filter-menu-item-name) true)} [:span {:class (stl/css ::stl/filter-menu-item-name)}
(tr "workspace.sidebar.layers.texts")]] (tr "workspace.sidebar.layers.texts")]]
(when (contains? current-filters :text) (when (contains? current-filters :text)
[:span {:class (dom/classnames (css :filter-menu-item-tick) true)} i/tick-refactor])] [:span {:class (stl/css ::stl/filter-menu-item-tick)} i/tick-refactor])]
[:li {:class (dom/classnames [:li {:class (stl/css-case
(css :filter-menu-item) true :filter-menu-item true
(css :selected) (contains? current-filters :image)) :selected (contains? current-filters :image))
:data-filter "image" :data-filter "image"
:on-click add-filter} :on-click add-filter}
[:div {:class (dom/classnames (css :filter-menu-item-name-wrapper) true)} [:div {:class (stl/css ::stl/filter-menu-item-name-wrapper)}
[:span {:class (dom/classnames (css :filter-menu-item-icon) true)} i/img-refactor] [:span {:class (stl/css ::stl/filter-menu-item-icon)} i/img-refactor]
[:span {:class (dom/classnames (css :filter-menu-item-name) true)} [:span {:class (stl/css ::stl/filter-menu-item-name)}
(tr "workspace.sidebar.layers.images")]] (tr "workspace.sidebar.layers.images")]]
(when (contains? current-filters :image) (when (contains? current-filters :image)
[:span {:class (dom/classnames (css :filter-menu-item-tick) true)} i/tick-refactor])] [:span {:class (stl/css ::stl/filter-menu-item-tick)} i/tick-refactor])]
[:li {:class (dom/classnames [:li {:class (stl/css-case
(css :filter-menu-item) true :filter-menu-item true
(css :selected) (contains? current-filters :shape)) :selected (contains? current-filters :shape))
:data-filter "shape" :data-filter "shape"
:on-click add-filter} :on-click add-filter}
[:div {:class (dom/classnames (css :filter-menu-item-name-wrapper) true)} [:div {:class (stl/css ::stl/filter-menu-item-name-wrapper)}
[:span {:class (dom/classnames (css :filter-menu-item-icon) true)} i/path-refactor] [:span {:class (stl/css ::stl/filter-menu-item-icon)} i/path-refactor]
[:span {:class (dom/classnames (css :filter-menu-item-name) true)} [:span {:class (stl/css ::stl/filter-menu-item-name)}
(tr "workspace.sidebar.layers.shapes")]] (tr "workspace.sidebar.layers.shapes")]]
(when (contains? current-filters :shape) (when (contains? current-filters :shape)
[:span {:class (dom/classnames (css :filter-menu-item-tick) true)} i/tick-refactor])]] [:span {:class (stl/css ::stl/filter-menu-item-tick)} i/tick-refactor])]]
[:div.filters-container [:div.filters-container
[:span {:data-filter "frame" [:span {:data-filter "frame"
@ -435,7 +425,7 @@
i/curve (tr "workspace.sidebar.layers.shapes")]]))] i/curve (tr "workspace.sidebar.layers.shapes")]]))]
(if ^boolean new-css-system (if ^boolean new-css-system
[:div {:class (dom/classnames (css :tool-window-bar) true)} [:div {:class (stl/css :tool-window-bar)}
[:& title-bar {:collapsable? false [:& title-bar {:collapsable? false
:title (:name page) :title (:name page)
:on-btn-click toggle-search :on-btn-click toggle-search
@ -516,38 +506,28 @@
(when sticky? (when sticky?
(dom/add-class! last-hidden-frame "sticky"))))))] (dom/add-class! last-hidden-frame "sticky"))))))]
[:div#layers [:div#layers
{:class (if new-css-system {:class (if ^boolean new-css-system
(dom/classnames (css :layers) true) (stl/css ::stl/layers)
(dom/classnames :tool-window true))} (stl/css* :tool-window))}
(if (d/not-empty? focus) (if (d/not-empty? focus)
[:div [:div
{:class (if new-css-system {:class (stl/css new-css-system ::stl/tool-window-bar)}
(dom/classnames (css :tool-window-bar) true) [:button {:class (stl/css new-css-system :focus-title)
(dom/classnames :tool-window-bar true))}
[:button {:class (if new-css-system
(dom/classnames (css :focus-title) true)
(dom/classnames :focus-title true))
:on-click #(st/emit! (dw/toggle-focus-mode))} :on-click #(st/emit! (dw/toggle-focus-mode))}
[:span {:class (if new-css-system [:span {:class (stl/css new-css-system ::stl/back-button)}
(dom/classnames (css :back-button) true)
(dom/classnames :back-button true))}
(if new-css-system (if new-css-system
i/arrow-refactor i/arrow-refactor
i/arrow-slide)] i/arrow-slide)]
[:div {:class (if new-css-system [:div {:class (stl/css new-css-system ::stl/focus-name)}
(dom/classnames (css :focus-name) true)
(dom/classnames :focus-name true))}
(or title (tr "workspace.sidebar.layers"))] (or title (tr "workspace.sidebar.layers"))]
(if new-css-system (if ^boolean new-css-system
[:div {:class (dom/classnames (css :focus-mode-tag-wrapper) true)} [:div {:class (stl/css ::stl/focus-mode-tag-wrapper)}
[:div {:class (dom/classnames (css :focus-mode-tag) true)} (tr "workspace.focus.focus-mode")]] [:div {:class (stl/css ::stl/focus-mode-tag)} (tr "workspace.focus.focus-mode")]]
[:div.focus-mode (tr "workspace.focus.focus-mode")])]] [:div.focus-mode (tr "workspace.focus.focus-mode")])]]
(filter-component)) (filter-component))
(if (some? filtered-objects) (if (some? filtered-objects)
[:* [:*
[:div {:class (if new-css-system [:div {:class (stl/css new-css-system ::stl/tool-window-content)
(dom/classnames (css :tool-window-content) true)
(dom/classnames :tool-window-content true))
:ref on-render-container} :ref on-render-container}
[:& filters-tree {:objects filtered-objects [:& filters-tree {:objects filtered-objects
:key (dm/str (:id page)) :key (dm/str (:id page))
@ -555,18 +535,14 @@
[:div.lazy {:ref lazy-load-ref [:div.lazy {:ref lazy-load-ref
:style {:min-height 16}}]] :style {:min-height 16}}]]
[:div {:on-scroll on-scroll [:div {:on-scroll on-scroll
:class (if new-css-system :class (stl/css new-css-system ::stl/tool-window-content)
(dom/classnames (css :tool-window-content) true)
(dom/classnames :tool-window-content true))
:style {:display (when (some? filtered-objects) "none")}} :style {:display (when (some? filtered-objects) "none")}}
[:& layers-tree {:objects filtered-objects [:& layers-tree {:objects filtered-objects
:key (dm/str (:id page)) :key (dm/str (:id page))
:filtered? true :filtered? true
:parent-size size-parent}]]] :parent-size size-parent}]]]
[:div {:on-scroll on-scroll [:div {:on-scroll on-scroll
:class (if new-css-system :class (stl/css new-css-system ::stl/tool-window-content)
(dom/classnames (css :tool-window-content) true)
(dom/classnames :tool-window-content true))
:style {:display (when (some? filtered-objects) "none")}} :style {:display (when (some? filtered-objects) "none")}}
[:& layers-tree {:objects objects [:& layers-tree {:objects objects
:key (dm/str (:id page)) :key (dm/str (:id page))