From 1c21ca97a5820adf1226d726143c6d4f9fa74576 Mon Sep 17 00:00:00 2001 From: Kimo Knowles Date: Mon, 9 Dec 2024 00:05:08 +0100 Subject: [PATCH] [nested-v-grid] prototype --- src/re_com/nested_grid.cljs | 138 +++++++++++++++++++++++++++++ src/re_com/nested_grid/parts.cljs | 14 +++ src/re_com/nested_grid/util.cljc | 110 ++++++++++++++--------- src/re_com/theme/default.cljs | 62 +++++++++---- src/re_com/util.cljs | 15 ++-- src/re_demo/nested_grid.cljs | 141 +++++------------------------- 6 files changed, 294 insertions(+), 186 deletions(-) create mode 100644 src/re_com/nested_grid/parts.cljs diff --git a/src/re_com/nested_grid.cljs b/src/re_com/nested_grid.cljs index 8549c786..6e319c67 100644 --- a/src/re_com/nested_grid.cljs +++ b/src/re_com/nested_grid.cljs @@ -5,6 +5,7 @@ [clojure.string :as str] [re-com.util :as u :refer [px deref-or-value]] [re-com.nested-grid.util :as ngu] + [re-com.nested-grid.parts :as ngp] [reagent.core :as r] [re-com.debug :as debug] [re-com.config :as config :refer [include-args-desc?]] @@ -1184,3 +1185,140 @@ row-headers cells) overlays])))) + +(defn nested-v-grid [{:keys [row-tree column-tree + row-tree-depth column-tree-depth + column-header-heights + row-header-widths + theme + row-header-width column-header-height] + :or {row-header-width 40 column-header-height 40}}] + (let [[wx wy wh ww !wrapper-ref scroll-listener resize-observer] + (repeatedly #(r/atom nil)) + wrapper-ref! (partial reset! !wrapper-ref) + on-scroll! #(do (reset! wx (.-scrollLeft (.-target %))) + (reset! wy (.-scrollTop (.-target %)))) + on-resize! #(do (reset! wh (.-height (.-contentRect (aget % 0)))) + (reset! ww (.-width (.-contentRect (aget % 0))))) + internal-row-tree (r/atom (u/deref-or-value row-tree)) + internal-column-tree (r/atom (u/deref-or-value column-tree)) + size-cache (volatile! {}) + row-traversal (r/reaction (ngu/walk-size {:tree @internal-row-tree + :window-start (or @wy 0) + :window-end (+ @wy @wh) + :size-cache size-cache + :dimension :row + :tree-depth (u/deref-or-value + row-tree-depth)})) + column-traversal (r/reaction (ngu/walk-size {:tree @internal-column-tree + :window-start (or @wx 0) + :window-end (+ @wx @ww) + :size-cache size-cache + :dimension :column + :tree-depth (u/deref-or-value + column-tree-depth)})) + column-depth (r/reaction (:depth @column-traversal)) + column-header-heights (r/reaction (or (u/deref-or-value column-header-heights) + (repeat @column-depth column-header-height))) + column-header-height-total (r/reaction (apply + @column-header-heights)) + column-width-total (r/reaction (:sum-size @column-traversal)) + column-windowed-paths (r/reaction (:windowed-paths @column-traversal)) + column-windowed-leaf-paths (r/reaction (:windowed-leaf-paths @column-traversal)) + column-tokens (r/reaction (ngu/lazy-grid-tokens @column-traversal)) + column-template (r/reaction (ngu/lazy-grid-template @column-tokens)) + column-header-template (r/reaction (ngu/grid-template @column-header-heights)) + column-spans (r/reaction (ngu/grid-spans @column-tokens)) + row-depth (r/reaction (:depth @row-traversal)) + row-header-widths (r/reaction (or (u/deref-or-value row-header-widths) + (repeat @row-depth row-header-width))) + row-header-width-total (r/reaction (apply + @row-header-widths)) + row-height-total (r/reaction (:sum-size @row-traversal)) + row-windowed-paths (r/reaction (:windowed-paths @row-traversal)) + row-windowed-leaf-paths (r/reaction (:windowed-leaf-paths @row-traversal)) + row-tokens (r/reaction (ngu/lazy-grid-tokens @row-traversal)) + row-template (r/reaction (ngu/lazy-grid-template @row-tokens)) + row-header-template (r/reaction (ngu/grid-template @row-header-widths)) + row-spans (r/reaction (ngu/grid-spans @row-tokens))] + (r/create-class + {:component-did-mount + #(do (reset! scroll-listener + (.addEventListener @!wrapper-ref "scroll" on-scroll!)) + (reset! resize-observer + (.observe (js/ResizeObserver. on-resize!) @!wrapper-ref))) + :component-did-update + #(let [[_ {:keys [row-tree column-tree]}] (r/argv %)] + (reset! internal-row-tree (u/deref-or-value row-tree)) + (reset! internal-column-tree (u/deref-or-value column-tree))) + :reagent-render + (fn [{:keys [row-tree column-tree + cell + row-header-cell column-header-cell] + :as props}] + (u/deref-or-value row-tree) + (u/deref-or-value row-header-widths) + (u/deref-or-value column-header-heights) + (u/deref-or-value column-tree) + (let [theme (theme/defaults + props + {:user [(theme/<-props props {:part ::wrapper + :include [:style :class]})]}) + themed (fn [part props] (theme/apply props {:part part} theme)) + spacer-container [:div {:style {:position :sticky + :grid-row-start 1 + :grid-column-start 1 + :left 0 + :top 0 + :background-color :white}}] + row-header-container [:div {:style {:display :grid + :grid-template-rows @row-template + :grid-template-columns @row-header-template + :position :sticky + :left 0}}] + row-header-cells (for [row-path @row-windowed-paths + :let [props (themed ::row-header-wrapper + {:style {:grid-row-start (ngu/path->grid-line-name row-path) + :grid-row-end (str "span " (get @row-spans row-path)) + :grid-column-start (count row-path) + :grid-column-end (str "span " (inc (- @row-depth (count row-path)))) + :font-size 8} + :edge #{:start}})]] + (u/part row-header-cell props {:key row-path + :default ngp/row-header-wrapper})) + column-header-container [:div {:style {:display :grid + :grid-template-rows @column-header-template + :grid-template-columns @column-template + :position :sticky + :top 0}}] + column-header-cells (for [column-path @column-windowed-paths + :let [props (themed ::column-header-wrapper + {:style {:grid-column-start (ngu/path->grid-line-name column-path) + :grid-column-end (str "span " (get @column-spans column-path)) + :grid-row-start (count column-path) + :grid-row-end (str "span " (inc (- @column-depth (count column-path)))) + :overflow :hidden + :font-size 8} + :children [(pr-str column-path)]})]] + (u/part column-header-cell props {:key column-path})) + main-container [:div + (themed ::wrapper + {:style {:grid-template-rows (ngu/grid-template [@column-header-height-total @row-height-total]) + :grid-template-columns (ngu/grid-template [@row-header-width-total @column-width-total])} + :ref wrapper-ref!})] + cell-grid-container [:div (themed ::cell-grid + {:style {:display :grid + :grid-column-start 2 + :grid-row-start 2 + :grid-template-rows @row-template + :grid-template-columns @column-template}})] + cells (for [row-path @row-windowed-leaf-paths + column-path @column-windowed-leaf-paths + :let [props {:row-path row-path + :column-path column-path}]] + (u/part cell props {:key [row-path column-path] + :default ngp/cell}))] + (conj main-container + (into cell-grid-container cells) + (into column-header-container column-header-cells) + (into row-header-container row-header-cells) + spacer-container)))}))) + diff --git a/src/re_com/nested_grid/parts.cljs b/src/re_com/nested_grid/parts.cljs new file mode 100644 index 00000000..5af5eec8 --- /dev/null +++ b/src/re_com/nested_grid/parts.cljs @@ -0,0 +1,14 @@ +(ns re-com.nested-grid.parts + (:require [re-com.nested-grid.util :as ngu] + [re-com.nested-grid :as-alias ng])) + +(defn cell [{:keys [row-path column-path]}] + [:div {:style {:border "thin solid grey" + :grid-row-start (ngu/path->grid-line-name row-path) + :grid-column-start (ngu/path->grid-line-name column-path) + :font-size 6}} + (str (gensym))]) + +(defn row-header-wrapper [{:keys [style]}] + [:div {:style (merge style {:font-size 6})} + (gensym)]) diff --git a/src/re_com/nested_grid/util.cljc b/src/re_com/nested_grid/util.cljc index 47600915..bce57816 100644 --- a/src/re_com/nested_grid/util.cljc +++ b/src/re_com/nested_grid/util.cljc @@ -89,9 +89,15 @@ (map? node) (:size node) (keyword? node) 20))) -(defn walk-size [{:keys [window-start window-end tree size-cache]}] +(defn walk-size [{:keys [window-start window-end tree size-cache dimension tree-depth]}] (let [sum-size (volatile! 0) depth (volatile! 0) + tree-hash (hash tree) + cached-depth (and size-cache + (get-in @size-cache [dimension tree-hash ::depth])) + cached-sum-size (and size-cache + (get-in @size-cache [dimension tree-hash ::sum-size])) + tail-cached? (and cached-depth cached-sum-size) windowed-paths (volatile! []) windowed-leaf-paths (volatile! []) windowed-sizes (volatile! []) @@ -117,48 +123,53 @@ (>= x2 window-start)))) walk (fn walk [path node & {:keys [collect-me?] :or {collect-me? true}}] - (cond - (leaf? node) (let [sum @sum-size - leaf-size (leaf-size node) - leaf-path (conj path node) - level (count leaf-path) - bounds [sum (+ sum leaf-size)]] - (when (intersection? bounds) - (collect-leaf-path! leaf-path) - (when collect-me? - (collect-path! leaf-path) - (collect-sum! sum) - (collect-size! leaf-size))) - (vreset! sum-size (+ sum leaf-size)) - leaf-size) - (branch? node) (let [sum @sum-size - csize (lookup node) - cbounds (when csize [sum (+ sum csize)]) - skippable? (and csize (not (intersection? cbounds)))] - (if skippable? - (let [new-sum (+ sum csize)] - (vreset! sum-size new-sum) - csize) - (let [own-path (conj path (own-leaf node)) - level (count own-path) - own-size (walk path (own-leaf node) {:collect-me? false}) - _ (collect-path! own-path) - _ (collect-size! own-size) - _ (collect-sum! sum) - _ (collect-depth! (count own-path)) - descend-tx (map (partial walk own-path)) - total-size (+ own-size - (transduce descend-tx + (children node))) - total-bounds [sum (+ sum total-size)]] - (when-not (intersection? total-bounds) - (forget-path!) - (forget-sum!) - (forget-size!)) - (when-not csize (cache! node total-size)) - total-size)))))] + (let [sum @sum-size + passed-tail? (and tail-cached? (> sum window-end))] + (cond + passed-tail? :exit + (leaf? node) (let [leaf-size (leaf-size node) + leaf-path (conj path node) + bounds [sum (+ sum leaf-size)]] + (when (intersection? bounds) + (collect-leaf-path! leaf-path) + (when collect-me? + (collect-path! leaf-path) + (collect-sum! sum) + (collect-size! leaf-size))) + (vreset! sum-size (+ sum leaf-size)) + leaf-size) + (branch? node) (let [csize (lookup node) + cbounds (when csize [sum (+ sum csize)]) + skippable? (and csize (not (intersection? cbounds)))] + (if skippable? + (let [new-sum (+ sum csize)] + (vreset! sum-size new-sum) + csize) + (let [own-path (conj path (own-leaf node)) + own-size (walk path (own-leaf node) {:collect-me? false}) + _ (collect-path! own-path) + _ (collect-size! own-size) + _ (collect-sum! sum) + _ (when-not (or tree-depth + cached-depth) + (collect-depth! (count own-path))) + descend-tx (map (partial walk own-path)) + total-size (+ own-size + (transduce descend-tx + (children node))) + total-bounds [sum (+ sum total-size)]] + (when-not (intersection? total-bounds) + (forget-path!) + (forget-sum!) + (forget-size!)) + (when-not csize (cache! node total-size)) + total-size))))))] (walk [] tree) - {:sum-size @sum-size - :depth (inc @depth) + (when-not cached-depth + (vswap! size-cache assoc-in [dimension tree-hash ::depth] @depth)) + (when-not cached-sum-size + (vswap! size-cache assoc-in [dimension tree-hash ::sum-size] @sum-size)) + {:sum-size (or cached-sum-size @sum-size) + :depth (or tree-depth (inc cached-depth) (inc @depth)) :windowed-sums @windowed-sums :windowed-paths @windowed-paths :windowed-sizes @windowed-sizes @@ -184,6 +195,21 @@ [:y 40] [:z 20]]]) +(def big-test-tree + (into test-tree + (repeatedly 1000 #(do [(keyword (gensym)) + [:x 20] + [:y 40] + [:z 20]])))) + +(def huge-test-tree + (into test-tree + [(into [:hhh] + (repeatedly 10000 #(do [(keyword (gensym)) + [:x 20] + [:y 40] + [:z 20]])))])) + #_(walk-size {:window-start 372 :window-end 472 :size-cache (volatile! {}) diff --git a/src/re_com/theme/default.cljs b/src/re_com/theme/default.cljs index 3d2a141d..eb932ef7 100644 --- a/src/re_com/theme/default.cljs +++ b/src/re_com/theme/default.cljs @@ -5,6 +5,7 @@ [re-com.theme.util :refer [merge-props]] [re-com.dropdown :as-alias dropdown] [re-com.error-modal :as-alias error-modal] + [re-com.nested-grid-old :as-alias nested-grid-old] [re-com.nested-grid :as-alias nested-grid] [re-com.tree-select :as-alias tree-select])) @@ -73,22 +74,31 @@ :overflow "hidden" :position "relative"}) -(defmethod base ::nested-grid/cell-wrapper [props _] - (update props :style merge cell-wrapper-base)) +(defn style [props & ms] (apply update props :style merge ms)) -(def row-header-wrapper-base {:user-select "none" - :height "100%"}) +(defmethod base ::nested-grid/wrapper [props _] + (style props {:height 300 + :width 500 + :overflow :auto + :flex "0 0 auto" + :display :grid})) -(defmethod base ::nested-grid/row-header-wrapper [props _] +(defmethod base ::nested-grid-old/cell-wrapper [props _] + (style props cell-wrapper-base)) + +(def row-header-wrapper-base {:user-select "none" + :height "100%"}) + +(defmethod base ::nested-grid-old/row-header-wrapper [props _] (update props :style merge row-header-wrapper-base)) (defmethod base ::nested-grid/column-header-wrapper [props _] (update props :style merge {:user-select "none" - :width "100%" - :height "100%"})) + :width "100%" + :height "100%"})) -(defmethod base ::nested-grid/row-header +(defmethod base ::nested-grid-old/row-header [props {{:keys [sticky? sticky-top]} :state}] (update props :style merge {:width "100%" :text-overflow :ellipsis @@ -96,7 +106,7 @@ :position :sticky :top sticky-top})) -(defmethod base ::nested-grid/column-header +(defmethod base ::nested-grid-old/column-header [props _] (update props :style merge {:height "100%"})) @@ -152,12 +162,12 @@ :overflow-x "visible" :z-index 30}} - ::nested-grid/cell-grid-container + ::nested-grid-old/cell-grid-container {:style {:position "relative" :gap "0px"}} - ::nested-grid/cell-wrapper + ::nested-grid-old/cell-wrapper {:style {#_#_:pointer-events "none" :user-select "none" :overflow "hidden" @@ -180,7 +190,7 @@ :border-right "thin solid #ccc" :border-bottom "thin solid #ccc"})) -(defmethod main ::nested-grid/cell-wrapper +(defmethod main ::nested-grid-old/cell-wrapper [props {{:keys [edge value column-path]} :state}] (let [align (some :align column-path)] (update props :style merge @@ -210,12 +220,13 @@ :background-color light-background :color "#666" :text-align "left" - :font-size "13px" + #_#_:font-size "13px" + :font-size 6 :white-space "nowrap" :border-left "thin solid #ccc" :border-bottom "thin solid #ccc"})) -(defmethod main ::nested-grid/row-header-wrapper +(defmethod main ::nested-grid-old/row-header-wrapper [props {{:keys [edge]} :state}] (update props :style merge row-header-wrapper-main @@ -226,6 +237,11 @@ (when (contains? edge :bottom) {:border-bottom "thin solid #aaa"}))) +(defmethod main ::nested-grid/row-header-wrapper [props _] + (style props + row-header-wrapper-main + {#_#_:border "thin solid #aaa"})) + (defmethod main :default [props {:keys [state part] {:as $ :keys [sm-1 sm-2 sm-3 sm-4 sm-5 sm-6 md-1 md-2 @@ -275,11 +291,11 @@ (-> state :enable (= :disabled)) (merge {:background-color (:background-disabled $)}))} - ::nested-grid/cell-grid-container + ::nested-grid-old/cell-grid-container {:style {:padding "0px" :background-color "transparent"}} - ::nested-grid/header-spacer-wrapper + ::nested-grid-old/header-spacer-wrapper {:style {:border-left (when (contains? (:edge state) :left) (str "thin" " solid " border-dark)) :border-top (when (get (:edge state) :top) @@ -290,7 +306,7 @@ (str "thin" " solid " border)) :background-color light-background}} - ::nested-grid/column-header-wrapper + ::nested-grid-old/column-header-wrapper (let [{:keys [align-column align-column-header align]} (:header-spec state)] {:style {:padding-top sm-3 :padding-right sm-4 @@ -309,6 +325,18 @@ :else (str "thin" " solid " border))}}) + ::nested-grid/column-header-wrapper + (let [{:keys [align-column align-column-header align]} (:header-spec state)] + {:style {:padding-top sm-3 + :padding-right sm-4 + :padding-left sm-4 + :background-color light-background + :color "#666" + :text-align (or align-column-header align-column align :center) + #_#_:font-size "13px" + :font-size 6 + :border (str "thin solid " border)}}) + ::tree-select/dropdown-anchor {:style {:padding "0 0 0 0" :overflow "hidden" diff --git a/src/re_com/util.cljs b/src/re_com/util.cljs index 66a2c244..847d9a3d 100644 --- a/src/re_com/util.cljs +++ b/src/re_com/util.cljs @@ -243,15 +243,18 @@ (defn default-part [{:keys [class style attr children]}] (into [:div (merge {:class class :style style} attr)] - children)) + (into [(str (gensym))] children))) -(defn part [x props & {:keys [default]}] +(defn part [x props & {:keys [default key]}] (cond - (string? x) x + (ifn? x) (cond-> [x props] + key (with-meta {:key key})) (hiccup? x) x - (ifn? x) [x props] - default [part default props] - :else [default-part props])) + (string? x) x + default (cond-> [part default props] + key (with-meta {:key key})) + :else (cond-> [default-part props] + key (with-meta {:key key})))) (defn themed-part [x props & [default]] [x props default]) diff --git a/src/re_demo/nested_grid.cljs b/src/re_demo/nested_grid.cljs index 2d682358..cb1ca7d0 100644 --- a/src/re_demo/nested_grid.cljs +++ b/src/re_demo/nested_grid.cljs @@ -6,7 +6,7 @@ [re-com.theme :as theme] [re-com.nested-grid.util :as ngu] [reagent.core :as r] - [re-com.nested-grid :as grid :refer [nested-grid nested-grid-args-desc nested-grid-parts-desc]] + [re-com.nested-grid :as grid :refer [nested-grid nested-v-grid nested-grid-args-desc nested-grid-parts-desc]] [re-demo.utils :refer [source-reference panel-title title2 title3 args-table parts-table github-hyperlink status-text new-in-version]])) (def arg-style {:style {:display "inline-block" @@ -1061,136 +1061,35 @@ (map (fn [[a b]] (- b a)) (partition 2 1 v)))) (def wx (r/reaction @scroll-left)) -(def ww (r/atom 100)) +(def ww (r/atom 500)) (def wy (r/reaction @scroll-top)) -(def wh (r/atom 100)) +(def wh (r/atom 500)) -(defn new-nested-grid [{:keys [row-tree column-tree]}] - (let [internal-row-tree (r/atom (u/deref-or-value row-tree)) - internal-column-tree (r/atom (u/deref-or-value column-tree)) +(def rhw (r/reaction (repeat 5 (/ @ww 10)))) - row-traversal (r/reaction (ngu/walk-size {:tree @internal-row-tree - :window-start (* 2 @wy) - :window-end (+ (* 2 @wy) @wh)})) - column-traversal (r/reaction (ngu/walk-size {:tree @internal-column-tree - :window-start @wx - :window-end (+ @wx @ww)}))] - (r/create-class - {:component-did-update - #(let [[_ {:keys [row-tree column-tree]}] (r/argv %)] - (reset! internal-row-tree (u/deref-or-value row-tree)) - (reset! internal-column-tree (u/deref-or-value column-tree))) - :reagent-render - (fn [{:keys [row-tree column-tree cell row-header-width column-header-height] - :or {row-header-width 40 - column-header-height 25 - cell (fn [{:keys [row-path column-path]}] - [:div {:style {:border "thin solid grey" - :grid-row-start (ngu/path->grid-line-name row-path) - :grid-column-start (ngu/path->grid-line-name column-path)}}])}}] - (u/deref-or-value row-tree) - (u/deref-or-value column-tree) - (let [{row-depth :depth - row-space :level->space - row-height-total :sum-size - windowed-row-paths :windowed-paths - windowed-row-leaf-paths :windowed-leaf-paths} - @row-traversal - {column-depth :depth - column-space :level->space - column-width-total :sum-size - windowed-column-paths :windowed-paths - windowed-column-leaf-paths :windowed-leaf-paths} - @column-traversal - column-header-heights (repeat column-depth column-header-height) - column-header-height-total (apply + column-header-heights) - row-header-widths (repeat row-depth row-header-width) - row-header-width-total (apply + row-header-widths) - row-tokens (ngu/lazy-grid-tokens @row-traversal) - row-template (ngu/lazy-grid-template row-tokens) - row-spans (ngu/grid-spans row-tokens) - column-tokens (ngu/lazy-grid-tokens @column-traversal) - column-template (ngu/lazy-grid-template column-tokens) - column-spans (ngu/grid-spans column-tokens) - spacer-container [:div {:style {:border "thin solid lightblue"}}] - row-header-container [:div {:style {:display :grid - :grid-template-rows row-template - :grid-template-columns (ngu/grid-template row-header-widths)}}] - row-header-cells (for [path windowed-row-paths] - [:div {:style {:grid-row-start (ngu/path->grid-line-name path) - :grid-row-end (str "span " (get row-spans path)) - :grid-column-start (count path) - :grid-column-end (str "span " (+ 1 (- row-depth (count path)))) - :border-top "thin solid green" - :border-left "thin solid green" - :overflow :hidden - :font-size 8}} - (pr-str path)]) - column-header-container [:div {:style {:display :grid - :grid-template-rows (ngu/grid-template column-header-heights) - :grid-template-columns column-template}}] - column-header-cells (for [path windowed-column-paths] - [:div {:style {:grid-column-start (ngu/path->grid-line-name path) - :grid-column-end (str "span " (get column-spans path)) - :grid-row-start (count path) - :grid-row-end (str "span " (+ 1 (- column-depth (count path)))) - :border-top "thin solid green" - :border-left "thin solid green" - :overflow :hidden - :font-size 8}} - (pr-str path)]) - main-container [:div - {:style {:flex "0 0 auto" - :border "2px solid grey" - :display :grid - :grid-template-rows (ngu/grid-template [column-header-height-total row-height-total]) - :grid-template-columns (ngu/grid-template [row-header-width-total column-width-total])}}] - cell-grid-container [:div {:style {:display :grid - :grid-template-rows row-template - :grid-template-columns column-template}}] - cells (for [row-path windowed-row-leaf-paths - column-path windowed-column-leaf-paths] - (u/part cell {:row-path row-path :column-path column-path}))] - [rc/v-box - :style {:position :relative} - :children - [(conj main-container - spacer-container - (into column-header-container column-header-cells) - (into row-header-container row-header-cells) - (into cell-grid-container cells)) - [:div {:style {:position :absolute - :top (+ (* 2 @wy) column-header-height-total) - :left (+ @wx row-header-width-total) - :width @ww - :height @wh - :border "2px solid red"}}]]]))}))) +(def seqseq (r/atom [1 2 3 4])) -(def row-tree (r/atom ngu/test-tree)) +(defn upd! [] (swap! seqseq + (fn [ss] + (conj (vec (rest ss)) (inc (last ss)))))) (defn panel [] - [rc/h-box :gap "50px" :children [[rc/v-box :children - [[new-nested-grid {:row-tree row-tree - :column-tree [:a [:b 30 :d 40] [:e 30 :g 35] [:h 10 :j] [:k 20]]}] + [[rc/gap :size "50px"] + [nested-v-grid {:row-tree ngu/huge-test-tree + :row-tree-depth 5 + :column-tree-depth 4 + :row-header-widths [10 20 30 40 50] + :column-header-heights [10 20 30 40] + :column-tree ngu/test-tree + :style {:max-height @wh :max-width @ww} + :parts {:wrapper {:style {:height @wh + :width @ww}}}}] "Window width" - [rc/slider {:model ww :on-change (partial reset! ww) :min 50 :max 200}] + [rc/slider {:model ww :on-change (partial reset! ww) :min 200 :max 800}] "Window height" - [rc/slider {:model wh :on-change (partial reset! wh) :min 50 :max 200}]]] - [rc/box - :style {:margin-top 50} - :size "400px" - :child [window-search-test {:tree ngu/test-tree}]] - #_[:<> [linear-search-infinite-scroll-test - {:row-height 25 - :column-width 100 - :max-height "80vh" - :max-width "80vw" - :row-seq row-seq - :column-seq column-seq - :cell test-cell}] - [:div "rows loaded:" @rows-loaded]]]]) + [rc/slider {:model wh :on-change (partial reset! wh) :min 200 :max 800}]]]]])