Magnified Tab
Magnified Tab é um componente de navegação para React e Tailwind CSS, da biblioteca UI Layouts, com licença MIT. Copia e cola no teu projeto.
UI Layouts
MIT
navigation
O que é
Magnified Tab é um componente de navegação para React e Tailwind CSS, da biblioteca UI Layouts, com licença MIT. Copia e cola no teu projeto.
Como usar
Abre o componente no catálogo, carrega em copiar, e cola no teu projeto. O prompt copiado leva o código e as regras para o teu agente o reproduzir sem alterar nada.
Cinco cópias grátis por mês. Sem cartão.
Precisa de
npm i motion @radix-ui/react-tooltip
Licença
Este componente vem de UI Layouts e é redistribuído sob a licença MIT, que permite uso comercial. O aviso de copyright viaja com o código.
Magnified Tab
//@ts-nocheck
'use client';
import { Icons } from '@/assets/icons/Icons';
import preview from '@/assets/preview/Preview';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '@/components/ui/magnified-doc';
import { apps } from '@/components/website/constant';
import {
AnimatePresence,
type MotionValue,
motion,
useMotionValue,
useSpring,
useTransform,
} from 'motion/react';
import Image from 'next/image';
import React, { useRef, useState } from 'react';
const Component = React.forwardRef((props, ref) => <Image {...props} ref={ref} alt='App' />);
const MotionComponent = motion(Component);
function MagnifiedDocOneFile() {
const mouseX = useMotionValue(Number.POSITIVE_INFINITY);
const [index, setIndex] = useState(0);
const [prevIndex, setPrevIndex] = useState(0);
const handleClick = (i: React.SetStateAction<number>) => {
setPrevIndex(index);
setIndex(i);
};
const isForward = index > prevIndex || (index === 0 && prevIndex === apps.length - 1);
return (
<>
<div className='relative [box-shadow] w-4/5 mx-auto rounded-xl dark:bg-neutral-950 bg-neutral-300 [box-shadow:inset_1px_-1px_4px_rgba(0_0_0,0.5)] overflow-hidden '>
<div className='relative'>
{apps.map((app, i) => {
return (
<>
<AnimatePresence mode={'popLayout'}>
{index === i && (
<motion.div
initial={{
opacity: 0,
y: isForward ? 30 : -30,
}}
animate={{
opacity: 1,
y: 0,
}}
exit={{
opacity: 0,
y: isForward ? -30 : 30,
}}
transition={{
ease: 'easeInOut',
duration: 0.3,
delay: 0.4,
}}
className='w-full h-full cursor-pointer'
onClick={app?.onClick}
>
<Image
src={app?.imgSrc}
alt='images'
width={1000}
height={1000}
className='w-full sm:h-[500px] h-[400px] object-cover rounded-lg'
/>
</motion.div>
)}
</AnimatePresence>
</>
);
})}
<div className='absolute bottom-0 left-0 w-full z-20'>
<div className='w-fit mx-auto'>
<TooltipProvider delayDuration={0}>
<motion.div
onMouseMove={(e) => mouseX.set(e.pageX)}
onMouseLeave={() => mouseX.set(Number.POSITIVE_INFINITY)}
className='mx-auto flex sm:h-[57px] h-[52px] w-fit items-end gap-2 rounded-t-lg px-2 pb-2 dark:bg-neutral-800/80 bg-white/50 backdrop-blur-xs border-t border-l border-r '
>
{apps.map((app, i) => {
return (
<Tooltip key={app.id}>
<TooltipTrigger onClick={() => handleClick(i)}>
<span className='sr-only'>{app.name}</span>
<AppIcon mouseX={mouseX} src={app.icon} />
</TooltipTrigger>
<TooltipContent className='py-1 px-3 rounded-xs' sideOffset={8}>
<p className='text-xs'>{app.name}</p>
</TooltipContent>
</Tooltip>
);
})}
</motion.div>
</TooltipProvider>
</div>
</div>
</div>
</div>
</>
);
}
function AppIcon({ mouseX, src }: { mouseX: MotionValue; src: any }) {
const ref = useRef<HTMLDivElement>(null);
const distance = useTransform(mouseX, (val) => {
const bounds = ref.current?.getBoundingClientRect() ?? { x: 0, width: 0 };
return val - bounds.x - bounds.width / 2;
});
const widthSync = useTransform(distance, [-100, 0, 100], [40, 55, 40]);
const width = useSpring(widthSync, {
mass: 0.1,
stiffness: 150,
damping: 12,
});
return (
<>
<MotionComponent
src={src}
width={60}
height={60}
alt=''
quality={100}
ref={ref}
style={{ width }}
className='aspect-square rounded-lg sm:w-8 w-6 object-cover'
/>
</>
);
}
export default MagnifiedDocOneFile;
'use client';
import { cn } from '@/lib/utils';
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
import * as React from 'react';
const TooltipProvider = TooltipPrimitive.Provider;
const Tooltip = TooltipPrimitive.Root;
const TooltipTrigger = TooltipPrimitive.Trigger;
const TooltipContent = React.forwardRef<
React.ElementRef<typeof TooltipPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
>(({ className, sideOffset = 4, ...props }, ref) => (
<TooltipPrimitive.Portal>
<TooltipPrimitive.Content
ref={ref}
sideOffset={sideOffset}
className={cn(
'z-50 overflow-hidden rounded-lg border dark:bg-neutral-800 bg-neutral-50 backdrop-filter dark:border-[#2C2C2C] backdrop-blur-lg dark:bg-[#1A1A1A]/95 px-4 py-3 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
className
)}
{...props}
/>
</TooltipPrimitive.Portal>
));
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };