Skip to content

Commit 0418166

Browse files
committed
feat(ui): update shadcn/ui components, apply neutral theme, align Tailwind v4 config
1 parent f05e6e0 commit 0418166

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+5306
-668
lines changed

app/globals.css

Lines changed: 138 additions & 242 deletions
Large diffs are not rendered by default.

app/layout.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export default function RootLayout({
4949
<meta name="theme-color" content="#ffffff" />
5050
<meta
5151
name="theme-color"
52-
content="#000000"
52+
content="#0a0a0a"
5353
media="(prefers-color-scheme: dark)"
5454
/>
5555
</head>
@@ -89,7 +89,7 @@ export default function RootLayout({
8989
const isDark = document.documentElement.classList.contains('dark');
9090
const themeColorMeta = document.querySelector('meta[name="theme-color"]:not([media])');
9191
if (themeColorMeta) {
92-
themeColorMeta.setAttribute('content', isDark ? '#000000' : '#ffffff');
92+
themeColorMeta.setAttribute('content', isDark ? '#0a0a0a' : '#ffffff');
9393
}
9494
}
9595

app/page.tsx

Lines changed: 110 additions & 144 deletions
Large diffs are not rendered by default.

components.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"rsc": true,
55
"tsx": true,
66
"tailwind": {
7-
"config": "",
7+
"config": "tailwind.config.ts",
88
"css": "app/globals.css",
99
"baseColor": "neutral",
1010
"cssVariables": true,

components/ui/accordion.tsx

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
"use client"
2+
3+
import * as React from "react"
4+
import * as AccordionPrimitive from "@radix-ui/react-accordion"
5+
import { ChevronDownIcon } from "lucide-react"
6+
7+
import { cn } from "@/lib/utils"
8+
9+
function Accordion({
10+
...props
11+
}: React.ComponentProps<typeof AccordionPrimitive.Root>) {
12+
return <AccordionPrimitive.Root data-slot="accordion" {...props} />
13+
}
14+
15+
function AccordionItem({
16+
className,
17+
...props
18+
}: React.ComponentProps<typeof AccordionPrimitive.Item>) {
19+
return (
20+
<AccordionPrimitive.Item
21+
data-slot="accordion-item"
22+
className={cn("border-b last:border-b-0", className)}
23+
{...props}
24+
/>
25+
)
26+
}
27+
28+
function AccordionTrigger({
29+
className,
30+
children,
31+
...props
32+
}: React.ComponentProps<typeof AccordionPrimitive.Trigger>) {
33+
return (
34+
<AccordionPrimitive.Header className="flex">
35+
<AccordionPrimitive.Trigger
36+
data-slot="accordion-trigger"
37+
className={cn(
38+
"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180",
39+
className
40+
)}
41+
{...props}
42+
>
43+
{children}
44+
<ChevronDownIcon className="text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200" />
45+
</AccordionPrimitive.Trigger>
46+
</AccordionPrimitive.Header>
47+
)
48+
}
49+
50+
function AccordionContent({
51+
className,
52+
children,
53+
...props
54+
}: React.ComponentProps<typeof AccordionPrimitive.Content>) {
55+
return (
56+
<AccordionPrimitive.Content
57+
data-slot="accordion-content"
58+
className="data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm"
59+
{...props}
60+
>
61+
<div className={cn("pt-0 pb-4", className)}>{children}</div>
62+
</AccordionPrimitive.Content>
63+
)
64+
}
65+
66+
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }

components/ui/alert-dialog.tsx

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
"use client"
2+
3+
import * as React from "react"
4+
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"
5+
6+
import { cn } from "@/lib/utils"
7+
import { buttonVariants } from "@/components/ui/button"
8+
9+
function AlertDialog({
10+
...props
11+
}: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {
12+
return <AlertDialogPrimitive.Root data-slot="alert-dialog" {...props} />
13+
}
14+
15+
function AlertDialogTrigger({
16+
...props
17+
}: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {
18+
return (
19+
<AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />
20+
)
21+
}
22+
23+
function AlertDialogPortal({
24+
...props
25+
}: React.ComponentProps<typeof AlertDialogPrimitive.Portal>) {
26+
return (
27+
<AlertDialogPrimitive.Portal data-slot="alert-dialog-portal" {...props} />
28+
)
29+
}
30+
31+
function AlertDialogOverlay({
32+
className,
33+
...props
34+
}: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>) {
35+
return (
36+
<AlertDialogPrimitive.Overlay
37+
data-slot="alert-dialog-overlay"
38+
className={cn(
39+
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
40+
className
41+
)}
42+
{...props}
43+
/>
44+
)
45+
}
46+
47+
function AlertDialogContent({
48+
className,
49+
...props
50+
}: React.ComponentProps<typeof AlertDialogPrimitive.Content>) {
51+
return (
52+
<AlertDialogPortal>
53+
<AlertDialogOverlay />
54+
<AlertDialogPrimitive.Content
55+
data-slot="alert-dialog-content"
56+
className={cn(
57+
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
58+
className
59+
)}
60+
{...props}
61+
/>
62+
</AlertDialogPortal>
63+
)
64+
}
65+
66+
function AlertDialogHeader({
67+
className,
68+
...props
69+
}: React.ComponentProps<"div">) {
70+
return (
71+
<div
72+
data-slot="alert-dialog-header"
73+
className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
74+
{...props}
75+
/>
76+
)
77+
}
78+
79+
function AlertDialogFooter({
80+
className,
81+
...props
82+
}: React.ComponentProps<"div">) {
83+
return (
84+
<div
85+
data-slot="alert-dialog-footer"
86+
className={cn(
87+
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
88+
className
89+
)}
90+
{...props}
91+
/>
92+
)
93+
}
94+
95+
function AlertDialogTitle({
96+
className,
97+
...props
98+
}: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {
99+
return (
100+
<AlertDialogPrimitive.Title
101+
data-slot="alert-dialog-title"
102+
className={cn("text-lg font-semibold", className)}
103+
{...props}
104+
/>
105+
)
106+
}
107+
108+
function AlertDialogDescription({
109+
className,
110+
...props
111+
}: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {
112+
return (
113+
<AlertDialogPrimitive.Description
114+
data-slot="alert-dialog-description"
115+
className={cn("text-muted-foreground text-sm", className)}
116+
{...props}
117+
/>
118+
)
119+
}
120+
121+
function AlertDialogAction({
122+
className,
123+
...props
124+
}: React.ComponentProps<typeof AlertDialogPrimitive.Action>) {
125+
return (
126+
<AlertDialogPrimitive.Action
127+
className={cn(buttonVariants(), className)}
128+
{...props}
129+
/>
130+
)
131+
}
132+
133+
function AlertDialogCancel({
134+
className,
135+
...props
136+
}: React.ComponentProps<typeof AlertDialogPrimitive.Cancel>) {
137+
return (
138+
<AlertDialogPrimitive.Cancel
139+
className={cn(buttonVariants({ variant: "outline" }), className)}
140+
{...props}
141+
/>
142+
)
143+
}
144+
145+
export {
146+
AlertDialog,
147+
AlertDialogPortal,
148+
AlertDialogOverlay,
149+
AlertDialogTrigger,
150+
AlertDialogContent,
151+
AlertDialogHeader,
152+
AlertDialogFooter,
153+
AlertDialogTitle,
154+
AlertDialogDescription,
155+
AlertDialogAction,
156+
AlertDialogCancel,
157+
}

components/ui/alert.tsx

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import * as React from "react"
2+
import { cva, type VariantProps } from "class-variance-authority"
3+
4+
import { cn } from "@/lib/utils"
5+
6+
const alertVariants = cva(
7+
"relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current",
8+
{
9+
variants: {
10+
variant: {
11+
default: "bg-card text-card-foreground",
12+
destructive:
13+
"text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90",
14+
},
15+
},
16+
defaultVariants: {
17+
variant: "default",
18+
},
19+
}
20+
)
21+
22+
function Alert({
23+
className,
24+
variant,
25+
...props
26+
}: React.ComponentProps<"div"> & VariantProps<typeof alertVariants>) {
27+
return (
28+
<div
29+
data-slot="alert"
30+
role="alert"
31+
className={cn(alertVariants({ variant }), className)}
32+
{...props}
33+
/>
34+
)
35+
}
36+
37+
function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
38+
return (
39+
<div
40+
data-slot="alert-title"
41+
className={cn(
42+
"col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight",
43+
className
44+
)}
45+
{...props}
46+
/>
47+
)
48+
}
49+
50+
function AlertDescription({
51+
className,
52+
...props
53+
}: React.ComponentProps<"div">) {
54+
return (
55+
<div
56+
data-slot="alert-description"
57+
className={cn(
58+
"text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed",
59+
className
60+
)}
61+
{...props}
62+
/>
63+
)
64+
}
65+
66+
export { Alert, AlertTitle, AlertDescription }

components/ui/aspect-ratio.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 * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio"
4+
5+
function AspectRatio({
6+
...props
7+
}: React.ComponentProps<typeof AspectRatioPrimitive.Root>) {
8+
return <AspectRatioPrimitive.Root data-slot="aspect-ratio" {...props} />
9+
}
10+
11+
export { AspectRatio }

components/ui/avatar.tsx

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
"use client"
2+
3+
import * as React from "react"
4+
import * as AvatarPrimitive from "@radix-ui/react-avatar"
5+
6+
import { cn } from "@/lib/utils"
7+
8+
function Avatar({
9+
className,
10+
...props
11+
}: React.ComponentProps<typeof AvatarPrimitive.Root>) {
12+
return (
13+
<AvatarPrimitive.Root
14+
data-slot="avatar"
15+
className={cn(
16+
"relative flex size-8 shrink-0 overflow-hidden rounded-full",
17+
className
18+
)}
19+
{...props}
20+
/>
21+
)
22+
}
23+
24+
function AvatarImage({
25+
className,
26+
...props
27+
}: React.ComponentProps<typeof AvatarPrimitive.Image>) {
28+
return (
29+
<AvatarPrimitive.Image
30+
data-slot="avatar-image"
31+
className={cn("aspect-square size-full", className)}
32+
{...props}
33+
/>
34+
)
35+
}
36+
37+
function AvatarFallback({
38+
className,
39+
...props
40+
}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
41+
return (
42+
<AvatarPrimitive.Fallback
43+
data-slot="avatar-fallback"
44+
className={cn(
45+
"bg-muted flex size-full items-center justify-center rounded-full",
46+
className
47+
)}
48+
{...props}
49+
/>
50+
)
51+
}
52+
53+
export { Avatar, AvatarImage, AvatarFallback }

components/ui/badge.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const badgeVariants = cva(
1414
secondary:
1515
'border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90',
1616
destructive:
17-
'border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
17+
'border-transparent bg-destructive text-destructive-foreground [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
1818
outline:
1919
'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground',
2020
},

0 commit comments

Comments
 (0)