glass mode
This commit is contained in:
@@ -1,87 +1,17 @@
|
||||
"use client";
|
||||
|
||||
import { useGetAbout } from "@/app/[name]/(Main)/about/hooks/useAboutData";
|
||||
import {
|
||||
applyPatternCssVariables,
|
||||
clearPatternCssVariables,
|
||||
colorizeSvg,
|
||||
hexToRgba,
|
||||
isPatternBackground,
|
||||
PATTERN_BACKGROUND_OPACITY,
|
||||
} from "@/lib/helpers/backgroundUtils";
|
||||
import { useParams } from "next/navigation";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { usePatternBackground } from "@/components/background/PatternBackgroundProvider";
|
||||
import { useEffect, useState } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
|
||||
const DEFAULT_MENU_COLOR = "#1E3A8A";
|
||||
|
||||
export default function AppBackground() {
|
||||
const { name: restaurantSlug } = useParams<{ name: string }>();
|
||||
const { data: aboutData } = useGetAbout();
|
||||
const restaurant = aboutData?.data;
|
||||
const { isPattern, backgroundStyle } = usePatternBackground();
|
||||
const [mounted, setMounted] = useState(false);
|
||||
const [patternImageUrl, setPatternImageUrl] = useState<string | null>(null);
|
||||
const blobUrlRef = useRef<string | null>(null);
|
||||
|
||||
const isPattern = restaurant ? isPatternBackground(restaurant) : false;
|
||||
const menuColor = restaurant?.menuColor || DEFAULT_MENU_COLOR;
|
||||
const baseTint = hexToRgba(menuColor, PATTERN_BACKGROUND_OPACITY);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const revokeBlobUrl = () => {
|
||||
if (blobUrlRef.current) {
|
||||
URL.revokeObjectURL(blobUrlRef.current);
|
||||
blobUrlRef.current = null;
|
||||
}
|
||||
setPatternImageUrl(null);
|
||||
};
|
||||
|
||||
if (!isPattern || !restaurant?.bgUrl || !restaurantSlug) {
|
||||
clearPatternCssVariables();
|
||||
revokeBlobUrl();
|
||||
return;
|
||||
}
|
||||
|
||||
applyPatternCssVariables(menuColor);
|
||||
|
||||
let cancelled = false;
|
||||
const proxyUrl = `/${restaurantSlug}/api/proxy-svg?url=${encodeURIComponent(restaurant.bgUrl)}`;
|
||||
|
||||
fetch(proxyUrl)
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch background pattern");
|
||||
}
|
||||
return response.text();
|
||||
})
|
||||
.then((svg) => {
|
||||
if (cancelled) return;
|
||||
|
||||
revokeBlobUrl();
|
||||
const blob = new Blob([colorizeSvg(svg, menuColor)], {
|
||||
type: "image/svg+xml;charset=utf-8",
|
||||
});
|
||||
const blobUrl = URL.createObjectURL(blob);
|
||||
blobUrlRef.current = blobUrl;
|
||||
setPatternImageUrl(blobUrl);
|
||||
})
|
||||
.catch(() => {
|
||||
if (!cancelled) {
|
||||
revokeBlobUrl();
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
clearPatternCssVariables();
|
||||
revokeBlobUrl();
|
||||
};
|
||||
}, [isPattern, menuColor, restaurant?.bgUrl, restaurantSlug]);
|
||||
|
||||
if (!mounted || !isPattern) {
|
||||
return null;
|
||||
}
|
||||
@@ -92,14 +22,7 @@ export default function AppBackground() {
|
||||
className="fixed inset-0 pointer-events-none"
|
||||
style={{
|
||||
zIndex: 0,
|
||||
backgroundColor: baseTint,
|
||||
...(patternImageUrl
|
||||
? {
|
||||
backgroundImage: `url("${patternImageUrl}")`,
|
||||
backgroundRepeat: "repeat",
|
||||
backgroundSize: "auto",
|
||||
}
|
||||
: {}),
|
||||
...backgroundStyle,
|
||||
}}
|
||||
/>,
|
||||
document.body,
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
"use client";
|
||||
|
||||
import { useGetAbout } from "@/app/[name]/(Main)/about/hooks/useAboutData";
|
||||
import {
|
||||
applyPatternCssVariables,
|
||||
clearPatternCssVariables,
|
||||
colorizeSvg,
|
||||
hexToRgba,
|
||||
isPatternBackground,
|
||||
PATTERN_BACKGROUND_OPACITY,
|
||||
} from "@/lib/helpers/backgroundUtils";
|
||||
import { useParams } from "next/navigation";
|
||||
import {
|
||||
createContext,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
type CSSProperties,
|
||||
type ReactNode,
|
||||
} from "react";
|
||||
|
||||
const DEFAULT_MENU_COLOR = "#1E3A8A";
|
||||
|
||||
type PatternBackgroundContextValue = {
|
||||
isPattern: boolean;
|
||||
backgroundStyle: CSSProperties;
|
||||
};
|
||||
|
||||
const PatternBackgroundContext = createContext<PatternBackgroundContextValue>({
|
||||
isPattern: false,
|
||||
backgroundStyle: {},
|
||||
});
|
||||
|
||||
export function PatternBackgroundProvider({ children }: { children: ReactNode }) {
|
||||
const { name: restaurantSlug } = useParams<{ name: string }>();
|
||||
const { data: aboutData } = useGetAbout();
|
||||
const restaurant = aboutData?.data;
|
||||
const [patternImageUrl, setPatternImageUrl] = useState<string | null>(null);
|
||||
const blobUrlRef = useRef<string | null>(null);
|
||||
|
||||
const isPattern = restaurant ? isPatternBackground(restaurant) : false;
|
||||
const menuColor = restaurant?.menuColor || DEFAULT_MENU_COLOR;
|
||||
const baseTint = hexToRgba(menuColor, PATTERN_BACKGROUND_OPACITY);
|
||||
|
||||
useEffect(() => {
|
||||
const revokeBlobUrl = () => {
|
||||
if (blobUrlRef.current) {
|
||||
URL.revokeObjectURL(blobUrlRef.current);
|
||||
blobUrlRef.current = null;
|
||||
}
|
||||
setPatternImageUrl(null);
|
||||
};
|
||||
|
||||
if (!isPattern || !restaurant?.bgUrl || !restaurantSlug) {
|
||||
clearPatternCssVariables();
|
||||
revokeBlobUrl();
|
||||
return;
|
||||
}
|
||||
|
||||
applyPatternCssVariables(menuColor);
|
||||
|
||||
let cancelled = false;
|
||||
const proxyUrl = `/${restaurantSlug}/api/proxy-svg?url=${encodeURIComponent(restaurant.bgUrl)}`;
|
||||
|
||||
fetch(proxyUrl)
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch background pattern");
|
||||
}
|
||||
return response.text();
|
||||
})
|
||||
.then((svg) => {
|
||||
if (cancelled) return;
|
||||
|
||||
revokeBlobUrl();
|
||||
const blob = new Blob([colorizeSvg(svg, menuColor)], {
|
||||
type: "image/svg+xml;charset=utf-8",
|
||||
});
|
||||
const blobUrl = URL.createObjectURL(blob);
|
||||
blobUrlRef.current = blobUrl;
|
||||
setPatternImageUrl(blobUrl);
|
||||
})
|
||||
.catch(() => {
|
||||
if (!cancelled) {
|
||||
revokeBlobUrl();
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
clearPatternCssVariables();
|
||||
revokeBlobUrl();
|
||||
};
|
||||
}, [isPattern, menuColor, restaurant?.bgUrl, restaurantSlug]);
|
||||
|
||||
const backgroundStyle = useMemo<CSSProperties>(
|
||||
() => ({
|
||||
backgroundColor: baseTint,
|
||||
...(patternImageUrl
|
||||
? {
|
||||
backgroundImage: `url("${patternImageUrl}")`,
|
||||
backgroundRepeat: "repeat",
|
||||
backgroundSize: "auto",
|
||||
}
|
||||
: {}),
|
||||
}),
|
||||
[baseTint, patternImageUrl],
|
||||
);
|
||||
|
||||
const value = useMemo(
|
||||
() => ({ isPattern, backgroundStyle }),
|
||||
[backgroundStyle, isPattern],
|
||||
);
|
||||
|
||||
return (
|
||||
<PatternBackgroundContext.Provider value={value}>
|
||||
{children}
|
||||
</PatternBackgroundContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function usePatternBackground() {
|
||||
return useContext(PatternBackgroundContext);
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import React from 'react'
|
||||
import SearchIcon from '../icons/SearchIcon'
|
||||
import clsx from 'clsx'
|
||||
import { glassSurfaceFlat } from '@/lib/styles/glassSurface'
|
||||
|
||||
interface SearchboxProps
|
||||
extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'results'> {
|
||||
@@ -19,9 +19,9 @@ export default function SearchBox({
|
||||
}: SearchboxProps) {
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
'bg-container inline-flex rounded-xl px-4 h-10 w-full items-center content-center',
|
||||
className
|
||||
className={glassSurfaceFlat(
|
||||
'inline-flex rounded-xl px-4 h-10 w-full items-center content-center',
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<SearchIcon stroke='#8C90A3' />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { glassSurface } from '@/lib/styles/glassSurface';
|
||||
import React from 'react';
|
||||
|
||||
type Props = {
|
||||
@@ -8,7 +9,7 @@ type Props = {
|
||||
|
||||
function CategoryItemRenderer({ children, ...rest }: Props) {
|
||||
return (
|
||||
<div className={`${rest.className} cursor-pointer transition-all duration-200 ease-out gradient-border overflow-hidden rounded-xl backdrop-blur-md bg-container/40`}>
|
||||
<div className={glassSurface(rest.className, 'cursor-pointer transition-all duration-200 ease-out overflow-hidden rounded-xl')}>
|
||||
<div
|
||||
{...rest}
|
||||
className="rounded-normal w-[108px] h-[88px] flex flex-col justify-center items-center gap-2"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { glassSurface } from '@/lib/styles/glassSurface';
|
||||
import React from 'react';
|
||||
|
||||
type Props = {
|
||||
@@ -8,7 +9,7 @@ type Props = {
|
||||
|
||||
function CategorySmallItemRenderer({ children, ...rest }: Props) {
|
||||
return (
|
||||
<div className={`${rest.className} cursor-pointer transition-all duration-200 ease-out gradient-border overflow-hidden rounded-xl backdrop-blur-md bg-container/40 dark:bg-background`}>
|
||||
<div className={glassSurface(rest.className, 'cursor-pointer transition-all duration-200 ease-out overflow-hidden rounded-xl')}>
|
||||
<div
|
||||
{...rest}
|
||||
className="rounded-normal h-[44px] flex flex-row justify-center items-center p-2.5 gap-2"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { glassSurface } from '@/lib/styles/glassSurface';
|
||||
|
||||
type Props = {
|
||||
children: React.ReactNode;
|
||||
@@ -10,7 +11,10 @@ function MenuItemRendererComponent({ children, ...rest }: Props) {
|
||||
return (
|
||||
<div
|
||||
{...rest}
|
||||
className={`${rest.className} box-shadow-normal !pb-4 py-4 transition-all duration-200 ease-out w-full bg-container rounded-3xl px-4 flex items-center justify-between gap-4`}>
|
||||
className={glassSurface(
|
||||
rest.className,
|
||||
'!pb-4 py-4 transition-all duration-200 ease-out w-full rounded-3xl px-4 flex items-center justify-between gap-4',
|
||||
)}>
|
||||
|
||||
{children}
|
||||
</div>
|
||||
|
||||
@@ -19,6 +19,7 @@ import { useGetAbout } from '@/app/[name]/(Main)/about/hooks/useAboutData';
|
||||
import Image from 'next/image';
|
||||
import { useGetProfile } from '@/app/[name]/(Profile)/profile/hooks/userProfileData';
|
||||
import { toast, toastLoginRequired } from '../Toast';
|
||||
import { glassSurface } from '@/lib/styles/glassSurface';
|
||||
|
||||
type MenuItemType = {
|
||||
href: string | undefined;
|
||||
@@ -344,7 +345,7 @@ function SideMenu({ menuState, toggleMenuState, nightModeState, togglenightModeS
|
||||
</motion.nav>
|
||||
</BlurredOverlayContainer>
|
||||
<nav
|
||||
className="hidden fixed top-4 bottom-4 right-4 bg-container xl:w-[250px] xl:flex flex-col z-40 overflow-clip xl:rounded-4xl"
|
||||
className={glassSurface('hidden fixed top-4 bottom-4 right-4 xl:w-[250px] xl:flex flex-col z-40 overflow-clip xl:rounded-4xl')}
|
||||
>
|
||||
{renderMenu()}
|
||||
</nav>
|
||||
|
||||
@@ -13,6 +13,8 @@ import { useTranslation } from 'react-i18next';
|
||||
import { useCart } from '@/app/[name]/(Main)/cart/hook/useCart';
|
||||
import { Building } from 'iconsax-react';
|
||||
import clsx from 'clsx';
|
||||
import { glassSurfaceNav } from '@/lib/styles/glassSurface';
|
||||
import { getBottomNavMaskStyle } from './bottomNavShape';
|
||||
import { useGetProfile } from '@/app/[name]/(Profile)/profile/hooks/userProfileData';
|
||||
import { toastLoginRequired } from '../Toast';
|
||||
|
||||
@@ -37,6 +39,8 @@ function BottomNavBar({ onPagerClick }: BottomNavBarProps) {
|
||||
});
|
||||
const { items } = useCart();
|
||||
|
||||
const navMaskStyle = React.useMemo(() => getBottomNavMaskStyle(), []);
|
||||
|
||||
const cartItemsCount = React.useMemo(() => {
|
||||
return Object.values(items).reduce((total, item) => {
|
||||
return total + (item?.quantity || 0);
|
||||
@@ -56,119 +60,72 @@ function BottomNavBar({ onPagerClick }: BottomNavBarProps) {
|
||||
return (
|
||||
<div className="fixed bottom-0 left-0 w-full bg-transparent pointer-events-none">
|
||||
<div className="max-w-md mx-auto w-full aspect-436/104 relative z-30">
|
||||
<svg
|
||||
viewBox="0 0 436 104"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="w-full h-full block"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
<div
|
||||
aria-hidden
|
||||
className={glassSurfaceNav('absolute inset-0 pointer-events-none')}
|
||||
style={navMaskStyle}
|
||||
/>
|
||||
|
||||
<nav
|
||||
className="absolute left-0 right-0 grid grid-cols-5 gap-x-1 items-end px-4 text-[10px] pointer-events-auto"
|
||||
style={{
|
||||
top: 'calc(10 / 104 * 100%)',
|
||||
height: 'calc(80 / 104 * 100%)',
|
||||
}}
|
||||
>
|
||||
<g filter="url(#filter0_d_9095_18036)" className='fill-container'>
|
||||
<path
|
||||
className='pointer-events-auto'
|
||||
d="M218 16C229.034 16 238.711 22.0313 244.148 31.0943C245.844 33.9222 248.724 36 252.022 36H406C414.837 36 422 43.1634 422 52V80C422 88.8366 414.837 96 406 96H30C21.1634 96 14 88.8366 14 80V52C14 43.1634 21.1634 36 30 36H183.979C187.277 36 190.157 33.9222 191.853 31.0943C197.29 22.0315 206.966 16.0001 218 16Z"
|
||||
/>
|
||||
</g>
|
||||
|
||||
{/* 🔽 Your HTML content inside SVG */}
|
||||
<foreignObject x="0" y="10" width="100%" height="80">
|
||||
<nav
|
||||
className="h-full px-4 grid grid-cols-5 gap-x-1 text-[10px] items-end"
|
||||
<BottomNavLink
|
||||
href={`/${name}/cart`}
|
||||
icon={<BagIcon width={20} height={20} />}
|
||||
value={t('Cart')}
|
||||
/>
|
||||
{onPagerClick ? (
|
||||
<button
|
||||
onClick={onPagerClick}
|
||||
className="flex flex-col justify-arround items-center gap-[5px] text-primary pointer-events-auto **:stroke-primary dark:text-white dark:**:stroke-white"
|
||||
>
|
||||
<BottomNavLink
|
||||
href={`/${name}/cart`}
|
||||
icon={<BagIcon width={20} height={20} />}
|
||||
value={t('Cart')}
|
||||
/>
|
||||
{onPagerClick ? (
|
||||
<button
|
||||
onClick={onPagerClick}
|
||||
className="flex flex-col justify-arround items-center gap-[5px] text-primary pointer-events-auto **:stroke-primary dark:text-white dark:**:stroke-white"
|
||||
>
|
||||
<PagerIcon width={20} height={20} />
|
||||
<span className="text-xs2 dark:text-white">
|
||||
{t('Pager')}
|
||||
</span>
|
||||
</button>
|
||||
) : (
|
||||
<BottomNavLink href={`/${name}/pager`} icon={<PagerIcon width={20} height={20} />} value={t('Pager')} />
|
||||
)}
|
||||
<BottomNavHighlightLink
|
||||
href={`/${name}`}
|
||||
icon={
|
||||
<HomeIcon
|
||||
className={clsx(
|
||||
'transition-all duration-200 stroke-primary dark:stroke-black! dark:text-white'
|
||||
)}
|
||||
fill="white"
|
||||
stroke="currentColor"
|
||||
variant={isHomeRoute ? 'Bold' : 'Outline'}
|
||||
width={20}
|
||||
height={20} />}
|
||||
value={t('Menu')} />
|
||||
<Link
|
||||
href={`/${name}/about`}
|
||||
<PagerIcon width={20} height={20} />
|
||||
<span className="text-xs2 dark:text-white">
|
||||
{t('Pager')}
|
||||
</span>
|
||||
</button>
|
||||
) : (
|
||||
<BottomNavLink href={`/${name}/pager`} icon={<PagerIcon width={20} height={20} />} value={t('Pager')} />
|
||||
)}
|
||||
<BottomNavHighlightLink
|
||||
href={`/${name}`}
|
||||
icon={
|
||||
<HomeIcon
|
||||
className={clsx(
|
||||
'flex flex-col justify-arround items-center gap-[5px] text-primary pointer-events-auto **:stroke-primary min-w-0 dark:text-white dark:**:stroke-white'
|
||||
'transition-all duration-200 stroke-primary dark:stroke-black! dark:text-white'
|
||||
)}
|
||||
>
|
||||
<div className="shrink-0 text-primary dark:text-white">
|
||||
<Building
|
||||
key={`building-${buildingVariant}-${isAboutRoute}`}
|
||||
size={20}
|
||||
variant={buildingVariant as 'Bold' | 'Outline'}
|
||||
color="currentColor"
|
||||
className='stroke-0'
|
||||
/>
|
||||
</div>
|
||||
<span className="text-xs2 text-center truncate w-full dark:text-white">
|
||||
{t('about')}
|
||||
</span>
|
||||
</Link>
|
||||
<BottomNavLink href={`/${name}/favorite`} onClick={handleFavoritesClick} icon={<HeartIcon width={20} height={20} />} value={t('Favorites')} />
|
||||
</nav>
|
||||
</foreignObject>
|
||||
fill="white"
|
||||
stroke="currentColor"
|
||||
variant={isHomeRoute ? 'Bold' : 'Outline'}
|
||||
width={20}
|
||||
height={20} />}
|
||||
value={t('Menu')} />
|
||||
<Link
|
||||
href={`/${name}/about`}
|
||||
className={clsx(
|
||||
'flex flex-col justify-arround items-center gap-[5px] text-primary pointer-events-auto **:stroke-primary min-w-0 dark:text-white dark:**:stroke-white'
|
||||
)}
|
||||
>
|
||||
<div className="shrink-0 text-primary dark:text-white">
|
||||
<Building
|
||||
key={`building-${buildingVariant}-${isAboutRoute}`}
|
||||
size={20}
|
||||
variant={buildingVariant as 'Bold' | 'Outline'}
|
||||
color="currentColor"
|
||||
className='stroke-0'
|
||||
/>
|
||||
</div>
|
||||
<span className="text-xs2 text-center truncate w-full dark:text-white">
|
||||
{t('about')}
|
||||
</span>
|
||||
</Link>
|
||||
<BottomNavLink href={`/${name}/favorite`} onClick={handleFavoritesClick} icon={<HeartIcon width={20} height={20} />} value={t('Favorites')} />
|
||||
</nav>
|
||||
|
||||
<defs>
|
||||
<filter
|
||||
id="filter0_d_9095_18036"
|
||||
x="0"
|
||||
y="0"
|
||||
width="100%"
|
||||
height="100%"
|
||||
filterUnits="userSpaceOnUse"
|
||||
colorInterpolationFilters="sRGB"
|
||||
>
|
||||
<feFlood floodOpacity="0" result="BackgroundImageFix" />
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
/>
|
||||
<feOffset dy="-2" />
|
||||
<feGaussianBlur stdDeviation="7" />
|
||||
<feComposite in2="hardAlpha" operator="out" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0"
|
||||
/>
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_9095_18036"
|
||||
/>
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_9095_18036"
|
||||
result="shape"
|
||||
/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
{/* Badge Layer - خارج از SVG - دقیقاً مثل foreignObject */}
|
||||
{cartItemsCount > 0 && (
|
||||
<div
|
||||
className="absolute left-0 right-0 pointer-events-none"
|
||||
@@ -195,4 +152,4 @@ function BottomNavBar({ onPagerClick }: BottomNavBarProps) {
|
||||
)
|
||||
}
|
||||
|
||||
export default BottomNavBar
|
||||
export default BottomNavBar
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import type { CSSProperties } from "react";
|
||||
|
||||
export const BOTTOM_NAV_SHAPE_PATH =
|
||||
"M218 16C229.034 16 238.711 22.0313 244.148 31.0943C245.844 33.9222 248.724 36 252.022 36H406C414.837 36 422 43.1634 422 52V80C422 88.8366 414.837 96 406 96H30C21.1634 96 14 88.8366 14 80V52C14 43.1634 21.1634 36 30 36H183.979C187.277 36 190.157 33.9222 191.853 31.0943C197.29 22.0315 206.966 16.0001 218 16Z";
|
||||
|
||||
export const BOTTOM_NAV_VIEWBOX = "0 0 436 104";
|
||||
|
||||
export function getBottomNavMaskStyle(): CSSProperties {
|
||||
const maskSvg = `<svg viewBox="${BOTTOM_NAV_VIEWBOX}" xmlns="http://www.w3.org/2000/svg"><path fill="white" d="${BOTTOM_NAV_SHAPE_PATH}"/></svg>`;
|
||||
const maskUrl = `url("data:image/svg+xml,${encodeURIComponent(maskSvg)}")`;
|
||||
|
||||
return {
|
||||
WebkitMaskImage: maskUrl,
|
||||
maskImage: maskUrl,
|
||||
WebkitMaskSize: "100% 100%",
|
||||
maskSize: "100% 100%",
|
||||
WebkitMaskRepeat: "no-repeat",
|
||||
maskRepeat: "no-repeat",
|
||||
};
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import { usePathname, useRouter } from 'next/navigation';
|
||||
import usePreference from '@/hooks/helpers/usePreference';
|
||||
import PagerModal from '../pager/PagerModal';
|
||||
import clsx from 'clsx';
|
||||
import { glassSurface } from '@/lib/styles/glassSurface';
|
||||
|
||||
type Props = {} & React.AllHTMLAttributes<HTMLBodyElementEventMap>
|
||||
|
||||
@@ -54,7 +55,7 @@ function ClientMenuRouteWrapper({ children }: Props) {
|
||||
return (
|
||||
<div className="h-svh overflow-hidden pt-10 flex flex-col pb-4 xl:pt-12">
|
||||
|
||||
<div className="z-50 fixed right-4 left-4 xl:right-[285px] top-4 xl:h-16 h-12 flex items-center px-4 bg-container justify-between rounded-[32px] xl:w-[calc(100%-305px)]">
|
||||
<div className={glassSurface('z-50 fixed right-4 left-4 xl:right-[285px] top-4 xl:h-16 h-12 flex items-center px-4 justify-between rounded-[32px] xl:w-[calc(100%-305px)]')}>
|
||||
<TopBar
|
||||
profileDropState={profileDrop}
|
||||
toggleProfileDropState={toggleProfileDrop}
|
||||
|
||||
Reference in New Issue
Block a user