47 lines
1.2 KiB
TypeScript
47 lines
1.2 KiB
TypeScript
import React, { FC, PropsWithChildren, ReactNode, useState } from "react";
|
|
import "./index.css";
|
|
|
|
interface IProps {
|
|
currentPage: number;
|
|
}
|
|
|
|
const AnimatedPageContainer: FC<PropsWithChildren<IProps>> = (
|
|
{ children, currentPage },
|
|
) => {
|
|
const [uuid] = useState(crypto.randomUUID());
|
|
|
|
const renderChild = (child: ReactNode, index: number) => {
|
|
const isActive = index === currentPage;
|
|
let position = "active";
|
|
switch ((index - currentPage) / Math.abs(index - currentPage)) {
|
|
case 1:
|
|
position = "right";
|
|
break;
|
|
case -1:
|
|
position = "left";
|
|
break;
|
|
default:
|
|
position = "active";
|
|
}
|
|
|
|
return (
|
|
<div
|
|
key={`page container ${uuid}: ${index}`}
|
|
data-active={isActive}
|
|
data-position={position}
|
|
className="data-[active=true]:opacity-100 data-[active=true]:static opacity-0 top-0 left-0 absolute page data-[position=left]:-translate-x-96 data-[position=right]:translate-x-96 translate-x-0"
|
|
>
|
|
{child}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
return (
|
|
<div className="relative overflow-hidden p-2">
|
|
{React.Children.map(children, renderChild)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default AnimatedPageContainer;
|