Skip to content

Commit 4e030f6

Browse files
committed
feat(ui): add Card, Input, and Textarea components with styling and structure
1 parent 63ad211 commit 4e030f6

5 files changed

Lines changed: 133 additions & 3 deletions

File tree

src/components/home/home-tabs.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export default function HomeTabs() {
2929
alt="Java programming docs and tutorials interface preview"
3030
width={800}
3131
height={600}
32-
className="h-auto w-full rounded-xl sm:rounded-3xl shadow-lg"
32+
className="h-auto w-full rounded-xl shadow-lg sm:rounded-3xl"
3333
priority
3434
/>
3535
),
@@ -50,7 +50,7 @@ export default function HomeTabs() {
5050
alt="Java programs interface preview"
5151
width={800}
5252
height={600}
53-
className="h-auto w-full rounded-xl sm:rounded-3xl shadow-lg"
53+
className="h-auto w-full rounded-xl shadow-lg sm:rounded-3xl"
5454
/>
5555
),
5656
},

src/components/ui/accordion.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,3 @@ function AccordionContent({
6464
}
6565

6666
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };
67-

src/components/ui/card.tsx

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import * as React from "react";
2+
3+
import { cn } from "@/lib/utils";
4+
5+
function Card({ className, ...props }: React.ComponentProps<"div">) {
6+
return (
7+
<div
8+
data-slot="card"
9+
className={cn(
10+
"bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
11+
className,
12+
)}
13+
{...props}
14+
/>
15+
);
16+
}
17+
18+
function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
19+
return (
20+
<div
21+
data-slot="card-header"
22+
className={cn(
23+
"@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
24+
className,
25+
)}
26+
{...props}
27+
/>
28+
);
29+
}
30+
31+
function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
32+
return (
33+
<div
34+
data-slot="card-title"
35+
className={cn("leading-none font-semibold", className)}
36+
{...props}
37+
/>
38+
);
39+
}
40+
41+
function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
42+
return (
43+
<div
44+
data-slot="card-description"
45+
className={cn("text-muted-foreground text-sm", className)}
46+
{...props}
47+
/>
48+
);
49+
}
50+
51+
function CardAction({ className, ...props }: React.ComponentProps<"div">) {
52+
return (
53+
<div
54+
data-slot="card-action"
55+
className={cn(
56+
"col-start-2 row-span-2 row-start-1 self-start justify-self-end",
57+
className,
58+
)}
59+
{...props}
60+
/>
61+
);
62+
}
63+
64+
function CardContent({ className, ...props }: React.ComponentProps<"div">) {
65+
return (
66+
<div
67+
data-slot="card-content"
68+
className={cn("px-6", className)}
69+
{...props}
70+
/>
71+
);
72+
}
73+
74+
function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
75+
return (
76+
<div
77+
data-slot="card-footer"
78+
className={cn("flex items-center px-6 [.border-t]:pt-6", className)}
79+
{...props}
80+
/>
81+
);
82+
}
83+
84+
export {
85+
Card,
86+
CardHeader,
87+
CardFooter,
88+
CardTitle,
89+
CardAction,
90+
CardDescription,
91+
CardContent,
92+
};

src/components/ui/input.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import * as React from "react";
2+
3+
import { cn } from "@/lib/utils";
4+
5+
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
6+
return (
7+
<input
8+
type={type}
9+
data-slot="input"
10+
className={cn(
11+
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
12+
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
13+
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
14+
className,
15+
)}
16+
{...props}
17+
/>
18+
);
19+
}
20+
21+
export { Input };

src/components/ui/textarea.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import * as React from "react";
2+
3+
import { cn } from "@/lib/utils";
4+
5+
function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
6+
return (
7+
<textarea
8+
data-slot="textarea"
9+
className={cn(
10+
"border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
11+
className,
12+
)}
13+
{...props}
14+
/>
15+
);
16+
}
17+
18+
export { Textarea };

0 commit comments

Comments
 (0)