shadcn-ui-react 0.5.3 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -26
- package/bin/shadcn-ui-react.mjs +99 -0
- package/dist/index.cjs +296 -119
- package/dist/index.d.cts +146 -9
- package/dist/index.d.ts +146 -9
- package/dist/index.js +300 -121
- package/dist/style.css +535 -21
- package/package.json +10 -5
- package/templates/vscode-settings.json +11 -0
package/README.md
CHANGED
|
@@ -18,6 +18,16 @@ pnpm add shadcn-ui-react
|
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
+
### Tailwind IntelliSense (VS Code)
|
|
22
|
+
|
|
23
|
+
To enable Tailwind CSS IntelliSense to detect classes within `cn(...)` and other utilities:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npx shadcn-ui-react init-vscode
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
21
31
|
## 🚀 Getting Started
|
|
22
32
|
|
|
23
33
|
### 1. Import Global Styles
|
|
@@ -361,65 +371,113 @@ export default function UserAuthForm() {
|
|
|
361
371
|
### 📊 DataTable
|
|
362
372
|
|
|
363
373
|
```tsx
|
|
364
|
-
import React, { useState } from "react";
|
|
374
|
+
import React, { useMemo, useState } from "react";
|
|
375
|
+
import type { ColumnDef } from "@tanstack/react-table";
|
|
365
376
|
import { DataTable } from "shadcn-ui-react";
|
|
366
|
-
import { ColumnDef } from "@tanstack/react-table";
|
|
367
377
|
|
|
368
378
|
type User = {
|
|
369
379
|
id: number;
|
|
370
380
|
name: string;
|
|
371
381
|
email: string;
|
|
382
|
+
role: "Admin" | "Editor" | "Viewer";
|
|
372
383
|
};
|
|
373
384
|
|
|
374
385
|
const columns: ColumnDef<User, any>[] = [
|
|
375
386
|
{ accessorKey: "id", header: "ID" },
|
|
376
|
-
{
|
|
387
|
+
{
|
|
388
|
+
accessorKey: "name",
|
|
389
|
+
header: "Name",
|
|
390
|
+
cell: ({ row }) => (
|
|
391
|
+
<div className="flex items-center gap-2">
|
|
392
|
+
<div className="h-2 w-2 rounded-full bg-primary" />
|
|
393
|
+
<span className="font-medium">{row.original.name}</span>
|
|
394
|
+
</div>
|
|
395
|
+
),
|
|
396
|
+
},
|
|
377
397
|
{ accessorKey: "email", header: "Email" },
|
|
398
|
+
{
|
|
399
|
+
accessorKey: "role",
|
|
400
|
+
header: "Role",
|
|
401
|
+
cell: ({ row }) => (
|
|
402
|
+
<span className="inline-flex items-center rounded-full border px-2 py-0.5 text-xs">
|
|
403
|
+
{row.original.role}
|
|
404
|
+
</span>
|
|
405
|
+
),
|
|
406
|
+
},
|
|
378
407
|
];
|
|
379
408
|
|
|
380
409
|
const data: User[] = [
|
|
381
|
-
{ id: 1, name: "John Doe", email: "john@example.com" },
|
|
382
|
-
{ id: 2, name: "Jane Smith", email: "jane@example.com" },
|
|
383
|
-
{ id: 3, name: "Sam Johnson", email: "sam@example.com" },
|
|
384
|
-
{ id: 4, name: "Alice Brown", email: "alice@example.com" },
|
|
385
|
-
{ id: 5, name: "Bob White", email: "bob@example.com" },
|
|
386
|
-
{ id: 6, name: "Charlie Black", email: "charlie@example.com" },
|
|
387
|
-
{ id: 7, name: "Diana Green", email: "diana@example.com" },
|
|
388
|
-
{ id: 8, name: "Eve Blue", email: "eve@example.com" },
|
|
389
|
-
{ id: 9, name: "Frank Yellow", email: "frank@example.com" },
|
|
390
|
-
{ id: 10, name: "Grace Red", email: "grace@example.com" },
|
|
410
|
+
{ id: 1, name: "John Doe", email: "john@example.com", role: "Admin" },
|
|
411
|
+
{ id: 2, name: "Jane Smith", email: "jane@example.com", role: "Editor" },
|
|
412
|
+
{ id: 3, name: "Sam Johnson", email: "sam@example.com", role: "Viewer" },
|
|
413
|
+
{ id: 4, name: "Alice Brown", email: "alice@example.com", role: "Editor" },
|
|
414
|
+
{ id: 5, name: "Bob White", email: "bob@example.com", role: "Viewer" },
|
|
415
|
+
{ id: 6, name: "Charlie Black", email: "charlie@example.com", role: "Admin" },
|
|
416
|
+
{ id: 7, name: "Diana Green", email: "diana@example.com", role: "Viewer" },
|
|
417
|
+
{ id: 8, name: "Eve Blue", email: "eve@example.com", role: "Editor" },
|
|
418
|
+
{ id: 9, name: "Frank Yellow", email: "frank@example.com", role: "Viewer" },
|
|
419
|
+
{ id: 10, name: "Grace Red", email: "grace@example.com", role: "Admin" },
|
|
391
420
|
];
|
|
392
421
|
|
|
393
422
|
const Example = () => {
|
|
394
423
|
const [page, setPage] = useState(1);
|
|
395
424
|
const [perPage, setPerPage] = useState(5);
|
|
396
425
|
|
|
397
|
-
const
|
|
426
|
+
const pageCount = useMemo(() => Math.ceil(data.length / perPage), [perPage]);
|
|
398
427
|
|
|
399
|
-
const
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
};
|
|
428
|
+
const paginatedData = useMemo(() => {
|
|
429
|
+
const start = (page - 1) * perPage;
|
|
430
|
+
const end = page * perPage;
|
|
431
|
+
return data.slice(start, end);
|
|
432
|
+
}, [page, perPage]);
|
|
405
433
|
|
|
406
434
|
return (
|
|
407
|
-
<div>
|
|
408
|
-
<
|
|
435
|
+
<div className="space-y-4">
|
|
436
|
+
<div className="space-y-1">
|
|
437
|
+
<h1 className="text-xl font-bold">DataTable v2</h1>
|
|
438
|
+
<p className="text-sm text-muted-foreground">
|
|
439
|
+
Manual pagination + templates + sticky header + accent
|
|
440
|
+
</p>
|
|
441
|
+
</div>
|
|
409
442
|
|
|
410
443
|
<DataTable
|
|
411
444
|
columns={columns}
|
|
412
445
|
data={paginatedData}
|
|
413
|
-
pageCount={
|
|
446
|
+
pageCount={pageCount}
|
|
414
447
|
page={page}
|
|
415
448
|
perPage={perPage}
|
|
416
|
-
onPageChange={
|
|
417
|
-
onPageSizeChange={
|
|
449
|
+
onPageChange={setPage}
|
|
450
|
+
onPageSizeChange={(size) => {
|
|
451
|
+
setPerPage(size);
|
|
452
|
+
setPage(1);
|
|
453
|
+
}}
|
|
454
|
+
totalRows={data.length}
|
|
455
|
+
isRowsSelected={false}
|
|
418
456
|
rowPerPageLabel="Rows per page"
|
|
419
457
|
pageLabel="Page"
|
|
420
458
|
ofLabel="of"
|
|
421
459
|
rowsSelectedLabel="rows selected"
|
|
422
|
-
emptyData={<div>No data available</div>}
|
|
460
|
+
emptyData={<div className="py-10 text-center">No data available</div>}
|
|
461
|
+
|
|
462
|
+
// ✨ NEW (v0.6.6)
|
|
463
|
+
template="neo" // neo | glass | compact | minimal | clean | elevated | grid | cards
|
|
464
|
+
accent="primary" // primary | emerald | indigo | rose | amber | zinc
|
|
465
|
+
stickyHeader={true}
|
|
466
|
+
headerScroll={false}
|
|
467
|
+
animate={true}
|
|
468
|
+
heightClassName="h-[420px]" // Important: Define the height for the ScrollArea to work.
|
|
469
|
+
|
|
470
|
+
onClick={(row) => {
|
|
471
|
+
// demo: click in row
|
|
472
|
+
console.log("Row clicked:", row);
|
|
473
|
+
}}
|
|
474
|
+
|
|
475
|
+
// optional
|
|
476
|
+
classNames={{
|
|
477
|
+
// root: "border-primary/20",
|
|
478
|
+
// th: "text-[10px]",
|
|
479
|
+
// td: "py-2",
|
|
480
|
+
}}
|
|
423
481
|
/>
|
|
424
482
|
</div>
|
|
425
483
|
);
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = path.dirname(__filename);
|
|
8
|
+
|
|
9
|
+
const cmd = process.argv[2];
|
|
10
|
+
|
|
11
|
+
const uniq = (arr) => {
|
|
12
|
+
const seen = new Set();
|
|
13
|
+
const out = [];
|
|
14
|
+
for (const item of arr) {
|
|
15
|
+
const key = JSON.stringify(item);
|
|
16
|
+
if (seen.has(key)) continue;
|
|
17
|
+
seen.add(key);
|
|
18
|
+
out.push(item);
|
|
19
|
+
}
|
|
20
|
+
return out;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
function ensureDir(dir) {
|
|
24
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function readJson(p) {
|
|
28
|
+
if (!fs.existsSync(p)) return null;
|
|
29
|
+
try {
|
|
30
|
+
return JSON.parse(fs.readFileSync(p, "utf8"));
|
|
31
|
+
} catch (e) {
|
|
32
|
+
console.error(`❌ No pude leer JSON: ${p}`);
|
|
33
|
+
console.error(e?.message ?? e);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function writeJson(p, obj) {
|
|
39
|
+
fs.writeFileSync(p, JSON.stringify(obj, null, 2) + "\n", "utf8");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function initVscode() {
|
|
43
|
+
const tplPath = path.join(__dirname, "..", "templates", "vscode-settings.json");
|
|
44
|
+
const tpl = readJson(tplPath) ?? {};
|
|
45
|
+
|
|
46
|
+
const vscodeDir = path.join(process.cwd(), ".vscode");
|
|
47
|
+
const settingsPath = path.join(vscodeDir, "settings.json");
|
|
48
|
+
|
|
49
|
+
ensureDir(vscodeDir);
|
|
50
|
+
|
|
51
|
+
const current = readJson(settingsPath) ?? {};
|
|
52
|
+
const next = { ...current };
|
|
53
|
+
|
|
54
|
+
// classRegex (merge + dedupe)
|
|
55
|
+
const curRegex = current["tailwindCSS.experimental.classRegex"] ?? [];
|
|
56
|
+
const tplRegex = tpl["tailwindCSS.experimental.classRegex"] ?? [];
|
|
57
|
+
next["tailwindCSS.experimental.classRegex"] = uniq([
|
|
58
|
+
...(Array.isArray(curRegex) ? curRegex : []),
|
|
59
|
+
...(Array.isArray(tplRegex) ? tplRegex : [])
|
|
60
|
+
]);
|
|
61
|
+
|
|
62
|
+
// includeLanguages (merge)
|
|
63
|
+
const curLang = current["tailwindCSS.includeLanguages"] ?? {};
|
|
64
|
+
const tplLang = tpl["tailwindCSS.includeLanguages"] ?? {};
|
|
65
|
+
next["tailwindCSS.includeLanguages"] = { ...(curLang || {}), ...(tplLang || {}) };
|
|
66
|
+
|
|
67
|
+
writeJson(settingsPath, next);
|
|
68
|
+
console.log("✅ Listo: actualizado .vscode/settings.json (Tailwind IntelliSense).");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function initExtensions() {
|
|
72
|
+
const vscodeDir = path.join(process.cwd(), ".vscode");
|
|
73
|
+
const extPath = path.join(vscodeDir, "extensions.json");
|
|
74
|
+
ensureDir(vscodeDir);
|
|
75
|
+
|
|
76
|
+
const current = readJson(extPath) ?? {};
|
|
77
|
+
const recs = Array.isArray(current.recommendations) ? current.recommendations : [];
|
|
78
|
+
const add = "bradlc.vscode-tailwindcss";
|
|
79
|
+
|
|
80
|
+
const next = {
|
|
81
|
+
...current,
|
|
82
|
+
recommendations: Array.from(new Set([...recs, add]))
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
writeJson(extPath, next);
|
|
86
|
+
console.log("✅ Listo: actualizado .vscode/extensions.json (recomendación Tailwind CSS).");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
switch (cmd) {
|
|
90
|
+
case "init-vscode":
|
|
91
|
+
initVscode();
|
|
92
|
+
initExtensions();
|
|
93
|
+
break;
|
|
94
|
+
default:
|
|
95
|
+
console.log(`Uso:
|
|
96
|
+
npx shadcn-ui-react init-vscode
|
|
97
|
+
`);
|
|
98
|
+
process.exit(cmd ? 1 : 0);
|
|
99
|
+
}
|