Tailwind Components
Table of Contents
Open Table of Contents
Navbar
Simple Navbar with animated hamburger icon

External package used: hamburger-react
npm i hamburger-react
Btn component
import React from 'react'
type BtnProps = {
variant: number;
href: string
children: React.ReactNode;
}
const btnStyles = [
'border-2 rounded px-6 py-1 hover:text-gray-950 hover:border-gray-950/60 transition',
'border-2 rounded px-6 py-2 text-white',
]
const Btn = ({ variant, href, children }: BtnProps) => {
const style = btnStyles[variant]
return (
<a className={style} href={href}>{children}</a>
)
}
export default Btn
Navbar
import { useState } from 'react'
import Hamburger from 'hamburger-react'
import Btn from './Btn'
enum BtnType {
NavbarLong = 0,
NavbarShort,
}
const Navbar = () => {
const [isOpen, setOpen] = useState(false)
return (
<nav className='max-w-7xl mx-auto flex items-center justify-between px-4'>
<a href='#'>
Logo
</a>
<div className="hidden md:flex space-x-20 font-roboto text-gray-700/70">
<Btn variant={BtnType.NavbarLong} href={'#'}>Blog</Btn>
<Btn variant={BtnType.NavbarLong} href={'#'}>Contacts</Btn>
<Btn variant={BtnType.NavbarLong} href={'#'}>About</Btn>
<Btn variant={BtnType.NavbarLong} href={'#'}>Login</Btn>
</div>
<div className="md:hidden relative"><Hamburger toggled={isOpen} toggle={setOpen} rounded />
<div className={`${isOpen ? 'max-h-[300px] py-2' : 'max-h-0 overflow-hidden py-0'} transition-all ease-in-out duration-200 flex flex-col font-roboto text-2xl text-gray-700 absolute -right-4 space-y-3 px-8 bg-gradient-to-t from-indigo-500 to-cyan-500 w-screen`}>
<Btn variant={BtnType.NavbarShort} href={'#'}>Blog</Btn>
<Btn variant={BtnType.NavbarShort} href={'#'}>Contacts</Btn>
<Btn variant={BtnType.NavbarShort} href={'#'}>About</Btn>
<Btn variant={BtnType.NavbarShort} href={'#'}>Login</Btn>
</div>
</div>
</nav>
)
}
export default Navbar
Theming in React/Nextjs
Important files
src
│── App.jsx
│── styles
│ ├── global.css
│ └── utils.css
└── tailwind.config.js
// App.jsx/layout.tsx
import "@/styles/globals.css";
import type { AppProps } from "next/app";
import { useEffect } from "react";
export default function App({ Component, pageProps }: AppProps) {
useEffect(() => {
// NOTE: This should be set based on some kind of toggle or theme selector.
// I've added this here for demonstration purposes
localStorage.setItem("theme", "light");
// If the user has selected a theme, use that
const selectedTheme = localStorage.getItem("theme");
if (selectedTheme) {
document.body.classList.add(selectedTheme);
// Else if the users OS preferences prefers dark mode
} else if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
document.body.classList.add("dark");
// Else use light mode
} else {
document.body.classList.add("light");
}
}, []);
return <Component {...pageProps} />;
}
@tailwind base;
@tailwind components;
@tailwind utilities;
.light {
--background: 245, 245, 245;
--border: 212, 212, 212;
--card: 255, 255, 255;
--copy-primary: 23, 23, 23;
--copy-secondary: 115, 115, 115;
--cta: 139, 92, 246;
--cta-active: 124, 58, 237;
--cta-text: 255, 255, 255;
background: rgba(var(--background));
}
.dark {
--background: 0, 0, 0;
--border: 38, 38, 38;
--card: 23, 23, 23;
--copy-primary: 250, 250, 250;
--copy-secondary: 115, 115, 115;
--cta: 99, 102, 241;
--cta-active: 79, 70, 229;
--cta-text: 255, 255, 255;
background: rgba(var(--background));
}
.red {
--background: 254, 202, 202;
--border: 185, 28, 28;
--card: 239, 68, 68;
--copy-primary: 250, 250, 250;
--copy-secondary: 254, 226, 226;
--cta: 250, 250, 250;
--cta-active: 254, 226, 226;
--cta-text: 239, 68, 68;
background: rgba(var(--background));
}
:root {
--grape: 114, 35, 204;
}
/* :root {
--background: 245, 245, 245;
--border: 212, 212, 212;
--card: 255, 255, 255;
--copy-primary: 23, 23, 23;
--copy-secondary: 115, 115, 115;
--cta: 139, 92, 246;
--cta-active: 124, 58, 237;
--cta-text: 255, 255, 255;
}
body {
background: rgba(var(--background));
}
@media (prefers-color-scheme: dark) {
:root {
--background: 0, 0, 0;
--border: 38, 38, 38;
--card: 23, 23, 23;
--copy-primary: 250, 250, 250;
--copy-secondary: 115, 115, 115;
--cta: 99, 102, 241;
--cta-active: 79, 70, 229;
--cta-text: 255, 255, 255;
}
} */
// tailwind.config.ts
import type { Config } from "tailwindcss";
const config: Config = {
content: [
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: {
extend: {
colors: {
background: "rgba(var(--background))",
border: "rgba(var(--border))",
card: "rgba(var(--card))",
"copy-primary": "rgba(var(--copy-primary))",
"copy-secondary": "rgba(var(--copy-secondary))",
cta: "rgba(var(--cta))",
"cta-active": "rgba(var(--cta-active))",
"cta-text": "rgba(var(--cta-text))",
grape: "rgba(var(--grape))",
},
},
},
plugins: [],
};
export default config;