Introduction
| Overview |
|---|
| Styling - TailwindCSS, Conditional styles or the asChild Parameter |
| Shadcn & Tweakcn - The component library from tomorrow |
| Dark and Light Mode - The most important functionality in web design |
| Lucide react - The easiest way to implement icons |
Styling
Tailwind CSS
Tailwind is a convenient way to make use of predefined classes that help me create good looking UIs. While it takes some time to get used to all this classes, after some time they will make development way faster - finally no headache wich dealing with plain css anymore.
There are some very useful VS Code Extensions for Tailwind.
| Extension | Description |
|---|---|
| Headwind | Sorts the classes in the same order |
| Tailwind CSS IntelliSense | VS Code auto completion and suggestions |
| Tailwind Documentation | Access the official Documentation inside VS Code |
| Tailwind Fold | Fold the classes, to make the files easier to view |
Here I list some interesting CSS classes so I hopefully will remember them.
| ClassName | Description |
|---|---|
| truncate | Breaks the sentence when to long⦠|
| line-clamp-3 | Max 3 lines of text before truncated⦠|
Conditional styles
One way of using conditional styling is with the tool clsx
npm install --save clsx
asChild
A convenient way to pass a certain style of element A to element B is with the asChild parameter. This parameter will pass down the style to is child without the parent element to be rendered.
<Button asChild variant="outline">
<Link href={ticketsPath()}>Go to Tickets</Link>
</Button>Alternative I could also pass to the child element this className to directly access the style of the button without having to wrap the link.
className={buttonVariants({ variant: "outline"}Shadcn & Tweakcn
The component library Shadcn
Creating every component dosenβt just take a lot of time, but often it also looks bad and the application ends up inconsistent. Because of that I like to use tools like shadcn wich delivers good looking components out of the box. Even better since these components can still be customized with Tailwind CSS since they themself were build with Tailwind CSS.
For setting up shadcn I only need to run inside my project this command:
npx shadcn@latest initI will be prompted wich base color I like, wich I often answer with Neutral, since Iβm gonna change the theme anyway later with tweakcn.
Shadcn will also add new files to the project structure and updated the global.css file
/components.json
/src/lib/utils.ts
/src/components/ui => once a component is added| Source |
|---|
| π Shadcn Documentation > Install in Next.js |
Adding components In order to add now shadcn components, I only need to look them up in the documentation and run the documented command.
This is the example command for a shadcn button
npx shadcn@latest add buttonCustom themes with tweakcn
Shadcn looks by default alredy pretty nice but together with tweakcn itβs just a completely different level. The way I can customize my whole theme with only a few button clicks just flashes me every time again. This is developer experience from another planet - big thanks to the creators <3
And thats not all, adding a new custom theme to my existing project couldnβt be easier. Literally all I need to do once Iβm happy with my theme, is to click on the {} Code Button and copy & paste the command.
npx shadcn@latest add https://tweakcn.com/r/themes/solar-dusk.jsonDark and Light
In order to enable the dark and light theme, I first need to install next-themes with this command
npm install next-themesAs next I will need a location for the theme provider and switcher.
src/
βββ components/
βββ theme/
βββ theme-provider.tsx
βββ theme-switcher.tsx
Theme Provider
The theme provider is used to take the default theme provider from next.js and customize it according to my preferring. With abstracting the theme-provider into its own file, itβs also gonna be easier to move it between different projects.
import { ThemeProvider as BaseThemeProvider } from "next-themes";
type ThemeProviderProps = {
children: React.ReactNode;
};
const ThemeProvider = ({ children }: ThemeProviderProps) => {
return (
<BaseThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
// disableTransitionOnChange
>
{children}
</BaseThemeProvider>
);
};
export { ThemeProvider };Now I need to wrap the whole <body> in the root layout.tsx with the <ThemeProvider>.
- Note for the HydrationWarning: For now I will add the suppressHydrationWarning to the <html> element. Later in the Road to Next course, I will learn a better way to handle this issue. lookupβοΈ
<html suppressHydrationWarning lang="en">
<body>
{/* Wrap here */}
<ThemeProvider>
<Header></Header>
<main>
{children}
</main>
</ThemeProvider>
</body>
</html>- Note for the import: I should not import the ThemeProvider from βnext-themesβ, instead I should choose my custom made ThemeProvider.
import { ThemeProvider } from "@/components/theme/theme-provider";ThemeSwitcher
The ThemeSwitcher component will enable me to switch between both themes. Its basically a button that onClick toggles the selectedThemes. Depending on the current theme, the button will contain a Moon or a Sun Icon.
"use client";
import { LucideMoon, LucideSun } from "lucide-react";
import { useTheme } from "next-themes";
import { Button } from "@/components/ui/button";
const ThemeSwitcher = () => {
const { theme, setTheme } = useTheme();
return (
<Button
variant="outline"
size="icon"
onClick={() => setTheme(theme === "light" ? "dark" : "light")}
>
<LucideSun
className="
h-4 w-4 rotate-0 scale-100 transition-all
dark:-rotate-90 dark:scale-0
"
/>
<LucideMoon
className="
absolute h-4 w-4 rotate-90 scale-0 transition-transform
dark:rotate-0 dark:scale-100
"
/>
<span className="sr-only">Toggle theme</span>
</Button>
);
};
export { ThemeSwitcher };Thatβs it, now I just need to add the ThemeSwitcherComponent somewhere within my application and then I can switch between light and dark mode.
| Sources |
|---|
| π₯ Road to Next Video > Light & Dark Mode |
Lucide react
Lucide is a great source for finding all kinds of icon. The icon variety is not only very diverse, but its also extremely easy to import them in my project.
| Source |
|---|
| Explore Lucide icons |
Installation
When creating a next.js project, it ususally supports lucide icons out of the box. However itβs also possible to install the package manually with
npm install lucide-reactAdd a icon to the project
All i need to do for importing a lucide icon, is to open the one i like and click on the Copy JSX button. Then head over to my codebase and paste it.
While itβs just optional, itβs recommended to use the prefix Lucide. With that I can avoid naming issues with other components like the once from shadcn, since both can have the same name quite often.
<Castle /> // Default
<LucideCastle />. // Preferred naming conventionConclusion
Next.js really manages it to get rid of my biggest issue when creating a software - they always look awful. Making use of the styling and theming ability of the ecosystem of Next.js, just brings my application on a completely different level without spending years on a design carrier. Alone tweakcn, which offers an incredible amount of flexibility to shadcn components, leaves me speakless. Finally Iβm able to create beautiful web apps in no time.