Skip to content

Commit

Permalink
test(Motion): add tests and codemod (#2436)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
saurabhdaware authored Dec 9, 2024
1 parent fa0c45e commit f1d81cf
Show file tree
Hide file tree
Showing 182 changed files with 6,005 additions and 2,871 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import { applyTransform } from '@hypermod/utils';
import transformer from '..';

it('should update token for dashboard sidebar example', async () => {
const result = await applyTransform(
transformer,
`
export const SidebarContainer = styled.div<SidebarContainerProps>(
({ theme, isRTUXHomepage, isVisible, isMobile }) => \`
display: flex;
flex-direction: column;
position: fixed;
top: 0;
bottom: 0;
background-color: \${
isRTUXHomepage
? isMobile
? theme.colors.surface.background.cloud.subtle
: 'transparent'
: '#2e3345'
};
transform: translate(-100%,0);
transition: transform \${makeMotionTime(theme.motion.delay.short)} \${
theme.motion.easing.standard.effective
};
\`);
`,
{ parser: 'tsx' },
);

expect(result).toMatchInlineSnapshot(`
"export const SidebarContainer = styled.div<SidebarContainerProps>(
({ theme, isRTUXHomepage, isVisible, isMobile }) => \`
display: flex;
flex-direction: column;
position: fixed;
top: 0;
bottom: 0;
background-color: \${
isRTUXHomepage
? isMobile
? theme.colors.surface.background.cloud.subtle
: 'transparent'
: '#2e3345'
};
transform: translate(-100%,0);
transition: transform \${makeMotionTime(theme.motion.delay.short)} \${
theme.motion.easing.standard
};
\`);"
`);
});

it('should update token when used as prop', async () => {
const result = await applyTransform(
transformer,
`
function App() {
const { theme } = useTheme();
return <Box easing={theme.motion.easing.standard.wary} />
}
`,
{ parser: 'tsx' },
);

expect(result).toMatchInlineSnapshot(`
"function App() {
const { theme } = useTheme();
return <Box easing={theme.motion.easing.shake} />
}"
`);
});

it('should update token as used in X payroll', async () => {
const result = await applyTransform(
transformer,
`
export const AnimatedContainer = styled.div<{ delay?: number }>(({ theme, delay = 0 }) => {
return css\`
animation: \${entry} \${makeMotionTime(theme.motion.duration['2xgentle'])}
\${theme.motion.easing.entrance.revealing} forwards;
animation-delay: \${delay}ms;
opacity: 0;
\`;
});
`,
{ parser: 'tsx' },
);

expect(result).toMatchInlineSnapshot(`
"export const AnimatedContainer = styled.div<{ delay?: number }>(({ theme, delay = 0 }) => {
return css\`
animation: \${entry} \${makeMotionTime(theme.motion.duration['2xgentle'])}
\${theme.motion.easing.entrance} forwards;
animation-delay: \${delay}ms;
opacity: 0;
\`;
});"
`);
});

it('should update token when variable name is not "theme"', async () => {
const result = await applyTransform(
transformer,
`
export const AnimatedContainer = styled.div<{ delay?: number }>(({ theme, delay = 0 }) => {
return css\`
animation: \${entry} \${makeMotionTime(paymentTheme.motion.duration['2xgentle'])}
\${paymentTheme.motion.easing.exit.effective} forwards;
animation-delay: \${delay}ms;
opacity: 0;
\`;
});
`,
{ parser: 'tsx' },
);

expect(result).toMatchInlineSnapshot(`
"export const AnimatedContainer = styled.div<{ delay?: number }>(({ theme, delay = 0 }) => {
return css\`
animation: \${entry} \${makeMotionTime(paymentTheme.motion.duration['2xgentle'])}
\${paymentTheme.motion.easing.exit} forwards;
animation-delay: \${delay}ms;
opacity: 0;
\`;
});"
`);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './migrate-motion';
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { FileInfo } from 'jscodeshift';
// eslint-disable-next-line import/extensions
import * as tokenMapping from './motionTokenMapping.json';

const transformer = (file: FileInfo): string => {
// Fairly simple usecases of motion tokens in razorpay files so this works.
// .replace has also worked well during rebranding
// eslint-disable-next-line no-useless-escape
const newSource = file.source.replace(/motion\.easing\.[\w\.]+/g, (matchingToken) => {
const match = Object.entries(tokenMapping).find(
([oldToken, _newToken]) => oldToken === matchingToken,
);

if (match) {
return match[1];
}

return matchingToken;
});

return newSource;
};

export default transformer;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"motion.easing.entrance.effective": "motion.easing.entrance",
"motion.easing.standard.effective": "motion.easing.standard",
"motion.easing.exit.effective": "motion.easing.exit",
"motion.easing.entrance.revealing": "motion.easing.entrance",
"motion.easing.standard.revealing": "motion.easing.emphasized",
"motion.easing.exit.revealing": "motion.easing.exit",
"motion.easing.entrance.attentive": "motion.easing.overshoot",
"motion.easing.exit.attentive": "motion.easing.exit",
"motion.easing.standard.wary": "motion.easing.shake"
}
22 changes: 14 additions & 8 deletions packages/blade/docs/migration-docs/upgrade-v12.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ Blade v12 introduces `motion` (prev `framer-motion`) as peer dependency and requ

- **Step 1:** Upgrade to latest `@razorpay/blade` package in your project
- **Step 2:** [Perform Tokens Changes](#token-changes) using Codemod or manually
- **Step 3:** Setup `motion/react` (or `framer-motion`)
- **Step 3:** [Setup `motion/react` (or `framer-motion`)](#motion-react-framer-motion-setup)

### Token Changes
## Token Changes

We have codemod to help you do the required token changes. You can run the codemod with following command (Replace `./PATH_TO_YOUR_DIR` with glob path of files / directories you want to migrate)-

Expand All @@ -43,26 +43,26 @@ You can skip this if you've run the codemod but in case not or you see some edge
</details>
### Motion React (Framer Motion) Setup
## Motion React (Framer Motion) Setup
> [!IMPORTANT]
>
> `framer-motion` library is now known as `motion/react`
>
> Checkout the [announcement by creator of framer-motion](https://bsky.app/profile/citizenofnowhe.re/post/3lar365ouuk2v)
### Version Compatibility for Consumers already using Framer Motion's Older Version
<details>
<summary>Version Compatibility Note for consumers already using framer-motion with older version</summary>
#### Version Compatibility Note for consumers already using framer-motion with older version
We realised that several projects in razorpay are already using `framer-motion` and are on older versions.
To give some time to consumers to upgrade to framer-motion v11+, we'll be supporting framer-motion v4+ from blade. Although we will be dropping this support in next major version of blade so we recommend planning out framer-motion upgrade in coming quarter.
- **If you're on React 18**, migrating to framer-motion v11 should be fairly simple and low-effort. Checkout [Migrating from framer-motion v4+ to motion/react v11+](#migrating-from-framer-motion-v4-to-motionreact-aka-framer-motion-v11)
- **For projects not on React 18 yet**, do plan out the upgrade soon to make sure future blade upgrades don't become blocker
### Migrating from `framer-motion` v4+ to `motion/react` (aka `framer-motion` v11)
#### Migrating from `framer-motion` v4+ to `motion/react` (aka `framer-motion` v11)
1. Ensure you're on React 18 as `framer-motion` v7 makes React 18 a minimum supported version.
a. [Checkout React 18 upgrade guide](https://react.dev/blog/2022/03/08/react-18-upgrade-guide) or use [React's official codemod for upgrading](https://github.com/reactjs/react-codemod)
Expand All @@ -73,10 +73,12 @@ These are mostly the changes you'll need if you're using core API. But if you're
</details>
- #### Install `motion
### Setting Up Motion in New Projects
- #### Install `motion`
```sh
yarn add `motion` --dev
yarn add motion --dev # or pnpm install motion --save-dev
```
- #### Setup reduced bundle version of `motion/react
Expand Down Expand Up @@ -131,3 +133,7 @@ These are mostly the changes you'll need if you're using core API. But if you're
);
}
```
---
Got stuck somewhere or have some doubts? reach out to `@blade-developers` on `#design-system` channel
3 changes: 1 addition & 2 deletions packages/blade/src/components/Accordion/Accordion.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import type { ReactElement } from 'react';
import { useCallback, useMemo, useState, cloneElement, Children } from 'react';
import React, { useCallback, useMemo, useState, cloneElement, Children } from 'react';
import type { AccordionContextState } from './AccordionContext';
import { AccordionContext } from './AccordionContext';
import { MAX_WIDTH } from './styles';
Expand Down
Loading

0 comments on commit f1d81cf

Please sign in to comment.