Skip to content

Commit 2fccb8a

Browse files
committed
✅ Table component
1 parent 7366940 commit 2fccb8a

File tree

18 files changed

+720
-20
lines changed

18 files changed

+720
-20
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@
66
],
77
"yaml.schemas": {
88
"https://json.schemastore.org/github-workflow.json": "file:///Users/arifhossain/Projects/ptm/retro-ui/.github/workflows/deploy.yml"
9-
}
9+
},
10+
"deno.enable": true
1011
}

app/(docs)/docs/[[...slug]]/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export default function page({ params }: IProps) {
4747
return (
4848
<div className="space-y-12 py-8">
4949
<div className="border-b border-black pb-6">
50-
<Text as="h1">{doc.title}</Text>
50+
<Text as="h1" className="text-4xl">{doc.title}</Text>
5151
<p className="text-lg text-muted-foreground mt-2">{doc.description}</p>
5252
{doc.links && (
5353
<div className="flex space-x-4 text-sm mt-4 text-black">

app/(sink)/demo/components/page.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ import {
1919
import { Card } from "@/components/retroui/Card";
2020
import BadgeStyleVariants from "@/preview/components/badge-style-variants";
2121
import TestimonialCard from "@/preview/components/card-style-testimonial";
22+
import { TableStyleDefault } from "@/preview/components/table-style-default";
23+
import { TableWithCheckbox } from "@/preview/components/table-with-checkbox";
24+
import { TableWithStickyHeader } from "@/preview/components/table-with-sticky-header";
2225
import { CheckCircle } from "lucide-react";
2326
import React from "react";
2427

@@ -148,6 +151,15 @@ export default function page() {
148151

149152
<TestimonialCard />
150153

154+
<div className="h-36"></div>
155+
<TableStyleDefault />
156+
157+
<div className="h-36"></div>
158+
<TableWithCheckbox />
159+
160+
<div className="h-36"></div>
161+
<TableWithStickyHeader />
162+
151163
<div className="h-36"></div>
152164
</div>
153165
);

app/global.css

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
--color-destructive: var(--destructive);
3131
--color-destructive-foreground: var(--destructive-foreground);
3232
--color-border: var(--border);
33-
3433
--background-image: var(--background-image);
3534
}
3635

@@ -74,6 +73,10 @@
7473
--background-image: url("/images/bg_void_3.svg"); /* Optional: A different image for dark mode */
7574
}
7675

76+
body {
77+
font-family: var(--font-sans);
78+
}
79+
7780
.bg-image {
7881
background-image: var(--background-image);
7982
background-size: cover;

app/layout.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,21 @@ import { Toaster } from "@/components/retroui";
66
import { Analytics } from "@vercel/analytics/next";
77
import { SpeedInsights } from "@vercel/speed-insights/next";
88

9-
const archivoBlack = Archivo_Black({
9+
const sans = Space_Grotesk({
1010
subsets: ["latin"],
1111
weight: "400",
12-
variable: "--font-head",
12+
variable: "--font-sans",
1313
display: "swap",
1414
});
1515

16-
const space = Space_Grotesk({
16+
const head = Archivo_Black({
1717
subsets: ["latin"],
1818
weight: "400",
19-
variable: "--font-sans",
19+
variable: "--font-head",
2020
display: "swap",
2121
});
2222

23-
const spaceMono = Space_Mono({
23+
const mono = Space_Mono({
2424
subsets: ["latin"],
2525
weight: "400",
2626
variable: "--font-mono",
@@ -70,7 +70,7 @@ export default function RootLayout({
7070
/>
7171
</head>
7272
<body
73-
className={`${space.className} ${archivoBlack.variable} ${space.variable} ${spaceMono.variable} bg-background text-foreground`}
73+
className={`${head.variable} ${sans.variable} ${mono.variable} bg-background text-foreground`}
7474
>
7575
<div className="relative z-40 pb-16">
7676
<TopNav />

components/MDX.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ const components = (type: "doc" | "blog") => ({
4141
<Text
4242
as="li"
4343
{...props}
44-
className="text-lg text-zinc-600 ml-4 lg:ml-8 mb-2"
44+
className="text-lg text-zinc-600 ml-4 lg:ml-8 mb-4"
4545
/>
4646
) : (
47-
<Text as="li" {...props} />
47+
<Text as="li" className="mb-2" {...props} />
4848
),
4949
img: (props: HTMLAttributes<HTMLImageElement>) => (
5050
<img className="mx-auto w-full max-w-[600px] my-8" {...props} />

components/retroui/Table.tsx

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import * as React from "react"
2+
3+
import { cn } from "@/lib/utils"
4+
5+
const Table = React.forwardRef<
6+
HTMLTableElement,
7+
React.HTMLAttributes<HTMLTableElement>
8+
>(({ className, ...props }, ref) => (
9+
// <div className="relative w-full overflow-auto border-2 shadow-lg">
10+
<table
11+
ref={ref}
12+
className={cn("w-full caption-bottom text-sm border-2 shadow-lg", className)}
13+
{...props}
14+
/>
15+
// </div>
16+
))
17+
Table.displayName = "Table"
18+
19+
const TableHeader = React.forwardRef<
20+
HTMLTableSectionElement,
21+
React.HTMLAttributes<HTMLTableSectionElement>
22+
>(({ className, ...props }, ref) => (
23+
<thead ref={ref} className={cn("[&_tr]:border-b bg-primary text-primary-foreground font-head", className)} {...props} />
24+
))
25+
TableHeader.displayName = "TableHeader"
26+
27+
const TableBody = React.forwardRef<
28+
HTMLTableSectionElement,
29+
React.HTMLAttributes<HTMLTableSectionElement>
30+
>(({ className, ...props }, ref) => (
31+
<tbody
32+
ref={ref}
33+
className={cn("[&_tr:last-child]:border-0", className)}
34+
{...props}
35+
/>
36+
))
37+
TableBody.displayName = "TableBody"
38+
39+
const TableFooter = React.forwardRef<
40+
HTMLTableSectionElement,
41+
React.HTMLAttributes<HTMLTableSectionElement>
42+
>(({ className, ...props }, ref) => (
43+
<tfoot
44+
ref={ref}
45+
className={cn(
46+
"border-t bg-accent font-medium [&>tr]:last:border-b-0",
47+
className
48+
)}
49+
{...props}
50+
/>
51+
))
52+
TableFooter.displayName = "TableFooter"
53+
54+
const TableRow = React.forwardRef<
55+
HTMLTableRowElement,
56+
React.HTMLAttributes<HTMLTableRowElement>
57+
>(({ className, ...props }, ref) => (
58+
<tr
59+
ref={ref}
60+
className={cn(
61+
"border-b transition-colors hover:bg-primary/50 hover:text-primary-foreground data-[state=selected]:bg-muted",
62+
className
63+
)}
64+
{...props}
65+
/>
66+
))
67+
TableRow.displayName = "TableRow"
68+
69+
const TableHead = React.forwardRef<
70+
HTMLTableCellElement,
71+
React.ThHTMLAttributes<HTMLTableCellElement>
72+
>(({ className, ...props }, ref) => (
73+
<th
74+
ref={ref}
75+
className={cn(
76+
"h-12 px-4 text-left align-middle font-medium text-primary-foreground [&:has([role=checkbox])]:pr-0",
77+
className
78+
)}
79+
{...props}
80+
/>
81+
))
82+
TableHead.displayName = "TableHead"
83+
84+
const TableCell = React.forwardRef<
85+
HTMLTableCellElement,
86+
React.TdHTMLAttributes<HTMLTableCellElement>
87+
>(({ className, ...props }, ref) => (
88+
<td
89+
ref={ref}
90+
className={cn("p-3 align-middle [&:has([role=checkbox])]:pr-0", className)}
91+
{...props}
92+
/>
93+
))
94+
TableCell.displayName = "TableCell"
95+
96+
const TableCaption = React.forwardRef<
97+
HTMLTableCaptionElement,
98+
React.HTMLAttributes<HTMLTableCaptionElement>
99+
>(({ className, ...props }, ref) => (
100+
<caption
101+
ref={ref}
102+
className={cn("my-2 text-sm text-muted-foreground", className)}
103+
{...props}
104+
/>
105+
))
106+
TableCaption.displayName = "TableCaption"
107+
108+
const TableObj = Object.assign(Table, {
109+
Header: TableHeader,
110+
Body: TableBody,
111+
Footer: TableFooter,
112+
Row: TableRow,
113+
Head: TableHead,
114+
Cell: TableCell,
115+
Caption: TableCaption,
116+
})
117+
118+
export {
119+
TableObj as Table,
120+
}

config/components.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { table } from "console";
12
import { lazy } from "react";
23

34
export const componentConfig: {
@@ -92,6 +93,10 @@ export const componentConfig: {
9293
name: "sonner",
9394
filePath: "components/retroui/Sonner.tsx",
9495
},
96+
table: {
97+
name: "table",
98+
filePath: "components/retroui/Table.tsx",
99+
},
95100
text: {
96101
name: "text",
97102
filePath: "components/retroui/Text.tsx",
@@ -333,6 +338,21 @@ export const componentConfig: {
333338
filePath: "preview/components/switch-style-disabled.tsx",
334339
preview: lazy(() => import("@/preview/components/switch-style-disabled")),
335340
},
341+
"table-style-default": {
342+
name: "table-style-default",
343+
filePath: "preview/components/table-style-default.tsx",
344+
preview: lazy(() => import("@/preview/components/table-style-default")),
345+
},
346+
"table-with-checkbox": {
347+
name: "table-with-checkbox",
348+
filePath: "preview/components/table-with-checkbox.tsx",
349+
preview: lazy(() => import("@/preview/components/table-with-checkbox")),
350+
},
351+
"table-with-sticky-header": {
352+
name: "table-with-sticky-header",
353+
filePath: "preview/components/table-with-sticky-header.tsx",
354+
preview: lazy(() => import("@/preview/components/table-with-sticky-header")),
355+
},
336356
"textarea-style-default": {
337357
name: "textarea-style-default",
338358
filePath: "preview/components/textarea-style-default.tsx",

config/navigation.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,10 @@ export const navConfig: INavigationConfig = {
1313
{
1414
title: "Getting Started",
1515
children: [
16-
{ title: "Introduction", href: "/docs", tag: "Updated" },
16+
{ title: "Introduction", href: "/docs" },
1717
{
1818
title: "Installation",
1919
href: "/docs/install",
20-
tag: "New",
2120
},
2221
],
2322
},
@@ -34,40 +33,36 @@ export const navConfig: INavigationConfig = {
3433
{ title: "Checkbox", href: `${componentsRoute}/checkbox` },
3534
{ title: "Dialog", href: `${componentsRoute}/dialog` },
3635
{ title: "Input", href: `${componentsRoute}/input` },
37-
{ title: "Label", href: `${componentsRoute}/label`, tag: "New" },
36+
{ title: "Label", href: `${componentsRoute}/label` },
3837
{ title: "Menu", href: `${componentsRoute}/menu` },
3938
{
4039
title: "Popover",
4140
href: `${componentsRoute}/popover`,
42-
tag: "New",
4341
},
4442
{ title: "Progress", href: `${componentsRoute}/progress` },
4543
{ title: "Radio", href: `${componentsRoute}/radio` },
4644
{ title: "Select", href: `${componentsRoute}/select` },
47-
{ title: "Slider", href: `${componentsRoute}/slider`, tag: "New" },
45+
{ title: "Slider", href: `${componentsRoute}/slider` },
4846
{
4947
title: "Sonner",
5048
href: `${componentsRoute}/sonner`,
51-
tag: "New",
5249
},
5350
{ title: "Switch", href: `${componentsRoute}/switch` },
5451
{ title: "Tab", href: `${componentsRoute}/tab` },
52+
{ title: "Table", href: `${componentsRoute}/table`, tag: "New" },
5553
{ title: "Textarea", href: `${componentsRoute}/textarea` },
5654
{ title: "Text", href: `${componentsRoute}/text` },
5755
{
5856
title: "Toggle",
5957
href: `${componentsRoute}/toggle`,
60-
tag: "New",
6158
},
6259
{
6360
title: "Toggle Group",
6461
href: `${componentsRoute}/toggle-group`,
65-
tag: "New",
6662
},
6763
{
6864
title: "Tooltip",
6965
href: `${componentsRoute}/tooltip`,
70-
tag: "New",
7166
},
7267
],
7368
},

content/docs/components/table.mdx

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
---
2+
title: Table
3+
description: Display your data in a structured tabular format.
4+
lastUpdated: 8 Jul, 2025
5+
links:
6+
source: https://github.com/Logging-Stuff/RetroUI/blob/main/components/retroui/Table.tsx
7+
---
8+
9+
<ComponentShowcase name="table-style-default" />
10+
<br />
11+
<br />
12+
13+
<ComponentInstall>
14+
<ComponentInstall.Cli npmCommand="npx shadcn@latest add 'https://retroui.dev/r/table.json'" />
15+
<ComponentInstall.Manual>
16+
#### 1. Install dependencies:
17+
18+
```sh
19+
npm install class-variance-authority
20+
```
21+
22+
<br />
23+
24+
#### 2. Copy the code 👇 into your project:
25+
26+
<ComponentSource name="table" />
27+
28+
</ComponentInstall.Manual>
29+
</ComponentInstall>
30+
31+
<br />
32+
<br />
33+
34+
## Examples
35+
36+
### Default
37+
38+
<ComponentShowcase name="table-style-default" />
39+
<br />
40+
<br />
41+
42+
### With Checkbox Selection
43+
44+
<ComponentShowcase name="table-with-checkbox" />
45+
<br />
46+
<br />
47+
48+
### With Sticky Header
49+
50+
<ComponentShowcase name="table-with-sticky-header" />
51+
<br />
52+
<br />
53+
54+
## API Reference
55+
56+
The Table component is composed of several sub-components:
57+
<br />
58+
59+
- `Table` - The main table wrapper
60+
- `Table.Header` - Table header section (`<thead>`)
61+
- `Table.Body` - Table body section (`<tbody>`)
62+
- `Table.Footer` - Table footer section (`<tfoot>`)
63+
- `Table.Row` - Table row (`<tr>`)
64+
- `Table.Head` - Table header cell (`<th>`)
65+
- `Table.Cell` - Table data cell (`<td>`)

0 commit comments

Comments
 (0)