Skip to content

Commit ba52f79

Browse files
committed
Theme provider added
1 parent 995cb04 commit ba52f79

File tree

7 files changed

+164
-23
lines changed

7 files changed

+164
-23
lines changed

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
components/ui/*

app/layout.tsx

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,45 @@
1-
import type { Metadata } from "next";
2-
import { Geist, Geist_Mono } from "next/font/google";
3-
import "./globals.css";
1+
import { ThemeProvider } from '@/components/theme-provider';
2+
import type { Metadata } from 'next';
3+
import { Geist, Geist_Mono } from 'next/font/google';
4+
import './globals.css';
45

56
const geistSans = Geist({
6-
variable: "--font-geist-sans",
7-
subsets: ["latin"],
7+
variable: '--font-geist-sans',
8+
subsets: ['latin'],
89
});
910

1011
const geistMono = Geist_Mono({
11-
variable: "--font-geist-mono",
12-
subsets: ["latin"],
12+
variable: '--font-geist-mono',
13+
subsets: ['latin'],
1314
});
1415

1516
export const metadata: Metadata = {
16-
title: "Create Next App",
17-
description: "Generated by create next app",
17+
title: 'Tarikul',
18+
description:
19+
'Tarikul is a software engineer with a passion for building web applications with 5+ years of experience.',
1820
};
1921

2022
export default function RootLayout({
21-
children,
23+
children,
2224
}: Readonly<{
23-
children: React.ReactNode;
25+
children: React.ReactNode;
2426
}>) {
25-
return (
26-
<html lang="en">
27-
<body
28-
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
29-
>
30-
{children}
31-
</body>
32-
</html>
33-
);
27+
return (
28+
<html
29+
lang="en"
30+
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
31+
suppressHydrationWarning
32+
>
33+
<body>
34+
<ThemeProvider
35+
attribute="class"
36+
defaultTheme="system"
37+
enableSystem
38+
disableTransitionOnChange
39+
>
40+
{children}
41+
</ThemeProvider>
42+
</body>
43+
</html>
44+
);
3445
}

app/page.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1+
import { Button } from '@/components/ui/button';
2+
13
const Home = () => {
2-
return <div>Home</div>;
4+
return (
5+
<div>
6+
<h1>Home</h1>
7+
<Button>Click me</Button>
8+
</div>
9+
);
310
};
411

512
export default Home;

components/theme-provider.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
'use client';
2+
3+
import { ThemeProvider as NextThemesProvider } from 'next-themes';
4+
import * as React from 'react';
5+
6+
export function ThemeProvider({
7+
children,
8+
...props
9+
}: React.ComponentProps<typeof NextThemesProvider>) {
10+
return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
11+
}

components/ui/button.tsx

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import * as React from "react"
2+
import { Slot } from "@radix-ui/react-slot"
3+
import { cva, type VariantProps } from "class-variance-authority"
4+
5+
import { cn } from "@/lib/utils"
6+
7+
const buttonVariants = cva(
8+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
9+
{
10+
variants: {
11+
variant: {
12+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
13+
destructive:
14+
"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
15+
outline:
16+
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
17+
secondary:
18+
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
19+
ghost:
20+
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
21+
link: "text-primary underline-offset-4 hover:underline",
22+
},
23+
size: {
24+
default: "h-9 px-4 py-2 has-[>svg]:px-3",
25+
xs: "h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
26+
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
27+
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
28+
icon: "size-9",
29+
"icon-xs": "size-6 rounded-md [&_svg:not([class*='size-'])]:size-3",
30+
"icon-sm": "size-8",
31+
"icon-lg": "size-10",
32+
},
33+
},
34+
defaultVariants: {
35+
variant: "default",
36+
size: "default",
37+
},
38+
}
39+
)
40+
41+
function Button({
42+
className,
43+
variant = "default",
44+
size = "default",
45+
asChild = false,
46+
...props
47+
}: React.ComponentProps<"button"> &
48+
VariantProps<typeof buttonVariants> & {
49+
asChild?: boolean
50+
}) {
51+
const Comp = asChild ? Slot : "button"
52+
53+
return (
54+
<Comp
55+
data-slot="button"
56+
data-variant={variant}
57+
data-size={size}
58+
className={cn(buttonVariants({ variant, size, className }))}
59+
{...props}
60+
/>
61+
)
62+
}
63+
64+
export { Button, buttonVariants }

package-lock.json

Lines changed: 47 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
"lint": "eslint"
1010
},
1111
"dependencies": {
12+
"@radix-ui/react-slot": "^1.2.4",
1213
"class-variance-authority": "^0.7.1",
1314
"clsx": "^2.1.1",
1415
"lucide-react": "^0.563.0",
1516
"next": "16.1.6",
17+
"next-themes": "^0.4.6",
1618
"react": "19.2.3",
1719
"react-dom": "19.2.3",
1820
"tailwind-merge": "^3.4.0"

0 commit comments

Comments
 (0)