Store Navigations
Store Navigations é um componente de navegação para React e Tailwind CSS, da biblioteca Bund UI, com licença MIT. Copia e cola no teu projeto.
Bund UI
MIT
navigation
O que é
Store Navigations é um componente de navegação para React e Tailwind CSS, da biblioteca Bund UI, 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 lucide-react
Licença
Este componente vem de Bund UI e é redistribuído sob a licença MIT, que permite uso comercial. O aviso de copyright viaja com o código.
Store Navigations
import * as React from "react";
export const BagIcon = (props: React.SVGProps<SVGSVGElement>) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1"
stroke-linecap="round"
stroke-linejoin="round"
{...props}>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M3 7m0 2a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v9a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z" />
<path d="M8 7v-2a2 2 0 0 1 2 -2h4a2 2 0 0 1 2 2v2" />
<path d="M12 12l0 .01" />
<path d="M3 13a20 20 0 0 0 18 0" />
</svg>
);
};
export const JewelryIcon = (props: React.SVGProps<SVGSVGElement>) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1"
stroke-linecap="round"
stroke-linejoin="round"
{...props}>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M6 5h12l3 5l-8.5 9.5a.7 .7 0 0 1 -1 0l-8.5 -9.5l3 -5" />
<path d="M10 12l-2 -2.2l.6 -1" />
</svg>
);
};
export const SunglassesIcon = (props: React.SVGProps<SVGSVGElement>) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1"
stroke-linecap="round"
stroke-linejoin="round"
{...props}>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M8 3h-2l-3 9" />
<path d="M16 3h2l3 9" />
<path d="M3 12v7a1 1 0 0 0 1 1h4.586a1 1 0 0 0 .707 -.293l2 -2a1 1 0 0 1 1.414 0l2 2a1 1 0 0 0 .707 .293h4.586a1 1 0 0 0 1 -1v-7h-18z" />
<path d="M7 16h1" />
<path d="M16 16h1" />
</svg>
);
};
export const HatIcon = (props: React.SVGProps<SVGSVGElement>) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1"
stroke-linecap="round"
stroke-linejoin="round"
{...props}>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M6 10.5l1.436 -4c.318 -.876 .728 -1.302 1.359 -1.302c.219 0 1.054 .365 1.88 .583c.825 .219 .733 -.329 .908 -.487c.176 -.158 .355 -.294 .61 -.294c.242 0 .553 .048 1.692 .448c.759 .267 1.493 .574 2.204 .922c1.175 .582 1.426 .913 1.595 1.507l.816 4.623c2.086 .898 3.5 2.357 3.5 3.682c0 1.685 -1.2 3.818 -5.957 3.818c-6.206 0 -14.043 -4.042 -14.043 -7.32c0 -1.044 1.333 -1.77 4 -2.18z" />
<path d="M6 10.5c0 .969 4.39 3.5 9.5 3.5c1.314 0 3 .063 3 -1.5" />
</svg>
);
};
export const BeltIcon = (props: React.SVGProps<SVGSVGElement>) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1"
stroke-linecap="round"
stroke-linejoin="round"
{...props}>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M7 17m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0" />
<path d="M17 17m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0" />
<path d="M9.15 14.85l8.85 -10.85" />
<path d="M6 4l8.85 10.85" />
</svg>
);
};
export const OtherIcon = (props: React.SVGProps<SVGSVGElement>) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1"
stroke-linecap="round"
stroke-linejoin="round"
{...props}>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M6 4a4 4 0 0 1 4 3.8l0 .2v10.5a1.5 1.5 0 0 1 -3 0v-6.5h-1a4 4 0 0 1 -4 -3.8l0 -.2a4 4 0 0 1 4 -4z" />
<path d="M18 4a4 4 0 0 0 -4 3.8l0 .2v10.5a1.5 1.5 0 0 0 3 0v-6.5h1a4 4 0 0 0 4 -3.8l0 -.2a4 4 0 0 0 -4 -4z" />
</svg>
);
};
"use client";
import * as React from "react";
import Link from "next/link";
import { HeartIcon, MenuIcon, SearchIcon, ShoppingBag } from "lucide-react";
import {
NavigationMenu,
NavigationMenuContent,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuList,
NavigationMenuTrigger,
navigationMenuTriggerStyle
} from "@/components/ui/navigation-menu";
import { Button } from "@/components/ui/button";
import { Sheet, SheetContent } from "@/components/ui/sheet";
import { Separator } from "@/components/ui/separator";
import { Badge } from "@/components/ui/badge";
import { BagIcon, BeltIcon, HatIcon, JewelryIcon, OtherIcon, SunglassesIcon } from "./icons";
type ListItemType = {
title: string;
href?: string;
description?: string;
icon?: React.ComponentType<React.SVGProps<SVGSVGElement>>;
};
const accessoriesMenuItems: ListItemType[] = [
{
title: "Bags",
href: "#",
icon: BagIcon
},
{
title: "Jewelry",
href: "#",
icon: JewelryIcon
},
{
title: "Sunglasses",
href: "#",
icon: SunglassesIcon
},
{
title: "Hats & Beanies",
href: "#",
icon: HatIcon
},
{
title: "Belts",
href: "#",
icon: BeltIcon
},
{
title: "All Accessories",
href: "#",
icon: OtherIcon
}
];
const collectionItems = [
{
title: "Trends",
href: "#",
description: "Discover this summer's trendy products."
},
{
title: "Best Sellers",
href: "#",
description: "We've collected the best-selling products for you."
},
{
title: "New Arrivals",
href: "#",
description: "Discover the most favorited products."
}
];
export default function NavigationMenuDemo() {
const [open, setOpen] = React.useState(false);
return (
<>
<header>
<div className="flex grid-cols-3 items-center justify-between p-4">
{/* left content and log */}
<Link href="/" className="flex items-center gap-2">
<img className="size-6" src="/logo.svg" alt="bundui svg logo" />
<span className="text-base font-medium">Bundui</span>
</Link>
{/* main navigation */}
<NavigationMenu className="hidden lg:block">
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuTrigger>Collections</NavigationMenuTrigger>
<NavigationMenuContent>
<ul className="grid gap-0 md:w-[400px] lg:w-[500px] lg:grid-cols-[.75fr_1fr]">
<li className="row-span-3">
<NavigationMenuLink asChild>
<Link
href="#"
className="block space-y-2"
onClick={(e) => e.preventDefault()}>
<img
src="/images/products/list1.png"
alt="..."
className="aspect-4/3 w-96 rounded object-cover"
/>
<div className="space-y-1">
<div className="text-sm leading-none font-medium">
Timeless Classics
</div>
<p className="text-muted-foreground line-clamp-2 text-sm leading-snug">
Elevate your style with essentials
</p>
</div>
</Link>
</NavigationMenuLink>
</li>
{collectionItems.map((item, i) => (
<Link
href={`${item.href}`}
className="hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground gap-2 space-y-1 rounded-md p-3 leading-none no-underline transition-colors outline-none select-none"
onClick={(e) => e.preventDefault()}>
<div className="text-sm leading-none font-medium">{item.title}</div>
<p className="text-muted-foreground line-clamp-2 text-sm leading-snug">
{item.description}
</p>
</Link>
))}
</ul>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuTrigger>Accessories</NavigationMenuTrigger>
<NavigationMenuContent>
<ul className="grid w-[400px] list-none grid-cols-2 gap-3 lg:w-[300px]">
{accessoriesMenuItems.map((item, i) => (
<NavigationMenuLink asChild>
<Link
href={`${item.href}`}
className="hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground flex justify-center gap-2 space-y-1 rounded-md p-3 text-center leading-none no-underline transition-colors outline-none select-none"
onClick={(e) => e.preventDefault()}>
{item.icon ? (
<item.icon className="text-muted-foreground mx-auto size-8" />
) : null}
<span className="block text-sm leading-none font-medium">
{item.title}
</span>
</Link>
</NavigationMenuLink>
))}
</ul>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink asChild>
<Link
href="#"
className={navigationMenuTriggerStyle()}
onClick={(e) => e.preventDefault()}>
Women
</Link>
</NavigationMenuLink>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink asChild>
<Link
href="#"
className={navigationMenuTriggerStyle()}
onClick={(e) => e.preventDefault()}>
Men
</Link>
</NavigationMenuLink>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
{/* right content */}
<div className="flex items-center gap-1">
<Button variant="ghost">
<SearchIcon />
</Button>
<Button variant="ghost">
<HeartIcon />
</Button>
<Button variant="ghost" size="icon" className="relative" aria-label="Cart">
<ShoppingBag aria-hidden="true" />
<Badge className="absolute -top-1 left-full size-4 -translate-x-1/2 rounded-full p-0 text-[10px]">
4
</Badge>
</Button>
<div className="ms-3 flex items-center gap-1">
<Button variant="secondary">Sign in</Button>
<Button variant="ghost" onClick={() => setOpen(true)} className="lg:hidden">
<MenuIcon />
</Button>
</div>
</div>
</div>
</header>
{/* for mobile navigation */}
<Sheet open={open} onOpenChange={setOpen}>
<SheetContent className="space-y-4 overflow-auto p-4">
<div className="space-y-2">
<div className="font-medium">Collections</div>
<ul className="space-y-4">
<li>
<Link
href="#"
className="block space-y-2 rounded-md border p-3"
onClick={(e) => e.preventDefault()}>
<img
src="/images/products/list1.png"
alt="..."
className="aspect-4/3 w-96 rounded object-cover"
/>
<div className="space-y-1">
<div className="text-sm leading-none font-medium">Timeless Classics</div>
<p className="text-muted-foreground line-clamp-2 text-sm leading-snug">
Elevate your style with essentials
</p>
</div>
</Link>
</li>
{collectionItems.map((item, i) => (
<li key={i}>
<Link
href={`${item.href}`}
className="block gap-2 space-y-1 leading-none no-underline outline-none"
onClick={(e) => e.preventDefault()}>
<div className="text-sm leading-none font-medium">{item.title}</div>
<p className="text-muted-foreground line-clamp-2 text-sm leading-snug">
{item.description}
</p>
</Link>
</li>
))}
</ul>
</div>
<Separator />
<div className="space-y-2">
<div className="font-medium">Accessories</div>
<ul className="grid list-none grid-cols-2 gap-2">
{accessoriesMenuItems.map((item, i) => (
<Link
key={i}
href={`${item.href}`}
className="bg-muted/50 flex flex-col justify-center gap-2 space-y-1 rounded-md p-3 text-center leading-none no-underline transition-colors"
onClick={(e) => e.preventDefault()}>
{item.icon ? (
<item.icon className="text-muted-foreground mx-auto size-8" />
) : null}
<span className="block text-sm leading-none font-medium">{item.title}</span>
</Link>
))}
</ul>
</div>
<div className="space-y-2">
<Link
href="#"
className="bg-muted/50 flex flex-col justify-center gap-2 space-y-1 rounded-md p-3 text-center leading-none no-underline transition-colors">
Men
</Link>
<Link
href="#"
className="bg-muted/50 flex flex-col justify-center gap-2 space-y-1 rounded-md p-3 text-center leading-none no-underline transition-colors">
Women
</Link>
</div>
</SheetContent>
</Sheet>
{/* fake content */}
<main className="bg-muted/50 min-h-[500px]"></main>
</>
);
}