🐛 Fix dropdown being cut off

This commit is contained in:
Aitor 2024-02-09 15:33:13 +01:00 committed by Alonso Torres
parent 08c8b938ae
commit b9b66aee85
3 changed files with 33 additions and 1 deletions

View file

@ -15,6 +15,7 @@
[app.util.dom :as dom]
[rumext.v2 :as mf]))
(defn- as-key-value
[item]
(if (map? item)
@ -37,6 +38,10 @@
current-label (get label-index current-value)
is-open? (:is-open? state)
dropdown-element* (mf/use-ref nil)
dropdown-direction* (mf/use-state "down")
dropdown-direction-change* (mf/use-ref 0)
open-dropdown
(mf/use-fn
(mf/deps disabled)
@ -81,6 +86,13 @@
(mf/with-effect [default-value]
(swap! state* assoc :current-value default-value))
(mf/with-effect [is-open? dropdown-element*]
(let [dropdown-element (mf/ref-val dropdown-element*)]
(when (and (= 0 (mf/ref-val dropdown-direction-change*)) dropdown-element)
(let [is-outside? (dom/is-element-outside? dropdown-element)]
(reset! dropdown-direction* (if is-outside? "up" "down"))
(mf/set-ref-val! dropdown-direction-change* (inc (mf/ref-val dropdown-direction-change*)))))))
(let [selected-option (first (filter #(= (:value %) default-value) options))
current-icon (:icon selected-option)
current-icon-ref (i/key->icon current-icon)]
@ -93,7 +105,7 @@
[:span {:class (stl/css :current-label)} current-label]
[:span {:class (stl/css :dropdown-button)} i/arrow-refactor]
[:& dropdown {:show is-open? :on-close close-dropdown}
[:ul {:class (dm/str dropdown-class " " (stl/css :custom-select-dropdown))}
[:ul {:ref dropdown-element* :data-direction @dropdown-direction* :class (dm/str dropdown-class " " (stl/css :custom-select-dropdown))}
(for [[index item] (d/enumerate options)]
(if (= :separator item)
[:li {:class (dom/classnames (stl/css :separator) true)

View file

@ -51,6 +51,12 @@
border-top: $s-1 solid var(--dropdown-separator-color);
}
}
.custom-select-dropdown[data-direction="up"] {
bottom: $s-32;
top: auto;
}
.checked-element {
@extend .dropdown-element-base;
.icon {

View file

@ -24,6 +24,7 @@
cljs.core/IDeref
(-deref [it] (.getBrowserEvent it)))
(declare get-window-size)
(defn browser-event?
[o]
@ -411,6 +412,19 @@
:width (.-width ^js rect)
:height (.-height ^js rect)}))
(defn is-bounding-rect-outside?
[rect]
(let [{:keys [left top right bottom]} rect
{:keys [width height]} (get-window-size)]
(or (< left 0)
(< top 0)
(> right width)
(> bottom height))))
(defn is-element-outside?
[element]
(is-bounding-rect-outside? (get-bounding-rect element)))
(defn bounding-rect->rect
[rect]
(when (some? rect)