Skip to content

docs(motion-presets): Motion Refresh / Presets RFC 2024 #2336

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 37 commits into from
Dec 6, 2024

Conversation

saurabhdaware
Copy link
Member

@saurabhdaware saurabhdaware commented Aug 22, 2024

This comment was marked as off-topic.

Copy link
Contributor

github-actions bot commented Aug 22, 2024

✅ PR title follows Conventional Commits specification.

Copy link

codesandbox-ci bot commented Aug 22, 2024

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 0419b6c:

Sandbox Source
razorpay/blade: basic Configuration

@rzpcibot
Copy link
Collaborator

rzpcibot commented Aug 22, 2024

Bundle Size Report

No bundle size changes detected.

Generated by 🚫 dangerJS against 0419b6c


## Library Comparison

### Goals of Ideal Library
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our goals should also tie in with design goals... evaluate libraries to see if something we want to do on design whether or not we can do it on dev. Good example you've added is morph animations... do we want to do morph now or later as per design?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup I've added morph and page transitions based on design expectations. We're doing morph now only.

Other things that are on design are simple opacity, slide, fade, etc transitions which are possible in every library

| **Easy to implement complex animations** | ✅ (Declarative API) | ❌ | ❌ | ❌ |
| **React Router Page Transition** | ✅ | ❌ (No native support but can be implemented) | ✅ | ❌ (No native support but can be implemented) |
| **Morph Animations / Layout Animations** | ✅ [Framer Motion POC](#morph-animations-with-framer-motion) | ❌ | ✅ | ❌ |
| **Small bundle size** | ❌ (4.6kb core + 40kb features that can be lazy loaded) | ✅ (4kb ) | ❌ (26kb core + features) | ✅ (0kb) |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets detail out the bundle size for framer motion. How will we load the core module only? In which cases will we need rest of the bundles?


### Morph / Layout Animations with Framer Motion

https://github.com/user-attachments/assets/ad3d4a23-c3b9-4980-a051-a0f44e7224dc
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try doing the morph animation with blade components?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup will do that POC with API decision now

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should try to replicate the Switch animation and see how our primitives plays out.

Switch has a 2 stage animation

Click Hold (Elongate the circle) -> Release (De-elongate the circle + move to the opposite side)

Scale, transformX both will have to animate at once.

| ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | -------------------------------------- | --------------------------------------------- |
| **License** (Preferrably free to use) | ✅ MIT | ✅ MIT | ❌ (Commercial License + Paid Plugins) | ✅ No License |
| **Hardware Accelarated Animations** | ✅ (Hybrid - WAAPI for some transformations with fallback to JS) [Hardware Accelarated POC](#hardware-accelarated-motion-using-framer-motion) | ✅ (Built on WAAPI) | ❌ | ✅ |
| **Easy to implement complex animations** | ✅ (Declarative API) | ❌ | ❌ | ❌ |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Motion one seems super light-weight. What is the difficulty in implementing animations with it? Can you add an example of an animation with framer vs with motion one?

Since we will be exposing presets to our end consumers won't it make sense to use a light-weight library within blade and abstract out complex animations within the presets?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will add more details here. Majority of things come from this article https://motion.dev/blog/should-i-use-framer-motion-or-motion-one (Find "Design goals" heading)

Overall its a low-level imperative API so requires us to call animate() function in vanilla JS and write react wrappers on top of it (which is something that we can do with CSS as well)

It lacks support for some important features like layout animations, page transitions, which we're expecting to do. So that will require custom implementation from scratch. It would've worked if we only had opacity, fade, transform transitions but we're doing more than that . If we implement such things from scratch, we'll anyway reach closer to framer-motion minified bundle.

There are projects like modular onboarding, frontend-website which are already using framer-motion and we have't seen load-time issues there. frontend-website had runtime laggy animation issues which are solved in their new update.

@saurabhdaware saurabhdaware changed the title rfc(motion-presets): Motion Refresh / Presets RFC 2024 docs(motion-presets): Motion Refresh / Presets RFC 2024 Aug 26, 2024
@saurabhdaware saurabhdaware marked this pull request as ready for review September 9, 2024 06:05
3. Easy to implement complex animations
4. React Router page transition support
5. Morph Animations / Layout Animations
6. Small bundle-size
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add Cross Platform as a goal as well? even though we might implement it later but we need to evaluate for RN as well. Eg: Vanilla CSS might not work on RN and we might as well use a diff lib for RN like ReAnimated

Copy link
Member Author

@saurabhdaware saurabhdaware Sep 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I can add as a note for react native here. Not sure if it'll make sense to add it as a factor in the library comparison table because no web animation library really supports react native so the library exploration for web and native will be different.

I can add a note saying how we use react-native-reanimated already and some of these presets can be built there. I saw that react-native-reanimated already supports a good amount of these presets. So we can re-export some of these with similar API in future - https://docs.swmansion.com/react-native-reanimated/docs/layout-animations/entering-exiting-animations

>
> The API decisions here are only there to give some basic idea on the structure and usage. More accurate props will be updated here later once they are finalised in design.

### Entry / Exit Animation Presets
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I was wondering can we go more specific here and in presets instead of giving like Fade, Scale presets what if we form patterns like PageTransition, Toggle, etc.

pros: this way it will reduce the learning curve and confusion and also minimise random animations for similar things and move us towards our eventual goal of streamlining patterns

cons: We might have to export similar behaviors like Fade, Scale in different components, might be reptitive. This might also feel restrictive at first

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes I was of similar opinion and I discussed this with design but what we realised is its valid case where card on some page might move up whereas card in some other page might fade in. We can't at one place define how section or component appears without knowing context.

From tech perspective I was also thinking of API like <Card animate> but in that case framer motion will always end up in bundle irrespective of whether animations are used or not since we'll have to define the node as motion node.

What I was also thinking is, once we have overall idea of animation patterns. Similar to how we have components and how we'll have patterns, we can have motion components and motion patterns (or incorporate motion in some our component patterns itself)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added our discussion points and why we're going this way in open questions section along with conclusion


# Adoption strategy

- We plan to target 1 project this quarter (Q2) to get motion adopted
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- We plan to target 1 project this quarter (Q2) to get motion adopted
- We plan to target 1 project this quarter (Q3) to get motion adopted

??

- The new projects that are built, should be built with motion presets on design and dev
- The earlier project that we have should use motion presets when they redesign / revamp

# How do we educate people?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets add how will we get this implemented on Figma for easing the hand-off as well here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup I'll update it here. We're still figuring out the right approach. We discussed few things yesterday, RK will just confirm it once if things are working fine or not

```jsx
import { Fade, Card, CardBody } from '@razorpay/components/blade';

<Fade isVisible={showCard}>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do we pass duration tokens etc?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can't. Which is why we have preset so that we can define durations and easing on preset level and make it consistent

Copy link

@Rozamo Rozamo Nov 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

define durations and easing on preset level

Do you mean when we define the tokens?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No like internally durations are defined for each preset. E.g Fade has certain given duration that cannot be changed on design as well

*
* @default ['mount']
*/
motionTriggers: ('mount' | 'hover' | 'tap' | 'inView')[];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to define tap and inview triggers?

Consumers can do this on their end also like so:

const isInView = useIsInView()

<Fade isVisible={isInView} />

Also if we are supporting tap, then we need to support click handlers too?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added all the triggers here which are natively supported by framer-motion so API is simpler

https://www.framer.com/motion/scroll-animations/#scroll-triggered-animations

Also if we are supporting tap, then we need to support click handlers too?

Nope. Click handlers can be added to children directly no if they support it? This is purely for animation component. It shouldn't be used to add any logic.

E.g. I can just add click handlers on children if needed for some logic

<Fade>
  <Card onClick={() => } />
</Fade>

Comment on lines +299 to +301
<AnimateInteractions motionTriggers={['hover']}>
<Card>
<CardBody>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will AnimateInteraction create a new div wrapper? or is this a enhancer component?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to create a div wrapper because something was not working. Lemme check again and see if it can be enhancer component

```

```ts
type FadeProps = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we provide atleast the delay prop to every primitive?

So that consumers can choose to delay the animation run by x duration?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These props are not finalized. Only structure is. Will add props depending on discussion with design

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the same note, should we have tokens for duration if we don't allow explicit values? Certain use cases might need animations to run for different times. I understand it won't be an issue for looped ones, but for non-looped ones, this will help

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Atleast from design-side we're saying that the enter and exit durations should have same duration always. Do you know any usecase where a single duration won't work? we can also add this prop in future if usecase comes since this anyways won't be a breaking change then.


// This animation will run when loadFeatures resolves.
function App({ children }) {
return <LazyMotion features={loadFeatures}>{children}</LazyMotion>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will consumer do this or we do this?

We will anyways have to use the framer-motion's provider right because blade components itself may also use the motion primitives.

But if we already have the provider and as a library we can't really do lazy import on our end then we don't really have choice other than to use the full framer motion right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consumer will do it. It will be required peer dependency.

We will use it in our components. Sort of like i18nify.

@saurabhdaware saurabhdaware changed the base branch from master to motion/integration December 4, 2024 09:52
@saurabhdaware saurabhdaware merged commit 3b5d17e into motion/integration Dec 6, 2024
15 checks passed
@saurabhdaware saurabhdaware deleted the rfc/motion-presets branch December 6, 2024 10:13
saurabhdaware added a commit that referenced this pull request Dec 11, 2024
* start integration branch

* docs(motion-presets): Motion Refresh / Presets RFC 2024 (#2336)

* feat: init motion presets rfc

* docs: add poc video

* docs: add comparison table and pocs

* feat: add gsap poc

* add layout animations poc with blade components

* feat: add basic API decision

* feat: add api decisions and memes

* feat: add api decisions and memes

* feat: remove unrelated changes

* docs: add morph note

* feat: add video example

* docs: add note for previews

* docs: add more videos

* fix: images

* fix: code alignments

* docs: fix widths of cols

* feat: add chat interface demo

* typo

* fix: width of previews

* docs: update animationInteractions docs

* feat: add view transitions API note

* feat: add view transitions API note

* feat: rename framer motion to motion/react

* feat: add framer motion name change note in library table

* docs: add new open questions and conclusions

* fix: change misleading scale heading

* feat: add videos locally

* feat: revert to previous fade video

* feat: rename transition prop to type

* docs: update AnimateInteractions prop

* remove unrelated changes

* feat: add PR link

* fix: PR link

* feat: add breaking change note

* feat(motion.ts): add refreshed tokens and internal components migration (#2356)

* feat: init motion presets rfc

* docs: add poc video

* docs: add comparison table and pocs

* feat: add gsap poc

* add layout animations poc with blade components

* feat: add basic API decision

* feat: add api decisions and memes

* feat: add api decisions and memes

* feat: remove unrelated changes

* docs: add morph note

* feat: add video example

* docs: add note for previews

* docs: add more videos

* fix: images

* fix: code alignments

* docs: fix widths of cols

* feat: add chat interface demo

* typo

* fix: width of previews

* feat: update all token values

* feat: motion, migrate internal motion tokens

* fix: ts check

* fix: ts

* fix: switch delay

* fix: durations map

* docs: update animationInteractions docs

* feat: add view transitions API note

* feat: add view transitions API note

* feat: rename framer motion to motion/react

* feat: add framer motion name change note in library table

* docs: add new open questions and conclusions

* fix: change misleading scale heading

* feat(motion): add initial presets code (#2360)

* feat: init motion presets rfc

* docs: add poc video

* docs: add comparison table and pocs

* feat: add gsap poc

* add layout animations poc with blade components

* feat: add basic API decision

* feat: add api decisions and memes

* feat: add api decisions and memes

* feat: remove unrelated changes

* docs: add morph note

* feat: add video example

* docs: add note for previews

* docs: add more videos

* fix: images

* fix: code alignments

* docs: fix widths of cols

* feat: add chat interface demo

* typo

* fix: width of previews

* feat: update all token values

* feat: motion, migrate internal motion tokens

* fix: ts check

* fix: ts

* fix: switch delay

* feat: add base entry exit presets

* fix: example card alignment

* feat: add stagger component

* feat: add animateInteractions

* refactor: use common BaseMotionBox

* refactor: move stagger and animateinteraction check

* fix: durations map

* feat: add morph and scale preset

* feat: add Slide

* refactor: remove unused code add todo

* docs: update animationInteractions docs

* feat: add css bezier function

* feat: add view transitions API note

* feat: add view transitions API note

* feat: add controled scale, enhancer animateinteraction

* feat: replace framer-motion imports with motion/react

* feat: rename framer motion to motion/react

* feat: add framer motion name change note in library table

* docs: add new open questions and conclusions

* fix: change misleading scale heading

* feat: add fade token values

* fix(AnimateInteractions): a11y focus issues

* feat: add token valyes for move

* feat: add slide tokens

* fix: stories

* fix: typecheck

* feat: add refs to components till checkbox

* feat: add refs till radio

* feat: migration to ref till typography

* feat: add withRef story

* fix: scale box

* feat: add shouldUnmountWhenHidden

* feat: handle no unmount transitions in stagger

* feat: add slideFromOffset prop

* refactor: simplify basemotion

* feat: add memo for variants object

* fix: focus on animate interactions

* fix: resolve anurag's comments

* feat: add comments for getOuterMotionRef

* feat: add delay prop

* fix: stagger type

* feat: support framer-motion v4

* feat: add borderRadius and backgroundColor morph support

* feat: remove reduced motion handling

* docs(Motion Presets): add motion presets documentation (#2428)

* feat: init motion presets rfc

* docs: add poc video

* docs: add comparison table and pocs

* feat: add gsap poc

* add layout animations poc with blade components

* feat: add basic API decision

* feat: add api decisions and memes

* feat: add api decisions and memes

* feat: remove unrelated changes

* docs: add morph note

* feat: add video example

* docs: add note for previews

* docs: add more videos

* fix: images

* fix: code alignments

* docs: fix widths of cols

* feat: add chat interface demo

* typo

* fix: width of previews

* feat: update all token values

* feat: motion, migrate internal motion tokens

* fix: ts check

* fix: ts

* fix: switch delay

* feat: add base entry exit presets

* fix: example card alignment

* feat: add stagger component

* feat: add animateInteractions

* refactor: use common BaseMotionBox

* refactor: move stagger and animateinteraction check

* fix: durations map

* feat: add morph and scale preset

* feat: add Slide

* refactor: remove unused code add todo

* docs: update animationInteractions docs

* feat: add css bezier function

* feat: add view transitions API note

* feat: add view transitions API note

* feat: add controled scale, enhancer animateinteraction

* feat: replace framer-motion imports with motion/react

* feat: rename framer motion to motion/react

* feat: add framer motion name change note in library table

* docs: add new open questions and conclusions

* fix: change misleading scale heading

* feat: add fade token values

* fix(AnimateInteractions): a11y focus issues

* feat: add token valyes for move

* feat: add slide tokens

* fix: stories

* fix: typecheck

* feat: add refs to components till checkbox

* feat: add refs till radio

* feat: migration to ref till typography

* feat: add withRef story

* fix: scale box

* feat: add basic stories

* refactor: docs

* feat: add shouldUnmountWhenHidden

* docs: add docs for other entry/exit presets

* feat: add stagger documentation

* feat: handle no unmount transitions in stagger

* feat: add dashboard example

* fix: workspace animation on dashboard recipe

* feat: add slideFromOffset prop

* feat: add loading screen to dashboard example

* refactor: simplify basemotion

* feat: add slide docs fix

* docs: minor docs changes

* feat: add memo for variants object

* feat: add installation docs, expose overlay colors

* fix: focus on animate interactions

* docs: remove docs page of recipes

* fix: scale performance

* fix: ts

* feat: add basic intro page for motion

* docs: finish motion intro docs

* feat: add basic upgrade guide info

* fix: resolve anurag's comments

* feat: add comments for getOuterMotionRef

* feat: add delay prop

* fix: types

* fix: stagger type

* feat: support framer-motion v4

* feat: add version upgrade guide

* feat: add jsdoc, pass down boxProps to stagger

* feat: reuse motion installation mdx

* feat: add borderRadius and backgroundColor morph support

* fix: button morph example

* fix: morph showcase

* feat: add lazy motion

* test(Motion): add tests and codemod (#2436)

* feat: init motion presets rfc

* docs: add poc video

* docs: add comparison table and pocs

* feat: add gsap poc

* add layout animations poc with blade components

* feat: add basic API decision

* feat: add api decisions and memes

* feat: add api decisions and memes

* feat: remove unrelated changes

* docs: add morph note

* feat: add video example

* docs: add note for previews

* docs: add more videos

* fix: images

* fix: code alignments

* docs: fix widths of cols

* feat: add chat interface demo

* typo

* fix: width of previews

* feat: update all token values

* feat: motion, migrate internal motion tokens

* fix: ts check

* fix: ts

* fix: switch delay

* feat: add base entry exit presets

* fix: example card alignment

* feat: add stagger component

* feat: add animateInteractions

* refactor: use common BaseMotionBox

* refactor: move stagger and animateinteraction check

* fix: durations map

* feat: add morph and scale preset

* feat: add Slide

* refactor: remove unused code add todo

* docs: update animationInteractions docs

* feat: add css bezier function

* feat: add view transitions API note

* feat: add view transitions API note

* feat: add controled scale, enhancer animateinteraction

* feat: replace framer-motion imports with motion/react

* feat: rename framer motion to motion/react

* feat: add framer motion name change note in library table

* docs: add new open questions and conclusions

* fix: change misleading scale heading

* feat: add fade token values

* fix(AnimateInteractions): a11y focus issues

* feat: add token valyes for move

* feat: add slide tokens

* fix: stories

* fix: typecheck

* feat: add refs to components till checkbox

* feat: add refs till radio

* feat: migration to ref till typography

* feat: add withRef story

* fix: scale box

* feat: add basic stories

* refactor: docs

* feat: add shouldUnmountWhenHidden

* docs: add docs for other entry/exit presets

* feat: add stagger documentation

* feat: handle no unmount transitions in stagger

* feat: add dashboard example

* fix: workspace animation on dashboard recipe

* feat: add slideFromOffset prop

* feat: add loading screen to dashboard example

* refactor: simplify basemotion

* feat: add slide docs fix

* docs: minor docs changes

* feat: add memo for variants object

* feat: add installation docs, expose overlay colors

* fix: focus on animate interactions

* docs: remove docs page of recipes

* fix: scale performance

* fix: ts

* feat: add basic intro page for motion

* docs: finish motion intro docs

* feat: add tests for basic components

* tests: update snapshots

* feat: add interaction tests

* feat: add codemod

* feat: add basic upgrade guide info

* fix: resolve anurag's comments

* feat: add comments for getOuterMotionRef

* feat: add delay prop

* fix: types

* fix: stagger type

* feat: support framer-motion v4

* feat: add version upgrade guide

* feat: add jsdoc, pass down boxProps to stagger

* feat: reuse motion installation mdx

* fix: basemotion mock

* fix: motion/react instances

* fix: native test

* fix: transitions on card

* fix: snapshot for card

* fix: lint issues

* fix: typecheck

* fix: lint

* fix: regex lint

* fix: text lint

* feat: add borderRadius and backgroundColor morph support

* fix: slide test

* upgrade guide cleanup

* heading level cleanup in upgrade guide

* fix: button morph example

* fix: morph showcase

* feat: add lazy motion

* fix: typecheck

* fix: native snapshots

* Create fluffy-bikes-drop.md

* fix: conflicts

* fix: features.js extension in PR preview sandbox

* fix: GlobalStyles undefined

* feat: add motion to peerDependency as well like framer-motion

* fix: recommend `framer-motion` name installation instead of `motion/react` (#2443)

* fix: mark motion as optional peer deps

* feat: mark motion external

* fix: check if its working without motion as external

* fix: mark motion/react as external

* feat: recommend framer-motion name instead

* fix: stackblitz examples minor cleanup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants