feat: add header
This commit is contained in:
@@ -22,7 +22,7 @@ import menuIcon from "./assets/menu.svg";
|
||||
import rouletteIcon from "./assets/roulette.svg";
|
||||
import tasksIcon from "./assets/tasks.svg";
|
||||
import earningsIcon from "./assets/earnings.svg";
|
||||
import tg from "@/tg";
|
||||
import tg, { useTelegramViewportValue } from "@/tg";
|
||||
|
||||
const ANIMATION_DURATION = 0.2;
|
||||
const SPRING_ANIMATION = {
|
||||
@@ -62,33 +62,34 @@ type BarProps = {
|
||||
function NavBar({ labelKey, icon, active, entranceDelay, onClick }: BarProps) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const isInitial = useRef(true);
|
||||
useEffect(() => {
|
||||
isInitial.current = false;
|
||||
}, []);
|
||||
const [isReady, setIsReady] = useState(false);
|
||||
|
||||
const height = active ? ACTIVE_BAR_HEIGHT : BAR_HEIGHT;
|
||||
const safeAreaBottom = useTelegramViewportValue("safeAreaInsetBottom");
|
||||
const safeContentBottom = useTelegramViewportValue("contentSafeAreaInsetBottom");
|
||||
const height = (active ? ACTIVE_BAR_HEIGHT : BAR_HEIGHT) + safeAreaBottom + safeContentBottom;
|
||||
const offscreenOffset = height * 0.3;
|
||||
return (
|
||||
<GlassSurface
|
||||
className={[classes.bar, active && classes.active]}
|
||||
variants={{
|
||||
hidden: {
|
||||
translateY: ACTIVE_BAR_HEIGHT + OFFSCREEN_BAR_OFFSET,
|
||||
translateY: height + offscreenOffset,
|
||||
height,
|
||||
},
|
||||
visible: {
|
||||
translateY: OFFSCREEN_BAR_OFFSET,
|
||||
height: height + OFFSCREEN_BAR_OFFSET,
|
||||
translateY: offscreenOffset,
|
||||
height: height + offscreenOffset,
|
||||
transition: { ...SPRING_ANIMATION, delay: entranceDelay },
|
||||
},
|
||||
ready: {
|
||||
translateY: OFFSCREEN_BAR_OFFSET,
|
||||
height: height + OFFSCREEN_BAR_OFFSET,
|
||||
translateY: offscreenOffset,
|
||||
height: height + offscreenOffset,
|
||||
transition: SPRING_ANIMATION,
|
||||
},
|
||||
}}
|
||||
onAnimationComplete={(variant) => variant === "visible" && setIsReady(true)}
|
||||
initial="hidden"
|
||||
animate={isInitial.current ? "visible" : "ready"}
|
||||
animate={isReady ? "ready" : "visible"}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
onClick={onClick}
|
||||
>
|
||||
@@ -110,34 +111,37 @@ type MenuBarProps = {
|
||||
|
||||
const MENU_BAR_WIDTH = 94;
|
||||
const ACTIVE_MENU_BAR_WIDTH = 104;
|
||||
const OFFSCREEN_MENU_BAR_OFFSET = 20;
|
||||
|
||||
function MenuBar({ labelKey, icon, delay, active, onClick }: MenuBarProps) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [isReady, setIsReady] = useState(false);
|
||||
|
||||
const width = active ? ACTIVE_MENU_BAR_WIDTH : MENU_BAR_WIDTH;
|
||||
const safeAreaRight = useTelegramViewportValue("safeAreaInsetRight");
|
||||
const safeContentRight = useTelegramViewportValue("contentSafeAreaInsetRight");
|
||||
const width =
|
||||
(active ? ACTIVE_MENU_BAR_WIDTH : MENU_BAR_WIDTH) + safeAreaRight + safeContentRight;
|
||||
const offscreenOffset = width * 0.3;
|
||||
return (
|
||||
<GlassSurface
|
||||
className={[classes.menuBar, active && classes.active]}
|
||||
variants={{
|
||||
hidden: {
|
||||
translateX: width + OFFSCREEN_MENU_BAR_OFFSET,
|
||||
translateX: width + offscreenOffset,
|
||||
width,
|
||||
},
|
||||
visible: {
|
||||
translateX: OFFSCREEN_MENU_BAR_OFFSET,
|
||||
translateX: offscreenOffset,
|
||||
transition: { ...SPRING_ANIMATION, delay: delay },
|
||||
width,
|
||||
},
|
||||
ready: {
|
||||
translateX: OFFSCREEN_MENU_BAR_OFFSET,
|
||||
translateX: offscreenOffset,
|
||||
transition: SPRING_ANIMATION,
|
||||
width,
|
||||
},
|
||||
exit: {
|
||||
translateX: width + OFFSCREEN_MENU_BAR_OFFSET + 10,
|
||||
translateX: width + offscreenOffset,
|
||||
transition: { ...SPRING_ANIMATION, delay: delay },
|
||||
width,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user