Skip to content

Releases: nandorojo/moti

0.23.6

15 Feb 22:10
Compare
Choose a tag to compare

Bug Fixes

  • Fix MotiPressable detecting hover on Web without an SWC or Babel plugin.

0.23.4

14 Feb 16:37
Compare
Choose a tag to compare

Bug Fixes

  • Fix motifySvg type issues from #262 #264

0.23: SVG (+ more) 🎨

09 Feb 20:26
Compare
Choose a tag to compare

Fixes

  • MotiPressable on iOS should now have more consistent behavior. Moti no longer uses React Native Gesture Handler's TouchableWithoutFeedback, instead opting for Pressable.

SVG Support

Moti now has a first-class integration with react-native-svg, making cross-platform, performant SVG animations easier than ever.

import { motifySvg } from 'moti/svg'

A higher-order component that turns any React Native SVG component into an animated moti component. It's the same as motify, but for SVG elements.

import { motifySvg } from 'moti/svg'
import { Svg, Rect } from 'react-native-svg'

const MotiRect = motifySvg(Rect)()

You can now pass any SVG props to the animate property, and they will animate there:

<MotiRect
  animate={{
    // height sequence animation
    height: [50, 100],
    x: visible ? 0 : 10,
  }}
  transition={{
    // default all to timing
    type: 'timing',
    x: {
      // override the transition for x
    },
  }}
/>

This functionality compatible with all Moti features, including exit transitions & hooks like useDynamicAnimation:

import { Rect } from 'react-native-svg'
import { motifySvg } from 'moti/svg'
import { useDynamicAnimation } from 'moti'

const MotiRect = motifySvg(Rect)()

export default function App() {
  const animation = useDynamicAnimation<ComponentProps<typeof Rect>>(() => ({
    x: 0,
  }))

  return <MotiRect state={animation} />
}

0.22: Hermes Support 🏛️

20 Jan 23:30
Compare
Choose a tag to compare
yarn add moti

This version adds support for Hermes. It was long a mystery why this didn't work properly. (Read #214)

I suspected incrementing framer-motion's version was the cause. Its use of Proxy could complicate things with Hermes. But adding a resolution to older versions didn't help.

I diff'd the last version of Moti that worked with Hermes (0.17) with the first one that didn't (0.18) and spent hours comparing them line-by-line. To my surprise, the issue didn't lie in a lockfile – rather, it was the syntax of a for loop.

Changing for (const key in styles) to Object.keys(styles).forEach(key fixed it.

I have no idea why the former syntax didn't work properly. It didn't throw any sort of error. But it subtly resulted in useAnimatedStyle's worklet going stale after the first render.

You can see the one line-ish PR here at #253.

- for (const key in exitStyle || {}) {
+ Object.keys(exitStyle || {}).forEach((key) => {

Happy Friday night 🕺

v0.21.0

14 Nov 21:04
af8316f
Compare
Choose a tag to compare
yarn add moti

Resolves the question posed at #221 (comment)

Transitions per-variant

const state = useAnimationState({
  from: { scale: 0.5 },
  to: { scale: 1, transition: { type: 'timing' } },
  open: { scale: 0.7, transition: { delay: 300 } }
})

return <MotiView state={state} transition={{ delay: 50 }} />

Dynamic transitions

Same goes for useDynamicAnimation:

const state = useDynamicAnimation(() => ({ scale: 0.5 }))

const onPress = () => {
  state.animateTo({ scale: 1, transition: { delay: 300 } })
}

return <MotiView state={state} transition={{ delay: 50 }} />

v19

29 Jul 14:34
a976caf
Compare
Choose a tag to compare
v19

Overview

  • 🌲 Add Reanimated 3.0 tree shaking support for Web, reducing bundle size by 80%.
  • 👨🏻‍🔧 Fix sequences #195, #200
  • 🩻 Add Skeleton.Group component
  • ☯️ Improve skeleton memoization deep comparison
  • ✂️ Remove @motify/ packages
  • 🤖 Add option to pass worklet function to exitTransition, allowing for use of AnimatePresence's custom prop in exitTransition (closing #193)

Track the PR here: #216

Docs

Install

yarn add moti

Breaking Changes

  • @motify/ packages have been removed, greatly simplifying installation, types, maintenance, and Expo snack support.
    • This change should take you under a minute to update.
    • Next.js users: remove @motify/ entries from transpile modules next.config.js. You should only have moti there now.
    • Expo Web users: remove @motify/ from webpack.config.js. You should only have moti there now.
    • If your app accidentally imported from @motify/components somewhere, please change these imports to come from moti instead.
      • command + shift + F on VSCode, and search @motify
  • MotiPressable's containerStyle was changed to not apply to the container in #152. This broke styling on iOS like flex and position: 'absolute'. In 0.19, containerStyle is changed back to its original behavior from 0.17. If you need Android shadow styles on MotiPressable, use style instead of containerStyle.
    • It's likely this didn't affect you, but to be sure, I recommend searching all of your uses of containerStyle on MotiPressable and make sure it works after the update as expected.

Components

<Skeleton.Group />

If you have many skeleton components, you can now wrap them with a single <Skeleton.Group show={loading} /> component. This will help you achieve this type of effect.

0.18

25 Mar 19:11
Compare
Choose a tag to compare

yarn add moti

Fixes

  • Fix MotiPressable on Android, closing #179 #143

Features

  • Performance improvements with faster for-loops
  • Pass shared values & derived values from reanimated directly to the animate prop
  • Integration with React Native Gesture Handler using the animate function prop
  • Pass function child to MotiPressable
  • 🍿 Finally! VSCode Autoimport support for moti/skeleton and moti/interactions

animate prop as derived value

✅ This feature is working! You can pass the result of useDerivedValue.

const x = useSharedValue(0)

return (
  <MotiView
    animate={useDerivedValue(() => {
      return { translateX: x.value }
    })}
  />
)

This also works for transition and exitTransition:

const x = useSharedValue(0)

return (
  <MotiView
    transition={useDerivedValue(() => {
      return { type: x.value > 0 ? 'timing' : 'spring' }
    })}
  />
)

Breaking Changes

There are zero breaking changes in Moti 0.18.

In the next version, the already-deprecated @motify/skeleton will be removed in favor of moti/skeleton. The same goes for @motify/interactionsmoti/interactions.

In the next release, @motify/components and @motify/core will be deprecated, so if you import from those (which you shouldn't anyway), please change those imports to come from moti directly.

Future ideas

(Coming Soon) animate prop factory function

This next feature doesn't work yet, due to a limitation from Reanimated. I opened an issue here: software-mansion/react-native-reanimated#3123. Subscribe to #185 to find out when it's available. In the meantime, you can use a derived value instead of a plain factory function.

In addition to a plain object, you can pass a function to the animate prop. As long as it has worklet at the top of the function, you can now use any shared/derived values inside of the animate prop!

These values will automatically animate for you, so you don't need to use withTiming or import any hooks like useAnimatedStyle.

const x = useSharedValue(0)

return (
  <MotiView
    animate={() => {
      'worklet'

      return { translateX: x.value }
    }}
  />
)

This will work with React Native Gesture Handler gestures too!

(Coming Soon) Pass function child to MotiPressable

This next feature doesn't work yet, due to a limitation from Reanimated. I opened an issue here: software-mansion/react-native-reanimated#3123. Subscribe to #185 to find out when it's available.

As a consequence of the animate function supporting a worklet, I added a function as children of MotiPressable. This looks a lot like the Pressable from react-native. As long as you read interaction.value inside of the animate worklet, it will update responsively.

Notice here that we aren't importing any hooks 😎

<MotiPressable>
  {(interaction) => {
    return (
      <MotiView
        animate={() => {
          'worklet'

          const { pressed, hovered } = interaction.value

          return { opacity: pressed ? 0.9 : 1 }
        }}
      />
    )
  }}
</MotiPressable>

v0.17.1

15 Dec 23:53
Compare
Choose a tag to compare

0.17.1 (2021-12-15)

Features

  • 🚀 Add support for layout, entering & exiting props from reanimated (1d09705)

v0.17.0

15 Dec 23:09
Compare
Choose a tag to compare

0.17.0 (2021-12-15)

Additions

  • 🚀 Reanimated 2.3 support (+ layout animations)
  • 🎸 Expo SDK 44 support
  • ☝️ (Breaking change) Unified all moti packages into a single install (moti, moti/skeleton, moti/interactions)
  • 🕺 Add support for multiple transforms, without needing a transform array
  • 🤳🏽 Export MotiHover and useMotiHover() from moti/interactions to let library authors build their own hoverables

See the small breaking change at the bottom.

Bug Fixes

  • TypeScript type fixes (8586b26)
  • Dependencies (2495f64)
  • Expo SDK 44 Example (35be5a9)
  • Make hovered become false when you open a modal (aae7e16)

Features

  • Add decay support (be6618e)
  • Document the addition of dependency arrays for hooks #120 (96c01ec)
  • Add onFocus and onBlur to MotiPressable (a3ec203)
  • Add onContainerLayout & onLayout (b77bf3f)
  • Move skeleton into moti/skeleton (dab7a4f)
  • Pass accessibility props to MotiPressable (38e7ca8)
  • Pass worklet to MotiPressable transition prop (acf1981)

Breaking Changes

@motify/interactions and @motify/skeleton have been moved to moti/interactions and moti/skeleton respectively.

Please uninstall those packages if you have them, and upgrade moti.

yarn remove @motify/interactions @motify/skeleton
yarn add moti

Next, update your imports:

@motify/interactionsmoti/interactions
@motify/skeletonmoti/skeleton

If you're on VSCode, you can click command + shift + F and then find/replace all instances of from '@motify/interactions'.

Why?

From now on, you only need to install moti, and you get the skeleton and interactions packages alongside it. This greatly simplifies versioning and lets you more easily upgrade moti. It's inspired by the way Next.js uses next/link, next/router, etc.

View the PR.

v0.16.1

03 Nov 18:09
Compare
Choose a tag to compare

0.16.1 (2021-11-03)

  • Add forwardRef to MotiPressable component. This adds support for react-native-popper.