Created
August 29, 2022 15:25
-
-
Save Ivana-/5f3f01fe50d3887808001cf8c95d989f to your computer and use it in GitHub Desktop.
Toast cljs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; toast ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
(defn- create-element-from-hiccup [hiccup-data] | |
(let [tmp (.createElement js/document "div") | |
content (rds/render-to-static-markup hiccup-data)] | |
(aset tmp "innerHTML" content) | |
(.-firstChild tmp))) | |
(defn- get-create-toast-container [] | |
(let [container-id "ivana_toast_container"] | |
(or (.getElementById js/document container-id) | |
(let [container (create-element-from-hiccup | |
[:div {:id container-id | |
:style {:position :fixed | |
:top 0 | |
:right 0 | |
:left 0 | |
:bottom 0 | |
:margin :auto | |
:width "40%" | |
;; :min-height "40%" | |
:height :fit-content | |
:z-index 10 ;; 1 | |
:pointer-events :none | |
:display :flex | |
:flex-direction :column ;; :column-reverse | |
:justify-content :center | |
;; :border "3px solid red" | |
}}])] | |
(.appendChild (.-body js/document) container) | |
container)))) | |
(defn- toast-animate-show [elem] | |
(doto (.-style elem) | |
(aset "opacity" 1) | |
(aset "height" "4rem"))) | |
(defn- toast-animate-hide [elem] | |
(doto (.-style elem) | |
(aset "opacity" 0) | |
(aset "height" 0))) | |
(defn toast [{:keys [content timeout status]}] | |
(let [container (get-create-toast-container) | |
transition-time-ms (js/Math.floor (/ timeout 4)) | |
transition-time-ms (min 500 transition-time-ms) | |
toast-elem (create-element-from-hiccup | |
[:div {:style {:margin-bottom "4px" | |
:padding-left "20px" | |
:padding-right "20px" | |
:border-radius "10px" | |
:background-color (get {:info "#b3ffb3" | |
:error "#f6cdcd"} | |
(or status :info)) | |
:overflow :hidden | |
:display :flex | |
:flex-direction :column | |
:justify-content :center | |
;; values to transform | |
:opacity 0 | |
:height 0 | |
:-webkit-transition (str "all " transition-time-ms "ms ease-in") | |
;; :transition "opacity .5s" ;; linear" | |
}} | |
content])] | |
;; allow 5 toasts max at one time | |
(when (< 5 (or (.-childElementCount container) 0)) | |
(when-let [first-elem (.-firstChild container)] | |
;; (.remove first-elem) not remove immediatelly, but after toast-animate-hide | |
(toast-animate-hide first-elem) | |
(js/setTimeout #(.remove toast-elem) transition-time-ms))) | |
(.appendChild container toast-elem) | |
;; (.prepend container toast-elem) ;; for top-to-bottom scroll | |
;; https://stackoverflow.com/questions/24148403/trigger-css-transition-on-appended-element | |
(.getBoundingClientRect toast-elem) | |
(toast-animate-show toast-elem) | |
(js/setTimeout #(toast-animate-hide toast-elem) (- timeout transition-time-ms)) ;; transition back right before element deleting | |
(js/setTimeout #(.remove toast-elem) timeout))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment