Browse Source

fix: whiteboard ref dropdown not showing issue

Peng Xiao 3 years ago
parent
commit
5f8385b098
3 changed files with 38 additions and 32 deletions
  1. 17 15
      src/main/frontend/components/whiteboard.cljs
  2. 3 2
      src/main/frontend/ui.cljs
  3. 18 15
      src/main/frontend/util.cljc

+ 17 - 15
src/main/frontend/components/whiteboard.cljs

@@ -43,24 +43,27 @@
 
 (rum/defc dropdown
   [label children show? outside-click-hander]
-  (let [anchor-ref (rum/use-ref nil)
-        content-ref (rum/use-ref nil)
-        rect (util/use-component-size (when show? anchor-ref))
-        _ (util/use-click-outside content-ref outside-click-hander)
+  (let [[anchor-ref anchor-rect] (util/use-component-size)
+        [content-ref content-rect] (util/use-component-size)
+        offset-x (when (and anchor-rect content-rect)
+                   (+ (* 0.5 (- (.-width anchor-rect) (.-width content-rect)))
+                      (.-x anchor-rect)))
+        offset-y (when (and anchor-rect content-rect)
+                   (+ (.-y anchor-rect) (.-height anchor-rect) 8))
+        click-outside-ref (util/use-click-outside outside-click-hander)
         [d-open set-d-open] (rum/use-state false)
         _ (rum/use-effect! (fn [] (js/setTimeout #(set-d-open show?) 100))
                            [show?])]
     [:div.dropdown-anchor {:ref anchor-ref}
      label
-     (when (and rect show? (> (.-y rect) 0))
-       (ui/portal
-        [:div.fixed.shadow-lg.color-level.px-2.rounded-lg.transition
-         {:ref content-ref
-          :style {:opacity (if d-open 1 0)
-                  :width "240px"
-                  :min-height "40px"
-                  :left (+ (* 0.5 (.-width rect)) (.-x rect) -120)
-                  :top (+ (.-y rect) (.-height rect) 8)}} children]))]))
+     (ui/portal
+      [:div.fixed.shadow-lg.color-level.px-2.rounded-lg.transition.md:w-64.lg:w-128
+       {:ref (juxt content-ref click-outside-ref)
+        :style {:opacity (if d-open 1 0)
+                :transform (str "translateY(" (if d-open 0 10) "px)")
+                :min-height "40px"
+                :left offset-x
+                :top offset-y}} children])]))
 
 (rum/defc page-refs-count < rum/static
   ([page-name classname]
@@ -162,8 +165,7 @@
                            (sort-by :block/updated-at)
                            reverse)
           whiteboard-names (map :block/name whiteboards)
-          ref (rum/use-ref nil)
-          rect (util/use-component-size ref)
+          [ref rect] (util/use-component-size)
           [container-width] (when rect [(.-width rect) (.-height rect)])
           cols (cond (< container-width 600) 1
                      (< container-width 900) 2

+ 3 - 2
src/main/frontend/ui.cljs

@@ -1046,8 +1046,9 @@
 
 (rum/defc portal
   ([children]
-   (portal children #(js/document.createElement "div") false))
-  ([children attach-to prepend?]
+   (portal children {:attach-to (fn [] js/document.body)
+                     :prepend? false}))
+  ([children {:keys [attach-to prepend?]}]
    (let [[portal-anchor set-portal-anchor] (rum/use-state nil)]
      (rum/use-effect!
       (fn []

+ 18 - 15
src/main/frontend/util.cljc

@@ -1404,31 +1404,34 @@
 
 #?(:cljs
    (defn use-component-size
-     [ref]
-     (let [[rect set-rect] (rum/use-state nil)]
+     []
+     (let [[ref set-ref] (rum/use-state nil)
+           [rect set-rect] (rum/use-state nil)]
        (rum/use-effect!
         (if ref
           (fn []
-            (let [update-rect #(set-rect (when (.-current ref) (.. ref -current getBoundingClientRect)))
+            (let [update-rect #(set-rect (. ref getBoundingClientRect))
                   updator (fn [entries]
                             (when (.-contentRect (first (js->clj entries))) (update-rect)))
                   observer (js/ResizeObserver. updator)]
               (update-rect)
-              (.observe observer (.-current ref))
+              (.observe observer ref)
               #(.disconnect observer)))
           #())
         [ref])
-       rect)))
+       [set-ref rect])))
 
 #?(:cljs
    (defn use-click-outside
-     [ref handler]
-     (rum/use-effect!
-      (fn []
-        (let [listener (fn [e]
-                         (when (and (.-current ref)
-                                    (not (.. ref -current (contains (.-target e))) ))
-                           (handler e)))]
-           (js/document.addEventListener "click" listener)
-           #(.removeEventListener js/document "click" listener)))
-      [ref])))
+     [handler]
+     (let [[ref set-ref] (rum/use-state nil)]
+       (rum/use-effect!
+        (fn []
+          (let [listener (fn [e]
+                           (when (and ref
+                                      (not (.. ref (contains (.-target e)))))
+                             (handler e)))]
+            (js/document.addEventListener "click" listener)
+            #(.removeEventListener js/document "click" listener)))
+        [ref])
+       set-ref)))