Reputation:
I was looking through a tutorial located here: https://daily-dev-tips.com/posts/creating-a-sidebar-layout-in-nextjs-with-tailwind/ about a sidebar.
I was wondering if there was a way to use Icons (like heroicons) within the layout file. referenced below:
import Link from "next/link";
import { useRouter } from "next/router";
import HomeIcon from "@heroicons/react/outline";
export default function Layout({ children }) {
const router = useRouter();
const menuItems = [
{
href: "/",
title: "Home",
},
{
href: "/about",
title: "About",
},
{
href: "/contact",
title: "Contact",
},
];
return (
<div className="min-h-screen flex flex-col">
<header className="bg-white sticky top-0 h-14 flex justify-center items-center font-semibold uppercase">
Next.js sidebar menu
</header>
<div className="flex flex-col md:flex-row flex-1">
<aside className="bg-black w-full md:w-60">
<nav>
<ul>
{menuItems.map(({ href, title }) => (
<li className="m-2" key={title}>
<Link href={href}>
<a
className={`flex p-2 bg-black text-white rounded hover:bg-red-600 cursor-pointer ${
router.asPath === href && "bg-black text-red-600"
}`}
>
{title}
</a>
</Link>
</li>
))}
</ul>
</nav>
</aside>
<main className="flex-1">{children}</main>
</div>
</div>
);
}
I tried
href: "/",
title: "Home",
icon: <HomeIcon />,
but then I wasn't sure exactly how to incorporate it. Any ideas?
Upvotes: 3
Views: 7556
Reputation: 3925
One of the most preferred icons utility is React-icons
. You can simply install the npm
package from here.
And you can view & search icons from here.
In the code you can use it like this, suppose you want to use AiFillHome
icon, then just import it in the file like this,
import {AiFillHome} from "react-icons/ai";
And use it like
<AiFillHome />
You can check the props in the mentioned docs.
Upvotes: -1
Reputation: 2675
First, import as below:
import { ChatIcon, HomeIcon, PhoneIcon } from "@heroicons/react/outline";
Then put the icons in menu items:
const menuItems = [
{
href: "/",
title: "Homepage",
icon: <HomeIcon className="h-4 w-4 mx-2" />,
},
{
href: "/about",
title: "About",
icon: <ChatIcon className="h-4 w-4 mx-2" />,
},
{
href: "/contact",
title: "Contact",
icon: <PhoneIcon className="h-4 w-4 mx-2" />,
},
];
then, update your list by adding icon here {menuItems.map(({ href, title, icon })
and at the achor {icon} {title}
{menuItems.map(({ href, title, icon }) => (
<li className="m-2" key={title}>
<Link href={href}>
<a className={`inline-flex items-center w-full p-2 bg-fuchsia-200 rounded hover:bg-fuchsia-400 cursor-pointer ${router.asPath === href && "bg-fuchsia-600 text-white"}`}
>
{icon} {title}
</a>
</Link>
</li>
))}
and update the Link
anchor class flex
become inline-flex items-center w-full
Finally, the complete layout.js file is as follows:
import Link from "next/link";
import { useRouter } from "next/router";
import { ChatIcon, HomeIcon, PhoneIcon } from "@heroicons/react/outline";
export default function Layout({ children }) {
const router = useRouter();
const menuItems = [
{
href: "/",
title: "Homepage",
icon: <HomeIcon className="h-4 w-4 mx-2" />,
},
{
href: "/about",
title: "About",
icon: <ChatIcon className="h-4 w-4 mx-2" />,
},
{
href: "/contact",
title: "Contact",
icon: <PhoneIcon className="h-4 w-4 mx-2" />,
},
];
return (
<div className="min-h-screen flex flex-col">
<header className="bg-purple-200 sticky top-0 h-14 flex justify-center items-center font-semibold uppercase">
Next.js sidebar menu
</header>
<div className="flex flex-col md:flex-row flex-1">
<aside className="bg-fuchsia-100 w-full md:w-60">
<nav>
<ul>
{menuItems.map(({ href, title, icon }) => (
<li className="m-2" key={title}>
<Link href={href}>
<a
className={`inline-flex items-center w-full p-2 bg-fuchsia-200 rounded hover:bg-fuchsia-400 cursor-pointer ${
router.asPath === href && "bg-fuchsia-600 text-white"
}`}
>
{icon} {title}
</a>
</Link>
</li>
))}
</ul>
</nav>
</aside>
<main className="flex-1">{children}</main>
</div>
</div>
);
}
Upvotes: 2
Reputation: 545
i suggest change the array object like this.
sample https://codesandbox.io/s/epic-stitch-h5gn89?file=/src/App.js
{
href: "/",
title: "Home",
icon: "HomeIcon",
}
and use this component i found on this link.(i changed some of it) https://github.com/tailwindlabs/heroicons/issues/278#issuecomment-851594776
in this solution dont need to import eche icon one by one
DynamicHeroIcon.tsx
// DynamicHeroIcon.tsx
// Simple Dynamic HeroIcons Component for React (typescript / tsx)
// by: Mike Summerfeldt (IT-MikeS - https://github.com/IT-MikeS)
import { FC } from "react";
import * as HIcons from "@heroicons/react/outline";
const DynamicHeroIcon: FC<{ icon: string } & React.HTMLProps<HTMLElement>> = (
props
) => {
const { ...icons } = HIcons;
const Fprops = { ...props };
delete Fprops.icon;
// @ts-ignore
const TheIcon: JSX.Element = icons[props.icon];
return (
<>
{/* @ts-ignore */}
<TheIcon {...Fprops} aria-hidden="true" />
</>
);
};
export default DynamicHeroIcon;
and use it like this.
import DynamicHeroIcon from "./components/DynamicHeroIcon";
<DynamicHeroIcon style={{ width: "52px" }} icon={"HomeIcon"} />
{list.map((item) => {
return <DynamicHeroIcon style={{ width: "52px" }} icon={item.icon} />;
})}
Upvotes: 1