diff --git a/src/components/AnimateEntry.tsx b/src/components/AnimateEntry.tsx new file mode 100644 index 0000000..c4f66ec --- /dev/null +++ b/src/components/AnimateEntry.tsx @@ -0,0 +1,53 @@ +import React, { forwardRef } from "react"; +import { css, cx } from "@emotion/css"; + +export const AnimateEntry = forwardRef< + HTMLDivElement, + React.HTMLAttributes & { + as?: React.ElementType; + delay?: number; + } +>( + ( + { children, className, as: Component = "div", delay = 100, ...props }, + ref, + ) => { + return ( + * { + animation: slideIn 300ms backwards; + } + + ${React.Children.map( + children, + (child, i) => + child && + css` + & > *:nth-child(${i + 1}) { + animation-delay: ${i * delay}ms; + } + `, + )} + + @keyframes slideIn { + from { + opacity: 0; + transform: translateY(3rem); + } + to { + opacity: 1; + transform: translateY(0); + } + } + `, + className, + )} + {...props} + ref={ref}> + {children} + + ); + }, +); diff --git a/src/components/Container.tsx b/src/components/Container.tsx index 210bb9e..d599739 100644 --- a/src/components/Container.tsx +++ b/src/components/Container.tsx @@ -7,6 +7,7 @@ import { ReactComponent as Right } from "../assets/arrow-right.svg"; import { get, getTimeout } from "../util"; import Menu, { MenuEntries } from "./Menu"; import useMediaQuery from "../util/useMediaQuery"; +import { AnimateEntry } from "./AnimateEntry"; const [timer, clear] = getTimeout(); @@ -14,7 +15,8 @@ const Container: React.FC<{ children: React.ReactNode | React.ReactNode[]; hideNav?: boolean; className?: string; -}> = ({ children, hideNav = false, className, ...props }) => { + delay?: number; +}> = ({ children, hideNav = false, className, delay = 100, ...props }) => { const [location, navigate] = useLocation(); const mobile = useMediaQuery("(max-width: 50rem)"); @@ -273,7 +275,8 @@ const Container: React.FC<{ `} /> -
* { - animation: slideIn 300ms backwards; - } - - ${React.Children.map( - children, - (child, i) => - child && - css` - & > *:nth-child(${i + 1}) { - animation-delay: calc(${i} * 100ms); - } - `, - )} - - @keyframes slideIn { - from { - opacity: 0; - transform: translateY(3rem); - } - to { - opacity: 1; - transform: translateY(0); - } - } `, className, )} ref={containerChild} {...props}> {children} -
+ ); };