Fork me on GitHub
#reagent
<
2020-05-27
>
Spaceman03:05:29

How does one add an animation upon an element entering the dom?  like the

ReactCSSTransitionGroup
in react?

Lucy Wang11:05:44

Why not just use ReactCSSTransitionGroup then? Or you can simply call setTimeout in some hooks to add a new class to the component node (obtained from useRef) and define transitions rules on the new class

ouvasam09:05:01

framer motion is easy to use and very powerful

ouvasam09:05:05

(ns app.motion
    (:require
     [framer-motion :refer (motion MagicMotion  AnimateSharedLayout AnimatePresence useSpring useMotionValue useTransform useViewportScroll) :as motion]
     [cljs-bean.core :refer [bean ->clj ->js]]))

  (def div
    (.-div motion))

  (def span
    (.-span motion))

  (def li
    (.-li motion))

  (def img
    (.-img motion))

  (def button
    (.-button motion))

  (def input
    (.-input motion))

  (def textarea
    (.-textarea motion))

  (def label
    (.-label motion))

  (def transform #(motion/transform (->js %1) (->js %2) (->js %3)))
  (def animate-presence AnimatePresence)

ouvasam09:05:46

(defn my-component
  []
  [:> motion/animate-presence
   [:> motion/div
     {:key :my-component
       :class [:my-component (<class styles/my-component)]
       :variants {:initial {:opacity 0}
                  :animate {:opacity 1}
                  :exit {:opacity 0}}
       :initial :initial
       :animate :animate
       :exit :exit}
    "My component"]])

ouvasam09:05:01

You could do some amazing animations with it

Spaceman14:05:41

@U0F7M1KA7 that gives me

--------------------------------------------------------------------------------
  12 |     [:> motion/animate-presence
  13 |      [:> motion/div
  14 |       {:key :my-component
  15 |        :class [:my-component (<class styles/my-component)]
-------------------------------------^------------------------------------------
 Use of undeclared Var vendo.cart/<class
--------------------------------------------------------------------------------
  16 |        :variants {:initial {:opacity 0}
  17 |                   :animate {:opacity 1}
  18 |                   :exit {:opacity 0}}
  19 |        :initial :initial
-----------------------------------------------------------------------

ouvasam14:05:36

Yes you can remove (<class ...)

ouvasam14:05:18

It is roosta/herb

Spaceman14:05:11

I have the following now:

[:> motion/animate-presence
     [:> motion/div
      {:key :my-component
       :class [:my-component]
       :variants {:initial {:opacity 0}
                  :animate {:opacity 1}
                  :exit {:opacity 0}}
       :initial :initial
       :animate :animate
       :exit :exit}
      "My component"]]
And that gives in the console: react-dom.development.js:24037 Uncaught Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports. Check the render method of vendo.cart.cart`.` at createFiberFromTypeAndProps () at createFiberFromElement () at eval () at reconcileChildren () at finishClassComponent () at updateClassComponent () at beginWork$1 () at HTMLUnknownElement.callCallback () at Object.invokeGuardedCallbackImpl () at invokeGuardedCallback ()

Spaceman14:05:14

why would that be?

Spaceman14:05:30

would you please share a self-contained, working example?

ouvasam07:05:18

Do you use shadow-cljs ?

ouvasam08:05:36

This should work with it If you use it i'll send a self-contained example

Spaceman23:05:10

Yeah, for some reason, the :>div doesn't mount when I click the button, but only when I focus/refocus on the browser or click somewhere on the page.

Spaceman23:05:15

here's the code:

(def div (.-div motion))
[:> div
     {
      :initial {:opacity 0}
      :animate {:opacity 1}
      :exit {:opacity 0}}
     [:div "Show Me"]]

Spaceman23:05:43

also, wrapping the :>div with :>animate-presence (similarly defined), didn't change there result

ouvasam13:06:21

Hi @U010Z4Y1J4Q sorry i was off

ouvasam13:06:49

Here a sample of code that works and show how to. use animate-presence

(defn my-comp
  []
  (r/with-let
   [clicked (r/atom false)]
   [:<>
    [:div {:on-click #(swap! clicked not)}
     "click me"]
    [:> motion/animate-presence
     (if @clicked
       [:> motion/div
        {:key :my-comp
         :class [:my-comp]
         :variants {:initial {:opacity 0
                              :y 100
                              :x 0
                              :scale 1}
                    :animate {:opacity 1
                              :y 0
                              :scale 1}
                    :exit {:opacity 0
                           :x 100
                           :scale 0.2}}
         :initial :initial
         :animate :animate
         :exit :exit}
        "my-comp"])]]))

ouvasam13:06:23

The key part is important and should be. different for each componentthat use motion

ouvasam13:06:11

Here is the same example without if and with a different key based on an atom

ouvasam13:06:32

(defn my-comp
  []
  (r/with-let
   [clicked (r/atom false)]
   [:<>
    [:div {:on-click #(swap! clicked not)}
     "click me"]
    [:> motion/animate-presence
     [:> motion/div
      {:key (str :my-comp @clicked)
       :class [:my-comp]
       :variants {:initial {:opacity 0
                            :y 100
                            :x 0
                            :scale 1}
                  :animate {:opacity 1
                            :y 0
                            :scale 1}
                  :exit {:opacity 0
                         :x 100
                         :scale 0.2}}
       :initial :initial
       :animate :animate
       :exit :exit}
      (str "my-comp" @clicked)]]]))

ouvasam13:06:50

r/with-let is reagent/with-let