Skip to content

Instantly share code, notes, and snippets.

@gaurangrshah
Last active June 12, 2023 08:04
Show Gist options
  • Save gaurangrshah/80e0af801677354b007ad21f6f73df58 to your computer and use it in GitHub Desktop.
Save gaurangrshah/80e0af801677354b007ad21f6f73df58 to your computer and use it in GitHub Desktop.
Chakra-UI hook for quick & easy css animations.
import { keyframes, usePrefersReducedMotion } from '@chakra-ui/react';
/*
* Types
*/
type CSSAnimation = {
keyframes: string;
animation: string;
};
export type CSSAnim = Record<string, CSSAnimation>;
export type UseCssAnimationesult = string | undefined;
/*
* cssAnimations: pre-defined object of animations, the key of each animation is used to access the animation.
*/
export const cssAnimations: CSSAnim = {
'slide-in-top': {
keyframes: keyframes`from {transform: translateY(100);}
to {transform: translateY(-100px);}`,
animation: '0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both',
},
'slide-in-bottom': {
keyframes: keyframes`from {transform: translateY(-100);}
to {transform: translateY(100px);}`,
animation: '0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both',
},
};
/*
* animateCSS: helper fn that returns an css animation string given a matching key.
*/
export const animateCSS: (
prefersMotion: boolean,
anim: string
) => string | undefined = (prefersMotion = false, anim = 'slide-in-top') => {
const animation = cssAnimations[anim] as CSSAnimation;
return prefersMotion && !!animation
? undefined
: `${animation.keyframes && animation.keyframes} ${
animation?.animation && animation?.animation
}`;
};
/*
* useCssAnimation: takes in a key which is used to access the corresponding animation using the animateCSS fn above.
* The final animation string is then returned from the hook
*/
export function useCssAnimation(key = 'slideInTop') {
const prefersReducedMotion = usePrefersReducedMotion();
const animation = animateCSS(prefersReducedMotion, key);
return animation as UseCssAnimationesult;
}
/*
* USAGE:
*/
const Home = () => {
const animation = useCssAnimation('slide-in-top');
return (
<Container pos="relative" mt={32} maxW="2xl">
<Heading as="h1" animation={animation}>
Create{' '}
<Text as="span" color="brand.300">
My
</Text>{' '}
App
</Heading>
</Container>
);
};
@BitWizardCap
Copy link

Hi, Wonderful!
I hope you will write a lot of same articles so that it will help lots of people make awesome web applications.

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment