Skip to content

Instantly share code, notes, and snippets.

@ajchemist
Forked from martinklepsch/reagent-autoscroll.cljs
Created December 14, 2018 06:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ajchemist/1d353ed713ee1db9845b383dea798d41 to your computer and use it in GitHub Desktop.
Save ajchemist/1d353ed713ee1db9845b383dea798d41 to your computer and use it in GitHub Desktop.
;; Auto-scrolling ==============================================================
(defn scroll! [el start end time]
(.play (goog.fx.dom.Scroll. el (clj->js start) (clj->js end) time)))
(defn scrolled-to-end? [el tolerance]
;; at-end?: element.scrollHeight - element.scrollTop === element.clientHeight
(> tolerance (- (.-scrollHeight el) (.-scrollTop el) (.-clientHeight el))))
(defn autoscroll-list [{:keys [children class scroll?] :as opts}]
(let [should-scroll (reagent/atom true)]
(reagent/create-class
{:display-name "autoscroll-list"
:component-did-mount
(fn [this]
(let [n (reagent/dom-node this)]
(scroll! n [0 (.-scrollTop n)] [0 (.-scrollHeight n)] 0)))
:component-will-update
(fn [this]
(let [n (reagent/dom-node this)]
;; (pp/pprint {:scrollheight (.-scrollHeight n)
;; :scrolltop (.-scrollTop n)
;; :clientHeight (.-clientHeight n)
;; :to-scroll (- (.-scrollHeight n) (.-scrollTop n))
;; :scrolled [(- (.-scrollHeight n) (.-scrollTop n)) (.-clientHeight n)]})
(reset! should-scroll (scrolled-to-end? n 100))))
:component-did-update
(fn [this]
(let [scroll? (:scroll? (reagent/props this))
n (reagent/dom-node this)]
(when (and scroll? @should-scroll)
(scroll! n [0 (.-scrollTop n)] [0 (.-scrollHeight n)] 600))))
:reagent-render
;; When getting next and prev props here it would be possible to detect if children have changed
;; and to disable scrollbars for the duration of the scroll animation
(fn [{:keys [children]}]
(into [:div {:class class}] children))})))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment