From 3ff11b25ea62c85b30c0cd2f240a4ef995551420 Mon Sep 17 00:00:00 2001 From: Kimo Knowles Date: Thu, 25 Jul 2024 17:42:19 +0200 Subject: [PATCH] [dropdown] add `:height`, `:body-height` & `:body-width` props --- CHANGELOG.md | 6 ++ src/re_com/dropdown.cljs | 23 ++++- src/re_demo/dropdown.cljs | 99 ++++++++++++------ src/re_demo/tree_select.cljs | 195 +++++++---------------------------- src/re_demo/utils.cljs | 32 +++++- 5 files changed, 160 insertions(+), 195 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0183e17c..90a0e630 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ > Committed but unreleased changes are put here, at the top. Older releases are detailed chronologically below. +## 2.21.14 (2024-07-25) + +#### Added + +- `dropdown` - `:height`, `:body-height` & `:body-width` props + ## 2.21.13 (2024-07-23) #### Added diff --git a/src/re_com/dropdown.cljs b/src/re_com/dropdown.cljs index ad3ccb68..376af86b 100644 --- a/src/re_com/dropdown.cljs +++ b/src/re_com/dropdown.cljs @@ -145,6 +145,16 @@ :required false :type "integer | string" :validate-fn number-or-string?} + {:description "height of the :body-wrapper part" + :name :body-height + :required false + :type "integer | string" + :validate-fn number-or-string?} + {:description "width of the :body-wrapper part" + :name :body-width + :required false + :type "integer | string" + :validate-fn number-or-string?} {:description "height of the :body-wrapper part" :name :height :required false @@ -165,6 +175,11 @@ :required false :type "integer | string" :validate-fn number-or-string?} + {:description "height of the :body-wrapper part" + :name :width + :required false + :type "integer | string" + :validate-fn number-or-string?} {:description "min-width of the :anchor-wrapper and :body-wrapper parts" :name :min-width :required false @@ -311,11 +326,12 @@ (fn dropdown-render [& {:keys [disabled? on-change tab-index direction anchor-height anchor-width + body-height body-width model label placeholder anchor backdrop body body-header body-footer indicator parts theme main-theme theme-vars base-theme - width] + width height] :or {placeholder "Select an item" model default-model direction :toward-center} @@ -349,9 +365,10 @@ :width (or width anchor-width)}) {:part ::anchor-wrapper :exclude [:max-height :min-height]}) - (theme/<-props args + (theme/<-props (merge args {:height (or height body-height) + :width (or width body-width)}) {:part ::body-wrapper - :include [:width :min-width + :include [:width :height :min-width :min-height :max-height]}) (theme/<-props args {:part ::wrapper diff --git a/src/re_demo/dropdown.cljs b/src/re_demo/dropdown.cljs index 1483ea5e..56d3c219 100644 --- a/src/re_demo/dropdown.cljs +++ b/src/re_demo/dropdown.cljs @@ -4,46 +4,77 @@ (:require [re-com.core :refer [at h-box v-box single-dropdown label hyperlink-href p p-span]] [re-com.dropdown :refer [dropdown-parts-desc dropdown-args-desc dropdown]] - [re-demo.utils :refer [panel-title title2 parts-table args-table status-text]] - [reagent.core :as reagent])) + [re-demo.utils :refer [panel-title title2 title3 parts-table args-table status-text prop-slider]] + [re-com.util :refer [px]] + [reagent.core :as r])) -(def model (reagent/atom false)) +(def model (r/atom false)) (defn panel* [] - (fn [] - [v-box :src (at) :size "auto" :gap "10px" - :children - [[panel-title "[dropdown ... ]" - "src/re_com/dropdown.cljs" - "src/re_demo/dropdown.cljs"] - [h-box :src (at) :gap "100px" + (let [width (r/atom 200) + height (r/atom 200) + min-width (r/atom 200) + max-width (r/atom 200) + max-height (r/atom 200) + min-height (r/atom 200) + body-width (r/atom 200) + anchor-width (r/atom 200)] + (fn [] + [v-box :src (at) :size "auto" :gap "10px" :children - [[v-box :src (at) :gap "10px" :width "450px" + [[panel-title "[dropdown ... ]" + "src/re_com/dropdown.cljs" + "src/re_demo/dropdown.cljs"] + [h-box :src (at) :gap "100px" :children - [[title2 "Notes"] - [status-text "Alpha" {:color "red"}] - [p-span "A generic dropdown component. You pass in your own components for " - [:code ":anchor"] " and " [:code ":body"] "."] - [p-span [:code ":dropdown"] " provides: "] - [:ul - [:li "state management (" [:span {:style {:color "red"}} "alpha!"] ") for opening and closing"] - [:li "dynamically positioned container elements"]] - [args-table dropdown-args-desc]]] - [v-box :src (at) :width "700px" :gap "10px" - :children - [[title2 "Demo"] - [dropdown - {:anchor (fn [{:keys [state]}] - [:div "I am " (:openable state) " ;)"]) - #_#_:parts {:backdrop {:style {:background-color "blue"}}} - :body [:div "Hello World!"] - :model model - :min-width "300px" - :max-height "300px" - :min-height "200px" - :on-change #(reset! model %)}]]]]] - [parts-table "dropdown" dropdown-parts-desc]]])) + [[v-box :src (at) :gap "10px" :width "450px" + :children + [[title2 "Notes"] + [status-text "Alpha" {:color "red"}] + [p-span "A generic dropdown component. You pass in your own components for " + [:code ":anchor"] " and " [:code ":body"] "."] + [p-span [:code ":dropdown"] " provides: "] + [:ul + [:li "state management (" [:span {:style {:color "red"}} "alpha!"] ") for opening and closing"] + [:li "dynamically positioned container elements"]] + [args-table dropdown-args-desc]]] + [v-box :src (at) :width "700px" :gap "10px" + :children + [[title2 "Demo"] + [dropdown + {:anchor (fn [{:keys [state]}] + [:div "I am " (:openable state) " ;)"]) + #_#_:parts {:backdrop {:style {:background-color "blue"}}} + :body [:div "Hello World!"] + :model model + :width (some-> @width px) + :height (some-> @height px) + :min-width (some-> @min-width px) + :max-width (some-> @max-width px) + :max-height (some-> @max-height px) + :min-height (some-> @min-height px) + :body-width (some-> @body-width px) + :anchor-width (some-> @anchor-width px) + :on-change #(reset! model %)}] + [v-box :src (at) + :gap "10px" + :style {:min-width "550px" + :padding "15px" + :border-top "1px solid #DDD" + :background-color "#f7f7f7"} + :children [[title3 "Interactive Parameters" {:margin-top "0"}] + [v-box :src (at) + :gap "20px" + :children [[prop-slider {:prop width :id :width :default 212 :default-on? false}] + [prop-slider {:prop height :id :height :default 212 :default-on? false}] + [prop-slider {:prop min-width :id :min-width :default 212 :default-on? false}] + [prop-slider {:prop max-width :id :max-width :default 212 :default-on? false}] + [prop-slider {:prop min-height :id :min-height :default 212 :default-on? false}] + [prop-slider {:prop max-height :id :max-height :default 212 :default-on? false}] + [prop-slider {:prop body-width :id :body-width :default 212 :default-on? false}] + [prop-slider {:prop anchor-width :id :anchor-width :default 212 :default-on? false}]]]]]]]]] + [parts-table "dropdown" dropdown-parts-desc]]]))) ;; core holds a reference to panel, so need one level of indirection to get figwheel updates (defn panel diff --git a/src/re_demo/tree_select.cljs b/src/re_demo/tree_select.cljs index 2e92414a..8781d85d 100644 --- a/src/re_demo/tree_select.cljs +++ b/src/re_demo/tree_select.cljs @@ -6,7 +6,8 @@ [re-com.radio-button :refer [radio-button]] [re-com.slider :refer [slider]] [re-com.tree-select :refer [tree-select-parts-desc tree-select-dropdown-parts-desc tree-select-dropdown-args-desc tree-select-args-desc]] - [re-demo.utils :refer [panel-title title2 title3 parts-table args-table status-text new-in-version]])) + [re-demo.utils :refer [panel-title title2 title3 parts-table args-table status-text new-in-version prop-slider]] + [re-com.util :refer [px]])) (def cities [{:id :sydney :label "Sydney" :group [:oceania :australia :nsw]} {:id :newcastle :label "Newcastle" :group [:oceania :australia :nsw]} @@ -32,42 +33,36 @@ label-fn (reagent/atom nil) group-label-fn (reagent/atom nil) choice-disabled-fn (reagent/atom nil) - width? (reagent/atom nil) width (reagent/atom 212) - min-width? (reagent/atom true) min-width (reagent/atom 200) - max-width? (reagent/atom true) max-width (reagent/atom 300) - min-height? (reagent/atom true) min-height (reagent/atom 100) - max-height? (reagent/atom true) max-height (reagent/atom 350) - anchor-width? (reagent/atom nil) anchor-width (reagent/atom 212) - tree-select* (fn [& {:as props}] - [tree-select - (-> - {:src (at) - :width (when @width? (str @width "px")) - :min-width (when @min-width? (str @min-width "px")) - :max-width (when @max-width? (str @max-width "px")) - :min-height (when @min-height? (str @min-height "px")) - :max-height (when @max-height? (str @max-height "px")) - :attr {:key (gensym)} - :disabled? disabled? - :label-fn @label-fn - :group-label-fn @group-label-fn - :choice-disabled-fn @choice-disabled-fn - :choices cities - :model model - :expanded-groups groups - :on-change #(reset! model %1)} - (merge props))]) - open-to-chosen (fn [] [tree-select* {:initial-expanded-groups :chosen}]) - open-to-nil (fn [] [tree-select*]) - open-to-all (fn [] [tree-select* {:initial-expanded-groups :all}]) - open-to-none (fn [] [tree-select* {:initial-expanded-groups :none}]) - open-to-specified (fn [] [tree-select* {:initial-expanded-groups #{[:oceania] [:oceania :new-zealand]}}])] + tree-select* (fn [& {:as props}] + [tree-select + (-> + {:src (at) + :width (some-> @width px) + :min-width (some-> @min-width px) + :max-width (some-> @max-width px) + :min-height (some-> @min-height px) + :max-height (some-> @max-height px) + :attr {:key (gensym)} + :disabled? disabled? + :label-fn @label-fn + :group-label-fn @group-label-fn + :choice-disabled-fn @choice-disabled-fn + :choices cities + :model model + :expanded-groups groups + :on-change #(reset! model %1)} + (merge props))]) + open-to-chosen (fn [] [tree-select* {:initial-expanded-groups :chosen}]) + open-to-nil (fn [] [tree-select*]) + open-to-all (fn [] [tree-select* {:initial-expanded-groups :all}]) + open-to-none (fn [] [tree-select* {:initial-expanded-groups :none}]) + open-to-specified (fn [] [tree-select* {:initial-expanded-groups #{[:oceania] [:oceania :new-zealand]}}])] (fn [] [v-box :src (at) :gap "11px" @@ -86,12 +81,12 @@ [label :src (at) :label "[tree-select-dropdown ... ]"] [gap :src (at) :size "5px"] [tree-select-dropdown - {:width (when @width? (str @width "px")) - :min-width (when @min-width? (str @min-width "px")) - :max-width (when @max-width? (str @max-width "px")) - :min-height (when @min-height? (str @min-height "px")) - :max-height (when @max-height? (str @max-height "px")) - :anchor-width (when @anchor-width? (str @anchor-width "px")) + {:width (some-> @width px) + :min-width (some-> @min-width px) + :max-width (some-> @max-width px) + :min-height (some-> @min-height px) + :max-height (some-> @max-height px) + :anchor-width (some-> @anchor-width px) :disabled? disabled? :show-reset-button? @show-reset-button? :label-fn @label-fn @@ -195,126 +190,12 @@ :on-change (fn [] (swap! choice-disabled-fn (fn [x] (if x nil #(contains? (set (:group %)) :australia)))))]]] - [h-box :src (at) - :align :center - :children [[checkbox :src (at) - :label [box :src (at) - :align :start - :child [:code ":min-width"]] - :model min-width? - :on-change #(reset! min-width? %)] - [gap :src (at) :size "5px"] - (when @min-width? - [:<> - [slider - :model min-width - :on-change #(reset! min-width %) - :min 50 - :max 400 - :step 1 - :width "300px"] - [gap :src (at) :size "5px"] - [label :src (at) :label (str @min-width "px")]])]] - [h-box :src (at) - :align :center - :children [[checkbox :src (at) - :label [box :src (at) - :align :start - :child [:code ":max-width"]] - :model max-width? - :on-change #(reset! max-width? %)] - [gap :src (at) :size "5px"] - (when @max-width? - [:<> - [slider - :model max-width - :on-change #(reset! max-width %) - :min 50 - :max 400 - :step 1 - :width "300px"] - [gap :src (at) :size "5px"] - [label :src (at) :label (str @max-width "px")]])]] - [h-box :src (at) - :align :center - :children [[checkbox :src (at) - :label [box :src (at) - :align :start - :child [:code ":min-height"]] - :model min-height? - :on-change #(reset! min-height? %)] - [gap :src (at) :size "5px"] - (when @min-height? - [:<> - [slider - :model min-height - :on-change #(reset! min-height %) - :min 50 - :max 400 - :step 1 - :width "300px"] - [gap :src (at) :size "5px"] - [label :src (at) :label (str @min-height "px")]])]] - [h-box :src (at) - :align :center - :children [[checkbox :src (at) - :label [box :src (at) - :align :start - :child [:code ":max-height"]] - :model max-height? - :on-change #(reset! max-height? %)] - [gap :src (at) :size "5px"] - (when @max-height? - [:<> - [slider - :model max-height - :on-change #(reset! max-height %) - :min 50 - :max 400 - :step 1 - :width "300px"] - [gap :src (at) :size "5px"] - [label :src (at) :label (str @max-height "px")]])]] - [h-box :src (at) - :align :center - :children [[checkbox :src (at) - :label [box :src (at) - :align :start - :child [:code ":anchor-width"]] - :model anchor-width? - :on-change #(reset! anchor-width? %)] - [gap :src (at) :size "5px"] - (when @anchor-width? - [:<> - [slider - :model anchor-width - :on-change #(reset! anchor-width %) - :min 50 - :max 400 - :step 1 - :width "300px"] - [gap :src (at) :size "5px"] - [label :src (at) :label (str @anchor-width "px")]])]] - [h-box :src (at) - :align :center - :children [[checkbox :src (at) - :label [box :src (at) - :align :start - :child [:code ":width"]] - :model width? - :on-change #(reset! width? %)] - [gap :src (at) :size "5px"] - (when @width? - [:<> - [slider - :model width - :on-change #(reset! width %) - :min 50 - :max 400 - :step 1 - :width "300px"] - [gap :src (at) :size "5px"] - [label :src (at) :label (str @width "px")]])]]]]]] + [prop-slider {:prop width :id :width :default 212 :default-on? false}] + [prop-slider {:prop min-width :id :min-width :default 212 :default-on? false}] + [prop-slider {:prop max-width :id :max-width :default 212 :default-on? false}] + [prop-slider {:prop min-height :id :min-height :default 212 :default-on? false}] + [prop-slider {:prop max-height :id :max-height :default 212 :default-on? false}] + [prop-slider {:prop anchor-width :id :anchor-width :default 212 :default-on? false}]]]]] [gap :src (at) :size "10px"]]]))) (defn panel [] diff --git a/src/re_demo/utils.cljs b/src/re_demo/utils.cljs index 4e2bf5e2..857c1b1e 100644 --- a/src/re_demo/utils.cljs +++ b/src/re_demo/utils.cljs @@ -1,6 +1,6 @@ (ns re-demo.utils (:require - [re-com.core :refer [title line label hyperlink-href align-style at]] + [re-com.core :as rc :refer [title line label hyperlink-href align-style at]] [re-com.box :refer [box gap h-box v-box]] [re-com.text :refer [p]] [re-com.util :refer [px]])) @@ -215,3 +215,33 @@ (defn scroll-to-top [element] (set! (.-scrollTop element) 0)) + +(defn prop-slider [{:keys [prop default default-on? id] :or {default-on? true}}] + (let [default (or @prop default)] + (when (and default-on? default) + (reset! prop default)) + (when-not default-on? + (reset! prop nil)) + (fn [{:keys [prop default]}] + [h-box :src (at) + :align :center + :children [[rc/checkbox :src (at) + :label [box :src (at) + :align :start + :child [:code id]] + :model (some? @prop) + :on-change (if @prop + #(reset! prop nil) + #(reset! prop default))] + [gap :src (at) :size "5px"] + (when @prop + [:<> + [rc/slider + :model prop + :on-change #(reset! prop %) + :min 50 + :max 400 + :step 1 + :width "300px"] + [gap :src (at) :size "5px"] + [label :src (at) :label (str @prop "px")]])]])))